/* ═══════════════════════════════════════════════════════════════════
   delight.css — lớp hiệu ứng tương tác dùng chung cho toàn hệ thống.
   Nguyên tắc: chỉ thêm chuyển động, KHÔNG đổi bố cục/màu sắc sẵn có.
   Tắt toàn bộ bằng <html data-delight="off"> hoặc khi máy bật
   "giảm chuyển động" (prefers-reduced-motion).
   ═══════════════════════════════════════════════════════════════════ */

:root {
    --dl-spring: cubic-bezier(.34, 1.46, .64, 1);
    --dl-smooth: cubic-bezier(.22, .61, .36, 1);
    --dl-green: #10b981;
}

/* ───────── 1. Thanh tiến trình khi chuyển trang ───────── */
#dl-progress {
    position: fixed;
    top: 0;
    left: 0;
    height: 3px;
    width: 0;
    z-index: 100000;
    background: linear-gradient(90deg, #059669, #10b981, #6ee7b7);
    box-shadow: 0 0 10px rgba(16, 185, 129, .8);
    border-radius: 0 4px 4px 0;
    opacity: 0;
    pointer-events: none;
    transition: width .3s var(--dl-smooth), opacity .3s ease;
}

#dl-progress.on { opacity: 1; }

/* ───────── 2. Trang vào / trang đi ───────── */
@keyframes dlPageIn {
    from { opacity: 0; transform: translateY(10px); }
    to   { opacity: 1; transform: none; }
}

.main-content { animation: dlPageIn .42s var(--dl-smooth) backwards; }
/* "backwards" chứ không "both": giữ fill sau khi chạy xong thì .main-content mang transform
   (translateY(0)) mãi → thành khung chứa của mọi position:fixed bên trong, modal trên trang dài
   bị căn giữa theo cả trang và nằm khuất ngoài màn hình. */

/* animation đang chạy thì đè giá trị thường, nên phải !important */
body.dl-leaving .main-content {
    opacity: .5 !important;
    transform: translateY(-6px) !important;
    transition: opacity .22s ease, transform .22s ease;
}

/* thẻ/khối hiện lên lần lượt cho đỡ khô khan */
@keyframes dlRise {
    from { opacity: 0; transform: translateY(14px) scale(.985); }
    to   { opacity: 1; transform: none; }
}

.dl-rise {
    animation: dlRise .5s var(--dl-smooth) backwards;
    animation-delay: calc(var(--dl-i, 0) * 55ms);
}

/* ───────── 3. Gợn sóng khi bấm (ripple) ───────── */
.dl-ripple {
    position: fixed;
    pointer-events: none;
    z-index: 100000;
    overflow: hidden;
}

.dl-ripple i {
    position: absolute;
    display: block;
    border-radius: 50%;
    background: currentColor;
    opacity: .3;
    transform: translate(-50%, -50%) scale(0);
    animation: dlRipple .6s var(--dl-smooth) forwards;
}

@keyframes dlRipple {
    to { transform: translate(-50%, -50%) scale(1); opacity: 0; }
}

/* ───────── 4. Nút bấm: nhún xuống khi nhấn ───────── */
button,
.btn, a.btn, .s-btn, .tr-btn, .action-btn, .header-btn, .page-btn,
.btn-modern-primary, .btn-modern-outline, .btn-modern-danger,
.collapse-btn, .back-btn, .mobile-nav-item, .nav-item, .nav-sub,
.nav-group-header, .user-profile {
    -webkit-tap-highlight-color: transparent;
    transition: transform .16s var(--dl-spring), box-shadow .2s ease,
                background-color .18s ease, color .18s ease,
                border-color .18s ease, opacity .18s ease;
}

button:active,
.btn:active, a.btn:active, .s-btn:active, .tr-btn:active, .action-btn:active,
.header-btn:active, .page-btn:active, .btn-modern-primary:active,
.btn-modern-outline:active, .btn-modern-danger:active, .collapse-btn:active,
.back-btn:active, .nav-sub:active, .nav-item:active, .nav-group-header:active {
    transform: scale(.955);
}

.mobile-nav-item:active { transform: scale(.9); }

