/* ============================================================
   board.css — Bàn cờ 11×11 của Cờ Tỷ Phú
   Tách riêng khỏi cotyphu.css vì đây là CSS khó nhất module, sẽ sửa độc lập.

   ⚠️ HAI LUẬT TUYỆT ĐỐI, đọc trước khi sửa file này:

   1. KHÔNG BAO GIỜ cho .mb-tile một `border`.
      40 ô có bề rộng phân số (1fr chia 9) — border trên chúng tạo seam 0.5px
      và mép đôi ở mọi zoom. Đường kẻ của bàn được vẽ bằng `gap:1px` +
      background của .mb-board. Sở hữu vẽ bằng `box-shadow: inset`.

   2. KHÔNG transform .mb-tile — chỉ transform .mb-tile-in.
      transform trên .mb-tile tạo containing block mới và phá vị trí
      absolute của inner.
   ============================================================ */

/* ---- Khung bàn ---- */
.mb-board {
  /* --side do .mb-stage quyết định (xem cotyphu.css). Mọi kích thước bên trong
     suy ra từ nó, nên bàn tự vừa mọi khổ mà không cần breakpoint. */
  --gap: 1px;
  --d: calc(var(--side) * 0.128);                                  /* độ sâu vành */
  --e: calc((var(--side) - 2 * var(--d) - 10 * var(--gap)) / 9);   /* bề rộng ô cạnh */

  position: relative;
  width: var(--side);
  height: var(--side);

  display: grid;
  grid-template-columns: var(--d) repeat(9, minmax(0, 1fr)) var(--d);
  grid-template-rows:    var(--d) repeat(9, minmax(0, 1fr)) var(--d);
  /* gap CHÍNH LÀ đường kẻ in của bàn — xem luật 1 ở đầu file.
     Màu kẻ RIÊNG, đậm hơn --mb-rule: ở 1px trên nền kem, --mb-rule (#e6d4b4)
     gần như tàng hình nên 40 ô nhòe thành một mảng trắng. Không sửa
     --mb-rule vì nó còn dùng cho grip sheet + swatch danh sách. */
  gap: var(--gap);
  background: #c9a97a;

  border-radius: 14px;
  overflow: hidden;
  /* viền ngoài đặt trên .mb-board (1 element) thì an toàn — luật 1 chỉ cấm
     border trên từng ô */
  box-shadow:
    0 18px 50px -18px rgba(120, 75, 25, 0.32),
    inset 0 0 0 1px rgba(217, 138, 10, 0.28);
}

/* ---- Ô ---- */
.mb-tile {
  position: relative;
  overflow: hidden;             /* chặn nội dung đã rotate của ô tràn qua gap */
  border: 0;                    /* xem luật 1 */
  padding: 0;
  margin: 0;
  font: inherit;
  color: inherit;
  background: var(--mb-face);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: background 0.18s ease;
}
/* KHÔNG nới vùng chạm bằng ::before inset âm: .mb-tile có overflow:hidden nên
   nó bị cắt ngay, mà các ô lại kề nhau (gap 1px) nên có nới cũng chồng ô cạnh.
   Ô 28px là affordance "xem", mọi QUYẾT ĐỊNH nằm trên nút ≥48px ở action bar,
   kèm danh sách 40 ô trong sheet làm đường đi thay thế (WCAG 2.5.8). */
