/* ===================================================================
   BARBER KIT — lớp "da" thị giác thống nhất cho các section dưới hero
   Giai đoạn 1: 4RAU CÓ GÌ / Counter / Ưu đãi (xem tài liệu kiến trúc,
   mục 12 "Redesign từng section"). Chỉ thêm CSS lên HTML có sẵn,
   không đổi layout gốc.
   =================================================================== */

/* ---- 4RAU CÓ GÌ: 4 badge "bay xung quanh" object — quỹ đạo elip nhẹ +
   xoay nhẹ, biên độ lớn hơn hẳn floatX/floatY gốc (chỉ ±8px 1 trục) và
   lệch giờ nhau để không đồng bộ nhìn máy móc. Đặc hiệu hơn .top-left gốc
   (thêm .barber-frame) nên thắng, chỉ áp dụng cho CÓ GÌ (nơi duy nhất còn
   dùng .testimonial-box). ---- */
@keyframes cogi-orbit-a { 0%, 100% { transform: translate(0, 0) rotate(0deg); } 50% { transform: translate(-12px, -16px) rotate(-2deg); } }
@keyframes cogi-orbit-b { 0%, 100% { transform: translate(0, 0) rotate(0deg); } 50% { transform: translate(14px, -12px) rotate(2deg); } }
@keyframes cogi-orbit-c { 0%, 100% { transform: translate(0, 0) rotate(0deg); } 50% { transform: translate(-14px, 12px) rotate(2deg); } }
@keyframes cogi-orbit-d { 0%, 100% { transform: translate(0, 0) rotate(0deg); } 50% { transform: translate(12px, 16px) rotate(-2deg); } }
.testimonial-box.barber-frame.top-left     { animation: cogi-orbit-a 5s ease-in-out infinite; }
.testimonial-box.barber-frame.top-right    { animation: cogi-orbit-b 6s ease-in-out infinite; }
.testimonial-box.barber-frame.bottom-left  { animation: cogi-orbit-c 5.5s ease-in-out infinite; }
.testimonial-box.barber-frame.bottom-right { animation: cogi-orbit-d 6.5s ease-in-out infinite; }
@media (prefers-reduced-motion: reduce) {
  .testimonial-box.barber-frame.top-left,
  .testimonial-box.barber-frame.top-right,
  .testimonial-box.barber-frame.bottom-left,
  .testimonial-box.barber-frame.bottom-right { animation: none; }
}

/* Desktop: 4 badge to hơn nữa + kéo gần sát object hơn nữa — vòng trước
   (260px/-80px) vẫn chưa đủ theo yêu cầu, tăng thêm 1 nấc + phóng to luôn
   chữ bên trong (tieudelydo/stars gốc cố định px, không tự scale theo
   card to hơn). */
@media (min-width: 769px) {
  #tongdo-cogi .testimonial-box.barber-frame {
    max-width: 320px;
    min-width: 240px;
    padding: 30px;
  }
  #tongdo-cogi .testimonial-box.barber-frame .tieudelydo {
    font-size: 29px;
  }
  #tongdo-cogi .testimonial-box.barber-frame .stars {
    font-size: 20px;
  }
  #tongdo-cogi .testimonial-box.barber-frame.top-left,
  #tongdo-cogi .testimonial-box.barber-frame.bottom-left {
    margin-right: -130px;
  }
  #tongdo-cogi .testimonial-box.barber-frame.top-right,
  #tongdo-cogi .testimonial-box.barber-frame.bottom-right {
    margin-left: -130px;
  }
}

/* ---- 4RAU CÓ GÌ: sticky-stage giống Hero/Counter — object không bao giờ
   cần cuộn ra ngoài viewport lúc đang active (né hẳn bug canvas WebGL
   không vẽ ra gì khi top âm, thay vì chỉ kẹp/ẩn tạm ở updateMountPosition). ---- */
.cogi-wrap {
  position: relative;
  z-index: 1;
  height: 170vh;
  background: transparent;
}
.cogi-stage {
  position: sticky;
  top: 0;
  height: 100vh;
  height: 100dvh;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 4vh 0;
}
@media (prefers-reduced-motion: reduce) {
  .cogi-wrap { height: auto; }
  .cogi-stage { position: relative; height: auto; }
}
/* .center-image chỉ có min-width (280px) trên desktop, tự co theo nội
   dung cột "auto" của grid — barber pole ra rất nhỏ (~17vw thực đo) thay
   vì to rõ như yêu cầu (~40vw). Ép width VÀ height cụ thể (id-selector để
   thắng .center-image) — riêng max-height:500px có sẵn của .center-image
   mới là thứ thực sự giới hạn khung dọc camera (fov tính theo chiều cao),
   chỉ nới width trước đó gần như không ăn thua, chỉ thêm khoảng trống 2 bên. */
@media (min-width: 769px) {
  #slot-cogi {
    width: min(46vw, 760px);
    height: min(62vh, 620px);
    max-height: none;
    min-width: 340px;
  }
}

