* {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  height: 100%;
  font-family: system-ui, -apple-system, 'Segoe UI', sans-serif;
  background: #f4f4f2;
  overflow: hidden;
}

body {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 10px;
  user-select: none;
  touch-action: none;
}

/* Nền trang trí — nằm dưới cùng nhờ là phần tử đầu tiên trong <body> (thứ tự
   DOM quyết định lớp vẽ, không cần z-index, cùng cách làm với `.map-bg` ở
   public/games/kham-pha-the-gioi/style.css). Không cần giảm opacity nhiều
   như game đó: `.topbar`/`.grid` ở đây đều có nền đặc riêng (#ffffff/
   #ecfdf5) nên chữ/táo không bao giờ đè trực tiếp lên ảnh nền — ảnh chỉ lộ
   ra ở phần khung viền quanh 2 khối đó. */
.game-bg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  opacity: 0.85;
  pointer-events: none;
}

.topbar {
  /* `position: relative` (không đổi layout, chỉ đổi thứ tự vẽ) — bắt buộc để
     nằm TRÊN `.game-bg` (position: absolute): phần tử có position luôn vẽ
     sau/trên phần tử static dù đứng trước trong DOM (đã kiểm chứng — không
     có dòng này, nền trắng của topbar bị `.game-bg` che mất hoàn toàn dù
     `.game-bg` đứng trước trong HTML). `.grid` đã có sẵn `position:relative`
     nên không bị lỗi này. */
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 8px 14px;
  border-radius: 10px;
  border: 1px solid #d9d9d5;
  background: #ffffff;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
}

.score,
.time {
  font-size: 18px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.time.warning {
  color: #dc2626;
}

/* Vùng chứa `.grid` — `flex:1` lấy hết chiều cao còn lại sau `.topbar`,
   `min-height: 0` bắt buộc để flex item này được phép NHỎ HƠN kích thước nội
   dung mặc định (mặc định flex item không co dưới min-content, khiến `.grid`
   tràn ra ngoài `body{overflow:hidden}` — chính là nguyên nhân bị crop trước
   đây). `.grid` được JS đặt width/height cố định (px) giữ đúng tỉ lệ
   COLS:ROWS rồi canh giữa bằng `align-items`/`justify-content` ở đây. */
.grid-area {
  flex: 1;
  min-height: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}

.grid {
  position: relative;
  display: grid;
  gap: 2px;
  padding: 6px;
  border-radius: 10px;
  border: 1px solid #d9d9d5;
  /* Alpha ở MÀU NỀN (không phải `opacity` trên cả khối) — `opacity` sẽ làm
     mờ luôn táo/số bên trong (con kế thừa opacity của cha), trong khi chỉ
     muốn lộ nền vườn táo (`.game-bg`) qua phần NỀN, táo/số vẫn phải nét
     100%. rgba tương đương #ecfdf5 ở alpha 0.7. */
  background: rgba(236, 253, 245, 0.7);
}

.cell {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
}

.cell.removed {
  visibility: hidden;
}

.cell .apple {
  /* `--cell-size` (đặt bởi `layoutGrid()` trong game.js) là kích thước ô
     thật đo được — trước đây cỡ chữ táo cố định 20px bất kể ô to/nhỏ, tạo
     nhiều khoảng trống quanh táo khi ô lớn hơn 20px. Tỉ lệ 0.62 (thay vì
     0.55) — to hơn 1 chút nhưng vẫn chừa đủ lề trong ô (gap 2px + padding
     6px của `.grid`) để không bị cắt hình ở ô sát biên/góc lưới. */
  font-size: calc(var(--cell-size, 20px) * 0.62);
  line-height: 1;
  transition: transform 0.1s ease;
}

.cell.matched .apple {
  transform: scale(1.1);
  filter: drop-shadow(0 0 5px rgba(37, 99, 235, 0.9));
}

.cell .value {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding-top: 15%;
  font-size: calc(var(--cell-size, 20px) * 0.28);
  font-weight: 700;
  color: #fff;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.7);
  pointer-events: none;
}

.selection-box {
  position: absolute;
  pointer-events: none;
  border: 2px solid #2563eb;
  background: rgba(37, 99, 235, 0.1);
  border-radius: 6px;
}

.game-over {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.35);
}

/* `display: flex` ở trên là CSS tác giả — luôn thắng quy tắc `[hidden] {
   display: none }` của UA stylesheet bất kể độ đặc hiệu (origin tác giả >
   UA trong cascade), nên thuộc tính `hidden`/`.hidden` JS trước đây KHÔNG
   ẩn được khung này: nó hiện sẵn ngay từ lúc trang load, dù `phase` đang là
   `PLAYING`. Độ đặc hiệu của selector này (0,2,0) cao hơn `.game-over`
   (0,1,0) nên thắng được, khôi phục đúng hành vi ẩn/hiện theo `hidden`. */
.game-over[hidden] {
  display: none;
}

.game-over-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  padding: 20px 28px;
  border-radius: 12px;
  background: #ffffff;
}

.game-over p {
  margin: 0;
  font-size: 18px;
  font-weight: 700;
  text-align: center;
}

.game-over button {
  border: none;
  border-radius: 999px;
  padding: 8px 20px;
  font-size: 14px;
  font-weight: 600;
  color: #ffffff;
  background: #2563eb;
  cursor: pointer;
}

.game-over button:hover {
  opacity: 0.9;
}
