/* ═══ MOBILE (≤899px) — semua aturan tampilan HP dipusatkan DI SINI ═══
   Agar layout mobile tidak ikut terombang-ambing tiap kali shared.css
   dirombak untuk desktop. Aturan di file ini dimuat PALING AKHIR
   (lihat index.html) sehingga menimpa aturan dasar shared.css.

   Breakpoint: 899px (modal/table/mobile) & 700px (search/master-grid).
   Untuk menambah/mengubah tampilan mobile: edit file ini saja. */

/* ── Search box: penuh selebar layar di HP ── */
@media (max-width: 700px) {
    .search-box .sp-input { width: 100% !important; max-width: none; min-width: 0; }
    .search-box { flex-wrap: wrap; }
    .search-box .sp-btn { flex-shrink: 0; }
}

/* ── Master grid: turun ke 2 kolom (tablet sempit) lalu 1 kolom (HP) ── */
@media (max-width: 1100px) {
    .master-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 700px) {
    .master-grid { grid-template-columns: 1fr; }
}

/* ── Modal & toast: clearance dari Bottom Navigation (56px) ──
   .bottom-nav (fixed, z-1050) berada DI ATAS .modal-overlay (z-1000),
   jadi tanpa clearance footer modal (Simpan/Batal) tertutup nav.
   padding-bottom 56px pada overlay + max-height dikurangi → modal
   selalu berhenti di atas nav walau setinggi apa pun. ── */
@media (max-width: 899px) {
    /* Tinggi nav + safe-area bawah (iPhone bergestur) — nilainya dari token :root di bawah,
       bukan angka 56px yang ditulis ulang di sini dan di paging.css. */
    .modal-overlay { padding-bottom: calc(var(--bn-h, 56px) + var(--safe-b, 0px)); }
    .modal,
    .modal-wide {
        width: calc(100vw - 24px - var(--safe-l, 0px) - var(--safe-r, 0px));
        max-width: 540px;
        max-height: calc(100vh - var(--bn-h, 56px) - var(--safe-b, 0px) - 16px);
        /* dvh: tinggi viewport NYATA di HP (bilah alamat yang muncul/hilang ikut dihitung).
           Tanpa ini, tombol Simpan di dasar modal tertutup bilah alamat begitu keyboard
           ditutup — kelas cacat yang hanya muncul di HP, bukan di desktop. */
        max-height: calc(100dvh - var(--bn-h, 56px) - var(--safe-b, 0px) - 16px);
    }
    /* Jarak aman dari bottom nav untuk apa pun yang MENGAPUNG di dasar viewport.
       Dipakai juga oleh halaman yang menulis `bottom:` di gaya INLINE (pesan AccountList,
       toast Pembayaran): media query tidak bisa ditulis di gaya inline, jadi rumusnya
       `calc(<jarak desktop> + var(--toast-bawah, 0px))` — di desktop token ini tidak ada,
       sehingga nilainya kembali ke jarak desktop. Tanpa token ini, setiap "toast" baru
       mendarat di balik bottom nav (nyata: 3 dari 4 toast aplikasi, ketemu 2026-09-21). */
    :root { --toast-bawah: calc(var(--bn-h) + var(--safe-b)); }
    .toast { bottom: calc(24px + var(--toast-bawah, 0px)); }

    /* ── Modal: pas di layar HP, header & body ringkas ── */
    .modal-header h3 { font-size: 16px; }
    .modal-body { padding: 12px 16px; }
    .modal-footer { padding: 0 16px 12px; }
    .page-header { margin-bottom: 8px; gap: 6px; }
    .page-title { font-size: 18px; }
    .page-sub { font-size: 11px; }
}

/* ── Form di mobile: SATU grid 2-kolom untuk seluruh body modal ──
   Semua baris (form-row / form-row-3 / adm-form .form-row) di-flatten
   (display: contents) sehingga SETIAP field menjadi item dari satu grid
   2-kolom dengan packing rapat (grid-auto-flow: dense). Efeknya:

   • Field lebar (col-6/7/8/9/12, field form-row tanpa col, inline-switch,
     anak modal-body non-form) → lebar penuh (span 2).
   • Field pendek (col-3/4/5, field form-row-3 tanpa col, .sp-narrow)
     → setengah baris (span 1).
   • "Orphan" pendek TIDAK melebar penuh lagi — dia otomatis berpasangan
     dengan field pendek berikutnya lewat dense packing (mis. Jatuh Tempo
     + Auto Perpanjang di Deposito, Jatuh Tempo + Kolektor di Kredit).
     Hanya field pendek yang DIKUTI field lebar yang melebar penuh. */
