/*
 * bong-bong-qua.css — Bảng kiểu của bong bóng quà (`src/live/bongBongQua.js`).
 *
 * ─── VÌ SAO TÁCH RA KHỎI styles.css ────────────────────────────────────────
 * Bong bóng quà là lớp phủ DOM, nên nó cần CSS — mà HAI trang cần nó lại KHÔNG
 * dùng chung bảng kiểu: sàn nhảy nạp `styles.css` (hơn hai nghìn dòng cho bảng
 * điều khiển, bảng tên, đồng hồ…), còn trang Đua Cờ Thế Giới cố ý không nạp file
 * đó — xem chú thích trong `dua-co.html`.
 *
 * Chép khối này sang trang thứ hai thì hai bản sẽ trôi dạt: sửa một bên là bên
 * kia âm thầm khác đi, và cái khác đi ấy chỉ lộ ra khi có khách tặng quà giữa
 * buổi phát sóng. Nên nó thành một file, cả hai trang cùng nạp.
 *
 * Đặt trong `assets/` chứ không ở gốc dự án: thư mục đó đã được phục vụ tĩnh sẵn,
 * còn thêm một file .css ở gốc thì phải khai thêm vào `STATIC_FILES` bên
 * server/index.js — một chỗ nữa để quên.
 */

/*
  Khi có người tặng quà: một bong bóng NỞ TO giữa khung, giữ một nhịp ngắn đủ đọc
  tên, rồi VỠ TAN thành mảnh bắn ra. Cả ba nhịp gói trong 1–2 giây (biến
  `--qua-nhip` do `src/live/bongBongQua.js` đặt), xong là biến mất sạch.

  ĐƯỢC PHÉP che sàn và nhân vật — chủ dự án đã chốt — vì nó chỉ che trong chớp mắt.

  ⚠ CHỈ ĐỘNG TỚI `transform` VÀ `opacity`. Đây là cảnh đang lên sóng: mọi thuộc tính bắt
  trình duyệt tính lại bố cục (width, top, margin… đổi theo từng khung) đều làm rớt
  khung hình của buổi phát sóng. Hai thuộc tính trên chạy thẳng trên GPU.

  Nằm trên bảng CÁCH CHƠI (15) và đồng hồ phiên (17), nhưng DƯỚI lớp thông báo
  phiên (20): lúc sàn đã tạm dừng thì không còn gì đáng nổ bong bóng nữa.
*/
#qua-lop {
  position: fixed;
  inset: 0;
  z-index: 18;
  pointer-events: none;
  overflow: hidden;
}

.qua-bong {
  --qua-nhip: 1500ms;
  --qua-co: 30vmin;

  position: absolute;
  left: 50%;
  /* Hơi cao hơn tâm khung: chừa đáy cho bảng CÁCH CHƠI và dải LED trong cảnh. */
  top: 45%;
  width: var(--qua-co);
  height: var(--qua-co);
  margin: calc(var(--qua-co) / -2) 0 0 calc(var(--qua-co) / -2);
  pointer-events: none;
}

/* --- Thân bong bóng --- */
.qua-cau {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: calc(var(--qua-co) * 0.03);
  border-radius: 50%;

  /* Chất xà phòng: sáng lệch về góc trên trái, trong dần về giữa. */
  background:
    radial-gradient(circle at 32% 26%, rgba(255, 255, 255, 0.55), rgba(255, 255, 255, 0.06) 42%, rgba(255, 255, 255, 0) 62%),
    radial-gradient(circle at 70% 78%, rgba(34, 232, 255, 0.30), rgba(34, 232, 255, 0) 58%),
    radial-gradient(circle at 50% 50%, rgba(20, 8, 34, 0.80), rgba(10, 6, 26, 0.62));
  border: 2px solid rgba(255, 255, 255, 0.42);
  box-shadow:
    0 0 0 1px rgba(255, 47, 185, 0.35),
    0 10px 46px rgba(0, 0, 0, 0.5),
    0 0 60px rgba(255, 47, 185, 0.28),
    inset 0 0 40px rgba(255, 255, 255, 0.12);

  transform-origin: 50% 55%;
  animation: qua-vong-doi var(--qua-nhip) cubic-bezier(0.34, 1.3, 0.5, 1) both;
  will-change: transform, opacity;
  backface-visibility: hidden;
}