/* ---- 4RAU CÓ GÌ: khung kim loại góc khắc vàng cho 4 badge ---- */
.testimonial-box.barber-frame {
  position: relative;
  background: linear-gradient(155deg, rgba(21, 21, 21, 0.92), rgba(10, 10, 10, 0.92));
  border: 1px solid #6f6f6f;
  color: #f4f4f4;
}
.testimonial-box.barber-frame::before,
.testimonial-box.barber-frame::after {
  content: "";
  position: absolute;
  width: 14px;
  height: 14px;
  border-color: #f5bd1c;
  border-style: solid;
  pointer-events: none;
}
.testimonial-box.barber-frame::before { top: 6px; left: 6px; border-width: 2px 0 0 2px; }
.testimonial-box.barber-frame::after  { bottom: 6px; right: 6px; border-width: 0 2px 2px 0; }
.testimonial-box.barber-frame .tieudelydo { color: #f5bd1c; }
.testimonial-box.barber-frame .stars { color: #e10600; }

/* .barber-frame ép position:relative (cần làm điểm neo cho corner-bracket
   ::before/::after) nhưng độ đặc hiệu cao hơn (2 class) vô tình đè mất
   position:absolute mà testimonial_optimized.css cần ở mobile (<=768px)
   để 4 badge thoát khỏi flex-row, nổi quanh center-image — không có nó,
   center-image (chứa object 3D) bị đẩy tràn ra ngoài màn hình. Counter đã
   bỏ layout badge-quanh-object này (xem .counter-scene bên dưới) nên chỉ
   còn cần fix cho 4RAU CÓ GÌ. */
@media (max-width: 768px) {
  #tongdo-cogi .testimonial-box.barber-frame {
    position: absolute;
  }
}

/* ---- Counter: ghế barber đỏ to đứng giữa, sticky suốt lúc cuộn qua
   section — 4 card lý do xếp chồng đúng 1 chỗ, hiện lần lượt từng cái
   (is-active) theo tiến trình cuộn thay vì hiện cùng lúc quanh object
   (xem POSES "#counter" trong hero-3d.js). Card (#counter-cards-mount)
   nằm NGOÀI #counter, sibling của #hero-3d-mount, hero-3d.js tự định vị
   — xem ghi chú trong index.html lý do không lồng vào #counter. ---- */
.counter-wrap {
  position: relative;
  z-index: 1;
  height: 280vh;
  background: transparent;
}
.counter-stage {
  position: sticky;
  top: 0;
  height: 100vh;
  height: 100dvh;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 5vh 24px 3vh;
}
/* Nền: ảnh tiệm thật (trống, không người) — z-index của .counter-wrap
   THẤP hơn #hero-3d-mount (2 > 1) nên ảnh này nằm ĐÚNG PHÍA SAU canvas
   3D một cách tự nhiên (không cần opacity giả để "xuyên thấu" như bản
   trước) — canvas WebGL có alpha:true nên chỉ vùng ngoài hình ghế mới
   trong suốt để lộ ảnh, còn bản thân ghế luôn vẽ đè lên, sắc nét 100%. */
.counter-object-area {
  position: relative;
  flex: 1 1 auto;
  width: 100%;
  min-height: 0;
  display: flex;
  justify-content: center;
  border-radius: 16px;
  overflow: hidden;
  background:
    linear-gradient(180deg, rgba(10, 8, 6, 0.08), rgba(10, 8, 6, 0.4) 85%),
    url("../img/counter-shop-bg.jpg") 32% 55% / cover no-repeat;
}
/* height:100% (bản cũ) khiến khối này cao gần hết .counter-object-area
   trong khi bề ngang bị giới hạn (90vw/340px) — tỉ lệ quá hẹp (~0.52 đo
   thực tế trên iPhone) khiến FOV NGANG của camera (phụ thuộc tỉ lệ khung,
   khác FOV dọc cố định) hẹp theo, ghế xoay bị cắt 2 bên dù trên-dưới đã ổn
   — đây là nguyên nhân thật, không phải do radius/lookY. Ép aspect-ratio
   để khung không bao giờ quá hẹp, an toàn cho FOV ngang ở mọi viewport. */
.counter-big-slot {
  width: min(82vw, 580px);
  aspect-ratio: 3 / 4;
  height: auto;
  align-self: center;
}
/* Cột phải desktop (#counter-info-slot) — trống, chỉ để dành chỗ layout
   cho #counter-cards-mount (fixed, JS canh giữa đúng vào rect này). Ẩn hẳn
   trên mobile (card quay lại đè giữa ghế, không cần cột riêng). */
.counter-info-col { display: none; }
@media (min-width: 769px) {
  .counter-object-area {
    display: grid;
    grid-template-columns: 1fr 1fr;
    align-items: center;
    column-gap: clamp(24px, 5vw, 64px);
  }
  .counter-big-slot {
    width: 100%;
    max-width: 480px;
    height: 74vh;
    justify-self: end;
  }
  .counter-info-col {
    display: block;
    width: 100%;
    max-width: 440px;
    height: 74vh;
    justify-self: start;
  }
}

/* #counter-cards-mount: fixed, JS định vị mỗi khung hình (hero-3d.js) —
   z-index CHẮC CHẮN thắng #hero-3d-mount (6 > 2) vì giờ là sibling thật
   ở body-level, không bị kẹt trong stacking context nào của #counter nữa. */
#counter-cards-mount {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 6;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 0.25s ease;
}
.counter-cards {
  position: relative;
  width: 100%;
  height: 100%;
}
#counter-cards-mount .counter-card {
  position: absolute;
  inset: 0;
  /* Overlay tối mờ (không phải khối đặc) để vẫn thấy được ghế phía sau —
     đúng yêu cầu "nền box text overlay đen mờ". Ghế cổ điển mới (crôm/da
     bóng, nhiều mảng sáng) làm nền 0.6 + blur 6px cũ không đủ tương phản,
     chữ đọc mờ — tăng độ đặc + blur mạnh hơn để chữ luôn rõ bất kể ghế nào
     đứng phía sau. */
  background: rgba(8, 8, 8, 0.78);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border: 1px solid rgba(245, 189, 28, 0.35);
  border-radius: 8px;
  color: #f4f4f4;
  padding: 18px 22px;
  text-align: center;
  opacity: 0;
  transform: translateY(10px);
  transition: opacity 0.5s ease, transform 0.5s ease;
  pointer-events: none;
}
#counter-cards-mount .counter-card.is-active {
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}
#counter-cards-mount .counter-card::before,
#counter-cards-mount .counter-card::after {
  content: "";
  position: absolute;
  width: 14px;
  height: 14px;
  border-color: #f5bd1c;
  border-style: solid;
  pointer-events: none;
}
#counter-cards-mount .counter-card::before { top: 8px; left: 8px; border-width: 2px 0 0 2px; }
#counter-cards-mount .counter-card::after  { bottom: 8px; right: 8px; border-width: 0 2px 2px 0; }
#counter-cards-mount .icon { color: #e10600; font-size: 2.3rem; }
/* Font gốc của .counter-value (style.css, trước khi có bản redesign này) là
   "Bugenvil" — chữ gothic có dấu tiếng Việt đẹp, bị mất khi dời qua khối
   #counter-cards-mount (không kế thừa lại). Khôi phục + phóng to hơn hẳn
   theo yêu cầu "to đẹp hơn". */