@media (max-width: 899px) {
    .modal-body:has(.form-row),
    .modal-body:has(.form-row-3) {
        display: grid;
        grid-template-columns: repeat(2, minmax(0, 1fr));
        grid-auto-flow: dense;
        gap: 0 10px; /* row-gap 0: jarak antar baris dari margin .form-group (12px) */
        align-items: start;
    }
    /* Baris jadi transparan — field ikut grid modal-body */
    .modal-body .form-row,
    .modal-body .form-row-3,
    .modal-body .adm-form .form-row {
        display: contents;
    }
    /* Anak modal-body yang bukan baris form / bukan field → lebar penuh */
    .modal-body > .form-group,
    .modal-body > :not(.form-row):not(.form-row-3) {
        grid-column: span 2;
    }
    /* Default: field form-row (2-kolom desktop) → penuh;
       field form-row-3 (3-kolom desktop, isi pendek) → 2-up */
    .modal-body .form-row > .form-group {
        grid-column: span 2;
        align-self: start;
        min-width: 0; /* cegah input date/select mendorong track grid tidak rata */
    }
    .modal-body .form-row-3 > .form-group {
        grid-column: span 1;
        align-self: start;
        min-width: 0;
    }
    /* Field pendek (col-3/4/5 / sp-narrow) → 2-up */
    .modal-body .form-row > .form-group.col-3,
    .modal-body .form-row-3 > .form-group.col-3,
    .modal-body .form-row > .form-group.col-4,
    .modal-body .form-row-3 > .form-group.col-4,
    .modal-body .form-row > .form-group.col-5,
    .modal-body .form-row-3 > .form-group.col-5,
    .modal-body .form-row > .form-group.sp-narrow,
    .modal-body .form-row-3 > .form-group.sp-narrow {
        grid-column: span 1;
    }
    /* Field yang memang harus penuh walau bertanda col-* */
    .modal-body .form-row > .form-group.col-6,
    .modal-body .form-row-3 > .form-group.col-6,
    .modal-body .form-row > .form-group.col-7,
    .modal-body .form-row-3 > .form-group.col-7,
    .modal-body .form-row > .form-group.col-8,
    .modal-body .form-row-3 > .form-group.col-8,
    .modal-body .form-row > .form-group.col-9,
    .modal-body .form-row-3 > .form-group.col-9,
    .modal-body .form-row > .form-group.col-12,
    .modal-body .form-row-3 > .form-group.col-12 {
        grid-column: span 2;
    }
    /* Toggle inline (label kiri + switch) — selalu penuh di mobile agar
       label + switch tidak terpotong di setengah baris */
    .modal-body .form-group.inline-switch {
        grid-column: span 2;
    }
    /* Anti-orphan: field pendek yang DIKUTI field lebar (col-6+) dalam baris
       yang sama → melebar penuh (pasangannya full-width). inline-switch
       TIDAK ikut — switch tetap penuh sendiri, field pendek di dekatnya
       dibiarkan 2-up agar bisa berpasangan dengan field pendek lain lewat
       dense packing (mis. Agama + Jenis Kelamin di Nasabah). */
    .modal-body :is(.form-row, .form-row-3) > .form-group:is(.col-3, .col-4, .col-5):has(~ .form-group:is(.col-6, .col-7, .col-8, .col-9, .col-12)) {
        grid-column: span 2;
    }

    /* ── Administrasi Kredit — form-row custom 4-kolom desktop → di-flatten
       ke grid 2-kolom di atas (display: contents meniadakan grid-template
       halaman .adm-form .form-row). Jaminan (3/4 desktop) → full-width. ── */
    .modal-body.adm-form .form-row > .form-group {
        grid-column: span 1 !important;
    }
    .modal-body.adm-form .adm-jaminan {
        grid-column: 1 / -1 !important;
    }

    /* ── Deposito — pasangan mobile dikunci via order: Jatuh Tempo + Auto
       Perpanjang dipaksa satu baris, JW + Akun Kas di baris terakhir
       (Kas_ID tetap input terakhir sebelum footer). Simpanan/Suku Bunga/
       Pajak/Tgl Simpan tidak diberi order (tetap urutan DOM di awal). ── */
    .modal-body .f-jt { order: 5; }
    .modal-body .f-ap { order: 6; }
    .modal-body .f-jw { order: 7; }
    .modal-body .f-kas { order: 8; }

    /* ── Nasabah — pasangan mobile dikunci (order + span eksplisit) agar
       tidak berantakan oleh dense packing. Pasangan: ID+No. KTP,
       Tempat Lahir+Tanggal Lahir, Kota+Provinsi, Wilayah+Pekerjaan,
       Telephone+Agama, Jenis Kelamin+Blocked (switch 2-up). Nama Lengkap
       & Alamat tetap penuh. f-id/f-jk/f-blk butuh !important untuk
       mengalahkan anti-orphan (col-4 diikuti col-8) & inline-switch. ── */
    .modal-body .form-row > .form-group.f-id,
    .modal-body .form-row > .form-group.f-jk,
    .modal-body .form-row > .form-group.f-blk {
        grid-column: span 1 !important;
    }
    .modal-body .f-noid { order: 1; }
    .modal-body .f-tl { order: 2; }
    .modal-body .f-ttl { order: 3; }
    .modal-body .f-kota { order: 4; }
    .modal-body .f-prov { order: 5; }
    .modal-body .f-wil { order: 6; }
    .modal-body .f-pek { order: 7; }
    .modal-body .f-telp { order: 8; }
    .modal-body .f-agama { order: 9; }
    .modal-body .f-jk { order: 10; }
    .modal-body .f-blk { order: 11; }

    /* ── TBB — pasangan mobile dikunci. Prefix tbb-* agar tidak bentrok
       dengan class f-* Nasabah/Deposito. Pasangan: Jenis+Saldo Awal,
       Suku Bunga+Penalti, Premi+Pembayaran Premi, Tgl Buka+JW,
       Jatuh Tempo+Kolektor. TBS Rek (tombol cari) & switch tetap penuh. ── */
    .modal-body .tbb-jenis { order: 1; }
    .modal-body .tbb-saldo { order: 2; }
    .modal-body .tbb-bunga { order: 3; }
    .modal-body .tbb-penalti { order: 4; }
    .modal-body .tbb-premi { order: 5; }
    .modal-body .tbb-bypremi { order: 6; }
    .modal-body .tbb-tglbuka { order: 7; }
    .modal-body .tbb-jw { order: 8; }
    .modal-body .tbb-jt { order: 9; }
    .modal-body .tbb-kolektor { order: 10; }
    .modal-body .tbb-tbsrek { order: 11; }
    .modal-body .tbb-b1 { order: 12; }
    .modal-body .tbb-status { order: 13; }
}