/* Vành cầu vồng mỏng — dấu hiệu nhận ra ngay là bong bóng xà phòng. */
.qua-cau::before {
  content: '';
  position: absolute;
  inset: -2px;
  border-radius: inherit;
  padding: 2px;
  background: conic-gradient(from 210deg, #ff2fb9, #22e8ff, #b06bff, #ffd84d, #ff2fb9);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
          mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
          mask-composite: exclude;
  opacity: 0.85;
  pointer-events: none;
}

/* Đốm sáng cao nhất trên mặt cầu */
.qua-cau::after {
  content: '';
  position: absolute;
  left: 22%;
  top: 15%;
  width: 20%;
  height: 13%;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.75);
  filter: blur(3px);
  pointer-events: none;
}

/* --- Ảnh món quà --- */
.qua-anh-hop {
  position: relative;
  width: calc(var(--qua-co) * 0.42);
  height: calc(var(--qua-co) * 0.42);
  display: grid;
  place-items: center;
}

/* Biểu tượng dự phòng hiện SẴN, ảnh thật chỉ thế chỗ khi đã tải xong. Ảnh quà
   hỏng hay chưa về thì vẫn có thứ để nhìn, không bao giờ là một ô trống. */
.qua-du-phong {
  font-size: calc(var(--qua-co) * 0.30);
  line-height: 1;
  filter: drop-shadow(0 0 12px rgba(255, 216, 77, 0.6));
}

.qua-anh {
  display: none;
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  filter: drop-shadow(0 4px 14px rgba(0, 0, 0, 0.55));
}
.qua-anh-hop.co-anh .qua-anh { display: block; }
.qua-anh-hop.co-anh .qua-du-phong { display: none; }

/* --- Số lượng (quà chuỗi combo đã gộp sẵn ở máy chủ) --- */
/* Vị trí kéo vào trong khá nhiều so với mép ô vuông: khung chứa là hình VUÔNG còn
   bong bóng là hình TRÒN, nên sát mép ô nghĩa là đã lòi ra ngoài vành. */