#counter-cards-mount .counter-value {
  color: #f5bd1c;
  font-variant-numeric: tabular-nums;
  font-family: "Bugenvil", "SFUFutura", Arial, sans-serif;
  font-size: clamp(3.2rem, 7vw, 4.4rem);
  font-weight: 400;
  letter-spacing: 0.5px;
  margin: 14px 0 10px;
  text-shadow: 0 2px 4px rgba(0, 0, 0, 0.9), 0 0 18px rgba(0, 0, 0, 0.6);
}
/* Label không có text-shadow trước đó — chữ trắng trơn nổi trực tiếp trên
   ảnh/ghế phía sau, đọc mờ tuỳ ghế nào đang hiện. Thêm bóng đen đậm để
   LUÔN đọc rõ bất kể nền gì, không lệ thuộc riêng độ đục overlay. */
#counter-cards-mount .label {
  color: #f4f4f4;
  font-size: 1.35rem;
  font-weight: 600;
  line-height: 1.3;
  text-shadow: 0 2px 4px rgba(0, 0, 0, 0.9), 0 0 12px rgba(0, 0, 0, 0.6);
}

@media (min-width: 769px) {
  /* Desktop: card đứng cạnh ghế (không đè lên), không cần nền mờ xuyên
     thấu nữa — khối đặc dễ đọc hơn, giống phong cách .counter-card gốc. */
  #counter-cards-mount .counter-card {
    background: #151515;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }
}

@media (max-width: 768px) {
  .counter-wrap { height: 240vh; }
  .counter-big-slot { width: min(90vw, 340px); }
}
@media (prefers-reduced-motion: reduce) {
  .counter-wrap { height: auto; }
  .counter-stage { position: relative; height: auto; min-height: 78vh; }
}

/* ---- Ưu đãi: thẻ dạng vé giảm giá xé (ticket-stub), giờ nhuộm gothic
   đồng bộ toàn site (trước đó vẫn nền trắng/viền đen — lạc hẳn tông so với
   phần còn lại). Giữ nguyên bố cục .offer-card gốc trong style.css (grid
   4 hàng, ảnh 16:9...), chỉ đè màu sắc + thêm góc khắc vàng quen thuộc. ---- */