/* ═══════════════════════════════════════════════════════════════════════════════
   SAPUAN TAMPILAN HP (2026-09-21) — sasaran sentuh, anti-zoom iOS, gulungan dalam
tabel/tab, dan safe-area. Seluruh blok berlaku HANYA ≤899px (desktop tidak berubah).
   Alasan tiap aturan yang tidak kentara ditulis di komentarnya, bukan dihafal.
   ═══════════════════════════════════════════════════════════════════════════════ */

/* Token tampilan HP. Didefinisikan di :root (bukan di .app-layout) karena
   MainLayout, paging.css, dan `…/cetak` sama-sama membacanya — dan karena
   env(safe-area-inset-*) baru bernilai bukan-nol bila viewport memakai
   `viewport-fit=cover` (lihat index.html) — tanpa itu, semua perhitungan
   safe-area di bawah jadi nol, dan aplikasi aman untuk layar tanpa takik. */
:root {
    --bn-h: 56px;    /* tinggi bottom nav */
    --mb-h: 52px;    /* tinggi bar atas HP */
    --tap: 44px;     /* sasaran sentuh minimum (iOS 44pt / Android 48dp) */
    --safe-t: env(safe-area-inset-top, 0px);
    --safe-b: env(safe-area-inset-bottom, 0px);
    --safe-l: env(safe-area-inset-left, 0px);
    --safe-r: env(safe-area-inset-right, 0px);
}