/* nút chính: nảy nhẹ khi rê chuột */
.btn-primary:hover, .s-btn-primary:hover, .tr-btn-primary:hover,
.btn-modern-primary:hover, .login-btn:hover {
    transform: translateY(-2px);
}

/* ───────── 5. Nút đang gửi: khoá + quay vòng + câu chữ vui ───────── */
.dl-busy {
    pointer-events: none;
    opacity: .85;
    position: relative;
}

.dl-spin {
    display: inline-block;
    width: 13px;
    height: 13px;
    margin-right: 7px;
    vertical-align: -2px;
    border: 2px solid currentColor;
    border-right-color: transparent;
    border-radius: 50%;
    animation: dlSpin .6s linear infinite;
}

@keyframes dlSpin { to { transform: rotate(360deg); } }

/* ───────── 6. Thẻ & bảng: nhấc lên khi rê chuột ───────── */
.metric-card, .stat-card, .widget-box, .feed-item-card, .task-list-item,
.action-setup-item, .timeline-item {
    transition: transform .25s var(--dl-spring), box-shadow .25s ease;
}

.metric-card:hover, .stat-card:hover, .feed-item-card:hover,
.task-list-item:hover, .action-setup-item:hover {
    transform: translateY(-3px);
    box-shadow: 0 14px 30px -14px rgba(15, 23, 42, .28);
}

.modern-table tbody tr { transition: background-color .18s ease, transform .18s ease; }
.modern-table tbody tr:hover { transform: translateX(3px); }

/* biểu tượng trong thẻ khẽ lắc khi rê chuột */
.metric-card:hover .stat-icon-box,
.stat-card:hover .stat-icon-box { animation: dlWiggle .5s ease-in-out; }

@keyframes dlWiggle {
    0%, 100% { transform: rotate(0); }
    25%      { transform: rotate(-9deg) scale(1.08); }
    60%      { transform: rotate(7deg) scale(1.08); }
}

/* ───────── 7. Ô nhập liệu ───────── */
.form-control, .form-input, input[type="text"], input[type="password"],
input[type="email"], input[type="number"], input[type="date"], select, textarea {
    transition: border-color .18s ease, box-shadow .18s ease, background-color .18s ease;
}

/* ───────── 8. Điều hướng ───────── */
.nav-sub, .nav-item { position: relative; }

.nav-sub.active::before, .nav-item.active::before {
    content: "";
    position: absolute;
    left: 4px;
    top: 50%;
    width: 3px;
    height: 0;
    border-radius: 3px;
    background: var(--dl-green);
    transform: translateY(-50%);
    animation: dlBar .35s var(--dl-spring) forwards;
}

@keyframes dlBar { to { height: 60%; } }

.nav-item:hover .nav-icon, .nav-group-header:hover .nav-icon {
    animation: dlWiggle .45s ease-in-out;
}

.user-avatar-wrap { transition: transform .3s var(--dl-spring); }
.user-profile:hover .user-avatar-wrap { transform: rotate(-6deg) scale(1.08); }

.sidebar-logo img { transition: transform .4s var(--dl-spring); }
.sidebar-logo:hover img, .mobile-header-logo:hover img { transform: rotate(12deg) scale(1.1); }

/* thanh điều hướng dưới cùng (mobile) */
.mobile-nav-item i, .mobile-nav-item svg { transition: transform .3s var(--dl-spring); }
.mobile-nav-item.active i, .mobile-nav-item.active svg { transform: translateY(-2px) scale(1.14); }
.mobile-nav-item.dl-pop i, .mobile-nav-item.dl-pop svg { animation: dlPop .45s var(--dl-spring); }

@keyframes dlPop {
    0%   { transform: scale(1); }
    45%  { transform: scale(1.35) translateY(-4px); }
    100% { transform: translateY(-2px) scale(1.14); }
}

/* chuông có thông báo thì lắc lư cho dễ thấy */
#notiBtn.dl-has-noti i, #notiBtn.dl-has-noti svg { animation: dlBell 2.6s ease-in-out infinite; transform-origin: 50% 10%; }

@keyframes dlBell {
    0%, 72%, 100% { transform: rotate(0); }
    76% { transform: rotate(13deg); }
    80% { transform: rotate(-11deg); }
    84% { transform: rotate(8deg); }
    88% { transform: rotate(-5deg); }
    92% { transform: rotate(0); }
}