.offer-card.barber-ticket {
  position: relative;
  background: #151515;
  color: #f4f4f4;
  border: 1px solid #6f6f6f;
}
.offer-card.barber-ticket::before,
.offer-card.barber-ticket::after {
  content: "";
  position: absolute;
  width: 14px;
  height: 14px;
  border-color: #f5bd1c;
  border-style: solid;
  pointer-events: none;
  z-index: 2;
  animation: gothic-corner-glow 3.2s ease-in-out infinite;
}
.offer-card.barber-ticket::before { top: 6px; left: 6px; border-width: 2px 0 0 2px; }
.offer-card.barber-ticket::after  { bottom: 6px; right: 6px; border-width: 0 2px 2px 0; animation-delay: 1.6s; }
.offer-card.barber-ticket .offer-title { color: #f5bd1c; font-family: "Espaavh", "Archivo Narrow", sans-serif; }
.offer-card.barber-ticket .offer-desc { color: #ccc; }
.offer-card.barber-ticket .offer-old { color: #8a8a8a; }
.offer-card.barber-ticket .offer-slot { background: #f5bd1c; border-color: #0a0a0a; color: #0a0a0a; }
.offer-card.barber-ticket .btn-cta { border-color: #0a0a0a; }
/* .offer-card đã có overflow:hidden sẵn trong style.css — dùng chính
   nó để "cắt" nửa hình tròn thành vết khía ở đúng mép trái/phải,
   không cần clip-path/mask (an toàn hơn cho Safari mobile). Chấm khía giờ
   màu vàng nền trang (thay vì trắng) — card đổi nền tối nên khía phải lộ
   đúng màu đằng sau card (nền trang), không phải trắng cứng. */
.offer-card.barber-ticket .offer-perf {
  position: relative;
  height: 0;
  border-top: 2px dashed #4a4a4a;
}
.offer-card.barber-ticket .offer-perf::before,
.offer-card.barber-ticket .offer-perf::after {
  content: "";
  position: absolute;
  top: -8px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: #f5bd1c;
}
.offer-card.barber-ticket .offer-perf::before { left: -8px; }
.offer-card.barber-ticket .offer-perf::after  { right: -8px; }

/* ---- Ưu đãi: cào để lộ số tiền giảm (scratch card) — số tiền THẬT đã có
   sẵn trong HTML (không phải random), lớp "lá vàng" chỉ che tạm bằng
   canvas rồi JS xoá dần theo thao tác cào (kỹ thuật canvas chuẩn
   globalCompositeOperation:"destination-out", xem js/scratch-card.js).
   Nếu JS không chạy được, HTML gốc vẫn hiện số bình thường (canvas chỉ
   được JS chèn thêm vào, không che bằng CSS) — không mất thông tin. ---- */
/* min-width:220px (bản trước) rộng hơn cả 1 nửa màn hình mobile (layout
   gốc .col-6 = 2 cột) — CSS ưu tiên min-width hơn max-width khi xung đột,
   nên nó ép khối này tràn ra ngoài cột, đúng bug "ống khói/cắt chữ" trên
   mobile. Đổi sang block + width:100% để luôn khớp đúng bề ngang cột thật,
   không tự đòi rộng hơn nội dung cha cho phép.
   .offer-scratch-hint TÁCH RA NGOÀI khối này (trước là con, bị JS ép
   el.style.height = chiều-cao-số-tiền nên phần hint tràn xuống đè lên hàng
   giá cũ / badge "Còn X Slot" bên dưới) — giờ khung chỉ ôm đúng .offer-price,
   canvas phủ khít, hint nằm hàng riêng phía dưới. */
.offer-price-scratch {
  position: relative;
  display: block;
  width: 100%;
  overflow: hidden;
  border-radius: 8px;
}
.offer-price-scratch canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  cursor: pointer;
  touch-action: none;
  border-radius: 8px;
}
.offer-price-scratch.is-revealed canvas {
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.6s ease;
}
.offer-scratch-hint {
  margin: 6px 0 0;
  max-height: 2.4em;
  overflow: hidden;
  font-size: 0.72rem;
  letter-spacing: 0.05em;
  color: #9a9a9a;
  text-transform: uppercase;
  opacity: 1;
  transition: opacity 0.4s ease, max-height 0.4s ease, margin 0.4s ease;
}
/* Đã cào xong: thu gọn hẳn hàng hint (không chỉ mờ đi) để không chừa
   khoảng trống lơ lửng giữa số tiền và hàng giá cũ. */
.offer-price-scratch.is-revealed + .offer-scratch-hint,
.offer-price-scratch.is-revealed ~ .offer-scratch-hint {
  opacity: 0;
  max-height: 0;
  margin-top: 0;
}
/* Không có canvas để cào (giảm chuyển động → toàn bộ barber-kit.js thoát
   sớm) thì câu "Cào để xem ưu đãi" vô nghĩa — ẩn đi, số tiền hiện thẳng. */
@media (prefers-reduced-motion: reduce) {
  .offer-scratch-hint { display: none; }
}
/* Số tiền: phóng to hẳn cho xứng tầm "phần thưởng vừa lộ ra", thêm glow
   vàng nhẹ đúng lúc lộ (is-revealed) — cảm giác "vừa trúng" nối liền sang
   nút CTA ngay bên dưới. */
.offer-card.barber-ticket .offer-price {
  font-family: "Bugenvil", "SFUFutura", Arial, sans-serif;
  color: #f5bd1c;
  /* Sàn 26px cũ vẫn quá rộng cho số tiền dài (vd "15.000.000đ") trong cột
     hẹp — hạ sàn xuống 18px để chữ có đường lùi thay vì tràn cột. */
  font-size: clamp(18px, 6vw, 34px);
  font-weight: 400;
  line-height: 1.15;
}
/* .offer-sub (giá cũ + badge "Còn X Slot") vốn flex không wrap — 2 khối
   cạnh nhau dễ tràn cột hẹp mobile, bị cắt cứng vì .offer-card có
   overflow:hidden sẵn (đúng bug "Còn" mất luôn số phía sau trong ảnh chụp
   thật). Cho phép xuống dòng khi không đủ chỗ thay vì cắt mất chữ. */
.offer-card.barber-ticket .offer-sub {
  flex-wrap: wrap;
  row-gap: 6px;
}
.offer-price-scratch.is-revealed .offer-price {
  animation: offer-price-pop 0.5s ease;
}
@keyframes offer-price-pop {
  0% { transform: scale(0.85); text-shadow: 0 0 0 rgba(245, 189, 28, 0); }
  60% { transform: scale(1.08); text-shadow: 0 0 18px rgba(245, 189, 28, 0.8); }
  100% { transform: scale(1); text-shadow: 0 0 10px rgba(245, 189, 28, 0.4); }
}
@media (prefers-reduced-motion: reduce) {
  .offer-card.barber-ticket::before,
  .offer-card.barber-ticket::after { animation: none; }
  .offer-price-scratch.is-revealed .offer-price { animation: none; }
}

/* ---- Marquee ảnh học viên: giữ nền tối riêng (không đổi, không bị
   phàn nàn) — dịch ngang theo % cuộn dọc thay vì swiper vuốt tay ---- */
.hv-marquee {
  position: relative;
  z-index: 1;
  background: transparent;
  overflow: hidden;
}

/* ---- .td-scene: CHỈ giữ position/z-index để nội dung luôn vẽ trên
   model 3D (fixed z-index thấp vẫn đè lên nội dung tĩnh nếu không có
   dòng này — xem ghi chú lúc phát hiện bug). KHÔNG ép màu nền/chữ nữa
   — giữ đúng màu nền gốc của từng section theo yêu cầu. ---- */
.td-scene {
  position: relative;
  z-index: 1;
}

/* Dự phòng: nếu canvas 3D không chạy được (WebGL lỗi / data-saver / JS tắt),
   các section này mất nguồn nền tối duy nhất — gán tạm nền tối, giữ chữ đọc được */
body.td-3d-unavailable .hv-marquee,
body.td-3d-unavailable .td-scene {
  background: #151515;
}

/* ================================================================
   BỎ SCROLL-JACK cho Hero / CÓ GÌ / Counter. 3 wrapper sticky cao
   (300vh/170vh/280vh) trước đây CHỈ collapse khi prefers-reduced-motion →
   di động bị hàng trăm vh trống + cuộn giật/kẹt vì camera scrub + WebGL.

   2 chế độ (hero-3d.js quyết định):
   • body.td-3d-lite       — DI ĐỘNG: object 3D VẪN hiện & TỰ XOAY, section
                             về chiều cao thường, cuộn 100% native.
   • body.td-3d-unavailable — WebGL lỗi / data-saver / reduced-motion: bỏ
                             hẳn canvas, bố cục tĩnh.
   Counter ở CẢ 2 chế độ đều là thẻ số tĩnh (#counter.counter-static).
   ================================================================ */

/* Ẩn canvas + ô 3D CHỈ khi thật sự không có 3D (không áp cho .td-3d-lite). */
body.td-3d-unavailable #hero-3d-mount,
body.td-3d-unavailable #td-loading,
body.td-3d-unavailable .td-3d-slot { display: none !important; }
body.td-3d-unavailable .counter-info-col,
body.td-3d-lite .counter-info-col { display: none !important; }

/* GSAP reveal engine đặt inline opacity:0 lên [data-reveal*] rồi fade khi
   ScrollTrigger bắn — site cuộn-ở-<body> nên hay không bắn → nội dung kẹt
   tàng hình. Ép hiện luôn (stylesheet !important thắng inline). */
body.td-3d-unavailable [data-reveal],
body.td-3d-unavailable [data-reveal-item],
body.td-3d-lite [data-reveal],
body.td-3d-lite [data-reveal-item] {
  opacity: 1 !important;
  visibility: visible !important;
  transform: none !important;
}

/* -- Hero: wrapper về chiều cao thường, stage hết sticky -- */
body.td-3d-unavailable .td-wrap,
body.td-3d-lite .td-wrap { height: auto; }
body.td-3d-unavailable .td-stage,
body.td-3d-lite .td-stage {
  position: relative;
  height: auto;
  min-height: 66vh;
  min-height: 66svh;
  justify-content: center;
  padding: 10vh 24px 7vh;
}
/* LITE: ô chứa tông đơ 3D vẫn hiện, cần chiều cao tối thiểu để object có chỗ. */
body.td-3d-lite #slot-hero {
  flex: 0 0 auto;
  width: min(82vw, 400px);
  max-height: none;
  min-height: 46vh;
  margin: 0 auto 6vh;
}

/* -- 4RAU CÓ GÌ -- */
body.td-3d-unavailable .cogi-wrap,
body.td-3d-lite .cogi-wrap { height: auto; }
body.td-3d-unavailable .cogi-stage,
body.td-3d-lite .cogi-stage {
  position: relative;
  height: auto;
  overflow: visible;
  padding: 4vh 0 6vh;
}
/* Bố cục: badge về lưới 2 cột. LITE thêm ô barber-pole 3D nằm TRÊN CÙNG. */
body.td-3d-unavailable #tongdo-cogi .testimonial-content,
body.td-3d-lite #tongdo-cogi .testimonial-content {
  display: flex !important;
  flex-flow: row wrap;
  justify-content: center;
  gap: 12px;
  max-width: 600px;
  margin: 16px auto 0;
  padding: 0 !important; /* testimonial_optimized.css cho 80px trên/dưới mobile */
}
body.td-3d-unavailable #tongdo-cogi .testimonial-box.barber-frame,
body.td-3d-lite #tongdo-cogi .testimonial-box.barber-frame {
  position: relative !important;
  inset: auto !important;
  top: auto !important; left: auto !important; right: auto !important; bottom: auto !important;
  margin: 0 !important;
  transform: none !important;
  animation: none !important;
  opacity: 1 !important;
  visibility: visible !important;
  grid-column: auto !important;
  grid-row: auto !important;
  flex: 0 0 calc(50% - 6px);
  width: auto;
  min-width: 0;
  max-width: none;
}
/* LITE: ô CÓ GÌ (#slot-cogi) hiện, chiếm cả hàng, nằm trên 4 badge. */
body.td-3d-lite #tongdo-cogi #slot-cogi {
  display: block;
  flex: 0 0 100%;
  order: -1;
  width: min(66vw, 280px);
  min-width: 0;
  min-height: 38vh;
  max-height: none;
  margin: 0 auto 8px;
}
body.td-3d-unavailable #tongdo-cogi #slot-cogi { display: none !important; }

