/* Dải ảnh đầu trang — nạp RIÊNG, chỉ trên trang thật sự có banner.

   Vì sao tách khỏi site.css: site.css là tệp chặn hiển thị của **mọi** trang
   và đã chạm trần ngân sách 30 KB. Chính test ngân sách
   (`tests/test_performance_budget.py`) đã ghi sẵn câu trả lời cho lần chạm
   trần tiếp theo: tách CSS theo trang. Khối này chỉ dùng được khi có banner,
   mà phần lớn trang không có — nên nó là phần đầu tiên nên rời đi.

   `templates/base.html` chỉ chèn `<link>` khi `page_banners` không rỗng. */

/* Vì sao không tự chuyển: xem templates/includes/banners.html.
   Màu chỉ lấy từ logo (đo lại trên tệp logo: xanh #1a7fab, vàng của ba ngôi
   sao); `--navy-900` là sắc tự pha đậm hơn hẳn, đặt cạnh logo là thấy lệch.
   Chiều cao theo `vw`: chiều cao cứng cắt mất hàng ghế đầu trên màn hình hẹp. */
.banners {
  position: relative;
  width: 100%;
  background: var(--brand-blue);
  overflow: hidden;
}
.banner-track {
  display: flex;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  scrollbar-width: none;
}
.banner-track::-webkit-scrollbar { display: none; }
.banner-slide {
  flex: 0 0 100%;
  min-width: 0;
  scroll-snap-align: start;
  scroll-margin-top: 9rem;
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  height: clamp(360px, 38vw, 640px);
  isolation: isolate;
  overflow: hidden;
}
.banner-slide:focus { outline: none; }
.banner-image {
  position: absolute;
  inset: 0;
  z-index: -2;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 35%;
  display: block;
}
/* Lớp phủ tối CHỈ khi có chữ: phủ kín một tấm ảnh hội nghị thì không còn gì
   để khoe, mà chữ trắng trên ảnh sáng lại không đọc được. */
