/* Trùm sống động (QĐ-34) — dùng chung cho thẻ trùm trên Training và trang Hang Trùm. Tệp viết tay.
   Ba lớp lồng nhau, mỗi lớp một việc, chỉ transform/opacity (không đụng bố cục):
     .ts-cu   cử chỉ tự động + nảy khi chạm (trum-song.js, Web Animations)
     .ts-tho  nhịp thở CSS luôn chạy, gốc ở đáy hình (--goc-y, đo từ ảnh bởi cat_nen.py), nhịp theo chặng cuồng nộ
     .ts-anh  ảnh WebP trong suốt (+ .ts-mat: khung mắt nhắm tuỳ chọn để chớp mắt)
   Hơi nước (chặng 1–2) và tim (chặng 4) là phần tử phụ bay trong .ts-fx, không vẽ lại ảnh.
   Máy bật "giảm chuyển động": đứng yên hoàn toàn, chạm vào vẫn hiện câu thoại (không nảy). */

.ts { position: relative; display: block; width: 100%; height: 100%; --goc-y: 92%; --dinh: 16%; --dau: 50%; }
.ts-cham {
  position: absolute; inset: 0; display: block; width: 100%; height: 100%; margin: 0; padding: 0; border: 0; border-radius: 50%;
  background: none; color: inherit; cursor: pointer; -webkit-tap-highlight-color: transparent; touch-action: manipulation;
}
.ts-cham:focus-visible { outline: 2px solid #FFD3E2; outline-offset: 3px; }
.ts-cu, .ts-tho { position: absolute; inset: 0; display: block; transform-origin: 50% var(--goc-y); }
.ts .ts-anh, .ts .ts-mat {
  position: absolute; inset: 0; left: 0; top: 0; display: block; width: 100%; height: 100%; max-width: none;
  margin: 0; padding: 0; border-radius: 0; background: none; box-shadow: none; translate: none; object-fit: contain;
}
/* chớp mắt: lớp mắt nhắm cùng khung vuông, cùng cỡ với ảnh chính (trong suốt trừ hai mắt) và cùng luật CSS ở trên — trang nào
   đặt đệm/lọc màu cho ảnh trùm (vd .ht-luoi.sap .trum-hinh img) thì lớp mắt nhận y như ảnh chính → trùng từng điểm.
   Ẩn, chỉ hiện 120 ms khi .ts-chop (trum-song.js). Lớp ghép riêng (will-change: opacity): không có thì Chrome vẽ lại cả lớp thở
   (.ts-tho có will-change: transform) theo đường khác lúc lớp mắt hiện → viền cả con trùm nhoè/xê dịch dưới 1 px mỗi lần chớp
   (đo: 2 704 điểm đổi quanh viền ở 375 px); có lớp riêng thì chỉ hai mắt đổi, lúc mở mắt trùm y hệt khi chưa có lớp mắt. */
.ts .ts-mat { opacity: 0; pointer-events: none; will-change: opacity; }
/* Thời lượng nhắm do HOẠT ẢNH CSS giữ (chạy trên luồng ghép hình), không do hẹn giờ JS: trang đang bận (tải, dựng) thì lớp
   .ts-chop có thể gỡ muộn, nhưng mắt vẫn mở lại đúng 120 ms (soát: một lần hẹn giờ trễ thành nhắm 1,2 giây). ts-chop2 = chớp đôi. */
@media (prefers-reduced-motion: no-preference) {
  .ts.ts-chop .ts-mat { animation: ts-chop .12s linear; }
  .ts.ts-chop2 .ts-mat { animation: ts-chop2 .4s linear; }
}
@keyframes ts-chop { from, to { opacity: 1; } }
@keyframes ts-chop2 { 0%, 30% { opacity: 1; } 30.1%, 70% { opacity: 0; } 70.1%, 100% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .ts .ts-mat { display: none; } }
.ts-fx { position: absolute; inset: 0; pointer-events: none; }

/* ---------------------------------------------------------------- nhịp thở theo chặng (biên độ 1,5–3 %, có nhún nhẹ) */
@media (prefers-reduced-motion: no-preference) {
  .ts-tho { animation: ts-tho-2 3s ease-in-out infinite; animation-delay: var(--tre, 0s); will-change: transform; }
  .ts[data-chang="1"] .ts-tho { animation-name: ts-tho-1; animation-duration: 2.2s; }
  .ts[data-chang="3"] .ts-tho { animation-name: ts-tho-3; animation-duration: 5s; }
  .ts[data-chang="4"] .ts-tho { animation-name: ts-tho-4; animation-duration: 3.5s; }
  .ts.ts-khuat .ts-tho, :root.ts-an .ts-tho { animation-play-state: paused; }
}
/* chặng 1: thở gấp, phì phò */
@keyframes ts-tho-1 {
  0%, 100% { transform: scale(1, 1); }
  38% { transform: scale(1.012, 1.024); }
  62% { transform: scale(1.006, 1.012); }
  86% { transform: scale(1.006, .992); }
}
/* chặng 2: đều hơn, vẫn hơi dỗi */
@keyframes ts-tho-2 {
  0%, 100% { transform: scale(1, 1); }
  45% { transform: scale(1.01, 1.02); }
  85% { transform: scale(1.004, .994); }
}
/* chặng 3: chậm sâu như hơi thở yoga — hít dài, giữ một chút, thở ra dài */
@keyframes ts-tho-3 {
  0%, 100% { transform: scale(1, 1); }
  40% { transform: scale(1.014, 1.03); }
  52% { transform: scale(1.014, 1.03); }
  92% { transform: scale(1.003, .996); }
}
/* chặng 4: vui vẻ, có nảy nhẹ */
@keyframes ts-tho-4 {
  0%, 100% { transform: translateY(0) scale(1, 1); }
  30% { transform: translateY(-1.2%) scale(.996, 1.022); }
  55% { transform: translateY(0) scale(1.01, 1.012); }
  75% { transform: translateY(0) scale(1.012, .99); }
}

/* ---------------------------------------------------------------- hơi nước và tim (phần tử phụ, JS tạo rồi xoá) */
.ts-hoi {
  position: absolute; left: var(--dau); top: var(--dinh); width: 9%; aspect-ratio: 1; margin: -4.5% 0 0 -4.5%; border-radius: 50%;
  background: radial-gradient(circle at 38% 34%, #FFFFFF, #F1ECF6 55%, #DCD3E6);
  box-shadow: -.55em .18em 0 -.12em #F4F0F8, .55em .2em 0 -.14em #EDE7F3;
  font-size: 6px; opacity: 0;              /* cỡ cụm mây: JS đặt theo bề rộng trùm */
}
.ts-tim { position: absolute; left: var(--dau); top: var(--dinh); width: 10%; aspect-ratio: 1; margin: -5% 0 0 -5%; opacity: 0; }
.ts-tim svg { display: block; width: 100%; height: 100%; }
/* QĐ-51 N06 — Ngôi Sao: giọt mưa từ đám mây nhỏ (chặng 1–2) và đốm lấp lánh (chặng 3–4), cùng khuôn .ts-hoi / .ts-tim */
.ts-giot {
  position: absolute; left: calc(var(--dau) + 14%); top: calc(var(--dinh) - 4%); width: 3.2%; aspect-ratio: .7; margin-left: -1.6%;
  border-radius: 50% 50% 50% 50% / 62% 62% 38% 38%; background: linear-gradient(#DDEBFF, #9EC3F2); opacity: 0;
}
.ts-lap { position: absolute; left: var(--dau); top: var(--dinh); width: 7%; aspect-ratio: 1; margin: -3.5% 0 0 -3.5%; opacity: 0; }
.ts-lap svg { display: block; width: 100%; height: 100%; }

/* ---------------------------------------------------------------- QĐ-51 N05 — Ngôi Sao Tự Ti sáng dần theo --sang (0 … 1) */
/* Lọc sáng trên lớp cử chỉ (ảnh + lớp mắt nhắm cùng nhận), không đụng bóng thoại. Quầng vàng mật lớn dần.
   Giảm chuyển động: giữ lọc + quầng (tĩnh), không giọt, không lấp lánh (trum-song.js không chạy cử chỉ).
   Mây mưa: ảnh chặng 1–2 đã vẽ sẵn (không thêm mây CSS). */
.ts[data-ma="ngoisao"] .ts-cu {
  filter: brightness(calc(.78 + .22 * var(--sang, 0))) saturate(calc(.55 + .45 * var(--sang, 0)));
}
.ts[data-ma="ngoisao"]::before {
  content: ""; position: absolute; left: 50%; top: 50%; width: calc(76% + 48% * var(--sang, 0)); aspect-ratio: 1;
  translate: -50% -50%; border-radius: 50%; pointer-events: none;
  background: radial-gradient(circle, rgb(255 222 120 / .55) 0%, rgb(255 233 92 / .22) 45%, rgb(255 233 92 / 0) 70%);
  opacity: calc(.12 + .88 * var(--sang, 0));
}

/* ---------------------------------------------------------------- bóng thoại khi chạm */
.ts-thoai {
  position: absolute; z-index: 5; left: 50%; bottom: calc(100% - var(--dinh) + 4px);
  width: max-content; max-width: min(15rem, calc(100vw - 32px)); padding: 8px 12px; border-radius: 14px;
  font: 600 .86rem/1.4 var(--f-than, system-ui, sans-serif); color: #2A1B38; text-align: left; text-wrap: pretty;
  background: #FFF6FA; box-shadow: 0 10px 24px -10px rgb(0 0 0 / .7), 0 0 0 1px rgb(245 139 175 / .35);
  transform: translate(calc(-50% + var(--lech, 0px)), 6px); opacity: 0; pointer-events: none;
}
.ts-thoai::after {
  content: ""; position: absolute; left: calc(50% - var(--lech, 0px)); bottom: -6px; width: 12px; height: 12px; margin-left: -6px;
  background: #FFF6FA; transform: rotate(45deg); box-shadow: 1px 1px 0 rgb(245 139 175 / .35);
}
.ts-thoai.hien { transform: translate(calc(-50% + var(--lech, 0px)), 0); opacity: 1; }
@media (prefers-reduced-motion: no-preference) {
  .ts-thoai { transition: opacity .2s ease, transform .28s cubic-bezier(.16, 1, .3, 1); }
}

/* ---------------------------------------------------------------- chỗ đặt trùm trong từng khung có sẵn */
/* Training: vòng 21 cánh sen quanh trùm; con số "x/21 cánh sen" là nút riêng bên dưới (không lồng nút trong nút) */
.tr-hinh { display: flex; flex-direction: column; align-items: center; }
.tr-vong-hinh .ts {
  position: absolute; left: 50%; top: 50%; width: 74%; height: 74%; translate: -50% -50%; border-radius: 50%;
  background: radial-gradient(circle at 50% 40%, #4A3570, #241836 72%); box-shadow: inset 0 0 0 1px rgb(255 255 255 / .08);
}
.tr-hinh .tr-vong { min-width: 44px; min-height: 44px; justify-content: center; white-space: nowrap; }
/* Hang Trùm: thẻ trùm, ảnh đầu trang, hộp thách đấu */
.trum-hinh .ts { position: absolute; inset: 6px; width: auto; height: auto; }
.ht-mat .ts { width: 86%; height: 86%; }
