/* =========================================================
   Hiệu ứng chuyển động toàn site (02/11/2026)
   html.motion      : bật hiệu ứng (đoạn script trong <head>; không gắn khi người dùng chọn "Giảm chuyển động")
   html.is-loading  : màn hình chờ đang hiện
   html.loader-out  : màn hình chờ đang kéo lên
   html.loaded      : bắt đầu hiệu ứng mở trang
   ========================================================= */

/* ---------- Màn hình chờ (vẽ bằng CSS, không cần thêm HTML) ---------- */
html.is-loading, html.is-loading body { overflow: hidden; }
html.is-loading::before, html.loader-out::before {
  content: ""; position: fixed; inset: 0; z-index: 2147483000;
  background: #fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 72 72'%3E%3Crect width='72' height='72' rx='16' fill='%23fecd0d'/%3E%3Ctext x='36' y='49' text-anchor='middle' font-family='Arial,Helvetica,sans-serif' font-weight='800' font-size='38' fill='%23222'%3EV%3C/text%3E%3C/svg%3E") center calc(50% - 26px) / 72px 72px no-repeat;
}
html.is-loading::after, html.loader-out::after {
  content: "Vương Hữu Vĩnh"; position: fixed; z-index: 2147483001; left: 50%; top: calc(50% + 28px); transform: translateX(-50%);
  font: 600 18px/1 "Commissioner", Arial, sans-serif; color: #222; letter-spacing: .01em; white-space: nowrap;
  padding-bottom: 16px;
  background: linear-gradient(90deg, #fecd0d, #fecd0d) 0 100% / 0% 3px no-repeat, linear-gradient(#eee, #eee) 0 100% / 100% 3px no-repeat;
  animation: vhv-load-bar 1.6s ease-in-out infinite;
}
html.is-loading::before { animation: vhv-logo-pop .6s cubic-bezier(.2, .9, .3, 1.3) both; }
@keyframes vhv-logo-pop { from { background-size: 30px 30px; opacity: .2; } to { background-size: 72px 72px; opacity: 1; } }
@keyframes vhv-load-bar { 0% { background-size: 0% 3px, 100% 3px; background-position: 0 100%, 0 100%; } 60% { background-size: 100% 3px, 100% 3px; background-position: 0 100%, 0 100%; } 100% { background-size: 0% 3px, 100% 3px; background-position: 100% 100%, 0 100%; } }
html.loader-out::before { animation: vhv-curtain .75s cubic-bezier(.7, 0, .3, 1) forwards; }
html.loader-out::after { animation: vhv-fade-out .3s ease forwards; }
@keyframes vhv-curtain { from { transform: translateY(0); } to { transform: translateY(-100%); } }
@keyframes vhv-fade-out { to { opacity: 0; } }

/* ---------- Mở trang: menu trượt xuống ---------- */
html.motion .hdr { opacity: 0; }
html.motion.loaded .hdr { animation: vhv-drop .7s cubic-bezier(.2, .65, .3, 1) .15s both; }
@keyframes vhv-drop { from { opacity: 0; transform: translateY(-100%); } to { opacity: 1; transform: none; } }

/* ---------- Mở trang: tiêu đề trang con hiện lần lượt ---------- */
html.motion .page-banner .container > *, html.motion .page-banner .crumbs, html.motion .page-banner h1, html.motion .page-banner p,
html.motion .kt-crumbs, html.motion .kt-intro > * { opacity: 0; }
html.motion.loaded .page-banner .crumbs, html.motion.loaded .kt-crumbs { animation: vhv-rise .7s cubic-bezier(.2, .65, .3, 1) .3s both; }
html.motion.loaded .page-banner h1, html.motion.loaded .kt-intro > :nth-child(1) { animation: vhv-rise .8s cubic-bezier(.2, .65, .3, 1) .45s both; }
html.motion.loaded .page-banner p, html.motion.loaded .kt-intro > :nth-child(2) { animation: vhv-rise .8s cubic-bezier(.2, .65, .3, 1) .65s both; }
html.motion.loaded .page-banner .container > * { animation: vhv-rise .8s cubic-bezier(.2, .65, .3, 1) .3s both; }

/* ---------- Trang chủ: khối ảnh lớn ---------- */
/* ảnh: từ mờ & phóng to → rõ nét, rồi phóng to rất chậm (Ken Burns) */
html.motion .h-banner picture { display: block; opacity: 0; }
html.motion.loaded .h-banner picture { animation: vhv-unblur 1.5s cubic-bezier(.2, .65, .3, 1) both; }
@keyframes vhv-unblur { from { opacity: 0; transform: scale(1.12); filter: blur(10px); } to { opacity: 1; transform: none; filter: none; } }
html.motion.loaded .h-banner img { transform-origin: 68% 42%; animation: vhv-kenburns 24s ease-in-out 1.5s infinite alternate; will-change: transform; }
@keyframes vhv-kenburns { from { transform: scale(1); } to { transform: scale(1.07); } }
/* câu trích dẫn, nút, dòng tên */
html.motion .h-quote p, html.motion .h-quote .h-banner-cta .btn, html.motion .h-caption { opacity: 0; }
html.motion.loaded .h-quote p, html.motion.loaded .h-quote .h-banner-cta .btn, html.motion.loaded .h-caption { animation: vhv-rise .9s cubic-bezier(.2, .65, .3, 1) both; }
html.motion.loaded .h-quote p:nth-child(1) { animation-delay: .6s; }
html.motion.loaded .h-quote p:nth-child(2) { animation-delay: 1.05s; }
html.motion.loaded .h-quote .h-banner-cta .btn:nth-child(1) { animation-delay: 1.45s; }
html.motion.loaded .h-quote .h-banner-cta .btn:nth-child(2) { animation-delay: 1.6s; }
html.motion.loaded .h-caption { animation-delay: 1.85s; }
@keyframes vhv-rise { from { opacity: 0; transform: translateY(18px); } to { opacity: 1; transform: none; } }

/* vệt sáng lướt qua nút chính */
.h-banner-cta .btn:not(.ghost), .h-form .btn:not(.ghost) { position: relative; overflow: hidden; isolation: isolate; }
html.motion.loaded .h-banner-cta .btn:not(.ghost)::after,
html.motion.loaded .h-form .btn:not(.ghost)::after { content: ""; position: absolute; inset: -2px auto -2px -60%; width: 45%; background: linear-gradient(100deg, transparent, rgba(255,255,255,.65), transparent); transform: skewX(-18deg); animation: vhv-shine 4.5s ease-in-out 2.6s infinite; pointer-events: none; z-index: -1; }
@keyframes vhv-shine { 0% { left: -60%; } 22%, 100% { left: 130%; } }

/* nút liên hệ nổi bật lên, nút gọi điện có vòng sóng */
html.motion .float-ct a { opacity: 0; }
html.motion.loaded .float-ct a { animation: vhv-pop .5s cubic-bezier(.2, .9, .3, 1.4) both; }
html.motion.loaded .float-ct a:nth-child(1) { animation-delay: 1.9s; }
html.motion.loaded .float-ct a:nth-child(2) { animation-delay: 2.05s; }
@keyframes vhv-pop { from { opacity: 0; transform: scale(.4); } to { opacity: 1; transform: none; } }
.float-ct a { position: relative; }
html.motion.loaded .float-ct a:first-child::before { content: ""; position: absolute; inset: 0; border-radius: 50%; border: 2px solid #fecd0d; animation: vhv-ping 2.4s cubic-bezier(0, 0, .2, 1) 2.4s infinite; opacity: 0; }
@keyframes vhv-ping { 0% { transform: scale(1); opacity: .9; } 80%, 100% { transform: scale(1.75); opacity: 0; } }

/* ---------- Hiện dần khi cuộn tới ---------- */
html.motion .rv { opacity: 0; transform: translateY(26px); transition: opacity .75s cubic-bezier(.2, .65, .3, 1), transform .75s cubic-bezier(.2, .65, .3, 1); transition-delay: var(--d, 0ms); }
html.motion .rv.rv-left { transform: translateX(-30px); }
html.motion .rv.rv-right { transform: translateX(30px); }
html.motion .rv.rv-zoom { transform: scale(.94); }
html.motion .rv.in { opacity: 1; transform: none; }

/* lộ trình ước tính (trang chủ) */
html.motion .route.anim .st { animation: vhv-rise .55s cubic-bezier(.2, .65, .3, 1) both; animation-delay: calc(var(--i, 0) * 90ms); }
html.motion .route.anim .st::after { transform-origin: left; animation: vhv-grow .6s ease-out both; animation-delay: calc(var(--i, 0) * 90ms + 200ms); }
@keyframes vhv-grow { from { transform: scaleX(0); } to { transform: scaleX(1); } }

/* ---------- Rê chuột ---------- */
.h-courses a { transition: background .2s, border-color .2s, transform .2s, box-shadow .2s; }
.h-courses a:hover { transform: translateY(-3px); box-shadow: 0 10px 22px rgba(0,0,0,.08); }
.h-courses a:hover i { animation: vhv-bob .6s ease; }
@keyframes vhv-bob { 0%, 100% { transform: translateY(0) rotate(0); } 35% { transform: translateY(-4px) rotate(-8deg); } 70% { transform: translateY(1px) rotate(4deg); } }
.song, .kt-post .kt-thumb, .doc { transition: transform .25s, box-shadow .25s; }
.song:hover, .doc:hover { transform: translateY(-4px); box-shadow: 0 16px 34px rgba(0,0,0,.1); }
.kt-thumb img { transition: transform .8s cubic-bezier(.2, .65, .3, 1); }
.kt-post:hover .kt-thumb img { transform: scale(1.05); }
.about-img img { transition: transform 1.2s cubic-bezier(.2, .65, .3, 1); }
.about-img:hover img { transform: scale(1.04); }
.paper { transition: border-color .2s, transform .2s, box-shadow .2s; }
.paper:hover { box-shadow: 0 14px 30px rgba(0,0,0,.08); }

/* ---------- Thanh menu đổ bóng khi cuộn ---------- */
.hdr { transition: box-shadow .25s; }
.hdr.scrolled { box-shadow: 0 6px 20px rgba(0,0,0,.07); }

/* ---------- "Giảm chuyển động": tắt hết ---------- */
@media (prefers-reduced-motion: reduce) {
  html::before, html::after { display: none !important; }
  html.motion *, html.motion *::before, html.motion *::after { animation: none !important; transition: none !important; }
  html.motion .rv, html.motion .hdr, html.motion .h-banner picture, html.motion .h-quote p, html.motion .h-quote .h-banner-cta .btn,
  html.motion .h-caption, html.motion .float-ct a, html.motion .page-banner .container > *, html.motion .kt-crumbs, html.motion .kt-intro > * { opacity: 1 !important; transform: none !important; }
}

/* ---------- Bỏ màn hình chờ & trễ mở trang (02/11/2026) ----------
   Người dùng: "hiệu ứng này làm cảm giác trang tải chậm, bỏ".
   Phần đầu trang (menu, tiêu đề, ảnh lớn, câu trích dẫn, nút) hiện ngay;
   vẫn giữ hiệu ứng hiện dần khi cuộn xuống. */
html.is-loading, html.is-loading body { overflow: visible !important; }
html.is-loading::before, html.is-loading::after, html.loader-out::before, html.loader-out::after { content: none !important; display: none !important; }
html.motion .hdr,
html.motion .page-banner .container > *, html.motion .page-banner .crumbs, html.motion .page-banner h1, html.motion .page-banner p,
html.motion .kt-crumbs, html.motion .kt-intro > *,
html.motion .h-banner picture, html.motion .h-quote p, html.motion .h-quote .h-banner-cta .btn, html.motion .h-caption {
  opacity: 1 !important; animation: none !important; transform: none !important; filter: none !important;
}