.mb-tile:hover { background: #fff8e8; }
.mb-tile:focus-visible {
  outline: 2px solid var(--mb-gold);
  outline-offset: -2px;
  z-index: 7;
}

/* Inner LUÔN --e rộng × --d cao (toạ độ local của ô cạnh DƯỚI), rồi rotate.
   Nhờ vậy 4 cạnh dùng CHUNG một ruleset thay vì 4 bộ layout riêng. */
.mb-tile-in {
  position: absolute;
  left: 50%;
  top: 50%;
  width: var(--e);
  height: var(--d);
  transform: translate(-50%, -50%) rotate(var(--rot, 0deg));
  display: flex;
  flex-direction: column;       /* dải màu ở TRÊN = hướng vào tâm bàn */
  align-items: stretch;
  overflow: hidden;
  pointer-events: none;
}
.mb-tile[data-side="b"] { --rot:   0deg; }
.mb-tile[data-side="l"] { --rot:  90deg; }
.mb-tile[data-side="t"] { --rot: 180deg; }
.mb-tile[data-side="r"] { --rot: -90deg; }

/* Nền ô nhuốm NHẸ màu nhóm của chính nó. Trước đây cả 36 ô cạnh đều
   #fffdf8 nên bàn đọc ra "mảng trắng có mấy vạch màu"; 7% là đủ để mỗi cạnh
   có thân nhiệt riêng mà chữ 7px vẫn thừa tương phản.
   ⚠️ Cùng specificity (0,3,0) với rule tint chủ sở hữu 18% ở mục "Sở hữu" —
   rule đó PHẢI nằm sau trong file mới thắng. Đừng đảo thứ tự 2 mục. */
.mb-tile:not(.is-corner) .mb-tile-in {
  background: color-mix(in srgb, var(--grp) 7%, var(--mb-face));
}

/* Cạnh TRÊN: inner xoay 180° để dải màu hướng vào tâm bàn (đúng dáng bàn cờ),
   NHƯNG chữ thì phải xoay lại cho đọc được. Bàn cờ giấy in ngược ở cạnh xa vì
   người chơi ngồi đối diện — trên 1 màn hình chỉ có 1 người xem, chữ lộn ngược
   là thù địch. Giữ cấu trúc thật, lật chữ về xuôi. */
.mb-tile[data-side="t"] .mb-body { transform: rotate(180deg); }

/* ---- Dải màu nhóm ----
   Vẫn 26% chứ KHÔNG dày hơn: xem phép tính chỗ-chứa-chữ ở fitBoard()
   (render.js) — dày hơn là tên ô mất chỗ ở khổ điện thoại. Độ "đậm đà" lấy từ
   gradient + mép tối, không lấy từ bề dày.
   background-color/-image tách riêng (KHÔNG dùng shorthand) để render.js khỏi
   phải set inline màu — inline shorthand sẽ xoá mất lớp gradient. */
.mb-band {
  flex: 0 0 26%;
  min-height: 0;
  background-color: var(--grp, transparent);
  background-image: linear-gradient(to bottom, rgba(255, 255, 255, 0.26), rgba(0, 0, 0, 0.16));
  box-shadow: inset 0 -1px 0 rgba(60, 30, 0, 0.28);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8%;
  position: relative;
}
/* Độc quyền cả nhóm: hairline TRẮNG trong dải — tín hiệu "sắp đau".
   KHÔNG dùng vàng: nhóm Lúa Vàng có dải #d98a0a nên vàng-trên-vàng tàng hình.
   Trắng đọc được trên cả 8 màu nhóm vì cả 8 đều mid-dark. */
.mb-tile.is-mono .mb-band { box-shadow: inset 0 0 0 1.5px rgba(255, 255, 255, 0.92); }

/* ---- Thân ô ---- */
.mb-body {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2%;
  /* padding NGANG 2% chứ không 4%: padding % tính theo width của .mb-tile-in
     (= --e ≈ 27px trên điện thoại) nên 4% ngốn ~2.2px — vừa đủ để "NGUYỄN"
     không còn chỗ và bị overflow-wrap:anywhere ngắt giữa từ ("NGUY ỄN"). */
  padding: 3% 2%;
  text-align: center;
}

.mb-name {
  /* CHỈ khai báo display 1 lần ở đây (none), bản -webkit-box nằm trong rule
     [data-size="lg"]. Viết cả 2 trong cùng rule thì cái sau thắng ⇒ tên luôn
     hiện, sai ở khổ sm/md. */
  display: none;
  /* min 7px (không phải 6.5): 6.5px là ngưỡng chữ Việt có dấu bắt đầu nhòe
     thành vệt. Con số này đi kèm phép tính ngưỡng lg trong fitBoard() —
     đổi nó thì phải tính lại ngưỡng. */
  font-size: clamp(7px, calc(var(--e) * 0.19), 9.5px);
  font-weight: 800;
  /* 1.28 chứ KHÔNG phải 1.08: chữ HOA tiếng Việt có dấu xếp tầng (Ế, Ộ, Ỷ) bị
     cắt mất dấu khi line-height quá chặt — đúng loại lỗi .l-brand-name từng mắc
     ("Increased to prevent accent cutting"). */
  line-height: 1.28;
  letter-spacing: -0.01em;
  text-transform: uppercase;
  color: var(--mb-ink);
  text-wrap: balance;
  /* Lưới an toàn: 1 TỪ đơn dài hơn bề rộng ô (vd "LANDMARK" ~62px trên ô 43px)
     không có điểm ngắt nên sẽ bị CẮT NGANG mất chữ đầu. Cho phép ngắt trong từ
     để thà xuống dòng còn hơn mất chữ. Tên nên đặt ≤2 từ ngắn để không phải dùng. */
  overflow-wrap: anywhere;
  overflow: hidden;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}
.mb-price {
  display: none;                /* hiện từ data-size="md" */
  font-size: clamp(7px, calc(var(--e) * 0.30), 11px);
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
  color: var(--mb-ink-soft);
}
.mb-ticon {
  font-size: clamp(9px, calc(var(--e) * 0.42), 20px);
  line-height: 1;
  color: var(--grp, var(--mb-ink-soft));
}

/* Thang hiển thị — JS đo rồi set board.dataset.size.
   Media query KHÔNG làm được việc này vì cạnh bàn phụ thuộc CẢ vw LẪN dvh. */
.mb-board[data-size="sm"] .mb-name  { display: none; }
.mb-board[data-size="sm"] .mb-price { display: none; }
.mb-board[data-size="md"] .mb-price { display: block; }
.mb-board[data-size="md"] .mb-name  { display: none; }
.mb-board[data-size="lg"] .mb-price { display: block; }
.mb-board[data-size="lg"] .mb-name  { display: -webkit-box; }
/* ở lg, ô đất có tên rồi thì icon thu nhỏ nhường chỗ */
.mb-board[data-size="lg"] .mb-tile[data-kind="dat"] .mb-ticon { display: none; }
/* …và ngược lại: ô KHÔNG phải đất thì icon đã nói hết nghĩa (máy bay, tia
   điện, tiền thuế) nên bỏ tên đi để không phải nhồi icon + tên + giá vào
   ~30px. Riêng 22 ô đất mới thật sự cần tên vì chúng chỉ khác nhau ở tên.
   (0,5,0) nên thắng rule `[data-size="lg"] .mb-name` (0,3,0) ở trên. */
.mb-board[data-size="lg"] .mb-tile:not([data-kind="dat"]) .mb-name { display: none; }

/* ---- Ô góc: vuông --d × --d, nội dung xoay 45° ---- */
/* 4 góc là 4 MỐC khác nhau về ý nghĩa nhưng increment 1 tô cả 4 giống hệt
   (kem + icon vàng) nên chúng đọc ra như ô trống. Cho mỗi góc một thân nhiệt
   riêng: Xuất Phát vàng (lộc), Trạm Giam xám lam (trung tính — chỉ "ghé"),
   Bãi Đỗ xanh (an toàn), Vào Tù đỏ (nguy). */
.mb-tile[data-i="0"]  { --cnr: #d98a0a; }
.mb-tile[data-i="10"] { --cnr: #5b7186; }
.mb-tile[data-i="20"] { --cnr: #0d9668; }
.mb-tile[data-i="30"] { --cnr: #b91c1c; }

.mb-tile.is-corner .mb-tile-in {
  width: var(--d);
  height: var(--d);
  transform: translate(-50%, -50%);   /* góc KHÔNG dùng --rot */
  align-items: center;
  justify-content: center;
  background:
    radial-gradient(circle at 50% 38%, color-mix(in srgb, var(--cnr, var(--mb-gold)) 30%, transparent), transparent 72%),
    color-mix(in srgb, var(--cnr, var(--mb-gold)) 10%, var(--mb-face));
}
.mb-corner {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6%;
  transform: rotate(var(--crot, -45deg));
}
.mb-tile[data-i="0"]  .mb-corner { --crot: -45deg; }
.mb-tile[data-i="10"] .mb-corner { --crot:  45deg; }
.mb-tile[data-i="20"] .mb-corner { --crot: -45deg; }
.mb-tile[data-i="30"] .mb-corner { --crot:  45deg; }
.mb-corner-icon {
  font-size: clamp(11px, calc(var(--d) * 0.30), 26px);
  line-height: 1;
  color: var(--cnr, var(--mb-gold));
}
.mb-corner-label {
  font-size: clamp(5.5px, calc(var(--d) * 0.135), 9px);
  font-weight: 800;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--mb-ink);
  white-space: nowrap;
}
/* góc để artwork PHẲNG hơn có chủ ý — 4 quân dồn ở Xuất Phát lúc mở ván
   phải đọc được TRÊN nền góc */
.mb-tile.is-corner:hover { background: var(--mb-face); }

/* ---- Sở hữu: 4 tín hiệu DƯ THỪA để sống ở 28px + an toàn mù màu ---- */
/* (1) tint nền theo màu chủ — 18% (không phải 12%): giờ ô CHƯA có chủ đã
   nhuốm 7% màu nhóm, nên 12% không còn đủ khác biệt để đọc ra "đã có chủ" */
.mb-tile[data-owner] .mb-tile-in {
  background: color-mix(in srgb, var(--own) 18%, var(--mb-face));
}
/* (2) ring trong — đọc được ở 28px, khác với 1 dấu chấm góc thì không */
.mb-tile[data-owner] { box-shadow: inset 0 0 0 2px var(--own); }
/* (3) cờ góc dạng HÌNH — tín hiệu shape, không phụ thuộc màu */
.mb-flag {
  position: absolute;
  right: 0;
  bottom: 0;
  width: 30%;
  aspect-ratio: 1;
  background: var(--own);
  clip-path: polygon(100% 0, 100% 100%, 0 100%);
  display: none;
}
.mb-tile[data-owner] .mb-flag { display: block; }

/* (4) nhà = pip vuông CSS, khách sạn = 1 khối to. KHÔNG BAO GIỜ emoji 🏠
   (iOS ép emoji màu, bỏ qua fillStyle/màu CSS — xem js/mystic-fx.js:29) */
.mb-house {
  width: 22%;
  max-width: 5px;
  aspect-ratio: 1;
  border-radius: 1px;
  background: #166534;
  box-shadow: 0 0 0 0.5px rgba(255, 255, 255, 0.7);
}
.mb-hotel {
  width: 58%;
  max-width: 11px;
  height: 46%;
  border-radius: 2px;
  background: #9f1239;
  box-shadow: 0 0 0 0.5px rgba(255, 255, 255, 0.8);
}

/* ---- Ô đang được chọn: phóng to TẠI CHỖ thay cho pinch-zoom ----
   Lấy được cái hay của zoom mà không phải viết ~200 dòng xử lý gesture. */
.mb-tile.is-focus {
  overflow: visible;            /* cho phép inner tràn ra ngoài khi scale */
  z-index: 6;
}
.mb-tile.is-focus .mb-tile-in {
  transform: translate(-50%, -50%) rotate(var(--rot, 0deg)) scale(1.75);
  box-shadow: 0 12px 30px -8px rgba(120, 75, 25, 0.5);
  border-radius: 3px;
  background: var(--mb-face);
}
.mb-tile.is-corner.is-focus .mb-tile-in {
  transform: translate(-50%, -50%) scale(1.5);
}

/* ---- Ô của lượt hiện tại ---- */
.mb-tile.is-here { z-index: 5; }
.mb-tile.is-here::after {
  content: '';
  position: absolute;
  inset: 0;
  outline: 2px solid var(--mb-gold);
  outline-offset: -2px;
  pointer-events: none;
}
/* bloom báo trước ô đích — chạy TRƯỚC khi quân tới, làm cú tung có sức nặng */
.mb-tile.is-target::after {
  content: '';
  position: absolute;
  inset: 0;
  background: radial-gradient(circle at 50% 50%, rgba(217, 138, 10, 0.45), transparent 70%);
  animation: mb-bloom 0.42s ease-out;
  pointer-events: none;
}
@keyframes mb-bloom {
  from { opacity: 0; transform: scale(0.6); }
  50%  { opacity: 1; }
  to   { opacity: 0; transform: scale(1.15); }
}

/* ============================================================
   Tâm bàn
   ============================================================ */
.mb-centre {
  grid-column: 2 / 11;
  grid-row: 2 / 11;
  position: relative;
  /* 3 chặng + vignette thay cho 2 chặng gần-như-cùng-màu: tâm bàn là mảng lớn
     nhất trên màn nên nó phẳng là cả bàn trông nhạt */
  background:
    radial-gradient(circle at 50% 38%, #fdf7e8 0%, #f4e6c8 55%, #e9d4a9 100%);
  box-shadow:
    inset 0 0 26px rgba(140, 95, 30, 0.18),
    inset 0 0 0 1px rgba(217, 138, 10, 0.34);
  display: grid;
  place-items: center;
  overflow: hidden;
}
.mb-centre-art {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}
/* Khu "đang diễn ra" ở tâm bàn. Neo ĐÁY (không phải giữa) để không đè
   wordmark ở y≈43% và dòng LATBAI.VN ở y≈61% của viewBox 200.
   Đây là thứ biến tâm bàn từ tranh trang trí tĩnh thành chỗ báo nhịp ván. */
.mb-centre-live {
  position: absolute;
  left: 5%;
  right: 5%;
  bottom: 9%;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  text-align: center;
  pointer-events: none;
}
/* cỡ chữ suy từ --side (kế thừa từ .mb-board) — tâm bàn co theo bàn */
.mb-cl-who {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  max-width: 100%;
  font-size: clamp(8px, calc(var(--side) * 0.030), 15px);
  font-weight: 900;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--mb-ink);
}
.mb-cl-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mb-cl-dot {
  width: 0.72em;
  height: 0.72em;
  flex-shrink: 0;
  border-radius: 50%;
  background: var(--tk);
  box-shadow: 0 0 0 1.5px #fff, 0 0 0 2.5px rgba(120, 80, 25, 0.22);
}
.mb-cl-what {
  font-size: clamp(7px, calc(var(--side) * 0.024), 12px);
  font-weight: 700;
  color: var(--mb-ink-soft);
}
.mb-cl-what.is-money { color: var(--mb-accent); }

/* vòng astrolabe quay — cùng ngôn ngữ với /images/logo.svg */
.mb-ring-spin { animation: mb-spin 60s linear infinite; transform-origin: 50% 50%; }
@keyframes mb-spin { to { transform: rotate(360deg); } }

/* ============================================================
   Quân (token)
   ============================================================ */
.mb-tokens {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 8;
}
.mb-token {
  position: absolute;
  left: 0;
  top: 0;
  width: var(--tok, 18px);
  height: var(--tok, 18px);
  margin: calc(var(--tok, 18px) / -2) 0 0 calc(var(--tok, 18px) / -2);
  will-change: transform;
  /* Bước nhảy tile-by-tile (app.js) đổi transform mỗi ~140ms — transition ngắn
     hơn khoảng đó thì mượt mà không trễ nhịp lượt kế tiếp. */
  transition: transform .16s ease-out;
}
/* Bóng nằm ở element NGOÀI nên nó Ở LẠI mặt đất khi thân bay lên.
   Chi tiết này là khác biệt giữa "một chấm trượt" và "một quân nhảy". */
.mb-token::after {
  content: '';
  position: absolute;
  left: 50%;
  bottom: -12%;
  width: 78%;
  height: 22%;
  transform: translateX(-50%);
  background: radial-gradient(ellipse, rgba(90, 60, 20, 0.42), transparent 72%);
}
.mb-token-body {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: var(--tk);
  box-shadow:
    0 0 0 2px #fff,
    0 2px 5px rgba(90, 60, 20, 0.45),
    inset 0 -2px 3px rgba(0, 0, 0, 0.22),
    inset 0 2px 3px rgba(255, 255, 255, 0.4);
  display: grid;
  place-items: center;
  color: #fff;
  font-size: calc(var(--tok, 18px) * 0.5);
  will-change: transform;
}
/* quân của người đang đi: vành vàng thở */
.mb-token.is-turn .mb-token-body { animation: mb-tok-turn 1.8s ease-in-out infinite; }
@keyframes mb-tok-turn {
  0%, 100% { box-shadow: 0 0 0 2px #fff, 0 0 0 2px var(--mb-gold), 0 2px 5px rgba(90,60,20,.45); }
  50%      { box-shadow: 0 0 0 2px #fff, 0 0 0 5px rgba(217,138,10,.55), 0 2px 8px rgba(90,60,20,.5); }
}
.mb-token.is-out { opacity: 0.35; filter: grayscale(1); }

/* Nảy từng bước khi đi. HAI class luân phiên a/b vì animation phải khởi động
   LẠI mỗi ô — cùng một class thì trình duyệt coi là animation đang chạy và
   không replay (mẹo thay cho hack void offsetWidth để buộc reflow).
   Lưu ý CHỦ Ý: `animation` là shorthand nên trong 0.15s nảy, vành vàng
   mb-tok-turn tạm dừng. Đổi được bằng cách thêm 1 lớp DOM bọc ngoài, nhưng
   không đáng — mắt không thấy vành ngắt trong lúc quân đang bay. */
.mb-token.is-hop-a .mb-token-body,
.mb-token.is-hop-b .mb-token-body { animation: mb-hop 0.15s ease-out; }
@keyframes mb-hop {
  0%   { transform: translateY(0) scale(1); }
  45%  { transform: translateY(-36%) scale(1.07); }
  100% { transform: translateY(0) scale(1); }
}

@media (prefers-reduced-motion: reduce) {
  .mb-ring-spin,
  .mb-token.is-turn .mb-token-body,
  .mb-token.is-hop-a .mb-token-body,
  .mb-token.is-hop-b .mb-token-body,
  .mb-tile.is-target::after { animation: none; }
  .mb-token { transition: none; }
}
