/*
 * Kontrak viewport untuk seluruh modal PayDay.
 *
 * Markup lama aplikasi memakai beberapa bentuk: header/body/footer langsung,
 * <form> sebagai pembungkus, serta wrapper yang diisi lewat AJAX. Aturan ini
 * menjaga semua bentuk tersebut di dalam viewport. Hanya area isi yang boleh
 * bergulir; header, tombol tutup, dan footer selalu dapat dijangkau.
 */

.modal {
    --payday-modal-gap-y: 32px;
    --payday-modal-gap-x: 24px;
    padding-right: max(12px, env(safe-area-inset-right)) !important;
    padding-left: max(12px, env(safe-area-inset-left)) !important;
}

/* Scroll luar dimatikan agar tidak ada dua scrollbar. */
.modal.show,
.modal.in {
    overflow-x: hidden !important;
    overflow-y: hidden !important;
}

.modal .modal-dialog,
.modal .modal-dialog.modal-dialog-centered {
    display: flex !important;
    flex-direction: column !important;
    height: auto !important;
    min-height: 0 !important;
    max-height: calc(100vh - var(--payday-modal-gap-y)) !important;
    max-height: calc(100dvh - var(--payday-modal-gap-y)) !important;
    margin-top: calc(var(--payday-modal-gap-y) / 2) !important;
    margin-bottom: calc(var(--payday-modal-gap-y) / 2) !important;
}

.modal .modal-dialog:not(.modal-dialog-centered) {
    justify-content: flex-start !important;
}

.modal .modal-dialog.modal-dialog-scrollable {
    height: auto !important;
    max-height: calc(100vh - var(--payday-modal-gap-y)) !important;
    max-height: calc(100dvh - var(--payday-modal-gap-y)) !important;
}

.modal .modal-dialog.modal-dialog-scrollable > .modal-content,
.modal .modal-dialog.modal-dialog-scrollable > form.modal-content {
    flex: 0 1 auto !important;
    height: auto !important;
    max-height: 100% !important;
    min-height: 0 !important;
}

.modal .modal-dialog.modal-dialog-scrollable .modal-body {
    flex: 1 1 auto !important;
}

.modal .modal-dialog.modal-dialog-centered {
    justify-content: center !important;
}

.modal .modal-dialog.modal-dialog-centered::before {
    display: none !important;
    content: none !important;
}

.modal .modal-content {
    display: flex !important;
    flex: 0 1 auto !important;
    flex-direction: column !important;
    height: auto !important;
    min-height: 0 !important;
    max-height: calc(100vh - var(--payday-modal-gap-y)) !important;
    max-height: calc(100dvh - var(--payday-modal-gap-y)) !important;
    overflow: hidden !important;
}

/*
 * Rantai flex untuk modal yang menaruh form atau target AJAX langsung di
 * dalam .modal-content. :has() juga mencakup wrapper lama tanpa class khusus.
 */
.modal .modal-content > form,
.modal .modal-content > .tm-modal-ajax-content,
.modal .modal-content > :has(> .modal-body),
.modal .tm-modal-ajax-content > form,
.modal .tm-modal-ajax-content > :has(> .modal-body) {
    display: flex !important;
    flex: 0 1 auto !important;
    flex-direction: column !important;
    height: auto !important;
    min-height: 0 !important;
    max-height: 100% !important;
    overflow: hidden !important;
}