/* -- Counter: thẻ số về lưới 2 cột trên ảnh tiệm (cả 2 chế độ) -- */
.counter-wrap.counter-static { height: auto; }
#counter.counter-static .counter-stage {
  position: relative;
  height: auto;
  overflow: visible;
  padding: 6vh 16px 7vh;
}
/* Counter KHÔNG có object 3D ở cả 2 chế độ → ẩn ô 3D rỗng (LITE không tự ẩn
   .td-3d-slot như td-3d-unavailable, ô rỗng đội section cao thêm ~440px). */
#counter.counter-static #slot-counter,
#counter.counter-static .counter-big-slot { display: none !important; }
#counter.counter-static .counter-object-area {
  min-height: 0;
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  padding: clamp(18px, 5vw, 40px);
}
#counter.counter-static #counter-cards-mount {
  position: static !important;
  visibility: visible !important;
  width: 100%;
  z-index: auto;
}
#counter.counter-static .counter-cards {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
  height: auto;
}
#counter.counter-static #counter-cards-mount .counter-value { font-size: clamp(2rem, 9vw, 3.2rem); }
#counter.counter-static #counter-cards-mount .label { font-size: 1.05rem; }
#counter.counter-static #counter-cards-mount .icon { font-size: 1.9rem; }
#counter.counter-static #counter-cards-mount .counter-card {
  position: relative !important;
  inset: auto !important;
  opacity: 1 !important;
  transform: none !important;
}

/* Dải phim (film roll) — lỗ tròn (sprocket hole) chạy dọc mép trên/dưới,
   khung ảnh ít bo góc + viền đen như 1 khung phim thật */
.hv-marquee-row {
  position: relative;
  overflow: hidden;
  margin: 6px 0;
  padding: 12px 0;
  background: #0a0a0a;
}
.hv-marquee-row::before,
.hv-marquee-row::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  height: 8px;
  background-image: radial-gradient(circle, #f5bd1c 2.4px, transparent 2.6px);
  background-size: 22px 8px;
  background-repeat: repeat-x;
  opacity: 0.5;
}
.hv-marquee-row::before { top: 2px; }
.hv-marquee-row::after { bottom: 2px; }

.hv-marquee-track {
  display: flex;
  gap: 6px;
  width: max-content;
  will-change: transform;
  /* Ảnh trong track đã lặp sẵn 3 lần trong HTML — trượt đúng 1/3 chiều
     rộng là quay lại y hệt điểm đầu, vòng lặp liền mạch không giật.
     Chạy độc lập với JS, giống 1 cuộn phim tự chạy liên tục. */
  animation: hv-marquee-slide 32s linear infinite;
}
.hv-marquee-row[data-marquee-dir="left"] .hv-marquee-track {
  animation-direction: reverse;
}
@keyframes hv-marquee-slide {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(-33.3333%, 0, 0); }
}
@media (prefers-reduced-motion: reduce) {
  .hv-marquee-track { animation: none; }
}
.hv-marquee-track img {
  width: 150px;
  height: 100px;
  object-fit: cover;
  border-radius: 4px;
  border: 2px solid #0a0a0a;
  outline: 1px solid rgba(245, 189, 28, 0.3);
  flex: none;
  display: block;
}
@media (min-width: 768px) {
  .hv-marquee-track img { width: 240px; height: 150px; }
}