/* ───────── 9. Bảng thông báo / dropdown mở ra mượt ───────── */
.noti-panel, .user-dropdown, .app-search-res {
    transform-origin: top right;
    transition: opacity .18s ease, transform .22s var(--dl-spring);
}

/* ───────── 10. Lời nhắn nổi (toast) ───────── */
#dl-toast-wrap {
    position: fixed;
    left: 50%;
    bottom: 26px;
    transform: translateX(-50%);
    z-index: 100001;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
    pointer-events: none;
}

.dl-toast {
    background: #0f172a;
    color: #fff;
    font-size: 13px;
    font-weight: 600;
    padding: 11px 18px;
    border-radius: 999px;
    box-shadow: 0 12px 30px -8px rgba(15, 23, 42, .55);
    animation: dlToastIn .4s var(--dl-spring) both;
    max-width: min(88vw, 420px);
    text-align: center;
    line-height: 1.4;
}

.dl-toast.out { animation: dlToastOut .3s ease forwards; }

@keyframes dlToastIn {
    from { opacity: 0; transform: translateY(24px) scale(.9); }
    to   { opacity: 1; transform: none; }
}

@keyframes dlToastOut {
    to { opacity: 0; transform: translateY(12px) scale(.94); }
}

/* ───────── 11. Pháo giấy ăn mừng ───────── */
#dl-confetti {
    position: fixed;
    inset: 0;
    z-index: 100002;
    pointer-events: none;
    overflow: hidden;
}

.dl-cf {
    position: absolute;
    width: 9px;
    height: 14px;
    border-radius: 2px;
    animation: dlFall linear forwards;
}

@keyframes dlFall {
    from { transform: translateY(-10vh) rotate(0); opacity: 1; }
    to   { transform: translateY(110vh) rotate(720deg); opacity: .9; }
}

/* ───────── 12. Riêng cho mobile ───────── */
@media (max-width: 768px) {
    .metric-card:hover, .stat-card:hover, .feed-item-card:hover,
    .task-list-item:hover, .action-setup-item:hover {
        transform: none;
        box-shadow: none;
    }

    .metric-card:active, .stat-card:active, .feed-item-card:active,
    .task-list-item:active {
        transform: scale(.98);
    }

    .modern-table tbody tr:hover { transform: none; }
    #dl-toast-wrap { bottom: 86px; }
    .dl-toast { font-size: 12.5px; padding: 10px 16px; }
}

/* ───────── 13. Tôn trọng lựa chọn của người dùng ───────── */
html[data-delight="off"] *,
html[data-delight="off"] *::before,
html[data-delight="off"] *::after {
    animation: none !important;
    transition: none !important;
}

html[data-delight="off"] #dl-progress,
html[data-delight="off"] #dl-confetti { display: none !important; }

@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: .01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .01ms !important;
    }
}

/* ═══════════════════════════════════════════════════════════════════
   14. CHUYỂN CẢNH GIỮA CÁC TRANG (View Transitions API)
   Trình duyệt tự chụp ảnh trang cũ, giữ nguyên khung (sidebar/header)
   và chuyển cảnh sang trang mới — mượt như cắt cảnh trong video.
   Trình duyệt chưa hỗ trợ (Firefox) thì tự động rơi về hiệu ứng mờ
   dần ở mục 2, không có lỗi gì.
   ═══════════════════════════════════════════════════════════════════ */

@view-transition { navigation: auto; }

/* Khung ứng dụng được tách riêng nên KHÔNG bị nháy khi đổi trang:
   chỉ vùng nội dung mới chuyển cảnh, y như app gốc. */
@media (min-width: 769px) {
    .sidebar { view-transition-name: dl-sidebar; }
}

.header, .topbar { view-transition-name: dl-header; }
.mobile-bottom-nav { view-transition-name: dl-bottomnav; }

/* khung chỉ hoà nhẹ, không trượt */
::view-transition-group(dl-sidebar),
::view-transition-group(dl-header),
::view-transition-group(dl-bottomnav) {
    animation-duration: .22s;
}

/* Lần tải nào thực sự có chuyển cảnh thì tắt hiệu ứng mờ thủ công để khỏi
   chạy hai lớp chồng nhau (JS gắn cờ trong sự kiện pagereveal). */
