/* ═══════════════════════════════════════════════════════════════════════════
   css/trochoi.css — [TRÒ CHƠI GĐ1]
   ───────────────────────────────────────────────────────────────────────────
   Trang TỐI ở cả 2 giao diện (cùng lựa chọn với phong-than.html): sân chơi là
   không gian vũ trụ, đảo sang nền sáng là hỏng toàn bộ tương phản của chữ rơi.

   ⚠️ RULE CỨNG S178 — canh TRỤC CHIỀU CAO. Toàn dự án có 234 @media thì 182
   canh chiều RỘNG, chỉ 3 canh chiều CAO; lỗi luôn nằm ở trục không ai canh gác.
   Máy học viên hay là laptop 1366×768 có thanh bookmark (~600px thật) hoặc
   1920×1080 ở mức phóng to 150%. Vì vậy: dùng svh, KHÔNG khoá cứng chiều cao,
   và sân chơi có SÀN để không bị bóp thành khe hẹp.
   ═══════════════════════════════════════════════════════════════════════════ */

:root {
  --tc-nen:      #070512;
  --tc-nen2:     #0d0a22;
  --tc-vien:     rgba(126, 232, 255, 0.22);
  --tc-lam:      #7ee8ff;
  --tc-vang:     #ffd54f;
  --tc-hong:     #ff4081;
  --tc-luc:      #6ee7a8;
  --tc-tim:      #c792ff;        /* chế độ Nhớ Nghĩa — thêm 2026-09-03 */
  --tc-chu:      #e8ecff;
  --tc-chu-mo:   #8b93b8;
  --tc-the-nen:  rgba(16, 22, 52, 0.86);
}

html, body {
  margin: 0; padding: 0;
  background: var(--tc-nen);
  color: var(--tc-chu);
  font-family: 'Be Vietnam Pro', 'Segoe UI', system-ui, -apple-system, sans-serif;
  overflow: hidden;
}

.tc-boc {
  display: flex;
  flex-direction: column;
  height: 100vh;
  height: 100svh;          /* svh: trừ đúng thanh công cụ trình duyệt di động */
  min-height: 420px;       /* SÀN — dưới mức này thì cuộn, không bóp nát sân */
  box-sizing: border-box;
  padding: 10px 12px 12px;
  gap: 8px;
}

/* ── Thanh trên: tên + HUD ─────────────────────────────────────────────── */
.tc-dau {
  display: flex; align-items: center; gap: 12px;
  flex: 0 0 auto;                 /* khối ĐIỀU KHIỂN — cấm nén, nén là giấu nút */
  min-height: min-content;
}
.tc-ten { display: flex; align-items: center; gap: 9px; font-weight: 700; }
.tc-ten .bieu { font-size: 1.25rem; }
.tc-ten .chu  { font-size: clamp(0.92rem, min(1.6vw, 2.2svh), 1.12rem); letter-spacing: .2px; }
.tc-ten .phu  { font-size: .72rem; color: var(--tc-chu-mo); font-weight: 500; }

#tc-hud { display: flex; align-items: center; gap: 14px; margin-left: auto; flex-wrap: wrap; }
/* ⚠️ RULE S125 — BẮT BUỘC. `display:flex` vô điều kiện có ĐỘ ƯU TIÊN NGANG với
   `[hidden]{display:none}` của trình duyệt, mà rule của tác giả đứng sau nên
   THẮNG ⇒ đặt el.hidden=true mà HUD vẫn hiện. Bắt được lỗi này bằng cách NHÌN
   ẢNH màn kết thúc (HUD còn nguyên trên đó), máy đo hoàn toàn không thấy. */
#tc-hud[hidden] { display: none !important; }
.tc-o {
  display: flex; align-items: baseline; gap: 6px;
  background: rgba(255,255,255,.05);
  border: 1px solid var(--tc-vien);
  border-radius: 9px; padding: 4px 10px;
  white-space: nowrap;                 /* rule S151: nút/chip trong hàng flex */
  flex-shrink: 0;
}
.tc-o .nhan { font-size: .66rem; color: var(--tc-chu-mo); text-transform: uppercase; letter-spacing: .5px; }
.tc-o .so   { font-size: .98rem; font-weight: 700; font-variant-numeric: tabular-nums; }
#tc-diem { color: var(--tc-vang); }
#tc-mang { font-size: .95rem; letter-spacing: 2px; }
#tc-chuoi { color: #ff9f43; font-weight: 700; font-size: .9rem; }
/* Chuỗi dưới 3 thì KHÔNG hiện ô — ô rỗng nhìn như giao diện hỏng.
   :has() không dùng được ở đây vì phải chạy cả trên trình duyệt cũ, nên
   tầng giao diện tự bật/tắt bằng thuộc tính hidden (đã có rule [hidden]). */
#tc-o-chuoi[hidden] { display: none !important; }

.tc-nut-nho {
  background: rgba(255,255,255,.06); color: var(--tc-chu);
  border: 1px solid var(--tc-vien); border-radius: 9px;
  padding: 5px 11px; cursor: pointer; font-size: .82rem; white-space: nowrap;
}
.tc-nut-nho:hover { background: rgba(126,232,255,.14); }

/* ── Sân chơi ──────────────────────────────────────────────────────────── */
#tc-san {
  position: relative;
  flex: 1 1 auto;
  min-height: 260px;              /* SÀN đo từ nội dung: đủ chỗ cho 1 thẻ rơi */
  border-radius: 14px;
  overflow: hidden;
  background:
    radial-gradient(120% 80% at 50% 0%, #16123a 0%, var(--tc-nen2) 45%, var(--tc-nen) 100%);
  border: 1px solid var(--tc-vien);
  isolation: isolate;
}
#tc-canvas { position: absolute; inset: 0; display: block; }
#tc-lop-the { position: absolute; inset: 0; pointer-events: none; }

@keyframes tcRung {
  0%,100% { transform: translateX(0); }
  20% { transform: translateX(-6px); } 40% { transform: translateX(5px); }
  60% { transform: translateX(-3px); } 80% { transform: translateX(2px); }
}
#tc-san.rung { animation: tcRung .22s ease; }

/* ── Thẻ từ rơi ────────────────────────────────────────────────────────── */
.tc-the {
  position: absolute; top: 0; left: 0;
  text-align: center;
  padding: 7px 13px;
  border-radius: 11px;
  background: var(--tc-the-nen);
  border: 1px solid rgba(255,255,255,.10);
  backdrop-filter: blur(2px);
  will-change: transform;
  transition: border-color .12s, box-shadow .12s, opacity .2s, scale .2s;
}
.tc-the .tc-han {
  font-size: clamp(1.5rem, min(2.6vw, 4.2svh), 2.15rem);
  font-weight: 700; line-height: 1.16;
  font-family: 'Noto Sans SC', 'Microsoft YaHei', 'PingFang SC', sans-serif;
}
.tc-the .tc-py { font-size: .84rem; color: var(--tc-chu-mo); margin-top: 1px; letter-spacing: .4px; }
.tc-the .tc-py.tc-go { font-family: 'Consolas', ui-monospace, monospace; letter-spacing: 1.5px; font-size: .92rem; }
.tc-the .tc-py.tc-go b { color: var(--tc-luc); }
.tc-the .tc-py.tc-go i { color: var(--tc-chu-mo); font-style: normal; opacity: .62; }