.modal .modal-header,
.modal .modal-footer {
    position: relative;
    z-index: 2;
    flex: 0 0 auto !important;
    background: var(--tm-surface, #ffffff);
}

.modal .modal-body {
    flex: 1 1 auto !important;
    min-height: 0 !important;
    max-height: 100% !important;
    overflow-x: hidden !important;
    overflow-y: auto !important;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
}

/* Modal proporsional: jaga tubuh modal pada ukuran alaminya tanpa kekosongan */
.modal:not([data-modal-height-locked="true"]) .modal-body,
.modal:not([data-modal-height-locked="true"]) .modal-content > form > .modal-body {
    flex: 0 1 auto !important;
}

/* Modal media lama (carousel pengumuman login) tidak mempunyai .modal-body. */
.modal .modal-content:not(:has(.modal-body)) {
    overflow-x: hidden !important;
    overflow-y: auto !important;
    overscroll-behavior: contain;
}

.modal .modal-content > .carousel {
    min-height: 0;
    max-height: 100%;
}

/* ==========================================================================
   DESKTOP COMPACT FALLBACK (SMALL SCREENS / LANDSCAPE)
   ========================================================================== */
@media (min-width: 768px) and (max-height: 560px) {
    .modal {
        --payday-modal-gap-y: 16px;
        --payday-modal-gap-x: 16px;
    }

    .modal .modal-dialog,
    .modal .modal-dialog.modal-dialog-centered {
        width: calc(100% - var(--payday-modal-gap-x)) !important;
        margin-right: auto !important;
        margin-left: auto !important;
    }
}

@media (max-height: 420px) {
    .modal {
        --payday-modal-gap-y: 8px;
    }
}

/* ==========================================================================
   MOBILE BOTTOM SHEET MODAL (iOS & ANDROID COMPLIANT)
   Menampilkan seluruh modal di layar smartphone (<= 767.98px) dalam format
   Bottom Sheet modern seperti Smart Search:
   - Menempel di tepi bawah layar (bottom: 0)
   - Sudut atas membulat modern (20px), sudut bawah lurus (0)
   - Lebar penuh (100% viewport)
   - Safe-area insets untuk iOS Home Indicator dan gesture bar Android
   - Momentum touch scrolling & overscroll containment
   - Transisi slide-up halus dari bawah
   ========================================================================== */
@media (max-width: 767.98px) {
    .modal {
        --payday-modal-gap-y: 0px !important;
        --payday-modal-gap-x: 0px !important;
        padding: 0 !important;
        padding-left: 0 !important;
        padding-right: 0 !important;
        padding-bottom: 0 !important;
        margin: 0 !important;
        overscroll-behavior: contain;
        touch-action: manipulation;
    }

    /*
     * Layout flex HANYA saat modal terbuka. Sebelumnya `display: flex !important`
     * berlaku juga untuk modal tertutup sehingga lapisan transparan penuh layar
     * (z-index 1050) dapat menghalangi sentuhan pada halaman di iOS & Android.
     *
     * Saat keyboard layar muncul, tinggi & posisi modal mengikuti Visual Viewport
     * (--payday-vv-height / --payday-vv-top diisi modal-viewport.js) agar sheet
     * tetap berada di atas keyboard, baik di iOS Safari maupun Chrome Android.
     */
    .modal.show,
    .modal.in {
        top: var(--payday-vv-top, 0px) !important;
        height: var(--payday-vv-height, 100%) !important;
    }

    /*
     * Posisi sheet TIDAK boleh bergantung pada display flex / class .in.
     * Bootstrap 3 memasang display:block lebih dulu, baru menambah .in; saat
     * menutup kebalikannya. Layout berbasis flex membuat dialog melompat ke atas
     * layar di awal buka dan di awal tutup (terlihat tidak mulus). Dengan
     * position:absolute; bottom:0 dialog selalu menempel di dasar, apa pun
     * display kontainernya.
     */
    .modal .modal-dialog,
    .modal .modal-dialog.modal-dialog-centered,
    .modal .modal-dialog.modal-dialog-scrollable {
        position: absolute !important;
        left: 0 !important;
        right: 0 !important;
        bottom: 0 !important;
        top: auto !important;
        pointer-events: none;
    }

    .modal .modal-dialog > .modal-content,
    .modal .modal-dialog > form.modal-content {
        pointer-events: auto;
    }

    /*
     * Kontainer .modal tidak ikut memudar (opacity .15s bawaan Bootstrap): bila
     * memudar, sheet menghilang dalam 150ms padahal masih meluncur. Visibilitas
     * dikendalikan oleh gerakan dialog + pemudaran backdrop saja.
     */
    .modal.fade,
    .modal.fade:not(.show):not(.in) {
        opacity: 1 !important;
        transition: none !important;
    }

    /* Animasi slide up dari bawah untuk tampilan mobile */
    .modal.fade .modal-dialog {
        transform: translate3d(0, 100%, 0) !important;
        /* Hanya transform (dikomposit GPU). Durasi < 300ms (batas emulateTransitionEnd
           Bootstrap 3) agar display:none tidak memotong animasi tutup. Kurva ala sheet iOS. */
        transition: transform 0.28s cubic-bezier(0.32, 0.72, 0, 1) !important;
        will-change: transform;
        backface-visibility: hidden;
        -webkit-backface-visibility: hidden;
        -webkit-transform-style: preserve-3d;
    }

    /* Animasi bawaan konten modal (mis. animate__flipInY di modal login) bertabrakan
       dengan gerakan slide sheet dan membuat tampilan patah-patah. */
    .modal .modal-content.animate__animated,
    .modal .modal-dialog.animate__animated {
        animation: none !important;
    }

    /* Backdrop cukup memudar; tanpa blur (mahal di GPU perangkat menengah). */
    .modal-backdrop {
        -webkit-backdrop-filter: none !important;
        backdrop-filter: none !important;
        transition: opacity 0.2s linear !important;
    }

    .modal.show .modal-dialog,
    .modal.in .modal-dialog {
        transform: translate3d(0, 0, 0) !important;
    }

    .modal .modal-dialog,
    .modal .modal-dialog.modal-dialog-centered,
    .modal .modal-dialog.modal-dialog-scrollable {
        width: 100% !important;
        max-width: 100% !important;
        min-width: 100% !important;
        margin: 0 !important;
        margin-top: auto !important;
        margin-bottom: 0 !important;
        margin-left: 0 !important;
        margin-right: 0 !important;
        height: auto !important;
        max-height: calc(100vh - 24px) !important;
        max-height: calc(100dvh - 24px) !important;
    }

    .modal .modal-content {
        width: 100% !important;
        border-top-left-radius: 20px !important;
        border-top-right-radius: 20px !important;
        border-bottom-left-radius: 0 !important;
        border-bottom-right-radius: 0 !important;
        border-left: none !important;
        border-right: none !important;
        border-bottom: none !important;
        border-top: 1px solid rgba(0, 0, 0, 0.08) !important;
        box-shadow: 0 -8px 32px rgba(15, 23, 42, 0.18) !important;
        max-height: calc(100vh - 24px) !important;
        max-height: calc(100dvh - 24px) !important;
    }

    /* Handle bar halus di atas modal untuk visual affordance bottom sheet */
    .modal .modal-header::before {
        content: '' !important;
        display: block !important;
        position: absolute !important;
        top: 6px !important;
        left: 50% !important;
        transform: translateX(-50%) !important;
        width: 36px !important;
        height: 4px !important;
        background-color: #cbd5e1 !important;
        border-radius: 999px !important;
        z-index: 10 !important;
    }

    .modal .modal-header {
        position: relative !important;
        padding-top: 18px !important;
        padding-bottom: 12px !important;
        padding-left: max(18px, env(safe-area-inset-left)) !important;
        padding-right: max(18px, env(safe-area-inset-right)) !important;
        border-top-left-radius: 20px !important;
        border-top-right-radius: 20px !important;
        border-bottom: 1px solid rgba(0, 0, 0, 0.06) !important;
    }

    .modal .modal-header .close {
        min-width: 40px !important;
        min-height: 40px !important;
        display: inline-flex !important;
        align-items: center !important;
        justify-content: center !important;
        font-size: 24px !important;
        color: #64748b !important;
        opacity: 0.8 !important;
        padding: 0 !important;
        margin: -8px -6px -8px auto !important;
    }

    .modal .modal-body {
        padding-left: max(18px, env(safe-area-inset-left)) !important;
        padding-right: max(18px, env(safe-area-inset-right)) !important;
        padding-top: 14px !important;
        padding-bottom: 16px !important;
        -webkit-overflow-scrolling: touch !important;
        overscroll-behavior: contain !important;
    }

    /* Modal tanpa footer: pastikan padding bawah melindungi dari Home Indicator iOS */
    .modal .modal-body:last-child,
    .modal .modal-content > form > .modal-body:last-child {
        padding-bottom: max(24px, calc(16px + env(safe-area-inset-bottom))) !important;
    }

    /* Modal dengan footer: beri safe-area padding di footer */
    .modal .modal-footer {
        padding-left: max(18px, env(safe-area-inset-left)) !important;
        padding-right: max(18px, env(safe-area-inset-right)) !important;
        padding-top: 12px !important;
        padding-bottom: max(16px, env(safe-area-inset-bottom)) !important;
        border-bottom-left-radius: 0 !important;
        border-bottom-right-radius: 0 !important;
        border-top: 1px solid rgba(0, 0, 0, 0.06) !important;
    }

    /* Mencegah iOS Safari auto-zoom pada input form saat disentuh */
    .modal input:not([type="checkbox"]):not([type="radio"]),
    .modal select,
    .modal textarea {
        font-size: 16px !important;
    }

    /* Area sentuh minimum 44px (Apple HIG) / 48dp (Material) pada tombol modal */
    .modal .modal-footer .btn,
    .modal .modal-footer .tm-btn {
        min-height: 44px;
    }

    /* Kunci scroll halaman di belakang modal. iOS Safari mengabaikan
       overflow:hidden pada body, jadi body di-fix oleh modal-viewport.js
       (posisi scroll disimpan lalu dipulihkan saat modal ditutup). */
    body.payday-modal-locked {
        position: fixed !important;
        left: 0;
        right: 0;
        width: 100%;
        overflow: hidden !important;
    }

    /* SweetAlert2 (dialog konfirmasi/pemberitahuan) memakai bentuk yang sama.
       Toast tidak diubah. */
    /*
     * SweetAlert2 11 memakai layout GRID 3x3 (bukan flex), sehingga popup dipusatkan
     * lewat `place-self: center` di kolom tengah; `align-items` pada container tidak
     * berpengaruh. Popup ditempatkan eksplisit di baris terbawah, melintang penuh.
     */
    .swal2-container.swal2-center {
        padding: 0 !important;
        overscroll-behavior: contain;
    }

    .swal2-container.swal2-center > .swal2-popup:not(.swal2-toast) {
        grid-row: 3 !important;
        grid-column: 1 / -1 !important;
        place-self: end stretch !important;
        position: relative;
        box-sizing: border-box;
        width: 100% !important;
        max-width: 100% !important;
        margin: 0 !important;
        max-height: calc(100vh - 24px);
        max-height: calc(100dvh - 24px);
        overflow-y: auto;
        overscroll-behavior: contain;
        -webkit-overflow-scrolling: touch;
        border-radius: 20px 20px 0 0 !important;
        box-shadow: 0 -8px 32px rgba(15, 23, 42, 0.18) !important;
        padding: 26px 20px max(20px, calc(12px + env(safe-area-inset-bottom))) !important;
        text-align: center;
    }

    /* Handle bar: penanda visual bahwa ini bottom sheet. */
    .swal2-container.swal2-center > .swal2-popup:not(.swal2-toast)::before {
        content: '';
        position: absolute;
        top: 8px;
        left: 50%;
        width: 36px;
        height: 4px;
        transform: translateX(-50%);
        border-radius: 999px;
        background: #cbd5e1;
    }

    /* Tipografi ringkas ala sheet mobile (bawaan Swal: judul 1.875em, terlalu besar). */
    .swal2-container.swal2-center .swal2-popup:not(.swal2-toast) .swal2-title {
        margin: 0 !important;
        padding: 0 !important;
        font-size: 1.2rem !important;
        font-weight: 700 !important;
        line-height: 1.35 !important;
        color: #0f172a;
    }

    .swal2-container.swal2-center .swal2-popup:not(.swal2-toast) .swal2-html-container {
        margin: 8px 0 0 !important;
        padding: 0 !important;
        font-size: 0.95rem !important;
        line-height: 1.5 !important;
        color: #475569;
    }

    /* Ikon lebih kecil agar sheet tidak terlalu tinggi. */
    .swal2-container.swal2-center .swal2-popup:not(.swal2-toast) .swal2-icon {
        font-size: 0.75rem !important;
        margin: 0 auto 10px !important;
    }

    /* Tombol: ditumpuk, penuh lebar, area sentuh 48px. Aksi utama selalu di atas,
       urutan visual tidak bergantung pada urutan DOM (mis. reverseButtons). */
    .swal2-container.swal2-center .swal2-popup:not(.swal2-toast) .swal2-actions {
        display: flex !important;
        flex-direction: column !important;
        align-items: stretch !important;
        gap: 8px;
        width: 100% !important;
        margin: 18px 0 0 !important;
        padding: 0 !important;
    }

    .swal2-container.swal2-center .swal2-popup:not(.swal2-toast) .swal2-actions .swal2-styled {
        width: 100% !important;
        min-height: 48px;
        margin: 0 !important;
        padding: 0 16px !important;
        border-radius: 14px !important;
        font-size: 1rem !important;
    }

    /* Dialog "Memproses…": loader berada di area tombol; pusatkan pada layout kolom. */
    .swal2-container.swal2-center .swal2-popup:not(.swal2-toast) .swal2-actions .swal2-loader {
        align-self: center;
        margin: 4px 0 !important;
    }

    .swal2-container.swal2-center .swal2-popup:not(.swal2-toast) .swal2-confirm { order: 1; }
    .swal2-container.swal2-center .swal2-popup:not(.swal2-toast) .swal2-deny { order: 2; }
    .swal2-container.swal2-center .swal2-popup:not(.swal2-toast) .swal2-cancel { order: 3; }

    /* Input di dalam dialog: 16px mencegah auto-zoom iOS, tinggi nyaman disentuh. */
    .swal2-container.swal2-center .swal2-popup:not(.swal2-toast) .swal2-input,
    .swal2-container.swal2-center .swal2-popup:not(.swal2-toast) .swal2-textarea,
    .swal2-container.swal2-center .swal2-popup:not(.swal2-toast) .swal2-select {
        width: 100% !important;
        max-width: 100% !important;
        margin: 14px 0 0 !important;
        font-size: 16px !important;
    }

    .swal2-container.swal2-center .swal2-popup:not(.swal2-toast) .swal2-input {
        height: 48px;
    }
}

@media (max-width: 767.98px) and (prefers-reduced-motion: no-preference) {
    .swal2-container.swal2-center .swal2-popup:not(.swal2-toast).swal2-show {
        animation: payday-sheet-up 0.28s cubic-bezier(0.32, 0.72, 0, 1) both !important;
    }

    /* Tutup: meluncur turun (bukan zoom-out bawaan Swal). Swal menunggu
       `animationend` sebelum membuang popup, jadi durasinya cukup pendek. */
    .swal2-container.swal2-center .swal2-popup:not(.swal2-toast).swal2-hide {
        animation: payday-sheet-down 0.2s cubic-bezier(0.4, 0, 1, 1) both !important;
    }

    @keyframes payday-sheet-up {
        from { transform: translate3d(0, 100%, 0); }
        to { transform: translate3d(0, 0, 0); }
    }

    @keyframes payday-sheet-down {
        from { transform: translate3d(0, 0, 0); }
        to { transform: translate3d(0, 100%, 0); }
    }
}

@media (max-width: 767.98px) and (prefers-reduced-motion: reduce) {
    .modal.fade .modal-dialog {
        transition: none !important;
    }
}