.banner-slide-co-chu::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(90deg, rgba(8, 34, 49, .94), rgba(8, 34, 49, .82) 35%, rgba(8, 34, 49, .28) 70%, rgba(8, 34, 49, .12));
}
.banner-body {
  grid-area: 1 / 1;
  position: relative;
  align-self: center;
  width: min(1180px, 100% - 2rem);
  margin-inline: auto;
  padding: 36px 40px 84px;
  min-width: 0;
  color: #fff;
}
.banner-title { color: #fff; max-width: 24ch; margin: 0 0 16px; font-size: clamp(1.4rem, 2.3vw, 2rem); line-height: 1.25; letter-spacing: -.025em; text-wrap: balance; }
.banner-summary { color: #e2edf2; font-size: .95rem; line-height: 1.75; margin: 0 0 24px; max-width: 44ch; }
.banner-body .btn { white-space: normal; text-align: center; }

/* Ảnh trần: cả ô ảnh là liên kết. Trên ảnh nhưng DƯỚI mũi tên, nếu không thì
   bấm mũi tên lại đi mất trang. */
.banner-hit { position: absolute; inset: 0; z-index: 1; }
.banner-hit:focus-visible { outline: 3px solid var(--brand-gold); outline-offset: -6px; }

/* Mũi tên: tròn, xanh logo, mũi nhọn trắng (4.51:1, có trong bảng tương phản). */
.banner-arrow {
  position: absolute;
  top: 50%;
  translate: 0 -50%;
  z-index: 2;
  width: 48px;
  height: 48px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--brand-blue);
  border: 2px solid #ffffffd9;
  color: #fff;
  font-size: 1.8rem;
  line-height: 1;
  text-decoration: none;
  box-shadow: 0 2px 12px #10465e4d;
}
.banner-arrow span[aria-hidden] { translate: 0 -2px; }
.banner-arrow:hover { background: var(--navy-800); border-color: #fff; }
.banner-arrow:focus-visible { outline: 3px solid var(--brand-gold); outline-offset: 2px; }
.banner-arrow-prev { left: 16px; }
.banner-arrow-next { right: 16px; }

.banner-dots { display: none; }
.banners-multi .banner-dots {
  position: absolute;
  bottom: clamp(56px, 6vw, 86px);
  inset-inline: 0;
  z-index: 2;
  display: flex;
  justify-content: center;
  gap: 2px;
}
.banner-dot {
  width: 36px;
  height: 36px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  text-decoration: none;
}
.banner-dot::before {
  content: "";
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 0 0 2px #1d7fa9cc;
}
.banner-dot:hover::before, .banner-dot:focus::before { background: var(--brand-gold); box-shadow: 0 0 0 4px #ffffff59; }
.banner-dot:focus-visible { outline: 2px solid #fff; outline-offset: 1px; }

/* Đường cong vàng logo nối ảnh vào nền trang. `pointer-events: none` để không
   chắn liên kết phủ toàn ảnh bên dưới. */
.banner-curve {
  position: absolute;
  left: 0;
  bottom: -1px;
  z-index: 3;
  width: 100%;
  height: clamp(40px, 5.5vw, 96px);
  display: block;
  pointer-events: none;
}
/* Màu nền khối ngay dưới: trang chủ xanh nhạt, trang khác trắng. Sai màu là
   lộ ra một vệt cắt ngang. */
.banner-curve-fill { fill: var(--banner-curve-fill, var(--paper)); }
.homepage .banners { --banner-curve-fill: var(--navy-050); }
.banner-curve-line { fill: none; stroke: var(--brand-gold); stroke-width: 5; }

@media (max-width: 700px) {
  /* Điện thoại: khung dọc ép ảnh ngang quá hẹp — cao theo tỉ lệ màn hình. */
  .banner-slide { height: clamp(300px, 52vh, 420px); }
  .banner-slide-co-chu::after { background: linear-gradient(0deg, rgba(8, 34, 49, .98), rgba(8, 34, 49, .86) 55%, rgba(8, 34, 49, .15)); }
  .banner-body { padding: 100px 8px 84px; align-self: end; }
  .banner-title { font-size: 1.4rem; margin-bottom: 12px; }
  .banner-summary { font-size: .875rem; margin-bottom: 20px; }
  .banner-arrow { width: 40px; height: 40px; font-size: 1.6rem; }
  .banner-arrow-prev { left: 8px; }
  .banner-arrow-next { right: 8px; }
}

/* ------------------------------------------------------------ chuyển động
   Cho trang "sống" mà không đụng tới quyết định "không tự chuyển": không có
   animation nào trên `.banner-track` hay vị trí của `.banner-slide` — dải ảnh
   chỉ đổi khi người xem bấm hoặc vuốt. Chỉ có:

   * ảnh phóng rất chậm (Ken Burns) — `overflow: hidden` trên từng slide giữ
     phần phóng to không lấn sang ảnh bên cạnh;
   * chữ trượt lên khi xuất hiện, và chạy lại khi bấm tới slide đó
     (`:target` — mũi tên và dấu tròn là liên kết neo);
   * đường cong vàng tự vẽ ra, rồi một vệt sáng chạy dọc theo nó.

   Người bật "giảm chuyển động" trong hệ điều hành thì không có gì chạy. */
@keyframes banner-zoom {
  from { transform: scale(1) translate3d(0, 0, 0); }
  to { transform: scale(1.08) translate3d(-1.2%, -1%, 0); }
}
@keyframes banner-rise {
  from { opacity: 0; transform: translateY(18px); }
  to { opacity: 1; transform: none; }
}
@keyframes banner-draw { from { stroke-dashoffset: 1; } to { stroke-dashoffset: 0; } }
@keyframes banner-shine { from { stroke-dashoffset: .14; } to { stroke-dashoffset: -1; } }

@media (prefers-reduced-motion: no-preference) {
  .banner-image { animation: banner-zoom 22s ease-in-out infinite alternate; will-change: transform; }
  .banner-body > * { animation: banner-rise .8s cubic-bezier(.2, .7, .2, 1) both; }
  .banner-body > :nth-child(2) { animation-delay: .15s; }
  .banner-body > :nth-child(3) { animation-delay: .3s; }
  .banner-slide:target .banner-body > * { animation-name: banner-rise-again; }
  .banner-curve-line { stroke-dasharray: 1; animation: banner-draw 1.6s ease-out both; }
  .banner-curve-shine { animation: banner-shine 7s linear 1.6s infinite; }
  .banner-arrow { transition: transform .2s ease, background-color .2s ease; }
  .banner-arrow:hover { transform: scale(1.08); }
}
/* Cùng nội dung, khác tên: đổi `animation-name` là cách duy nhất bằng CSS để
   trình duyệt chạy lại hiệu ứng khi một slide trở thành `:target`. */
@keyframes banner-rise-again {
  from { opacity: 0; transform: translateY(18px); }
  to { opacity: 1; transform: none; }
}
.banner-curve-shine { fill: none; stroke: #fff6c4; stroke-width: 3; stroke-linecap: round; stroke-dasharray: .14 1; stroke-dashoffset: .14; opacity: .9; }
@media (prefers-reduced-motion: reduce) { .banner-curve-shine { display: none; } }