.tc-the.khoa {
  border-color: var(--tc-lam);
  box-shadow: 0 0 0 1px var(--tc-lam), 0 0 22px rgba(126,232,255,.42);
}
.tc-the.nguy .tc-han { color: #ff8fa8; }
.tc-the.nguy { border-color: rgba(255,64,129,.55); }
.tc-the.bay-mat { opacity: 0; scale: 1.35; }

/* ── [GĐ3] Thẻ của Nhớ Nghĩa & Luyện Nghe ──────────────────────────────── */
/* Hai chế độ này KHÔNG được để lộ chữ Hán/pinyin trên thẻ — đề bài là NGHĨA
   hoặc là TIẾNG. Nếu lộ thì cả hai thành Bắn Chữ đội lốt. */
.tc-the .tc-han.de-nghia {
  font-size: clamp(.82rem, min(1.15vw, 2svh), .98rem);
  font-weight: 600; line-height: 1.3;
  font-family: inherit;                 /* nghĩa tiếng Việt — KHÔNG dùng phông Hán */
  color: var(--tc-chu);
  /* Nghĩa dài (đo thật: tới 90 ký tự) phải xuống dòng trong khung hẹp, nếu
     không thẻ kéo ngang hết sân và đè lên nhau. Kẹp 3 dòng rồi cắt gọn. */
  max-width: 15rem; white-space: normal;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3;
  overflow: hidden;
}
.tc-the .tc-han.de-loa { font-size: 1.6rem; line-height: 1.1; font-family: inherit; }
.tc-the .tc-han.de-loi {
  font-family: inherit; display: flex; align-items: center; gap: 7px;
  justify-content: center; font-size: 1.05rem;
}
/* Tiếng hỏng → hiện pinyin để thẻ VẪN chơi được. Tô vàng cho thấy rõ đây là
   trạng thái bất thường, không phải luật chơi. */
.tc-the .tc-han.de-loi .py-cuu { font-size: .92rem; color: var(--tc-vang); font-weight: 600; }

/* ⚠️ PHẢI viết lại màu báo nguy cho 3 dạng thẻ mới. Rule cũ `.tc-the.nguy
   .tc-han` có CÙNG độ ưu tiên (3 lớp) với `.tc-the .tc-han.de-nghia`, mà rule
   mới nằm SAU nên nó thắng ⇒ thẻ sắp chạm đáy chỉ đổi VIỀN, chữ vẫn trắng.
   Đo thật lúc đó: viền rgba(255,64,129,.55) nhưng chữ rgb(232,236,255).
   Mất một nửa tín hiệu báo nguy mà không có lỗi nào — chỉ nhìn ẢNH mới thấy. */
.tc-the.nguy .tc-han.de-nghia,
.tc-the.nguy .tc-han.de-loa,
.tc-the.nguy .tc-han.de-loi { color: #ff8fa8; }
/* Ô chữ cũng nhuốm đỏ theo — người chơi nhìn xuống ô là biết sắp mất mạng. */
.tc-the.nguy .tc-py.tc-o-day .o { border-bottom-color: rgba(255,143,168,.45); }

/* ── Dãy Ô CHỮ TRỐNG ───────────────────────────────────────────────────── */
/* Số ô = độ dài đáp án. Chính nó gỡ gần hết nhập nhằng "hai từ cùng nghĩa"
   (chang 5 ô ≠ changge 7 ô) — xem tools/build_game_pool.js. */
.tc-py.tc-o-day {
  display: flex; flex-wrap: wrap; gap: 3px; justify-content: center;
  margin-top: 5px; letter-spacing: 0;
  max-width: 15rem;                     /* thành ngữ 18 ô phải xuống hàng được */
}
.tc-py.tc-o-day .o {
  width: 1.02em; height: 1.42em; line-height: 1.42em;
  font-family: Consolas, ui-monospace, monospace;
  font-size: .95rem; text-align: center;
  border-bottom: 2px solid rgba(255,255,255,.22);
  color: transparent;
}
.tc-py.tc-o-day .o.da  { color: var(--tc-luc); border-bottom-color: var(--tc-luc); }
/* Gợi ý tô KHÁC MÀU chữ đã gõ: người chơi phải nhìn ra ngay đâu là phần mình
   tự làm được, đâu là phần máy hiện hộ. */
.tc-py.tc-o-day .o.goi { color: var(--tc-vang); opacity: .78; border-bottom-color: rgba(255,213,79,.5); }

/* ── Bắn hạ: hiện mặt chữ + phiên âm + nghĩa rồi mới bay đi ──────────────── */
/* Đây là chỗ HỌC thật sự của trò chơi: đúng lúc người chơi vừa nhớ ra từ thì
   cho xem đáp án đầy đủ. Ở Nhớ Nghĩa / Luyện Nghe, không có khối này thì bắn
   trúng xong vẫn không biết mình vừa bắn chữ nào. */
.tc-thuong {
  position: absolute; top: 0; left: 0;
  translate: -50% -100%;
  padding: 6px 12px 7px; border-radius: 10px;
  background: rgba(10, 16, 40, .92);
  border: 1px solid rgba(110, 231, 168, .45);
  box-shadow: 0 0 18px rgba(110, 231, 168, .22);
  text-align: center; pointer-events: none; white-space: nowrap;
  animation: tcThuong 1.5s cubic-bezier(.15, .7, .3, 1) forwards;
}
.tc-thuong .d {
  font-size: 1.12rem; font-weight: 700; line-height: 1.2;
  font-family: 'Noto Sans SC', 'Microsoft YaHei', 'PingFang SC', sans-serif;
  color: var(--tc-chu);
}
.tc-thuong .py {
  font-family: 'Be Vietnam Pro', system-ui, sans-serif;
  font-size: .82rem; font-weight: 600; color: var(--tc-lam); margin-left: 7px;
}
.tc-thuong .dm {
  font-family: 'Be Vietnam Pro', system-ui, sans-serif;
  font-size: .82rem; font-weight: 800; color: var(--tc-vang); margin-left: 8px;
  text-shadow: 0 0 10px rgba(255,213,79,.55);
}
/* Nghĩa có thể dài (đo thật: tới 90 ký tự) — cắt gọn một dòng, đây là phần
   thưởng chớp nhoáng chứ không phải chỗ đọc kỹ. */
.tc-thuong .ng {
  font-size: .8rem; color: var(--tc-luc); margin-top: 2px;
  max-width: 250px; overflow: hidden; text-overflow: ellipsis;
}
@keyframes tcThuong {
  0%   { opacity: 0; transform: translateY(6px) scale(.92); }
  12%  { opacity: 1; transform: translateY(0) scale(1); }
  70%  { opacity: 1; transform: translateY(-26px) scale(1); }
  100% { opacity: 0; transform: translateY(-46px) scale(.97); }
}

.tc-diem-bay {
  position: absolute; top: 0; left: 0;
  color: var(--tc-vang); font-weight: 800; font-size: 1.02rem;
  text-shadow: 0 0 12px rgba(255,213,79,.65);
  animation: tcBay .9s ease-out forwards; pointer-events: none;
}
@keyframes tcBay {
  0%   { opacity: 0; translate: -50% -50%; }
  18%  { opacity: 1; }
  100% { opacity: 0; translate: -50% -190%; }
}

/* Phi thuyền — ảnh GIF động nên PHẢI là DOM, canvas chỉ vẽ được khung đầu */
#tc-thuyen {
  position: absolute; left: 50%; bottom: 6px;
  width: 76px; transform: translateX(-50%);
  /* Xoay quanh ĐUÔI tàu, không quanh tâm: quanh tâm thì mũi tàu vừa quay vừa
     trượt ngang, nhìn như bị kéo lê. Quanh đuôi mới ra động tác "chĩa nòng". */
  transform-origin: 50% 88%;
  filter: drop-shadow(0 0 14px rgba(126,232,255,.5));
  pointer-events: none; user-select: none;
}

/* Bảng chữ lớn giữa sân (qua màn / lộ đáp án khi trượt) */
#tc-bang-chu {
  position: absolute; left: 50%; top: 34%;
  translate: -50% -50%;
  text-align: center; pointer-events: none; opacity: 0;
}
#tc-bang-chu.hien { animation: tcHienChu 1.7s ease-out forwards; }
@keyframes tcHienChu {
  0% { opacity: 0; scale: .82; } 14% { opacity: 1; scale: 1; }
  70% { opacity: 1; } 100% { opacity: 0; scale: 1.04; }
}
#tc-bang-chu .l1 { font-size: 2rem; font-weight: 800; color: var(--tc-vang); text-shadow: 0 0 26px rgba(255,213,79,.5); }
#tc-bang-chu .l2 { font-size: .95rem; color: var(--tc-chu); margin-top: 4px; }

/* ── Lớp phủ: menu / tạm dừng / kết thúc ───────────────────────────────── */
.tc-phu {
  position: absolute; inset: 0; z-index: 5;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 14px; padding: 18px;
  background: rgba(7,5,18,.90);
  overflow-y: auto;                    /* VAN XẢ — màn thấp thì cuộn, không nuốt */
  overscroll-behavior: contain;
}
.tc-phu[hidden] { display: none !important; }   /* rule S125: [hidden] cần tường minh */
.tc-phu h2 { margin: 0; font-size: clamp(1.15rem, min(2.4vw, 3.4svh), 1.6rem); }
.tc-phu .mo { color: var(--tc-chu-mo); font-size: .86rem; margin: 0; text-align: center; max-width: 540px; }

