/* Cùng bảng màu/khuôn với public/games/vua-tieng-viet/style.css (theme trang
   host khai lại bằng hex — bundle chạy độc lập trong iframe, không có
   Tailwind/CSS variables của trang host). */
* {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  height: 100%;
  font-family:
    'Be Vietnam Pro',
    system-ui,
    -apple-system,
    'Segoe UI',
    sans-serif;
  background: #fff8ed;
  color: #4a3b5c;
  overflow: hidden;
}

body {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 10px;
  user-select: none;
  /* fitToViewport() (game.js) scale body từ góc trên-trái khi khung lớn. */
  transform-origin: 0 0;
}

.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 8px 14px;
  border-radius: 16px;
  border: 2px solid #ffe1c2;
  background: #ffffff;
  box-shadow: 0 4px 0 #e7dcc7;
  flex-shrink: 0;
  flex-wrap: wrap;
}

.stats {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
}

.stat {
  font-size: 16px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.status {
  display: flex;
  align-items: center;
  gap: 10px;
}

.lives {
  display: flex;
  gap: 2px;
  font-size: 18px;
  line-height: 1;
  color: #e0554a;
}

.lives .heart.empty {
  color: #ffd8d3;
}

.timer {
  min-width: 46px;
  text-align: center;
  padding: 5px 10px;
  border-radius: 999px;
  border: 2px solid #ffe1c2;
  background: #fff8ed;
  font-size: 14px;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}

/* Đồng hồ của TỪ hiện tại (không phải cả vòng) — nhấp nháy khi từ khoá sắp
   chạm tới hiệp sĩ để tăng cảm giác gấp gáp. */
.timer.low {
  background: #ffe9e6;
  border-color: #e0554a;
  color: #c23f36;
  animation: pulse 1s ease-in-out infinite;
}

@keyframes pulse {
  0%,
  100% {
    transform: scale(1);
  }
  50% {
    transform: scale(1.08);
  }
}

/* flex-direction: column (không phải row mặc định) — để `.arena-card` co
   giãn được theo TRỤC DỌC bằng flex:1 (xem bên dưới), lấp vừa đúng khoảng
   trống còn lại giữa topbar và bàn phím ở MỌI chiều cao khung chơi, thay vì
   giữ kích thước cố định rồi tràn đè lên topbar khi khung hẹp lại (đã gặp
   thật khi test ở host width hẹp hơn — arena-card cao cố định không co
   được, tràn ngược lên che mất topbar). align-items: center giờ canh giữa
   THEO CHIỀU NGANG (đúng ý muốn: card rộng tối đa 760px nằm giữa). */
.play-area {
  position: relative;
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding-top: 4px;
}

/* Toast báo qua vòng, tự ẩn sau ROUND_BANNER_MS (game.js) — không chặn thao
   tác (pointer-events: none) vì lúc này trận đấu đã bị khoá bởi
   `game.locked`, không cần khoá kép. */
.round-banner {
  position: absolute;
  top: 6px;
  left: 50%;
  z-index: 2;
  padding: 10px 20px;
  border-radius: 999px;
  background: #4a3b5c;
  color: #fff8ed;
  font-size: 14px;
  font-weight: 800;
  text-align: center;
  white-space: nowrap;
  box-shadow: 0 4px 0 rgba(0, 0, 0, 0.15);
  opacity: 0;
  pointer-events: none;
  transform: translate(-50%, -14px);
  transition:
    opacity 0.2s ease,
    transform 0.2s ease;
}

.round-banner.show {
  opacity: 1;
  transform: translate(-50%, 0);
}

.arena-card {
  width: 100%;
  max-width: 760px;
  /* flex:1 + min-height:0 — co giãn lấp đúng phần cao còn lại play-area
     dành cho nó (xem giải thích ở .play-area), không giữ chiều cao cố định
     nên không bao giờ tràn ra ngoài dù khung chơi thấp/hẹp cỡ nào. */
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding: 12px 18px;
  border-radius: 22px;
  border: 2px solid #ffe1c2;
  background: #ffffff;
  box-shadow: 0 4px 0 #e7dcc7;
}

.question-count {
  align-self: flex-start;
  margin: 0;
  font-size: 13px;
  font-weight: 700;
  color: #7a6a8c;
}

/* "Chiến trường" — hiệp sĩ đứng cố định bên trái, từ khoá (kẻ địch) trượt từ
   phải sang. flex:1 (không phải height cố định) — lấp hết chiều cao còn lại
   trong `.arena-card` sau `.question-count`, tự co giãn theo khung chơi;
   min-height giữ 1 sàn tối thiểu để hiệp sĩ/thẻ từ khoá luôn còn chỗ đứng
   dù khung chơi rất thấp, max-height chặn không cho phình quá to lố trên
   màn hình rất rộng. */
.battlefield {
  position: relative;
  width: 100%;
  flex: 1;
  min-height: 150px;
  max-height: 320px;
  overflow: hidden;
  /* Màu nền dự phòng — trùng tông trời ban ngày (assets/sky-day.png), hiện
     ngay cả khi ảnh trời chưa kịp tải. */
  background-color: #6aadff;
}

/* Bầu trời đổi theo TỪNG CẶP VÒNG (2 vòng/mức độ từ, giống cách chia
   MS_PER_CHAR_BY_ROUND theo mức trong game.js) — vừa báo hiệu trực quan
   "sắp khó hơn" mỗi khi qua mức mới, vừa kể 1 câu chuyện nhỏ: trận đấu kéo
   dài từ sáng (.tier-1) sang hoàng hôn (.tier-2) rồi tới đêm khuya (.tier-3)
   khi thử thách lên đỉnh điểm. Cùng 3 ảnh trong bộ "New free backgrounds
   part1" (background 4/2/1 theo thứ tự) — background 3 (tím, có dơi) không
   dùng vì hơi rùng rợn so với đối tượng học sinh nhỏ tuổi.
   `background-size: cover` (không phải "100% 100%") để phóng đúng tỉ lệ gốc
   rồi cắt bớt phần thừa, TRÁNH méo hình (battlefield rất dẹt/ngang so với
   ảnh gốc gần vuông 16:9). `center top` giữ lại phần trời + đỉnh mây, bỏ
   viền mây lởm chởm sát đáy ảnh gốc (không hợp với dải đất pixel có sẵn).
   Đặt làm phần tử ĐẦU TIÊN trong `.battlefield` (index.html) để luôn nằm
   dưới nền đất/hiệp sĩ/thẻ từ khoá theo thứ tự DOM, không cần z-index. */
.sky-clouds {
  position: absolute;
  inset: 0;
  background-repeat: no-repeat;
  background-size: cover;
  background-position: center top;
}

.sky-clouds.tier-1 {
  background-image: url('assets/sky-day.png');
}

.sky-clouds.tier-2 {
  background-image: url('assets/sky-sunset.png');
}

.sky-clouds.tier-3 {
  background-image: url('assets/sky-night.png');
}

/* Nền đất pixel lặp lại (tự vẽ bằng lưới 16x16, xem assets/ground-tile.png)
   — chỉ có đốm sáng/tối/sỏi/cỏ nằm Ở TRONG lưới (không chạm biên trên/dưới/
   trái/phải), nhờ vậy ghép cạnh nhau tuyệt đối liền mạch, không lộ đường
   nối. Phóng 2x (32px) qua `background-size` khớp đúng tỉ lệ pixel của
   sprite hiệp sĩ (cũng phóng 2x từ khung gốc 120x80), giữ cảm giác cùng một
   "lưới pixel" giữa nhân vật và mặt đất nó đứng lên. */
.ground {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 20px;
  border-top: 2px solid #c9a86f;
  background-image: url('assets/ground-tile.png');
  background-size: 32px 32px;
  background-repeat: repeat;
  image-rendering: pixelated;
}

/* Sprite hiệp sĩ (FreeKnight_v1, ảnh cung cấp sẵn trong repo) — dựng bằng kỹ
   thuật sprite-sheet + `steps()`: mỗi ảnh nguồn là 1 dải khung hình ngang
   120x80px/khung, phóng 2x (240x160) rồi lùi `background-position` đúng số
   khung mỗi giây bằng `animation: steps(N)`. Class `.attack`/`.hit` đổi hẳn
   sheet nguồn + animation trong lúc xử lý kết quả 1 từ (game.js thêm/gỡ class
   theo timeout khớp ATTACK_RESOLVE_MS/HIT_RESOLVE_MS), mặc định luôn chạy
   Idle để nhân vật không bao giờ đứng im hoàn toàn. */
.knight {
  position: absolute;
  left: 16px;
  bottom: 10px;
  width: 240px;
  height: 160px;
  background-image: url('assets/knight-idle.png');
  background-repeat: no-repeat;
  background-size: 2400px 160px;
  image-rendering: pixelated;
  animation: knight-idle 1s steps(10) infinite;
}

@keyframes knight-idle {
  from {
    background-position: 0 0;
  }
  to {
    background-position: -2400px 0;
  }
}

.knight.attack {
  background-image: url('assets/knight-attack.png');
  background-size: 960px 160px;
  animation: knight-attack 0.32s steps(4) 1;
}

@keyframes knight-attack {
  from {
    background-position: 0 0;
  }
  to {
    background-position: -960px 0;
  }
}

/* Ảnh "Hit" chỉ có 1 khung (không cần steps) — dùng thêm hiệu ứng rung +
   nhoè đỏ nhẹ (drop-shadow) để báo hiệp sĩ vừa trúng đòn khi từ khoá chạm
   tới, tách biệt rõ với trạng thái tấn công. */
.knight.hit {
  background-image: url('assets/knight-hit.png');
  background-size: 240px 160px;
  animation: knight-hit-shake 0.4s ease;
  filter: drop-shadow(2px 0 0 #e0554a) drop-shadow(-2px 0 0 #e0554a);
}

@keyframes knight-hit-shake {
  0%,
  100% {
    transform: translateX(0);
  }
  25% {
    transform: translateX(-6px);
  }
  75% {
    transform: translateX(6px);
  }
}

/* Thẻ từ khoá "địch" — vị trí điều khiển bằng `right` (%), game.js đặt giá
   trị khởi đầu rồi đổi sang giá trị đích ở khung hình kế tiếp để trình
   duyệt tự chạy transition mượt, không cần vòng lặp requestAnimationFrame
   thủ công. */
.enemy-word {
  position: absolute;
  /* 36% (không phải 50%) — dồn lên trên 1 chút để chừa chỗ cho `.demon` bay
     BÊN DƯỚI thẻ từ (xem .demon) mà không đụng dải đất. */
  top: 36%;
  right: 4%;
  transform: translateY(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  min-width: 90px;
  padding: 8px 14px;
  border-radius: 12px;
  border: 2px solid #ffe1c2;
  background: #ffffff;
  box-shadow: 0 3px 0 #e7dcc7;
}

.enemy-word.wrong {
  animation: shake 0.22s ease;
}

@keyframes shake {
  0%,
  100% {
    transform: translateY(-50%) translateX(0);
  }
  25% {
    transform: translateY(-50%) translateX(-4px);
  }
  75% {
    transform: translateY(-50%) translateX(4px);
  }
}

/* 0.42s (không phải 0.25s trước đây) — kéo dài đúng bằng ATTACK_RESOLVE_MS
   (game.js) để thẻ từ mờ dần ĐỒNG THỜI với lúc quái vật `.demon` chạy hết
   chuỗi hurt->death bên dưới, không bị cắt cụt giữa chừng. */
.enemy-word.defeated {
  opacity: 0;
  transform: translateY(-50%) scale(0.6);
  transition:
    opacity 0.42s ease,
    transform 0.42s ease;
}

/* Quái vật bay mang theo thẻ từ khoá (bộ "Flying Demon 2D Pixel Art", bản
   with_outline cho khớp phong cách viền đen với sprite hiệp sĩ) — đặt BÊN
   DƯỚI thẻ từ (top: 100%), tự trôi theo đúng vị trí `right` của `.enemy-word`
   (cha) nên không cần đồng bộ toạ độ riêng. Mặc định luôn vỗ cánh bay
   (FLYING, lặp) như hiệp sĩ luôn có Idle chạy nền; game.js đổi hẳn sheet +
   animation sang .attack (né/lao vào lúc từ khoá chạm hiệp sĩ, khớp
   HIT_RESOLVE_MS) hoặc .hurt rồi .death (lúc gõ đúng, khớp ATTACK_RESOLVE_MS)
   — không dùng khung IDLE có sẵn trong bộ vì quái vật trong game này không
   bao giờ đứng yên, luôn ở 1 trong 3 trạng thái trên. */
.demon {
  position: absolute;
  top: 100%;
  left: 50%;
  transform: translateX(-50%);
  margin-top: 6px;
  width: 96px;
  height: 85px;
  background-repeat: no-repeat;
  image-rendering: pixelated;
  pointer-events: none;
  background-image: url('assets/demon-flying.png');
  background-size: 384px 85px;
  animation: demon-flying 0.6s steps(4) infinite;
}

@keyframes demon-flying {
  from {
    background-position: 0 0;
  }
  to {
    background-position: -384px 0;
  }
}

.demon.attack {
  background-image: url('assets/demon-attack.png');
  background-size: 768px 85px;
  animation: demon-attack 0.48s steps(8) 1;
}

@keyframes demon-attack {
  from {
    background-position: 0 0;
  }
  to {
    background-position: -768px 0;
  }
}

.demon.hurt {
  background-image: url('assets/demon-hurt.png');
  background-size: 384px 85px;
  animation: demon-hurt 0.12s steps(4) 1;
}

@keyframes demon-hurt {
  from {
    background-position: 0 0;
  }
  to {
    background-position: -384px 0;
  }
}

.demon.death {
  background-image: url('assets/demon-death.png');
  background-size: 672px 85px;
  animation: demon-death 0.3s steps(7) 1;
}

@keyframes demon-death {
  from {
    background-position: 0 0;
  }
  to {
    background-position: -672px 0;
  }
}

.word-progress {
  width: 100%;
  height: 4px;
  border-radius: 999px;
  background: #ffe1c2;
  overflow: hidden;
}

.word-progress-fill {
  height: 100%;
  width: 100%;
  background: #7bd8b0;
  transition:
    width 0.1s linear,
    background 0.2s ease;
}

.word-progress-fill.low {
  background: #e0554a;
}

.word-text {
  font-family: 'SFMono-Regular', Consolas, Menlo, monospace;
  font-size: 24px;
  font-weight: 800;
  letter-spacing: 1px;
  white-space: pre;
}

.word-text .char {
  color: #c9bfd6;
}

.word-text .char.done {
  color: #2f9e6c;
}

.word-text .char.missed {
  color: #c23f36;
}

/* Dấu cách để trống như chữ viết thường (không gạch chân) — con trỏ nhấp
   nháy vẫn đứng ở đó khi tới lượt bấm phím cách. */
.char.space {
  display: inline-block;
}

/* Con trỏ nhấp nháy trước chữ cần gõ tiếp theo — gợi ý rõ vị trí,
   đúng tinh thần "không nhìn bàn phím, nhìn màn hình" của luyện gõ 10 ngón. */
.char.next {
  display: inline-block;
  color: #4a3b5c;
  position: relative;
}

.char.next::before {
  content: '';
  position: absolute;
  left: -1px;
  top: 1px;
  bottom: 1px;
  width: 2px;
  background: #ff8e6c;
  animation: caret-blink 0.8s step-end infinite;
}

@keyframes caret-blink {
  0%,
  49% {
    opacity: 1;
  }
  50%,
  100% {
    opacity: 0;
  }
}

/* Bàn phím ảo dưới "màn hình" — mỗi `.key` sáng đèn XANH/ĐỎ đúng theo phím
   vừa gõ (game.js thêm/gỡ class theo KEY_FLASH_MS), không phải gợi ý phím
   kế tiếp (đã có con trỏ nhấp nháy riêng trên `.word-text`). Mỗi hàng tự
   canh giữa độc lập (không lệch bậc thang như bàn phím thật) — đơn giản hơn
   nhiều so với tính offset từng hàng mà vẫn nhìn cân đối, gọn. */
.keyboard {
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding: 8px 12px;
  border-radius: 16px;
  border: 2px solid #ffe1c2;
  background: #ffffff;
  box-shadow: 0 4px 0 #e7dcc7;
}

.kb-row {
  display: flex;
  justify-content: center;
  gap: 4px;
}

.key {
  width: 32px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  border-radius: 6px;
  border: 2px solid #ffe1c2;
  background: #fff8ed;
  color: #4a3b5c;
  font-family: inherit;
  font-size: 12px;
  font-weight: 800;
  transition:
    background-color 0.12s ease,
    border-color 0.12s ease,
    color 0.12s ease,
    box-shadow 0.12s ease;
}

/* Màu theo ngón phụ trách (data-finger, gán trong game.js) — đặt TRƯỚC
   .key.correct/.wrong để đèn đúng/sai vẫn đè lên màu ngón khi vừa gõ. */
[data-finger='pinky'] {
  background: #eadcff;
  border-color: #c9a7f5;
}

[data-finger='ring'] {
  background: #d6ebff;
  border-color: #8ec5ff;
}

[data-finger='middle'] {
  background: #d4f5e6;
  border-color: #7bd8b0;
}

[data-finger='index-left'] {
  background: #fff1c7;
  border-color: #ffc857;
}

[data-finger='index-right'] {
  background: #ffe0d3;
  border-color: #ff9f7a;
}

[data-finger='thumb'] {
  background: #f1ebf6;
  border-color: #c9bfd6;
}

.finger-legend {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 6px;
  margin-top: 2px;
}

.finger-legend span {
  padding: 1px 8px;
  border-radius: 999px;
  border: 2px solid;
  font-size: 10px;
  font-weight: 700;
}

/* Gờ định vị ngón trỏ trên phím F/J — đúng quy tắc đặt tay của luyện gõ 10
   ngón thật (xem nghiên cứu ở game.js): 2 ngón trỏ luôn về lại đây mà không
   cần nhìn bàn phím. */
.key[data-key='f']::after,
.key[data-key='j']::after {
  content: '';
  position: absolute;
  bottom: 4px;
  width: 10px;
  height: 2px;
  border-radius: 999px;
  background: #7a6a8c;
}

.key.correct {
  background: #7bd8b0;
  border-color: #4fae86;
  color: #ffffff;
  box-shadow: 0 0 0 4px rgba(123, 216, 176, 0.35);
}

.key.wrong {
  background: #e0554a;
  border-color: #c23f36;
  color: #ffffff;
  box-shadow: 0 0 0 4px rgba(224, 85, 74, 0.35);
}

.key--space {
  width: 220px;
  height: 28px;
  font-size: 11px;
  letter-spacing: 1px;
}

.dialog {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(74, 59, 92, 0.45);
}

.dialog[hidden] {
  display: none;
}

.dialog-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  padding: 22px 30px;
  max-width: 80%;
  border-radius: 26px;
  border: 2px solid #ffe1c2;
  background: #ffffff;
  box-shadow: 0 6px 0 #e7dcc7;
}

.dialog-card p {
  margin: 0;
  text-align: center;
}

#game-over-text {
  font-size: 18px;
  font-weight: 800;
}

#game-over-detail {
  font-size: 13px;
  font-weight: 600;
  color: #7a6a8c;
}

.dialog-card button {
  border: none;
  border-radius: 999px;
  padding: 9px 22px;
  font-size: 14px;
  font-weight: 700;
  color: #4a3b5c;
  background: #ff8e6c;
  cursor: pointer;
  transition:
    transform 0.12s ease,
    opacity 0.12s ease;
}

.dialog-card button:hover {
  transform: translateY(-1px);
  opacity: 0.92;
}