/* ---- Giảng viên: thẻ đeo nhân viên (ID badge) — dây/kẹp giả lập bằng CSS
   ở đỉnh thẻ, khẽ đung đưa lúc đứng yên; vuốt (Swiper effect:"cards", xem
   main.js) sang thẻ giảng viên tiếp theo như lật xấp thẻ thật. Không dùng
   physics engine Three.js thật cho dây đeo — nặng, không đáng cho hiệu ứng
   này, CSS đã cho cảm giác tương đương. ---- */
.gv-swipe-hint {
  color: #9a9a9a;
  font-size: 0.85rem;
  letter-spacing: 0.03em;
  margin: -10px 0 18px;
}
/* effect:"cards" của Swiper tự set width slide = 100% khung .swiper (đè cả
   inline style, mạnh hơn CSS ngoài) — phải ép cỡ khung .gv-badge-swiper
   chính nó, set width lên .swiper-slide sẽ vô tác dụng. */
/* #giang-vien .gv-badge-swiper (2 class/ID) để THẮNG rule gốc ".swiper{overflow:
   hidden}" của thư viện Swiper — swiper-bundle.min.css nạp SAU barber-kit.css
   trong <head> nên cùng độ đặc hiệu thì nó thắng theo thứ tự nạp sau, cắt mất
   phần thẻ tràn ra ngoài khung mỗi khi đung đưa (đúng bug "lắc bị cắt hình"). */
#giang-vien .gv-badge-swiper,
#giang-vien .gv-badge-swiper .swiper-slide {
  overflow: visible;
}
#giang-vien .gv-badge-swiper {
  width: min(78vw, 320px);
  max-width: 320px;
  margin: 0 auto;
  padding: 60px 10px 96px;
}
@media (min-width: 769px) {
  #giang-vien .gv-badge-swiper {
    width: min(32vw, 460px);
    max-width: 460px;
  }
}
/* Thẻ bài lính (dog tag) — ảnh thật bạn thiết kế (gv-dogtag.webp, nền
   TRONG SUỐT thật, dây xích đã vẽ sẵn trong ảnh) nên KHÔNG cần khung/dây
   CSS giả nữa — chỉ còn đè ảnh giảng viên vào vùng oval trống + tên vào
   vùng bảng tên trống (toạ độ % đo từ file gốc 1003×1568). overflow:visible
   để giữ đúng bug-fix "đung đưa không bị cắt" (khung Swiper cha đã set
   visible từ trước). */
.gv-badge {
  position: relative;
  overflow: visible;
  transform-origin: 50% 4%;
  animation: gv-badge-sway 4.6s ease-in-out infinite;
}
/* Ảnh khung giờ là lớp TRÊN (z-index cao hơn ảnh giảng viên) — bản dogtag
   mới bạn gửi có lỗ oval THẬT (alpha=0, không phải mảng xám giả), nên ảnh
   giảng viên chỉ cần nằm ĐẰNG SAU, to hơn khung lỗ 1 chút là tự động lộ
   đúng hình dạng lỗ thật (oval không đều tay, không phải ellipse toán học)
   — không cần CSS cắt tròn/oval giả nữa. */
.gv-badge-frame {
  position: relative;
  z-index: 2;
  display: block;
  width: 100%;
  height: auto;
  pointer-events: none;
}
@keyframes gv-badge-sway {
  0%, 100% { transform: rotate(-2deg); }
  50%      { transform: rotate(2deg); }
}
/* Vùng phủ ảnh giảng viên — to hơn hẳn kích thước lỗ oval thật (đo được:
   x 31%–70%, y 39%–73%) để chắc chắn che kín, phần tràn ra ngoài bị khung
   kim loại (lớp trên, z-index:2) che mất tự nhiên, không cần cắt hình. */
.gv-badge-photo-oval {
  position: absolute;
  z-index: 1;
  left: 25%;
  top: 34%;
  width: 50%;
  height: 44%;
  overflow: hidden;
}
.gv-badge-photo-oval img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  /* Ảnh màu thật -> xám bạc tương phản cao, giả đúng cảm giác "dập vào
     kim loại" thay vì dán ảnh màu lên thẻ bài. */
  filter: grayscale(1) contrast(1.15) brightness(0.95);
}
/* Bảng tên trống (dải kim loại uốn cong dưới oval) — đo được: x
   28.9%–72.8%, y 76.9%–83%. */
.gv-badge-nameplate {
  position: absolute;
  z-index: 3;
  left: 28.9%;
  top: 76.9%;
  width: 43.9%;
  height: 8%;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
}
.gv-badge-nameplate h5 {
  font-family: "Espaavh", "Archivo Narrow", sans-serif;
  color: #1a1a1a;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  font-size: clamp(0.85rem, 1vw + 0.6rem, 1.15rem);
  line-height: 1;
  margin: 0;
  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.25);
}
.gv-badge-swiper .swiper-slide:not(.swiper-slide-active) .gv-badge {
  animation-play-state: paused;
}
/* #giang-vien (ID) để thắng rule gốc ".swiper-pagination{position:absolute}"
   của Swiper (nạp sau barber-kit.css, cùng lỗi thứ tự nạp đã gặp ở
   .gv-badge-swiper/.swiper-slide) — không thì pagination đè tuyệt đối lên
   gần đáy khung, chồng lên nhãn vai trò đang tràn ra ngoài thẻ phía trên. */