/* ═══════════════════════════════════════════════════════════════════════════
   BA THẺ CHỌN CHẾ ĐỘ  [Founder 2026-09-03: "căn cho ngay ngắn, đổ thêm màu"]
   ───────────────────────────────────────────────────────────────────────────
   · NGAY NGẮN: `align-items: stretch` cho ba thẻ cao bằng nhau, rồi trong mỗi
     thẻ để phần MÔ TẢ nuốt chỗ thừa (`flex: 1 1 auto`) — nhờ vậy dòng trạng
     thái luôn dính đáy và ba dòng đó thẳng hàng nhau, dù mô tả dài ngắn khác
     nhau. Ép chiều cao cứng thì mô tả dài bị cắt; đó là cách sai.
   · MÀU: mỗi chế độ một màu riêng qua biến `--mau`, dùng lại cho viền, nền,
     biểu tượng, tên và dòng trạng thái ⇒ đổi một chỗ là cả thẻ đổi theo.
   ═══════════════════════════════════════════════════════════════════════════ */
.tc-the-chon {
  display: flex; gap: 12px; flex-wrap: wrap;
  justify-content: center; align-items: stretch;
}
.tc-nut-cd {
  --mau: var(--tc-lam);                     /* đường lui nếu thiếu data-che-do */
  width: 190px; padding: 15px 13px; cursor: pointer; text-align: left;
  display: flex; flex-direction: column;    /* để .mt nuốt được chỗ thừa */
  /* ⚠️ color-mix() cần Chrome 111+. Khai báo DỰ PHÒNG phải đứng TRƯỚC: trình
     duyệt cũ bỏ qua dòng nó không hiểu và giữ dòng trên, nên thẻ vẫn có nền và
     viền tử tế thay vì trơ khung. */
  background: linear-gradient(160deg, rgba(126,232,255,.13), rgba(255,255,255,.03));
  background:
    radial-gradient(120% 90% at 50% 0%,
      color-mix(in srgb, var(--mau) 22%, transparent) 0%, transparent 62%),
    linear-gradient(160deg, rgba(255,255,255,.05), rgba(255,255,255,.02));
  border: 1px solid var(--tc-vien);
  border-color: color-mix(in srgb, var(--mau) 38%, transparent);
  border-radius: 13px; color: var(--tc-chu);
  font-family: inherit;
  transition: transform .12s, border-color .12s, box-shadow .12s;
}
.tc-nut-cd[data-che-do="ban"]   { --mau: var(--tc-lam); }
.tc-nut-cd[data-che-do="nghia"] { --mau: var(--tc-tim); }
.tc-nut-cd[data-che-do="nghe"]  { --mau: var(--tc-luc); }
.tc-nut-cd:hover:not(:disabled) {
  transform: translateY(-3px);
  border-color: var(--mau);
  box-shadow: 0 6px 20px -8px color-mix(in srgb, var(--mau) 60%, transparent);
}
.tc-nut-cd:disabled { opacity: .38; cursor: not-allowed; }
.tc-nut-cd .bt {
  font-size: 1.5rem; line-height: 1;
  filter: drop-shadow(0 0 10px color-mix(in srgb, var(--mau) 55%, transparent));
}
.tc-nut-cd .tn { font-weight: 700; margin-top: 6px; font-size: 1rem; color: var(--mau); }
.tc-nut-cd .mt {
  font-size: .76rem; color: var(--tc-chu-mo); margin-top: 4px; line-height: 1.4;
  flex: 1 1 auto;                           /* nuốt chỗ thừa ⇒ dòng dưới dính đáy */
}
.tc-nut-cd .sap { font-size: .68rem; color: var(--tc-vang); margin-top: 6px; }
.tc-nut-cd .kho {
  font-size: .68rem; margin-top: 7px; padding-top: 5px;
  color: var(--mau);                        /* dự phòng cho trình duyệt cũ */
  color: color-mix(in srgb, var(--mau) 88%, #fff);
  border-top: 1px solid var(--tc-vien);
  border-top-color: color-mix(in srgb, var(--mau) 26%, transparent);
}

.tc-nut-to {
  background: linear-gradient(135deg, var(--tc-lam), #4aa8ff);
  color: #04121c; border: 0; border-radius: 11px; cursor: pointer;
  padding: 10px 26px; font-size: .96rem; font-weight: 800; font-family: inherit;
  white-space: nowrap;
}
.tc-nut-to.phu2 { background: rgba(255,255,255,.08); color: var(--tc-chu); border: 1px solid var(--tc-vien); }
.tc-hang-nut { display: flex; gap: 10px; flex-wrap: wrap; justify-content: center; }

/* ── Màn TỪ ĐÃ TRƯỢT [GĐ5] ─────────────────────────────────────────────── */
#tc-ds-truot {
  width: min(700px, 88vw); text-align: left;
  /* Lịch sử có thể tới 300 từ — bắt buộc cuộn, và thanh cuộn phải NHÌN THẤY
     được (rule S178: van xả vô hình coi như không có van). */
  max-height: min(44svh, 330px); overflow-y: auto; overscroll-behavior: contain;
  padding-right: 4px; margin: 6px 0 4px;
  display: flex; flex-direction: column; gap: 4px;
}
#tc-ds-truot::-webkit-scrollbar { width: 8px; }
#tc-ds-truot::-webkit-scrollbar-thumb { background: rgba(126,232,255,.28); border-radius: 4px; }

.tc-truot-hang {
  display: flex; align-items: center; gap: 9px;
  padding: 7px 10px; border-radius: 9px; cursor: pointer;
  border: 1px solid var(--tc-vien);
  background: rgba(255,255,255,.025);
}
.tc-truot-hang:hover { border-color: var(--tc-lam); background: rgba(126,232,255,.07); }
.tc-truot-hang input { accent-color: var(--tc-luc); width: 16px; height: 16px; flex-shrink: 0; }
.tc-truot-hang .han {
  font-family: 'Noto Sans SC', 'Microsoft YaHei', 'PingFang SC', sans-serif;
  font-size: 1.05rem; font-weight: 700; flex-shrink: 0; min-width: 3.4em;
}
.tc-truot-hang .py { font-size: .8rem; color: var(--tc-lam); flex-shrink: 0; min-width: 5.5em; }
/* Nghĩa dài thì cắt gọn MỘT dòng — hàng cao thấp khác nhau nhìn rất rối khi
   có mấy chục hàng xếp dọc. */
.tc-truot-hang .ng {
  font-size: .82rem; color: var(--tc-chu-mo); flex: 1;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* Trượt nhiều lần = tín hiệu mạnh nhất cho biết cần học — tô nổi hẳn lên. */
.tc-truot-hang .lan {
  font-size: .68rem; color: var(--tc-hong); font-weight: 700; flex-shrink: 0;
  border: 1px solid rgba(255,64,129,.4); border-radius: 20px; padding: 1px 8px;
}

#tc-nut-luu-truot.xong, #tc-nut-truot-luu.xong {
  border-color: var(--tc-luc); color: var(--tc-luc); pointer-events: none;
}
.tc-nut-nho.chinh { border-color: var(--tc-luc); color: var(--tc-luc); }
.tc-nut-nho:disabled, .tc-nut-to:disabled { opacity: .45; cursor: not-allowed; }

/* ── Màn chọn tiếng súng [GĐ3b] ────────────────────────────────────────── */
#tc-ds-am {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(238px, 1fr));
  gap: 9px; width: min(760px, 88vw);
  /* Sáu mẫu trên màn thấp (1366×768 có bookmark bar) là phải cuộn — cho cuộn
     hẳn kèm thanh cuộn NHÌN THẤY ĐƯỢC, đừng để trôi ra ngoài khung (rule S178). */
  max-height: min(46svh, 340px); overflow-y: auto; overscroll-behavior: contain;
  padding-right: 4px; margin: 4px 0 2px;
}
#tc-ds-am::-webkit-scrollbar { width: 8px; }
#tc-ds-am::-webkit-scrollbar-thumb { background: rgba(126,232,255,.28); border-radius: 4px; }
.tc-am-hang {
  border: 1px solid var(--tc-vien); border-radius: 11px;
  padding: 10px 12px; text-align: left;
  background: linear-gradient(160deg, rgba(126,232,255,.07), rgba(255,255,255,.02));
}
.tc-am-hang.chon { border-color: var(--tc-luc); background: rgba(110,231,168,.10); }
.tc-am-hang .tt { font-size: .93rem; display: flex; align-items: center; gap: 8px; }
.tc-am-hang .dau { font-size: .68rem; color: var(--tc-luc); font-weight: 700; }
.tc-am-hang .mt { font-size: .74rem; color: var(--tc-chu-mo); margin: 4px 0 8px; line-height: 1.42; }
.tc-am-hang .nut { display: flex; gap: 7px; flex-wrap: wrap; }
/* nowrap + không co: thiếu là nút bị bóp và chữ ngắt 2-3 dòng giữa nút (rule S151) */
.tc-am-hang .nut .tc-nut-nho { white-space: nowrap; flex-shrink: 0; }
.tc-am-hang .nut .chinh { border-color: var(--tc-luc); color: var(--tc-luc); }