html.dl-no-enter .main-content { animation: none; }

/* Ngay trước khi trình duyệt chụp ảnh trang cũ: trả nội dung về nguyên trạng
   để ảnh chụp không dính trạng thái đang mờ dần. */
html.dl-vt-snap .main-content {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
}

html.dl-vt-snap #dl-progress { opacity: 0 !important; }

/* ── Kiểu 1 (mặc định): HOÀ TAN — dissolve có chiều sâu ──
   Cảnh cũ và cảnh mới dùng CÙNG thời lượng + độ mờ bù nhau, vì trình duyệt
   trộn hai ảnh bằng plus-lighter: lệch nhau là loé sáng ngay giữa cảnh. */
::view-transition-old(root) {
    animation: dlVtFadeOut .34s cubic-bezier(.4, 0, .2, 1) both;
}

::view-transition-new(root) {
    animation: dlVtFadeIn .34s cubic-bezier(.4, 0, .2, 1) both;
}

@keyframes dlVtFadeOut {
    from { opacity: 1; transform: none; }
    to   { opacity: 0; transform: scale(.994) translateY(-8px); }
}

@keyframes dlVtFadeIn {
    from { opacity: 0; transform: scale(1.008) translateY(12px); }
    to   { opacity: 1; transform: none; }
}

/* ── Kiểu 2: TRƯỢT NGANG — như lật trang, biết hướng tiến/lùi ──
   Hai cảnh nằm cạnh nhau chứ không chồng nhau nên phải tắt plus-lighter. */
html[data-vt="slide"]::view-transition-old(root),
html[data-vt="slide"]::view-transition-new(root) {
    mix-blend-mode: normal;
    animation-duration: .36s;
    animation-timing-function: cubic-bezier(.4, 0, .2, 1);
    animation-fill-mode: both;
}

html[data-vt="slide"]::view-transition-old(root) { animation-name: dlVtPushOut; }
html[data-vt="slide"]::view-transition-new(root) { animation-name: dlVtPushIn; z-index: 1; }

html[data-vt="slide"][data-vt-dir="back"]::view-transition-old(root) { animation-name: dlVtPushOutBack; }
html[data-vt="slide"][data-vt-dir="back"]::view-transition-new(root) { animation-name: dlVtPushInBack; }

@keyframes dlVtPushOut     { from { transform: none; } to { transform: translateX(-22%); } }
@keyframes dlVtPushIn      { from { transform: translateX(100%); } to { transform: none; } }
@keyframes dlVtPushOutBack { from { transform: none; } to { transform: translateX(22%); } }
@keyframes dlVtPushInBack  { from { transform: translateX(-100%); } to { transform: none; } }

/* ── Kiểu 3: THU PHÓNG — cinematic, như đẩy máy quay vào cảnh mới ── */
html[data-vt="zoom"]::view-transition-old(root),
html[data-vt="zoom"]::view-transition-new(root) {
    animation-duration: .4s;
    animation-timing-function: cubic-bezier(.33, 0, .2, 1);
    animation-fill-mode: both;
}

html[data-vt="zoom"]::view-transition-old(root) { animation-name: dlVtZoomOut; }
html[data-vt="zoom"]::view-transition-new(root) { animation-name: dlVtZoomIn; }

html[data-vt="zoom"][data-vt-dir="back"]::view-transition-old(root) { animation-name: dlVtZoomOutBack; }
html[data-vt="zoom"][data-vt-dir="back"]::view-transition-new(root) { animation-name: dlVtZoomInBack; }

@keyframes dlVtZoomOut     { from { opacity: 1; transform: none; } to { opacity: 0; transform: scale(1.06); } }
@keyframes dlVtZoomIn      { from { opacity: 0; transform: scale(.94); } to { opacity: 1; transform: none; } }
@keyframes dlVtZoomOutBack { from { opacity: 1; transform: none; } to { opacity: 0; transform: scale(.94); } }
@keyframes dlVtZoomInBack  { from { opacity: 0; transform: scale(1.06); } to { opacity: 1; transform: none; } }

/* tắt hiệu ứng → chuyển cảnh cũng tắt luôn (JS gọi thêm skipTransition) */
html[data-delight="off"]::view-transition-group(*) { animation: none !important; }