#giang-vien .gv-badge-pagination {
  position: relative;
  /* position:relative VẪN tôn trọng top/bottom Swiper set sẵn (bottom:10px,
     top:-10px...) — phải trung hoà luôn, không chỉ đổi position. */
  top: auto;
  bottom: auto;
  margin-top: 48px;
}
.gv-badge-pagination .swiper-pagination-bullet { background: #6f6f6f; opacity: 0.6; }
.gv-badge-pagination .swiper-pagination-bullet-active { background: #f5bd1c; opacity: 1; }
@media (prefers-reduced-motion: reduce) {
  .gv-badge { animation: none; }
}


/* ---- FAQ: đổi từ card trắng/viền đen (lạc tông) sang dark card + khung
   góc khắc vàng, đồng bộ phong cách chung của toàn site. ---- */
#faq-4rau .accordion-item {
  position: relative;
  background: #151515;
  border: 1px solid #6f6f6f;
  border-radius: 8px;
}
#faq-4rau .accordion-item::before,
#faq-4rau .accordion-item::after {
  content: "";
  position: absolute;
  width: 14px;
  height: 14px;
  border-color: #f5bd1c;
  border-style: solid;
  pointer-events: none;
  z-index: 2;
}
#faq-4rau .accordion-item::before { top: 6px; left: 6px; border-width: 2px 0 0 2px; }
#faq-4rau .accordion-item::after  { bottom: 6px; right: 6px; border-width: 0 2px 2px 0; }
#faq-4rau .accordion-button {
  font-family: "Espaavh", var(--faq-font);
  letter-spacing: 0.02em;
  background: transparent;
  color: #f4f4f4;
  border-color: transparent;
}
#faq-4rau .accordion-button:not(.collapsed) {
  background: rgba(245, 189, 28, 0.08);
  color: #f5bd1c;
  border-color: transparent;
}
#faq-4rau .accordion-button:focus {
  border-color: transparent;
}
#faq-4rau .accordion-button::after {
  color: #f5bd1c;
}
#faq-4rau .accordion-collapse {
  border: 0;
  border-top: 1px solid rgba(245, 189, 28, 0.25);
}
#faq-4rau .accordion-body {
  color: #ccc;
  background: transparent;
}
#faq-4rau .accordion-body strong { color: #f5bd1c; }
#faq-4rau .accordion-body em { color: #ff8a7a; font-style: normal; }

/* ---- Hoa văn gothic chuyển động — góc khắc vàng là mô-típ lặp lại
   khắp site (badge CÓ GÌ, card Counter, card Giảng Viên, item FAQ). Thêm
   1 animation dùng chung cho tất cả thay vì làm riêng từng chỗ — phủ
   được nhiều vị trí nhất với 1 thay đổi, giữ đồng bộ. Glow nhẹ nhàng,
   không giật mắt; tắt hẳn khi prefers-reduced-motion. ---- */
@keyframes gothic-corner-glow {
  0%, 100% { opacity: 0.7; filter: drop-shadow(0 0 0 rgba(245, 189, 28, 0)); }
  50%      { opacity: 1;   filter: drop-shadow(0 0 3px rgba(245, 189, 28, 0.85)); }
}
.testimonial-box.barber-frame::before,
.testimonial-box.barber-frame::after,
#counter-cards-mount .counter-card::before,
#counter-cards-mount .counter-card::after,
#faq-4rau .accordion-item::before,
#faq-4rau .accordion-item::after {
  animation: gothic-corner-glow 3.2s ease-in-out infinite;
}
/* Lệch pha 4 góc trong cùng 1 khung (2 góc/khung) để không nhấp nháy
   đồng loạt như đèn báo lỗi — góc dưới-phải trễ nửa chu kỳ. */
.testimonial-box.barber-frame::after,
#counter-cards-mount .counter-card::after,
#faq-4rau .accordion-item::after {
  animation-delay: 1.6s;
}
@media (prefers-reduced-motion: reduce) {
  .testimonial-box.barber-frame::before,
  .testimonial-box.barber-frame::after,
  #counter-cards-mount .counter-card::before,
  #counter-cards-mount .counter-card::after,
  #faq-4rau .accordion-item::before,
  #faq-4rau .accordion-item::after {
    animation: none;
  }
}

/* Gạch dưới tiêu đề section (.section-title::after) — dùng CHUNG cho mọi
   section trên toàn site (style.css). Đổi từ vạch xám tĩnh sang tia sáng
   vàng chạy qua — phủ rộng nhất có thể chỉ với 1 rule, không cần sửa
   từng section-title riêng lẻ. */
.section-title::after {
  background: linear-gradient(90deg, transparent, #f5bd1c, transparent);
  background-size: 200% 100%;
  opacity: 0.7;
  animation: gothic-underline-shimmer 3.5s linear infinite;
}
@keyframes gothic-underline-shimmer {
  0% { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}
@media (prefers-reduced-motion: reduce) {
  .section-title::after { animation: none; background: currentColor; opacity: 0.15; }
}

/* ---- Không Gian Học Viện: Parallax Image — chia ảnh vào 2-3 cột (JS,
   xem mountTemplate trong main.js), mỗi cột trôi lệch tốc độ khi cuộn qua
   (GSAP ScrollTrigger scrub, đã dùng sẵn toàn site) — ảnh thật có chiều
   sâu, cột lệch cao/thấp sẵn tạo nhịp masonry ngay cả lúc đứng yên. ---- */
#khong-gian .csvc-parallax {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 12px;
  padding: 6px;
  overflow: hidden;
}
@media (min-width: 640px) {
  #khong-gian .csvc-parallax { grid-template-columns: repeat(3, 1fr); gap: 18px; padding: 10px; }
}
#khong-gian .csvc-col {
  display: flex;
  flex-direction: column;
  gap: 12px;
  will-change: transform;
}
@media (min-width: 640px) {
  #khong-gian .csvc-col { gap: 18px; }
  #khong-gian .csvc-col:nth-child(2) { margin-top: 42px; }
  #khong-gian .csvc-col:nth-child(3) { margin-top: 14px; }
}
#khong-gian .csvc-photo {
  display: block;
  border-radius: 10px;
  overflow: hidden;
  aspect-ratio: 3 / 4;
  border: 2px solid #0a0a0a;
  box-shadow: 0 14px 28px rgba(0, 0, 0, 0.35);
}
#khong-gian .csvc-photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  /* main.js (markLoadedImages) đã gắn class .is-loaded khi ảnh load xong
     từ trước — nhưng rule CSS mờ-dần tương ứng bị rớt mất lúc đổi từ
     masonry-gallery cũ sang .csvc-photo (chỉ còn ở .masonry-gallery không
     còn dùng nữa) nên ảnh cứ "bụp" hiện ra thẳng, đúng cảm giác "load
     chậm/giật" khi cuộn/đổi tab tới. Thêm lại đúng cơ chế mờ-dần. */
  opacity: 0;
  transition: opacity 0.4s ease, transform 0.5s ease;
}
#khong-gian .csvc-photo img.is-loaded { opacity: 1; }