.tc-am-luong {
  display: flex; align-items: center; gap: 10px;
  font-size: .8rem; color: var(--tc-chu-mo); margin-top: 6px;
}
.tc-am-luong input[type="range"] { width: 190px; accent-color: var(--tc-lam); }
#tc-vol-so { min-width: 42px; text-align: right; font-variant-numeric: tabular-nums; }

#tc-nut-am { margin-top: 4px; }

/* ── [GĐ2] Máy chủ: nhãn không-tính-hạng · kết quả chốt · mời chơi tiếp ── */
.tc-nhan-canh {
  background: rgba(255,159,67,.16); border: 1px solid rgba(255,159,67,.5);
  color: #ffcf9b; border-radius: 9px; padding: 4px 10px;
  font-size: .74rem; white-space: nowrap; flex-shrink: 0; cursor: help;
}
.tc-nhan-canh[hidden] { display: none !important; }

.tc-mchu {
  font-size: .88rem; color: var(--tc-chu-mo); text-align: center;
  min-height: 1.2em; padding: 6px 12px; border-radius: 9px;
}
.tc-mchu.cho    { opacity: .7; }
.tc-mchu.canh   { color: #ffcf9b; background: rgba(255,159,67,.12); }
.tc-mchu.ky-luc {
  color: #04121c; font-weight: 800; font-size: 1rem;
  background: linear-gradient(135deg, var(--tc-vang), #ffb300);
  box-shadow: 0 0 26px rgba(255,213,79,.45);
}

#tc-moi-tiep {
  background: rgba(126,232,255,.10); border: 1px solid rgba(126,232,255,.45);
  border-radius: 13px; padding: 14px 18px; text-align: center;
  display: flex; flex-direction: column; gap: 9px; align-items: center;
  max-width: min(520px, 92%);
}
#tc-moi-tiep[hidden] { display: none !important; }
#tc-moi-tiep .tt { font-weight: 700; font-size: 1rem; }
#tc-moi-tiep .tm { font-size: .84rem; color: var(--tc-chu-mo); }
#tc-moi-tiep b  { color: var(--tc-lam); }

/* ── Màn kết thúc ──────────────────────────────────────────────────────── */
.tc-so-lieu { display: flex; gap: 10px; flex-wrap: wrap; justify-content: center; }
.tc-so-lieu > div {
  background: rgba(255,255,255,.05); border: 1px solid var(--tc-vien);
  border-radius: 11px; padding: 9px 15px; text-align: center; min-width: 84px;
}
.tc-so-lieu .n { font-size: .66rem; color: var(--tc-chu-mo); text-transform: uppercase; letter-spacing: .5px; }
.tc-so-lieu .v { font-size: 1.25rem; font-weight: 800; font-variant-numeric: tabular-nums; }
.tc-so-lieu .v.vang { color: var(--tc-vang); }

#tc-kq-truot {
  width: min(560px, 92%);
  max-height: min(210px, 28svh);      /* trần theo CHIỀU CAO màn, không số cứng */
  overflow-y: auto; overscroll-behavior: contain;
  display: flex; flex-direction: column; gap: 5px;
  background: rgba(255,255,255,.03); border: 1px solid var(--tc-vien);
  border-radius: 11px; padding: 9px;
}
/* Van xả phải NHÌN THẤY ĐƯỢC — van vô hình coi như không có (rule S178) */
#tc-kq-truot::-webkit-scrollbar { width: 8px; }
#tc-kq-truot::-webkit-scrollbar-thumb { background: rgba(126,232,255,.3); border-radius: 4px; }

.tc-tu-truot { display: flex; align-items: baseline; gap: 9px; font-size: .84rem; }
.tc-tu-truot b { font-size: 1.05rem; min-width: 3.4em; font-family: 'Noto Sans SC', 'Microsoft YaHei', sans-serif; }
.tc-tu-truot .py { color: var(--tc-lam); min-width: 6.5em; }
.tc-tu-truot .ng { color: var(--tc-chu-mo); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tc-trong { color: var(--tc-luc); font-size: .88rem; text-align: center; padding: 8px; }

/* ── Cảnh báo bộ gõ tiếng Việt (rủi ro số 1 với người dùng Việt) ────────── */
#tc-canh-bao {
  position: absolute; left: 50%; bottom: 84px; translate: -50% 0; z-index: 6;
  background: rgba(255,159,67,.14); border: 1px solid rgba(255,159,67,.5);
  color: #ffcf9b; border-radius: 10px; padding: 8px 14px;
  font-size: .82rem; text-align: center; max-width: 88%;
}
#tc-canh-bao[hidden] { display: none !important; }

#tc-nhac-focus {
  position: absolute; left: 50%; top: 50%; translate: -50% -50%; z-index: 6;
  background: rgba(126,232,255,.14); border: 1px solid rgba(126,232,255,.55);
  color: #cdf3ff; border-radius: 11px; padding: 11px 18px;
  font-size: .92rem; text-align: center; max-width: 86%;
  animation: tcNhip 1.5s ease-in-out infinite;
}
#tc-nhac-focus[hidden] { display: none !important; }

/* Mẹo phím cách — góc dưới, không che sân. */
#tc-meo-nghe {
  position: absolute; right: 12px; bottom: 12px; z-index: 6;
  background: rgba(126,232,255,.10); border: 1px solid rgba(126,232,255,.32);
  color: #9fd8e8; border-radius: 8px; padding: 4px 10px;
  font-size: .74rem; pointer-events: none;
}
/* ⚠️ rule S125 — BẮT BUỘC tường minh: display của rule tác giả có cùng độ ưu
   tiên với [hidden] mặc định của trình duyệt, thiếu dòng này là phần tử "ẩn"
   vẫn hiện. */
#tc-meo-nghe[hidden] { display: none !important; }

#tc-nhac-am {
  position: absolute; left: 50%; bottom: 84px; translate: -50% 0; z-index: 6;
  background: rgba(255,213,79,.14); border: 1px solid rgba(255,213,79,.5);
  color: #ffe9a8; border-radius: 10px; padding: 8px 14px;
  font-size: .82rem; text-align: center; max-width: 88%;
}
#tc-nhac-am[hidden] { display: none !important; }
@keyframes tcNhip { 0%,100% { opacity: .75; } 50% { opacity: 1; } }
#tc-san:focus { outline: none; }
#tc-canh-bao b { color: #fff; }

#tc-nap, #tc-loi {
  position: absolute; inset: 0; z-index: 7;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 10px; background: rgba(7,5,18,.94); color: var(--tc-chu-mo); font-size: .9rem;
}
#tc-nap[hidden], #tc-loi[hidden] { display: none !important; }
@keyframes tcQuay { to { rotate: 360deg; } }
.tc-quay {
  width: 26px; height: 26px; border-radius: 50%;
  border: 3px solid rgba(126,232,255,.22); border-top-color: var(--tc-lam);
  animation: tcQuay .8s linear infinite;
}
#tc-loi-chi-tiet { color: #ff8fa8; font-size: .78rem; max-width: 80%; text-align: center; }

/* ── Màn hình cho điện thoại (bản đầu chỉ máy tính) ────────────────────── */
#tc-man-mobile { text-align: center; }
#tc-man-mobile .bt { font-size: 3rem; }