@media (max-width: 899px) {
    /* ── 1. Anti-zoom iOS ──
       Safari iOS MEMPERBESAR halaman saat field ber-font <16px difokuskan: layar
       melompat, tombol di sisi kanan keluar dari pandangan, dan setelah blur zoom-nya
       sering tidak kembali. Semua kontrol form di HP karena itu 16px.
       (Zoom manual dua jari tetap boleh — `maximum-scale` sengaja TIDAK dikunci.) */
    .sp-input,
    select.sp-select,
    textarea,
    .numinput { font-size: 16px; }
    .sp-input::placeholder,
    .numinput::placeholder,
    textarea::placeholder { font-size: 15px; }

    /* ── 2. Sasaran sentuh ≥44px ──
       Yang dulu 28–38px nyaman untuk tetikus, terlalu kecil untuk jari.
       Ukuran visualnya tetap ramping (ikon & teks tidak membesar) — yang tumbuh
       hanya bidang yang bisa ditekan. */
    .sp-btn { height: var(--tap); min-height: var(--tap); padding: 10px 18px; font-size: 14px; }
    .sp-btn-sm { height: var(--tap); min-height: var(--tap); font-size: 13px; padding: 8px 14px; }
    .icon-btn { width: var(--tap); height: var(--tap); border-radius: 10px; }
    .icon-btn .material-symbols-rounded { font-size: 20px; }
    /* tombol tutup dialog (×): dulu 28px di pojok — paling sering salah tekan di HP */
    .modal-close, .find-close, .confirm-close, .pindah-close, .pb-close, .sheet-close {
        min-width: var(--tap); min-height: var(--tap);
        display: inline-flex; align-items: center; justify-content: center;
    }
    .sp-check { min-height: var(--tap); }
    .sp-check input[type="checkbox"] { width: 20px; height: 20px; }
    .sp-check label { font-size: 14px; }
    /* switch: jalur 46x26 dengan tombol 20px (sebelumnya 40x22/16). Jalur 26px tetap
       terlalu tipis untuk ibu jari, jadi BIDANG SENTUHNYA dinaikkan ke ≥44px lewat lapisan
       tak terlihat (::after) tanpa mengubah bentuk visualnya. Kontrolnya adalah elemen
       <label class="sp-switch"> itu sendiri, jadi menekan lapisan ini benar-benar
       menyalakan switch — bukan sekadar membuatnya tampak bisa ditekan. */
    .sp-switch { width: 46px; height: 26px; }
    .sp-switch .sp-slider::before { width: 20px; height: 20px; }
    .sp-switch input:checked + .sp-slider::before { transform: translateX(20px); }
    .sp-switch::after { content: ""; position: absolute; left: 0; right: 0; top: -9px; bottom: -9px; }
    /* tab di dalam satu halaman (laporan bertab, Proses Bunga, Akuntansi) */
    .tab-btn { min-height: var(--tap); padding: 10px 14px; }

    /* ── 3. Strip tab MENGGULUNG mendatar, bukan membungkus ──
       Laporan Tabungan punya 7 tab: dengan `flex-wrap: wrap` di layar 360px tabnya jadi
       3–4 baris dan mendorong isi laporan jauh ke bawah lipatan. Sekarang satu baris yang
       bisa digeser (pola tab aplikasi HP). */
    .tab-strip {
        flex-wrap: nowrap;
        width: 100%; max-width: 100%;
        overflow-x: auto; overflow-y: hidden;
        -webkit-overflow-scrolling: touch;
        overscroll-behavior-x: contain;
        scrollbar-width: none;
    }
    .tab-strip::-webkit-scrollbar { display: none; }
    .tab-strip > .tab-btn { flex: 0 0 auto; }

    /* ── 4. Tabel lebar: kolom AKSI menempel di kiri ──
       Aksi datagrid ada di kolom pertama. Begitu petugas menggeser tabel ke kanan untuk
       melihat kolom nominal, kolom Edit/Hapus ikut hilang dari layar. Di HP kolom pertama
       dijadikan kolom menempel supaya selalu bisa ditekan tanpa menggeser balik.
       Latar OPAK wajib: tanpa itu isi kolom lain terlihat menembus saat bergeser. */
    .dg-table th:first-child,
    .dg-table td:first-child {
        position: sticky; left: 0; z-index: 3;
        background: var(--surface-solid);
        box-shadow: 1px 0 0 var(--border-color);
    }
    /* Sel kepala yang menempel tetap memakai warna helai kepala (garis tabel) — ditumpuk
       sebagai gradien di atas permukaan OPAK, bukan latar transparan, supaya isi kolom lain
       tidak tembus saat tabel digeser. Tanpa ini, sel kepala pertama berwarna beda dari
       sel kepala lainnya (terlihat seperti salah gambar). */
    .dg-table thead th:first-child {
        z-index: 6;
        background: linear-gradient(var(--table-stripe), var(--table-stripe)), var(--surface-solid);
    }
    .dg-table tr:hover td:first-child { background: var(--surface-solid); }

    /* ── 5. Gulungan dalam kotak: momentum + tidak diteruskan ke halaman ── */
    .dg-wrap, .data-table-wrap, .trx-wrap, .sa-panel-body,
    .coa-tree-container, .expand-card-body, .modal-body {
        -webkit-overflow-scrolling: touch;
        overscroll-behavior: contain;
    }

    /* ── 6. Toolbar: kotak cari & penyaring mengisi lebar layar ── */
    .dg-toolbar .sp-input,
    .dg-toolbar .search-box,
    .dg-toolbar .search-box .sp-input { max-width: none; width: 100%; }

    /* ── 7. Baris tabel sedikit lebih tinggi (bidang sentuh untuk jari) dan kolom berisi
       alamat/nama panjang dibatasi supaya tidak mendorong tabel melebar tanpa batas ── */
    .dg-table td, .data-table td, .trx-table td { padding-top: 9px; padding-bottom: 9px; }
    .dg-table td.td-clip, .dg-table td.td-addr { max-width: 46vw; }

    /* ── 8. Pager laporan: dua tombol sebaris, keterangan halaman di atasnya ──
       "Sebelumnya + Halaman 1 dari 12 · 600 baris + Berikutnya" tidak muat di 360px;
       dengan tombol 44px barisnya pasti patah di tengah kalimat. */
    .rep-pager { flex-wrap: wrap; gap: 8px; }
    .rep-pager-info { order: -1; width: 100%; text-align: center; }
    .rep-pager .sp-btn { flex: 1 1 0; }

    /* ── 9. Kepala halaman: judul & tombol aksi tidak saling mendesak ── */
    .page-header { align-items: flex-start; }

    /* ── 10. Laci sidebar ikut dipakai di HP (tombol ☰ di bar atas) — barisnya dulu 40px
       dan tombol temanya 32px: cukup untuk tetikus, terlalu rapat untuk ibu jari.
       (Brand sengaja dibiarkan kecil: itu tautan beranda, bukan aksi utama.) ── */
    .sidebar-item { min-height: var(--tap); }
    .sidebar-theme-btn { width: var(--tap); height: var(--tap); }

    /* ── 11. Tombol kecil ber-`style` INLINE di halaman (mis. ``Refresh`` Dashboard,
       yang tingginya 26px). Inline style mengalahkan kelas mana pun, jadi satu-satunya
       cara menaikkan sasaran sentuhnya dari sini adalah `!important` — dipakai sadar,
       hanya untuk tinggi/padding, dan hanya ≤899px. ── */
    .btn-refresh { min-height: var(--tap) !important; padding: 8px 14px !important; font-size: 13px !important; }

    /* ── 12. Isi cepat "Jumlah Bayar" di Penerimaan Angsuran (Min · Tagihan · Lunas).
       Hanya `flex-wrap` yang bisa diatur dari sini. JANGAN mencoba mengatur lebar/flex
       tombolnya dari berkas ini: halaman PbTrx punya blok `<style>` sendiri dengan selector
       SAMA (`.pb-quick .sp-btn`) dan blok itu dimuat SETELAH berkas ini, jadi aturannya
       menang tanpa error apa pun (terukur 2026-09-21: `flex-basis` tetap `0%` walau di sini
       ditulis `calc(50% - 3px)`, sehingga tombol tidak pernah jadi 2×2 seperti yang sempat
       dikira). Lebar tombol karena itu diatur di halaman itu sendiri — di sana "Alokasi
       pintar" dipindah ke barisnya sendiri (`.pb-alokasi`) supaya tiga tombol isi-cepat
       tetap sebaris dan labelnya tidak terpotong. ── */
    .pb-quick { flex-wrap: wrap; }

    /* ── 13. Datagrid transaksi → DAFTAR KARTU (acuan bentuk: kartu Master Data) ──
       Halaman transaksi menandai tiap selnya di markup: `data-label="Nama Kolom"`,
       `data-kepala` (judul kartu), `data-tebal` (nilai ditebalkan, mis. Nama),
       `data-aksi` (baris ikon aksi di kaki kartu). Selama tabelnya punya sel berlabel,
       di HP ia digambar sebagai kartu; tabel TANPA label (halaman lain) tetap tabel —
       jadi sapuan ini tidak mengubah halaman yang belum disiapkan.

       Kenapa label ada di markup, bukan disalin jadi blok kartu terpisah per halaman:
       bentuk kartu hanya boleh punya SATU definisi (di sini). Kalau tiap halaman menulis
       blok kartunya sendiri seperti `.nasabah-mobile`, kolom baru akan tertinggal di salah
       satunya — persis kelas bug yang sudah beberapa kali terjadi di aplikasi ini.

       `.pad-table` (dialog Pembayaran Grup / Alokasi Pintar) ikut memakai bentuk yang SAMA
       — 6 kolom nominal di dalam modal memang lebih lebar dari layar HP (temuan user
       2026-09-21). Kelasnya disebut di selector yang sama, jadi tidak ada salinan bentuk
       kartu kedua; markup dialog cuma menempelkan `data-label`. ── */
    :is(.trx-table, .pad-table):has(td[data-label]) { display: block; width: 100%; font-size: 13px; }
    :is(.trx-table, .pad-table):has(td[data-label]) thead { display: none; }
    :is(.trx-table, .pad-table):has(td[data-label]) tbody { display: block; }
    /* Grid 2 kolom, bukan satu kolom: 11 baris label/nilai satu per baris membuat kartu
       setinggi ~296px (terukur) sehingga cuma ~2 kartu yang muat di layar HP — kartu Master
       Data justru rapat. Bidang pendek (Jenis, No. Rek, nominal) berpasangan; bidang panjang
       (Nama, Keterangan) membentang penuh lewat perannya di markup. */
    :is(.trx-table, .pad-table):has(td[data-label]) tr {
        display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
        column-gap: 14px; row-gap: 2px;
        background: var(--surface-solid);
        border: 1px solid var(--border-light);
        border-radius: 14px;
        box-shadow: var(--shadow-card);
        padding: 12px 14px;
        margin-bottom: 10px;
    }
    :is(.trx-table, .pad-table):has(td[data-label]) tr:last-child { margin-bottom: 0; }
    /* Sorotan sentuh (HP tidak punya hover) + arah uang sebagai garis tepi kiri:
       debet = uang keluar (merah), kredit = uang masuk (hijau) — warna yang sama
       dengan sel nominalnya. */
    :is(.trx-table, .pad-table):has(td[data-label]) tr:active { background: var(--table-hover); }
    :is(.trx-table, .pad-table):has(td[data-label]) tr:hover td { background: transparent; }
    :is(.trx-table, .pad-table):has(td[data-label]) tr:has(td.debet) { box-shadow: inset 3px 0 0 var(--accent-red), var(--shadow-card); }
    :is(.trx-table, .pad-table):has(td[data-label]) tr:has(td.kredit) { box-shadow: inset 3px 0 0 var(--accent-green), var(--shadow-card); }

    :is(.trx-table, .pad-table):has(td[data-label]) td {
        display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
        padding: 2px 0; border: none; order: 2; min-width: 0;
        font-size: 12.5px;
        text-align: left !important;
        /* Sel di markup membawa gaya tabel (Keterangan: max-width 220px + ellipsis 1 baris).
           Di kartu barisnya harus utuh, jadi gaya inline itu dinetralkan — ini satu-satunya
           tempat `!important` dipakai untuk itu, dan hanya ≤899px. */
        max-width: none !important; white-space: normal !important;
        overflow: visible !important; text-overflow: clip !important;
        overflow-wrap: anywhere;
    }
    :is(.trx-table, .pad-table):has(td[data-label]) td::before {
        content: attr(data-label);
        flex: 0 0 auto;
        font-size: 10px; font-weight: 600; letter-spacing: 0.3px; text-transform: uppercase;
        color: var(--text-tertiary);
    }
    :is(.trx-table, .pad-table):has(td[data-label]) td { gap: 8px; }
    /* Tanggal panjangnya tetap (dd/MM/yyyy HH:mm) tetapi ruangnya sempit di separuh kolom:
       dibiarkan membungkus ia memakan satu baris penuh sendiri (terukur 40px vs 21px). */
    :is(.trx-table, .pad-table):has(td[data-label]) td[data-label="Tanggal"] { white-space: nowrap !important; }
    /* Kepala kartu: sel identitas (No. Transaksi / No. Rek) — tanpa label, seperti judul kartu. */
    :is(.trx-table, .pad-table):has(td[data-label]) td[data-kepala] {
        order: 1; grid-column: 1 / -1; align-items: center; gap: 8px;
        margin: 0 0 4px; padding: 0 0 8px;
        border-bottom: 1px solid var(--border-light);
        font-family: var(--font-mono); font-size: 14px; font-weight: 700;
        color: var(--text-primary);
    }
    :is(.trx-table, .pad-table):has(td[data-label]) td[data-kepala]::before { content: none; }
    /* Nama pemilik/nasabah = nilai terpenting setelah identitas (ikut membentang penuh);
       `data-lebar` = bidang yang isinya panjang (Keterangan), juga membentang penuh. */
    :is(.trx-table, .pad-table):has(td[data-label]) td[data-tebal] { font-weight: 700; }
    :is(.trx-table, .pad-table):has(td[data-label]) td[data-tebal],
    :is(.trx-table, .pad-table):has(td[data-label]) td[data-lebar] { grid-column: 1 / -1; }
    /* Kaki kartu: baris aksi (Edit/Hapus) — tetap ≥44px supaya bisa ditekan jari. */
    :is(.trx-table, .pad-table):has(td[data-label]) td[data-aksi] {
        order: 3; grid-column: 1 / -1; justify-content: flex-end; align-items: center; gap: 2px;
        margin-top: 8px; padding: 8px 0 0; border-top: 1px dashed var(--border-light);
    }
    :is(.trx-table, .pad-table):has(td[data-label]) td[data-aksi]::before { content: none; }
    :is(.trx-table, .pad-table):has(td[data-label]) td[data-aksi] .material-symbols-rounded { font-size: 20px; }
    /* Kolom yang tidak berlaku untuk baris itu (mis. Kredit saat transaksinya debet) tidak
       digambar — di HP ruang vertikal mahal, dan label tanpa nilai cuma jadi baris kosong. */
    :is(.trx-table, .pad-table):has(td[data-label]) td:empty { display: none; }
    /* Kotak pembungkus penggeser tidak lagi berguna dalam bentuk kartu (kartu tidak melebar
       keluar layar): batasnya jadi garis ganda di sekeliling kartu pertama/terakhir. */
    :is(.trx-wrap, .pad-scroll):has(:is(.trx-table, .pad-table):has(td[data-label])) {
        overflow: visible; border: none; background: transparent; border-radius: 0;
    }
    /* Kartu ikut rata dengan kartu Master Data (14px). */
    :is(.trx-table, .pad-table):has(td[data-label]) + .trx-footer { margin-top: 10px; }
}

/* Desktop (≥900px): token yang sama masih dipakai MainLayout — nilainya di sini juga
   supaya tidak ada dua angka tinggi nav di dua berkas. */
@media (min-width: 900px) {
    .mobile-bar { display: none !important; }
}