.qua-so {
  position: absolute;
  right: 11%;
  top: 23%;
  padding: 0.1em 0.5em;
  border-radius: 999px;
  background: linear-gradient(160deg, #ffd84d, #ff9d2f);
  color: #2a1400;
  font-size: calc(var(--qua-co) * 0.11);
  font-weight: 900;
  letter-spacing: 0.02em;
  box-shadow: 0 3px 12px rgba(0, 0, 0, 0.45);
}

/* --- Tên món quà --- */
.qua-ten-qua {
  /* Cùng lý do với `.qua-so`: bề ngang dùng được ở độ cao này hẹp hơn cạnh ô vuông. */
  max-width: 72%;
  text-align: center;
  font-size: calc(var(--qua-co) * 0.098);
  font-weight: 800;
  color: #fff;
  text-shadow: 0 2px 10px rgba(0, 0, 0, 0.7), 0 0 16px rgba(255, 216, 77, 0.5);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* --- Người tặng: ảnh đại diện + tên --- */
.qua-nguoi {
  display: flex;
  align-items: center;
  gap: calc(var(--qua-co) * 0.035);
  max-width: 76%;
  padding: calc(var(--qua-co) * 0.018) calc(var(--qua-co) * 0.055) calc(var(--qua-co) * 0.018) calc(var(--qua-co) * 0.018);
  border-radius: 999px;
  background: rgba(6, 4, 16, 0.62);
  border: 1px solid rgba(255, 255, 255, 0.16);
}

.qua-ava {
  position: relative;
  flex: 0 0 auto;
  width: calc(var(--qua-co) * 0.115);
  height: calc(var(--qua-co) * 0.115);
  border-radius: 50%;
  overflow: hidden;
  display: grid;
  place-items: center;
  box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.35);
}

.qua-chu-cai {
  font-size: calc(var(--qua-co) * 0.062);
  font-weight: 900;
  color: #fff;
}

.qua-ava-anh {
  display: none;
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.qua-ava.co-anh .qua-ava-anh { display: block; }
.qua-ava.co-anh .qua-chu-cai { display: none; }

.qua-ten-nguoi {
  font-size: calc(var(--qua-co) * 0.075);
  font-weight: 700;
  color: #fff;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* --- Nhãn ĐỒ THỬ --- */
/* Quà bắn thử từ bảng điều khiển. Phải nhìn là biết ngay không phải quà thật —
   nó cũng không được cộng vào bất kỳ số liệu hay bảng xếp hạng nào. */
.qua-thu {
  position: absolute;
  left: 50%;
  /* Sát vành trên, đủ để không đè lên ảnh món quà ở giữa bong bóng. */
  top: 4.5%;
  transform: translateX(-50%);
  padding: 0.12em 0.7em;
  border-radius: 999px;
  background: rgba(255, 210, 74, 0.92);
  color: #2a1e00;
  font-size: calc(var(--qua-co) * 0.062);
  font-weight: 900;
  letter-spacing: 0.16em;
}

/* --- Mảnh vỡ --- */
.qua-chum {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.qua-manh {
  position: absolute;
  left: 50%;
  top: 50%;
  width: calc(var(--qua-co) * 0.10);
  height: calc(var(--qua-co) * 0.07);
  margin: calc(var(--qua-co) * -0.035) 0 0 calc(var(--qua-co) * -0.05);
  border-radius: 60% 40% 55% 45%;
  background: linear-gradient(140deg, rgba(255, 255, 255, 0.95), rgba(34, 232, 255, 0.75) 55%, rgba(255, 47, 185, 0.7));
  box-shadow: 0 0 14px rgba(255, 255, 255, 0.65);

  /* Bay ra đúng lúc thân bong bóng bung: 74% quãng đời, chạy nốt 26% còn lại. */
  animation: qua-ban calc(var(--qua-nhip) * 0.26) cubic-bezier(0.15, 0.75, 0.4, 1) both;
  animation-delay: calc(var(--qua-nhip) * 0.74);
  will-change: transform, opacity;
}

/*
  Nở — giữ — vỡ, tính theo phần trăm của `--qua-nhip`:
    0–20%   nở bung ra, quá đà một chút rồi nảy về (chất bong bóng)
    20–74%  đứng yên cho người xem kịp đọc tên và nhìn ra món quà
    74–82%  căng phồng rồi BIẾN MẤT gọn trong ~8% quãng đời — vỡ chứ không mờ dần
    82–100% để trống cho mảnh vỡ bay nốt
*/
@keyframes qua-vong-doi {
  0%   { transform: scale(0.10); opacity: 0; }
  8%   { opacity: 1; }
  12%  { transform: scale(1.12); }
  17%  { transform: scale(0.94); }
  20%  { transform: scale(1); }
  74%  { transform: scale(1); opacity: 1; }
  78%  { transform: scale(1.13); opacity: 1; }
  82%  { transform: scale(1.24); opacity: 0; }
  100% { transform: scale(1.24); opacity: 0; }
}

/* Mảnh xuất phát trên vành bong bóng rồi văng hẳn ra ngoài, vừa bay vừa xoay và
   nhỏ lại. Toạ độ `--dx0/--dy0` và `--dx/--dy` do `bongBongQua.js` tính sẵn theo
   `--qua-co` — xem chú thích ở `_manhVo`. */
@keyframes qua-ban {
  0%   { transform: translate(var(--dx0), var(--dy0)) rotate(0deg) scale(0.65); opacity: 0; }
  15%  { opacity: 1; }
  100% { transform: translate(var(--dx), var(--dy)) rotate(var(--xoay)) scale(0.35); opacity: 0; }
}

/*
  Giảm chuyển động: bỏ hẳn nở và vỡ, chỉ hiện rồi ẩn.

  Có HAI đường vào cùng một kết quả, và cần cả hai. `bongBongQua.js` đọc
  `matchMedia` lúc dựng để KHÔNG tạo ra mảnh vỡ (đỡ hẳn phần việc), còn khối media
  dưới đây chặn hoạt ảnh kể cả khi người dùng đổi thiết lập giữa buổi.
*/
.qua-tinh .qua-cau {
  animation: qua-hien-an var(--qua-nhip) linear both;
}
.qua-tinh .qua-chum { display: none; }

@keyframes qua-hien-an {
  0%   { opacity: 0; }
  10%  { opacity: 1; }
  88%  { opacity: 1; }
  100% { opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .qua-cau { animation: qua-hien-an var(--qua-nhip) linear both; }
  .qua-chum { display: none; }
}


/* ═══════════════════════════════════════════════════════════════════════════
   KIỂU "THẺ" — dựng cho Câu Lạc Bộ V2 (kieu: 'the' bên bongBongQua.js)

   Một THẺ NGANG trượt vào từ mép trái, đứng lại một nhịp đủ đọc, một vệt sáng
   quét qua mặt thẻ, rồi nó trượt tiếp ra mép phải. Không nở, không vỡ.

   ─── VÌ SAO ĐỔI CẢ CHỖ ĐỨNG, KHÔNG CHỈ ĐỔI HÌNH ──────────────────────────
   Bong bóng kiểu cũ nở tới 40vmin ngay giữa khung: đúng chỗ sân khấu, màn hình
   và đám nhân vật đang diễn. Chấp nhận được ở sàn V1 vì nó chỉ che trong chớp
   mắt. Nhưng sàn V2 rộng gấp ba, thứ đáng nhìn trải rộng hơn hẳn, nên một khối
   tròn giữa khung che mất nhiều hơn nhiều.

   Thẻ ngang cao chỉ bằng nửa cỡ cũ và đứng ở 26% chiều cao — trên đầu đám đông,
   dưới dải LED chạy chữ.

   ─── DÙNG LẠI PHẦN LỚN BẢNG KIỂU CŨ ──────────────────────────────────────
   Mọi thứ bên trong (ô ảnh quà, huy hiệu số lượng, tên quà, ô người tặng, nhãn
   THỬ) giữ nguyên lớp CSS cũ — dưới đây chỉ ĐÈ phần bố cục và hoạt ảnh. Chép
   thành một bảng riêng là chép luôn mấy chỗ đã sửa (ảnh hỏng, tên tràn, emoji
   bị cắt đôi) rồi hai bản trôi dạt.

   ⚠ VẪN CHỈ ĐỘNG TỚI transform VÀ opacity. Vệt sáng quét bằng translateX, KHÔNG
   bằng left — đổi left mỗi khung là bắt trình duyệt tính lại bố cục giữa lúc
   đang phát sóng.
   ═══════════════════════════════════════════════════════════════════════════ */

.qua-the {
  /* 2,95 chứ không phải 1,95, và con số này đo ra chứ không ước.
   *
   * Hàng ngang chứa NĂM mắt xích: ảnh quà, huy hiệu ×số, tên quà, ô người tặng,
   * nhãn THỬ. Ở 1,95 tên quà bị cắt còn 'Rồng …' và tên người tặng teo về 0; ở
   * 2,35 vẫn cụt thành 'Cánh thiê…'. Mà hai cái tên ấy chính là thứ người bỏ
   * tiền ra tặng muốn nhìn thấy trên sóng.
   *
   * ⚠ Đây là bề ngang TỐI ĐA, không phải bề ngang luôn dùng: `--qua-co` đổi theo
   * giá trị quà (27 / 33 / 40vmin), nên quà nhỏ vẫn ra thẻ nhỏ. */
  --qua-rong: calc(var(--qua-co) * 2.95);
  --qua-cao: calc(var(--qua-co) * 0.5);

  left: 50%;
  /* Trên đầu đám đông, dưới dải LED chạy chữ quanh phòng. */
  top: 26%;
  width: var(--qua-rong);
  height: var(--qua-cao);
  margin: calc(var(--qua-cao) / -2) 0 0 calc(var(--qua-rong) / -2);
}

.qua-the .qua-cau {
  flex-direction: row;
  justify-content: flex-start;
  gap: calc(var(--qua-co) * 0.06);
  padding: 0 calc(var(--qua-co) * 0.1);
  border-radius: calc(var(--qua-cao) / 2);
  background:
    linear-gradient(100deg, rgba(10, 6, 26, 0.93), rgba(26, 10, 48, 0.88) 52%, rgba(10, 6, 26, 0.93));
  overflow: hidden;
  transform-origin: 50% 50%;
  animation: qua-the-truot var(--qua-nhip) cubic-bezier(0.22, 0.9, 0.28, 1) both;
}

/* Đốm sáng cao nhất của mặt cầu chỉ có nghĩa trên hình cầu. Vành cầu vồng thì
   giữ — nó nhận border-radius: inherit nên tự bo theo hình viên thuốc. */
.qua-the .qua-cau::after { display: none; }

.qua-the .qua-anh-hop {
  flex: 0 0 auto;
  width: calc(var(--qua-co) * 0.34);
  height: calc(var(--qua-co) * 0.34);
}

/* Huy hiệu số lượng thôi neo tuyệt đối ở góc — hàng ngang thì nó đứng thành một
   mắt xích trong hàng, ngay sau ảnh quà. */
.qua-the .qua-so {
  position: static;
  flex: 0 0 auto;
  align-self: center;
}

.qua-the .qua-ten-qua {
  flex: 1 1 auto;
  min-width: 0;
  max-width: none;
  text-align: left;
  font-size: calc(var(--qua-co) * 0.105);
}

/* Huy hiệu ×số nhỏ lại một bậc: ở hàng ngang nó tranh chỗ trực tiếp với tên quà,
   mà tên quà mới là thứ cần đọc trọn. */
.qua-the .qua-so { font-size: calc(var(--qua-co) * 0.095); }

.qua-the .qua-nguoi { flex: 0 1 auto; min-width: 0; max-width: 34%; }

/* Nhãn THỬ cũng thôi neo tuyệt đối: ở hàng ngang nó là mắt xích cuối. Để nguyên
   `position: absolute` thì nó nằm đè lên ô người tặng — đã thấy đúng thế khi đo. */
.qua-the .qua-thu {
  position: static;
  flex: 0 0 auto;
  align-self: center;
  transform: none;
}

/* Vệt sáng quét ngang mặt thẻ. */
.qua-the .qua-loe {
  position: absolute;
  top: -25%;
  bottom: -25%;
  left: 0;
  width: 20%;
  background: linear-gradient(100deg, rgba(255, 255, 255, 0), rgba(255, 255, 255, 0.8), rgba(255, 255, 255, 0));
  filter: blur(5px);
  pointer-events: none;
  transform: translateX(-160%) skewX(-18deg);
  animation: qua-the-loe calc(var(--qua-nhip) * 0.38) ease-out both;
  animation-delay: calc(var(--qua-nhip) * 0.22);
  will-change: transform, opacity;
}

/*
  Trượt vào từ NGOÀI mép trái, đứng yên gần hết quãng đời, rồi trượt ra ngoài
  mép phải.

  ⚠ Quãng dịch tính bằng "50vw + bề ngang thẻ", KHÔNG bằng phần trăm. Phần trăm
  trong translateX lấy mốc là bề ngang của CHÍNH cái thẻ (~60vmin), nên
  translateX(120%) chỉ đẩy nó nhích hơn một thân — thẻ tan biến ngay giữa màn
  hình thay vì đi khỏi khung. Đúng họ lỗi đã ghi ở _manhVo.
*/
@keyframes qua-the-truot {
  0%   { transform: translateX(calc(-50vw - var(--qua-rong))); opacity: 0; }
  6%   { opacity: 1; }
  16%  { transform: translateX(2%); }
  22%  { transform: translateX(0); opacity: 1; }
  80%  { transform: translateX(0); opacity: 1; }
  100% { transform: translateX(calc(50vw + var(--qua-rong))); opacity: 0; }
}

@keyframes qua-the-loe {
  0%   { transform: translateX(-160%) skewX(-18deg); opacity: 0; }
  18%  { opacity: 0.9; }
  100% { transform: translateX(540%) skewX(-18deg); opacity: 0; }
}

/*
  Giảm chuyển động, kiểu thẻ.

  ⚠ CẦN RIÊNG KHỐI NÀY. Luật chung ở trên viết là `.qua-cau` (một lớp), còn luật
  của thẻ là `.qua-the .qua-cau` (hai lớp) nên nó ĐÈ NGƯỢC lại luật giảm chuyển
  động — người bật thiết lập ấy vẫn lãnh nguyên cú trượt ngang.
*/
.qua-the.qua-tinh .qua-cau { animation: qua-hien-an var(--qua-nhip) linear both; }
.qua-the.qua-tinh .qua-loe { display: none; }

@media (prefers-reduced-motion: reduce) {
  .qua-the .qua-cau { animation: qua-hien-an var(--qua-nhip) linear both; }
  .qua-the .qua-loe { display: none; }
}