/* Màn RẤT thấp: thu gọn phần trang trí, giữ trọn sân chơi */
@media (max-height: 620px) {
  .tc-ten .phu { display: none; }
  #tc-thuyen { width: 60px; }
  #tc-bang-chu .l1 { font-size: 1.5rem; }
  .tc-nut-cd { width: 168px; padding: 12px 11px; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   [GĐ6] KHO PHI THUYỀN — túi đồ riêng, mua bằng Linh Thạch
   ═══════════════════════════════════════════════════════════════════════════ */
#tc-ds-kho {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(186px, 1fr));
  /* 4 chiếc PHẢI vừa MỘT hàng ở màn rộng: đo thật ra 3 cột (794px khung,
     ô 254px) nên chiếc thứ 4 rơi xuống hàng hai và phải cuộn dù còn thừa cả
     mảng chỗ ngang. 4x186 + 3x10 = 774 <= 900 ⇒ đủ 4 cột. */
  gap: 10px; width: min(900px, 92vw);
  /* Cùng lý do với #tc-ds-am: kho sẽ dài thêm mỗi lần Founder thêm phi thuyền,
     nên cho cuộn NGAY TỪ ĐẦU kèm thanh cuộn nhìn thấy được (rule S178) —
     đừng đợi tới lúc tràn mới đi sửa. */
  /* Trần chiều cao đo ngược từ chỗ PHI THUYỀN SÂN CHƠI đứng (đo thật: đỉnh
     tàu ở y=649 trên màn 756px). Trần cũ 386px đẩy nút Xong xuống 655 ⇒ nút
     ĐÈ LÊN phi thuyền — màn chọn tiếng súng không bị vì nó thấp hơn. */
  /* 6 phi thuyền = 2 hàng (504px). Trần theo svh chứ không số cứng: đặt cứng
     520px thì ở màn 600px nút Xong bị đẩy RA NGOÀI màn hình. */
  max-height: min(52svh, 520px); overflow-y: auto; overscroll-behavior: contain;
  padding-right: 4px; margin: 6px 0 2px;
}
#tc-ds-kho::-webkit-scrollbar { width: 8px; }
#tc-ds-kho::-webkit-scrollbar-thumb { background: rgba(126,232,255,.28); border-radius: 4px; }

.tc-thuyen-o {
  border: 1px solid var(--tc-vien); border-radius: 12px;
  padding: 10px; text-align: center;
  background: linear-gradient(160deg, rgba(126,232,255,.07), rgba(255,255,255,.02));
  display: flex; flex-direction: column; align-items: center; gap: 6px;
}
.tc-thuyen-o.dang { border-color: var(--tc-luc); background: rgba(110,231,168,.10); }
/* Chưa mua thì làm mờ ẢNH thôi, KHÔNG mờ cả ô — mờ cả ô là chữ giá cũng mờ
   theo, mà giá lại đúng là thứ người ta cần đọc rõ nhất ở đây. */
.tc-thuyen-o.chua .tc-thuyen-anh { opacity: .45; filter: grayscale(.65); }
.tc-thuyen-anh {
  /* 88px thay vì 104: với 6 phi thuyền thì hàng 2 bị cắt ngang giữa dòng mô tả,
     nhìn như hỏng. Thu lại vẫn đủ to để nhận ra từng chiếc. */
  width: 88px; height: 88px; object-fit: contain;
  filter: drop-shadow(0 4px 14px rgba(126,232,255,.25));
}
.tc-thuyen-o .tn { font-size: .9rem; font-weight: 700; }
.tc-thuyen-o .mt {
  font-size: .72rem; color: var(--tc-chu-mo); line-height: 1.4; min-height: 2.8em;
}
.tc-thuyen-o .gia { font-size: .82rem; font-weight: 700; color: #ffd76e; }
.tc-thuyen-o .dau { font-size: .72rem; color: var(--tc-luc); font-weight: 700; }
/* nowrap + không co — rule S151, giống hàng nút của màn chọn tiếng súng */
.tc-thuyen-o .tc-nut-nho { white-space: nowrap; flex-shrink: 0; }
.tc-thuyen-o .tc-nut-nho.chinh { border-color: var(--tc-luc); color: var(--tc-luc); }

.tc-kho-vi { font-size: .84rem; color: var(--tc-chu-mo); }
.tc-kho-vi b { color: #ffd76e; font-variant-numeric: tabular-nums; }
.tc-kho-loi {
  background: rgba(255,107,107,.14); border: 1px solid rgba(255,107,107,.45);
  color: #ffb3b3; border-radius: 10px; padding: 8px 12px;
  font-size: .8rem; max-width: min(640px, 88vw); line-height: 1.45;
}
/* Rule S125 — `[hidden]` mặc định THUA rule tác giả có display không điều kiện.
   Ba dòng này là bắt buộc, thiếu là hộp lỗi/ví hiện thường trực. */
.tc-kho-vi[hidden], .tc-kho-loi[hidden] { display: none !important; }
.tc-thuyen-o[hidden] { display: none !important; }
/* Rule S125 lần thứ 19 trong dự án: #tc-thuyen không có display không điều
   kiện nên [hidden] hiện đang ăn — nhưng viết tường minh để lần sau ai thêm
   một rule display cho nó thì túi đồ không âm thầm hỏng lại. */
#tc-thuyen[hidden] { display: none !important; }
/* ═══════════════════════════════════════════════════════════════════════════
   [GĐ6] VỤ NỔ KHI BẮN HẠ — dựng hoàn toàn bằng CSS, KHÔNG dùng ảnh nào
   ───────────────────────────────────────────────────────────────────────────
   Founder chốt 2026-09-02: mọi ảnh trong images/trochoi/ đều là PHI THUYỀN
   (kể cả khối lửa và Thần Tài), nên vụ nổ phải tự thiết kế.

   ⚠️ NHẸ là ràng buộc, không phải mong muốn — màn cao bắn ~3 từ/giây:
      · CHỈ animate `transform` + `opacity` (chạy thẳng trên GPU, không bắt
        trình duyệt tính lại bố cục)
      · KHÔNG box-shadow động, KHÔNG filter:blur động — hai thứ này vẽ lại
        từng khung và là nguyên nhân số một làm game rơi khung hình
      · gradient là ẢNH NỀN TĨNH, chỉ có phép biến hình thay đổi ⇒ trình duyệt
        vẽ một lần rồi tái sử dụng
   ═══════════════════════════════════════════════════════════════════════════ */
.tc-no {
  position: absolute; width: 0; height: 0;
  pointer-events: none; z-index: 3;
}
.tc-no > i { position: absolute; display: block; border-radius: 50%; }

/* ── Lớp 1: CHỚP tâm — loé rồi tắt gần như tức thì, báo "va chạm ở ĐÂY" ── */
.tc-no .ch {
  left: -50px; top: -50px; width: 100px; height: 100px;
  background: radial-gradient(circle,
              #fff 0%, #fff9dd 18%, rgba(255,186,74,.7) 42%, rgba(255,104,52,0) 70%);
  animation: tcChop .26s ease-out forwards;
}
@keyframes tcChop {
  0%   { opacity: 0;   transform: scale(.2); }
  12%  { opacity: 1;   transform: scale(1); }
  100% { opacity: 0;   transform: scale(1.7); }
}

/* ── Lớp 2: VÒNG XUNG KÍCH — lan ra ngoài, cho cảm giác có LỰC ──
   Màu cyan khớp tia đạn (#7ee8ff) để vụ nổ trông là hệ quả của phát bắn.
   Bắt đầu RẤT nhỏ và lan RẤT xa: bản đầu để vòng dày ôm sát tâm nên nó bó lấy
   cụm tia và cả vụ nổ trông như một cái nút bấm. */
.tc-no .vg {
  left: -9px; top: -9px; width: 18px; height: 18px;
  border: 2px solid rgba(126,232,255,.6);
  /* Delay .07s là mấu chốt: bản trước vòng nở CÙNG LÚC với chớp nên nó viền
     quanh chớp và cả vụ nổ trông như một cái NÚT BẤM. Để chớp loé xong rồi
     vòng mới đuổi theo thì mắt đọc ra hai sự kiện nối tiếp, đúng như nổ thật. */
  animation: tcVong .34s cubic-bezier(.1,.85,.25,1) .06s forwards;
}
@keyframes tcVong {
  0%   { opacity: 0;   transform: scale(1.2); border-width: 2.5px; }
  16%  { opacity: .8; }
  100% { opacity: 0;   transform: scale(8.2); border-width: .5px; }
}

/* ── Lớp 3: TIA bắn — 8 mảnh văng, KHÔNG ĐỀU NHAU ──
   Góc (--g), quãng bay (--d) và chiều dài (--l) đều do JS bốc ngẫu nhiên cho
   TỪNG tia. Để chúng bằng nhau là ra hình tròn cân đối giống biểu tượng đang
   tải — đã thử và nhìn ảnh mới phát hiện. */
.tc-no .ti {
  left: 0; top: 0; width: 3.5px; height: var(--l, 15px); border-radius: 2px;
  margin: -7px 0 0 -1.75px;
  background: linear-gradient(180deg, #fff, #ffc258 42%, #ff7a3c 78%, rgba(255,90,60,0));
  transform: rotate(var(--g, 0deg));
  animation: tcTia .50s cubic-bezier(.18,.72,.28,1) forwards;
}
@keyframes tcTia {
  0%   { opacity: 0;   transform: rotate(var(--g,0deg)) translateY(-2px) scaleY(.4); }
  12%  { opacity: 1; }
  62%  { opacity: 1; }
  100% { opacity: 0;   transform: rotate(var(--g,0deg)) translateY(var(--d,-46px)) scaleY(1.5); }
}

/* Người bật "giảm chuyển động": bỏ hết phần bay ra, chỉ giữ một cái chớp mờ
   dần — vẫn biết mình vừa bắn trúng, nhưng không có gì lao ra ngoài. */
@media (prefers-reduced-motion: reduce) {
  .tc-no .vg, .tc-no .ti { display: none; }
  .tc-no .ch { animation: tcChopNhe .3s linear forwards; }
  @keyframes tcChopNhe { 0% { opacity: .85; } 100% { opacity: 0; } }
}

/* [GĐ6] Ô thông báo VUI trong màn kho — tái dùng đúng phần tử của ô lỗi, chỉ
   đổi màu. Cố ý KHÔNG dựng hệ thống thông báo thứ hai trong game: rule cứng của
   dự án là mọi thông báo đi qua AI Buddy. Ô này là đường lui cho lối "mở thẳng
   địa chỉ" — khi đó không có trang cha nên không có AI Buddy nào để gọi. */
.tc-kho-loi.ok {
  background: rgba(110,231,168,.14);
  border-color: rgba(110,231,168,.5);
  color: #b8f5d4;
}

/* ═══════════════════════════════════════════════════════════════════════════
   [GĐ4] BẢNG XẾP HẠNG
   ───────────────────────────────────────────────────────────────────────────
   Xếp theo MÀN là chính, ĐIỂM chỉ phân định khi bằng màn — nên cột "Màn" phải
   là thứ mắt bắt được TRƯỚC, cột điểm nhạt hơn. Đặt điểm to ngang màn là nói
   sai luật chơi bằng thị giác.
   ═══════════════════════════════════════════════════════════════════════════ */
.tc-bang-tab {
  display: flex; gap: 6px; flex-wrap: wrap; justify-content: center;
  width: min(680px, 92vw);
}
.tc-bang-tab-nut {
  /* nowrap + shrink:0 là bộ đôi bắt buộc cho hàng nút flex (rule S151/S178):
     thiếu nó thì khung hẹp bóp nút lại và chữ tự ngắt 2-3 dòng giữa nút. */
  white-space: nowrap; flex-shrink: 0;
  border: 1px solid var(--tc-vien); border-radius: 999px;
  background: rgba(126,232,255,.06); color: var(--tc-chu-mo);
  padding: 6px 14px; font-size: .82rem; cursor: pointer;
  transition: background .15s, color .15s, border-color .15s;
}
.tc-bang-tab-nut:hover { background: rgba(126,232,255,.12); color: var(--tc-chu); }
.tc-bang-tab-nut.dang {
  border-color: var(--tc-lam); color: var(--tc-nen);
  background: linear-gradient(180deg, #9cf0ff, var(--tc-lam)); font-weight: 700;
}

#tc-ds-bang {
  display: flex; flex-direction: column; gap: 6px;
  width: min(680px, 92vw);
  /* Cùng lý do với #tc-ds-kho: 20 dòng thì luôn dài hơn màn thấp, nên cho cuộn
     NGAY TỪ ĐẦU kèm thanh cuộn NHÌN THẤY ĐƯỢC — van xả vô hình coi như không
     có (rule S178). Trần theo svh, không số cứng. */
  max-height: min(46svh, 460px); overflow-y: auto; overscroll-behavior: contain;
  scrollbar-width: thin; scrollbar-color: rgba(126,232,255,.28) transparent;
}
#tc-ds-bang::-webkit-scrollbar { width: 8px; }
#tc-ds-bang::-webkit-scrollbar-thumb { background: rgba(126,232,255,.28); border-radius: 4px; }

.tc-bang-dong {
  display: flex; align-items: center; gap: 9px;
  border: 1px solid var(--tc-vien); border-radius: 10px;
  padding: 7px 11px; background: rgba(126,232,255,.045);
}
/* Dòng của CHÍNH mình phải nhận ra được ngay giữa 20 dòng — đó là thông tin
   người chơi tìm đầu tiên khi mở bảng. */
.tc-bang-dong.toi {
  border-color: var(--tc-luc); background: rgba(110,231,168,.10);
}
.tc-bang-hang {
  flex: 0 0 30px; text-align: center; font-weight: 700;
  font-size: .95rem; color: var(--tc-chu-mo); font-variant-numeric: tabular-nums;
}
.tc-bang-hang.h1, .tc-bang-hang.h2, .tc-bang-hang.h3 { font-size: 1.15rem; }
/* .tc-bang-ava nay CHỈ còn là lớp bọc — kích thước/viền/nền do chính ảnh bên
   trong lo (xem khối (4) cuối file). Để lại viền + nền ở đây sẽ vẽ một vòng
   tròn thừa phía sau khung trang trí. */
.tc-bang-ten {
  flex: 1 1 auto; min-width: 0; font-size: .88rem; color: var(--tc-chu);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.tc-bang-toi {
  margin-left: 6px; font-size: .68rem; color: var(--tc-nen);
  background: var(--tc-luc); border-radius: 999px; padding: 1px 7px;
  vertical-align: middle;
}
.tc-bang-thuyen {
  flex: 0 0 auto; width: 34px; height: 26px; object-fit: contain;
  /* Ảnh phi thuyền là GIF động — để nguyên thì 20 con cùng bay trong một danh
     sách, mắt không đọc nổi chữ nữa. Thu nhỏ + hạ tương phản cho nó lùi về sau. */
  opacity: .85;
}
.tc-bang-man {
  flex: 0 0 auto; font-size: .82rem; color: var(--tc-chu-mo); white-space: nowrap;
}
.tc-bang-man b { color: var(--tc-lam); font-size: 1rem; font-variant-numeric: tabular-nums; }
.tc-bang-diem {
  flex: 0 0 auto; min-width: 62px; text-align: right;
  font-size: .78rem; color: var(--tc-chu-mo); font-variant-numeric: tabular-nums;
}
.tc-bang-luc { font-size: .72rem; color: var(--tc-chu-mo); }

/* Rule S125 — `[hidden]` thua rule tác giả có display không điều kiện. */
#tc-bang-loi[hidden] { display: none !important; }

/* Màn hẹp: bỏ cột điểm và ảnh phi thuyền trước, giữ hạng/tên/màn — đó là ba
   thứ trả lời đúng câu hỏi "ai đang đứng đâu". */
@media (max-width: 460px) {
  .tc-bang-diem { display: none; }
  .tc-bang-thuyen { width: 26px; height: 20px; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   HIỆU ỨNG NỔ MUA BẰNG LINH THẠCH (Founder 2026-09-02)
   ───────────────────────────────────────────────────────────────────────────
   Tái dùng nguyên bộ .tc-thuyen-o — hai kho cùng hình dạng dữ liệu (ảnh + tên
   + mô tả + giá + nút), dựng bộ class thứ hai chỉ để đổi vài pixel là tạo hai
   nơi phải sửa mỗi lần chỉnh giao diện.
   ═══════════════════════════════════════════════════════════════════════════ */
.tc-kho-h3 {
  margin: 14px 0 2px; font-size: .95rem; color: var(--tc-lam);
  letter-spacing: .02em;
}
#tc-ds-fx {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 10px; width: min(900px, 92vw);
  /* Kho hiệu ứng ngắn hơn kho phi thuyền nên trần thấp hơn — nhưng vẫn cho cuộn
     NGAY TỪ ĐẦU kèm thanh cuộn nhìn thấy được (rule S178), đừng đợi tràn mới sửa. */
  max-height: min(34svh, 330px); overflow-y: auto; overscroll-behavior: contain;
  scrollbar-width: thin; scrollbar-color: rgba(126,232,255,.28) transparent;
}
#tc-ds-fx::-webkit-scrollbar { width: 8px; }
#tc-ds-fx::-webkit-scrollbar-thumb { background: rgba(126,232,255,.28); border-radius: 4px; }

.tc-fx-o .tc-thuyen-anh { width: 64px; height: 64px; object-fit: contain; }
/* Đĩa tròn mờ phía sau MỌI ảnh hiệu ứng — Founder vòng 3: "cái cao cái thấp
   không đồng đều". Bốn ảnh là bốn hoạt ảnh có nhiều khung TRỐNG (đo thật: khung
   dày nhất cũng chỉ phủ 11-38% ô), nên lúc chạy tới khung trống thì ô đó trông
   như bị hỏng trong khi ô bên cạnh vẫn đầy. Đĩa tròn giữ cho cả hàng luôn có
   cùng một hình khối, dù hoạt ảnh đang ở khung nào. */
.tc-fx-o .tc-thuyen-anh {
  border-radius: 50%;
  background: radial-gradient(circle at 50% 50%, rgba(126,232,255,.10), rgba(126,232,255,0) 72%);
}

/* ── NÚT PHẢI THẲNG HÀNG GIỮA CÁC Ô (Founder vòng 3) ──────────────────────
   Gốc rễ KHÔNG phải chiều cao ô (lưới đã kéo mọi ô bằng nhau) mà là NỘI DUNG
   bên trong trôi tự do: mô tả dài ngắn khác nhau đẩy nút lên xuống lệch nhau
   tới ~60px giữa hai ô cạnh nhau.
   Cho ô mô tả NUỐT phần chỗ thừa (flex: 1) ⇒ mọi thứ sau nó bị đẩy xuống đáy,
   nên dòng giá và nút luôn nằm đúng một cao độ ở mọi ô.
   ⚠️ Chỉ đặt `flex: 1 1 auto` cho ĐÚNG ô mô tả — đặt lên cả thẻ thì ảnh và tên
   cũng giãn theo, đúng lỗi "flex kéo dãn con" đã trả giá ở S178. */
.tc-thuyen-o .mt { flex: 1 1 auto; }
/* Ô đã mua trước đây KHÔNG có dòng giá ⇒ thiếu hẳn một hàng so với ô chưa mua,
   nên nút của nó trôi lên cao hơn. Nay mọi ô đều có đúng một dòng trạng thái. */
.tc-thuyen-o .gia.co { color: var(--tc-chu-mo); font-weight: 600; }

/* Ô mô phỏng cho hiệu ứng MẶC ĐỊNH — nó là vụ nổ CSS nên KHÔNG có ảnh; để
   trống thì mục đó trông như bị hỏng. Vẽ lại đúng ba lớp của vụ nổ thật ở dạng
   tĩnh: lõi sáng, vòng xung kích lam, quầng ngoài. */
.tc-fx-css {
  display: block; width: 64px; height: 64px; border-radius: 50%;
  background:
    radial-gradient(circle at 50% 50%, #fff 0 8%, rgba(255,255,255,0) 22%),
    radial-gradient(circle at 50% 50%, rgba(126,232,255,0) 34%, rgba(126,232,255,.85) 42%, rgba(126,232,255,0) 52%),
    radial-gradient(circle at 50% 50%, rgba(126,232,255,.20) 0 62%, rgba(126,232,255,0) 72%);
}

/* Vụ nổ dạng ẢNH — thay hẳn ba lớp CSS, không chồng lên (chồng là được một mớ
   sáng loè không đọc ra hình gì). Ảnh neo theo TÂM điểm nổ. */
.tc-no.anh { width: 0; height: 0; }
.tc-no.anh > img {
  position: absolute; left: 50%; top: 50%;
  /* Founder 2026-09-03: "phóng to hiệu ứng cho độ lan rộng hơn tí". Chặn theo
     bề RỘNG màn hình để điện thoại không bị vụ nổ phủ kín sân. */
  width: min(196px, 46vw); height: min(196px, 46vw); object-fit: contain;
  transform: translate(-50%, -50%);
  /* Chỉ animate opacity — cùng ràng buộc hiệu năng với vụ nổ CSS: màn cao bắn
     ~3 từ/giây, mọi thứ bắt trình duyệt tính lại bố cục đều bị loại. */
  animation: tcNoAnh .76s ease-out forwards;
  pointer-events: none;
}
@keyframes tcNoAnh {
  0%   { opacity: 0; }
  12%  { opacity: 1; }
  72%  { opacity: 1; }
  100% { opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .tc-no.anh > img { animation: none; opacity: .9; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   MÀN TÚI ĐỒ: MỘT thanh cuộn duy nhất (sửa 2026-09-02, phát hiện bằng ẢNH)
   ───────────────────────────────────────────────────────────────────────────
   Thêm khu HIỆU ỨNG NỔ vào cùng màn làm kho phi thuyền bị chia chỗ: trần cuộn
   riêng của nó cắt NGANG giữa ô — dòng giá đứt đôi và nút "Mở khoá" biến mất
   hẳn. Người chơi nhìn thấy phi thuyền mà không có cách nào mua, trong khi
   máy đo vẫn báo "đạt" vì nó chỉ hỏi "danh sách có bị bóp dưới 90px không".
   Đúng bài học S178: số đo đạt ≠ giao diện đúng, phải NHÌN.

   Gốc rễ là CUỘN LỒNG HAI TẦNG — `.tc-phu` vốn đã `overflow-y: auto` (van xả),
   nên trần riêng của từng danh sách là tầng thứ hai. Founder đã chê đúng kiểu
   này ở S151. Bỏ tầng trong, giữ tầng ngoài.
   ⚠️ Chỉ áp trong #tc-man-kho — màn BẢNG XẾP HẠNG chỉ có MỘT danh sách nên
      cuộn riêng ở đó vẫn đúng và vẫn giữ được nút "Xong" luôn nhìn thấy.
   ═══════════════════════════════════════════════════════════════════════════ */
#tc-man-kho #tc-ds-kho,
#tc-man-kho #tc-ds-fx {
  max-height: none;
  overflow-y: visible;
  /* ⚠️ Bỏ trần thôi là CHƯA ĐỦ — đo bằng getComputedStyle mới thấy: max-height
     đã về `none` mà ô vẫn bị cắt, vì flex item mặc định `flex-shrink: 1` nên
     hộp bị bóp nhỏ hơn nội dung. Đây là khối DANH SÁCH nhưng cả hai đều mang
     nút hành động ("Mở khoá") ở đáy mỗi ô, nên nén nó = giấu mất chức năng —
     luật của khối ĐIỀU KHIỂN, xem rule S178. */
  flex: 0 0 auto;
}
/* Nội dung dài hơn màn thì `justify-content: center` cắt mất phần ĐẦU (tiêu đề
   + ví Linh Thạch) và không cuộn ngược lên được. `safe` giữ nguyên căn giữa khi
   còn vừa, và tự chuyển về căn đầu khi tràn. Trình duyệt cũ không hiểu `safe`
   thì rơi về đúng hành vi hiện nay, không vỡ thêm. */
.tc-phu { justify-content: safe center; }

/* ĐÃ THỬ VÀ BỎ: nút "Xong" bám đáy (position: sticky). Ảnh chụp cho thấy thanh
   bám đáy LUÔN đè lên nội dung đang cuộn qua — nó che đúng dòng giá và nút "Mở
   khoá" của hàng ô cuối, và làm chúng trông như bị vô hiệu hoá. Đã thử cả nền mờ
   dần lẫn nền đặc lẫn chừa đệm đáy: đệm chỉ cứu được lúc ĐÃ cuộn hết, còn lúc
   cuộn giữa chừng thì vẫn đè — đó là bản chất của sticky, không phải lỗi chỉnh sai.
   ĐỪNG cắm lại sticky mà không giải được việc nó che hàng cuối.
   ⇒ VÒNG 3 (Founder): nút lên GÓC PHẢI TRÊN, neo theo MÀN HÌNH.
   Phải là `fixed` chứ không `absolute` như màn bảng xếp hạng: ở màn túi đồ thì
   chính #tc-man-kho là khối đang cuộn, nên `absolute` sẽ cuộn trôi mất nút —
   đúng cái bệnh đang đi chữa. Cùng lý do với mũi tên cuộn ngay dưới đây. */
#tc-man-kho > .tc-nut-goc { position: fixed; top: 14px; right: 20px; }

/* ═══════════════════════════════════════════════════════════════════════════
   VÒNG 2 — 5 việc Founder báo 2026-09-02 (sau khi test thật trên production)
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── (1) BẢNG XẾP HẠNG CĂN TRÊN ────────────────────────────────────────────
   Founder: "bảng xếp hạng phải nằm ở phía trên chứ sao lại căn giữa web vậy?"
   Đúng — danh sách sẽ dài dần theo số người chơi, mà khối căn giữa thì mỗi lần
   thêm một dòng là cả bảng nhích lên một nửa dòng, đọc rất khó chịu. Căn trên
   thì hàng đầu đứng yên một chỗ. */
#tc-man-bang { justify-content: flex-start; padding-top: clamp(14px, 3.2svh, 34px); }

/* ── (2) NÚT "XONG" Ở GÓC PHẢI TRÊN (khuôn Bảng Phong Thần) ───────────────
   Founder: "danh sách xếp hạng dài mà nó sẽ xổ xuống" ⇒ nút nằm cuối danh sách
   sẽ trôi mất khỏi tầm nhìn. Neo góc thì lối ra luôn ở đúng một chỗ. */
.tc-nut-goc {
  position: absolute; top: 12px; right: 14px; z-index: 6;
  border: 1px solid var(--tc-vien); border-radius: 999px;
  background: rgba(20,16,34,.82); color: var(--tc-chu);
  padding: 6px 14px; font-size: .8rem; font-family: inherit; cursor: pointer;
  white-space: nowrap; backdrop-filter: blur(6px);
  transition: background .16s, border-color .16s, transform .16s;
}
.tc-nut-goc:hover { background: rgba(40,32,64,.95); border-color: var(--tc-lam); transform: scale(1.05); }

/* ── (3) MŨI TÊN CUỘN THAY THANH CUỘN ─────────────────────────────────────
   Founder: "bỏ cái thanh dọc cuộn đi, thiết kế nút mũi tên lên xuống mà các
   tính năng khác đang có cho đẹp." Dáng nút chép đúng .kn-corr-arrow-btn của
   Luyện Nói để cả site nhìn như một. Hành vi do js/scroll-arrows.js lo.
   ⚠️ Ẩn thanh cuộn chỉ được giấu phần VẼ — vẫn phải cuộn được bằng chuột/chạm/
   bàn phím, nếu không thì ai không bấm mũi tên sẽ kẹt. */
.tc-cuon-boc { position: relative; width: min(680px, 92vw); }
/* Chừa chỗ cho mũi tên ở mép phải. Không chừa thì nó ĐÈ lên cột điểm của
   dòng cuối — ảnh chụp cho thấy số bị che mất một nửa. */
/* ⚠️ box-sizing PHẢI là border-box. Đo thật: mặc định content-box khiến
   padding-right CỘNG THÊM vào bề rộng thay vì trừ vào trong — hộp nở ra 42px
   còn dòng vẫn tới đúng mép cũ, nên mũi tên vẫn đè lên cột điểm y như trước
   khi thêm padding. Nhìn ảnh thì tưởng "padding không ăn", đo mới ra. */
.tc-cuon-boc > #tc-ds-bang { width: 100%; padding-right: 42px; box-sizing: border-box; }
#tc-ds-bang, #tc-man-kho { scrollbar-width: none; }
#tc-ds-bang::-webkit-scrollbar, #tc-man-kho::-webkit-scrollbar { width: 0; height: 0; }
.tc-mui-ten {
  position: absolute; right: 8px; z-index: 4;
  width: 30px; height: 30px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  border: 1px solid rgba(255,255,255,.16);
  background: rgba(20,16,34,.82); color: var(--tc-chu);
  font-size: .72rem; line-height: 1; cursor: pointer;
  backdrop-filter: blur(6px);
  transition: opacity .18s ease, transform .18s ease, background .18s ease;
}
.tc-mui-ten:hover { background: rgba(40,32,64,.95); transform: scale(1.08); }
.tc-mui-ten[hidden] { display: none !important; }   /* rule S125 */
.tc-cuon-boc .tc-mui-ten.len   { top: 6px; }
.tc-cuon-boc .tc-mui-ten.xuong { bottom: 6px; }
/* Màn túi đồ: khung cuộn là CẢ MÀN nên mũi tên neo theo màn hình, không theo
   một khối con — dùng fixed để nó không trôi đi khi cuộn. */
#tc-man-kho > .tc-mui-ten { position: fixed; right: 20px; }
#tc-man-kho > .tc-mui-ten.len   { top: 76px; }
#tc-man-kho > .tc-mui-ten.xuong { bottom: 20px; }

/* ── (3b) DANH SÁCH LẤY HẾT CHỖ CÒN LẠI (vòng 3, phát hiện bằng ẢNH) ──────
   Trần `min(46svh, 460px)` đặt hồi bảng còn CĂN GIỮA — lúc đó phải chừa chỗ
   đều hai đầu nên trần thấp là đúng. Từ khi bảng căn TRÊN (vòng 2) thì con số
   đó thành thừa: ảnh chụp màn 1600x900 cho thấy danh sách dừng ở ~380px trong
   khi bên dưới còn trống hơn 300px, người chơi phải cuộn dù màn còn rộng.
   Bỏ hẳn số đoán, để phép chia của flex tự lo:
     · .tc-cuon-boc `flex: 0 1 auto` — co được khi thiếu chỗ, KHÔNG giãn khi
       thừa (giãn thì dòng "Cập nhật lúc" bị đẩy xuống tận đáy màn, rời hẳn
       khỏi bảng — nhìn như lạc mất)
     · #tc-ds-bang `flex: 1 1 auto; min-height: 0` — lấp trọn lớp bọc rồi tự
       cuộn bên trong. min-height:0 là BẮT BUỘC, thiếu nó flex item không co
       xuống dưới cỡ nội dung và trần lại vô hiệu. */
#tc-man-bang .tc-cuon-boc { flex: 0 1 auto; min-height: 120px; display: flex; }
#tc-man-bang #tc-ds-bang  { max-height: none; flex: 1 1 auto; min-height: 0; }

/* ── (4) KHUNG AVATAR + VƯƠNG MIỆN VIP ────────────────────────────────────
   ⚠️ VÒNG 3 — VIẾT LẠI. Founder: "avatar và khung không khớp."
   Vòng 2 tôi tự viết công thức ghép khung (tỉ lệ cứng 168% + biến --k-ty) và nó
   SAI, vì khung avatar của dự án còn ba thứ nữa mà công thức đó bỏ qua:
     · offsetX/offsetY — nhiều khung có lỗ LỆCH TÂM, không nằm giữa
     · mix-blend-mode  — khung .gif/.webm nền đen nướng sẵn, thiếu `screen` là
                         ra một ô vuông đen đè lên mặt người ta
     · avatarMask      — mặt nạ cắt avatar theo đúng hình lỗ thật
   Và tỉ lệ khung PHẢI là 1/avatarScale (khung 0,5 cần 200%, khung 0,8 cần 125%)
   chứ không thể là một con số cứng cho mọi khung.
   ⇒ Nay gọi thẳng window.getTuTienAvatarHtml (js/auth.js) — hàm đang chạy đúng
   ở Hồ Sơ, Bằng Hữu, Bảng Phong Thần. Nó tự sinh style nội tuyến đầy đủ, nên ở
   đây CHỈ còn lo phần bọc ngoài. ĐỪNG chép lại công thức lần thứ tư. */
.tc-bang-ava {
  position: relative; flex: 0 0 auto; display: inline-block; line-height: 0;
  /* Khung trang trí rộng hơn vòng avatar (tới 200% khi avatarScale = 0,5) nên
     phải chừa chỗ hai bên, nếu không nó đè sang huy hiệu hạng và tên. */
  margin: 0 9px;
}
/* Đường lui khi không có hàm chuẩn (mở thẳng trochoi.html, không có trang cha) */
.tc-bang-ava-anh {
  width: 34px; height: 34px; border-radius: 50%;
  object-fit: cover; display: block;
  border: 1px solid var(--tc-vien); background: var(--tc-nen2);
}
/* Vương miện = ĐÚNG ảnh vip.gif của dự án (Founder vòng 3: "cái vương miện vip
   là ảnh gif vip.gif mà chứ đâu phải đặt ở trên đầu như ảnh").
   Đặt CHỒNG LÊN góc trên-phải vòng avatar thay vì lơ lửng phía trên: ở trên đầu
   thì nó đội cả dòng cao lên và trông như rơi ra ngoài.
   mix-blend-mode: screen cố định — màn trò chơi LUÔN nền tối, giống lý do của
   .pt-vip-gif bên Bảng Phong Thần (không theo giao diện sáng/tối). */
.tc-bang-vm {
  position: absolute; right: -7px; top: -7px; z-index: 4;
  width: 19px; height: 19px; object-fit: contain;
  mix-blend-mode: screen;
  filter: drop-shadow(0 0 4px rgba(255, 215, 0, .55));
  pointer-events: none;
}
/* Dòng phải đủ cao cho khung tràn ra trên/dưới, nếu không khung bị hàng trên
   đè lên. */
.tc-bang-dong { min-height: 44px; }