/* ---- Ngoại Khóa: dải ảnh SỰ KIỆN cuộn ngang. ĐÃ BỎ scroll-jack (pin dọc +
   tự dịch track theo % cuộn — xem lý do ở barber-kit.js). Giờ là 1 dải
   overflow-x:auto + scroll-snap thuần: mobile vuốt native, desktop kéo-thả
   / lăn chuột (initNgoaiKhoaDrag). Không còn phụ thuộc ScrollTrigger đo
   đúng 22 ảnh, không còn ~3.800px cuộn chết, không còn layer composite
   khổng lồ. Slide đặt bề RỘNG theo viewport (không theo vh) để luôn vừa
   màn + hé ảnh kế, ép aspect-ratio nên ảnh lazy tải xong không giật layout. */
.ngoaikhoa-wrap {
  position: relative;
  z-index: 1;
  background: transparent;
}
.ngoaikhoa-stage {
  padding: 2vh 0 4vh;
}
.ngoaikhoa-track {
  display: flex;
  gap: 14px;
  overflow-x: auto;
  overflow-y: hidden;
  -webkit-overflow-scrolling: touch;
  scroll-snap-type: x mandatory;
  overscroll-behavior-x: contain;
  padding: 10px 6vw 16px;
  margin-top: 8px;
}
.ngoaikhoa-track.is-dragging {
  cursor: grabbing;
  scroll-snap-type: none;
  scroll-behavior: auto;
}
.ngoaikhoa-track::-webkit-scrollbar { height: 6px; }
.ngoaikhoa-track::-webkit-scrollbar-track {
  background: rgba(0, 0, 0, 0.15);
  border-radius: 999px;
}
.ngoaikhoa-track::-webkit-scrollbar-thumb {
  background: #0a0a0a;
  border-radius: 999px;
}
.ngoaikhoa-slide {
  flex: none;
  scroll-snap-align: center;
  width: min(82vw, 440px);
  aspect-ratio: 16 / 10;
  display: block;
  border-radius: 12px;
  overflow: hidden;
  border: 2px solid #0a0a0a;
  box-shadow: 0 14px 30px rgba(0, 0, 0, 0.32);
  background: #1a1a1a;
  cursor: zoom-in;
}
.ngoaikhoa-track.is-dragging .ngoaikhoa-slide { cursor: grabbing; }
.ngoaikhoa-slide img {
  width: 100%;
  height: 100%;
  display: block;
  object-fit: cover;
  -webkit-user-drag: none;
  user-select: none;
}
@media (min-width: 769px) {
  .ngoaikhoa-slide { width: min(46vw, 520px); }
}

/* ---- Viewer phóng to ảnh ngoại khóa (tự viết, position:fixed — không dùng
   Lightbox2 vì nó đặt vị trí theo window.scrollTop mà site này cuộn ở <body>
   → ảnh văng khỏi tầm nhìn). z-index vượt cả .ux-affix (2147483600). ---- */
.nk-viewer {
  position: fixed;
  inset: 0;
  z-index: 2147483646;
  display: none;
  align-items: center;
  justify-content: center;
  padding: max(16px, env(safe-area-inset-top)) 12px max(16px, env(safe-area-inset-bottom));
  background: #060606;
  -webkit-tap-highlight-color: transparent;
}
.nk-viewer.is-open { display: flex; }
.nk-viewer__img {
  max-width: 100%;
  max-height: 100%;
  width: auto;
  height: auto;
  object-fit: contain;
  border-radius: 6px;
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.6);
  cursor: zoom-out;
}
.nk-viewer__x {
  position: absolute;
  top: max(10px, env(safe-area-inset-top));
  right: 12px;
  width: 44px;
  height: 44px;
  border: 0;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.12);
  color: #fff;
  font-size: 26px;
  line-height: 1;
  cursor: pointer;
}
.nk-viewer__nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 46px;
  height: 46px;
  border: 0;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.12);
  color: #fff;
  font-size: 28px;
  line-height: 1;
  cursor: pointer;
}
.nk-viewer__prev { left: 10px; }
.nk-viewer__next { right: 10px; }
.nk-viewer__x:hover,
.nk-viewer__nav:hover { background: rgba(255, 255, 255, 0.24); }
.nk-viewer__count {
  position: absolute;
  bottom: max(12px, env(safe-area-inset-bottom));
  left: 0;
  right: 0;
  text-align: center;
  color: rgba(255, 255, 255, 0.75);
  font-size: 0.8rem;
  letter-spacing: 0.06em;
}
@media (max-width: 560px) {
  .nk-viewer__nav { width: 40px; height: 40px; font-size: 24px; }
}
/* khoá cuộn nền + giấu cụm nút nổi khi viewer mở (giống modal ghi danh) */
html.nk-viewer-open,
html.nk-viewer-open body { overflow: hidden !important; }
html.nk-viewer-open .ux-affix { visibility: hidden !important; }

#khong-gian .csvc-photo:hover img { transform: scale(1.07); }

/* ---- Bài viết liên quan: nền ảnh sự kiện + lớp phủ đen. Thẻ bài giữ nền
   trắng để nổi bật; tiêu đề/mô tả đổi sang sáng. ---- */
.blog-related {
  position: relative;
  background: #0f0f0f url("../img/anhthem/ws10.webp") center / cover no-repeat;
}
.blog-related::before {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(8, 8, 8, 0.84), rgba(8, 8, 8, 0.92));
  pointer-events: none;
}
.blog-related > .container {
  position: relative;
  z-index: 1;
}
.blog-related h2 { color: #fff; }
.blog-related > .container > p { color: rgba(255, 255, 255, 0.72); }
