/* ==========================================================================
   Design layer, mobile-first.

   Bagian 1 mendefinisikan token (warna, tipografi, jarak, radius, bayangan).
   Bagian 2 memakainya untuk menimpa komponen Bootstrap 5 supaya tidak lagi
   tampil seperti Bootstrap default. Markup halaman TIDAK diubah: semua
   penyesuaian dilakukan lewat kelas Bootstrap yang sudah dipakai.

   Aturan di luar @media berlaku untuk layar kecil; @media (min-width: 992px)
   yang menaikkannya ke tampilan tabel. Ambang 992px dipilih setelah diuji:
   di 768px tabel karyawan yang 9 kolom masih melimpah keluar layar. Dipakai
   halaman admin (lewat public/header.php) dan halaman publik
   pengajuan_bantuan.php.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. TOKEN

   Nilai terang ditaruh di :root, bukan di body.light, supaya halaman sudah
   berwarna benar sebelum JS sempat memasang kelas tema.
   -------------------------------------------------------------------------- */
:root {
    /* Netral - satu tangga abu kebiruan, dipakai untuk semua permukaan */
    --n-0:   #ffffff;
    --n-25:  #fbfcfd;
    --n-50:  #f6f8fa;
    --n-100: #eef1f5;
    --n-200: #e3e8ef;
    --n-300: #cdd5e0;
    --n-400: #9aa4b2;
    --n-500: #697586;
    --n-600: #4b5565;
    --n-700: #364152;
    --n-800: #202939;
    --n-900: #121926;

    /* Aksen. Indigo dipilih menggantikan biru Bootstrap (#0d6efd) yang
       terlalu jenuh dan membuat halaman terlihat seperti template bawaan. */
    --brand-50:  #eef2ff;
    --brand-100: #e0e7ff;
    --brand-300: #a5b4fc;
    --brand:     #4f46e5;
    --brand-600: #4338ca;
    --brand-700: #3730a3;

    --ok-50:   #ecfdf5;  --ok:   #059669;  --ok-600:   #047857;
    --warn-50: #fffbeb;  --warn: #d97706;  --warn-600: #b45309;
    --bad-50:  #fef2f2;  --bad:  #dc2626;  --bad-600:  #b91c1c;
    --info-50: #eff6ff;  --info: #0284c7;

    /* Peran semantik - ini yang dipakai komponen, bukan tangga di atas */
    --bg:        var(--n-50);
    --surface:   var(--n-0);
    --surface-2: var(--n-50);
    --surface-3: var(--n-100);
    --border:    var(--n-200);
    --border-2:  var(--n-300);
    --text:      var(--n-800);
    --text-2:    var(--n-600);
    --text-muted:var(--n-500);
    --accent:      var(--brand);
    --accent-hover:var(--brand-600);
    --accent-soft: var(--brand-50);
    --ring: rgba(79, 70, 229, 0.28);

    /* Tipografi - skala 1.2 dari 0.875rem */
    --font: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
            "Helvetica Neue", Arial, sans-serif;
    --fs-xs: 0.75rem;
    --fs-sm: 0.8125rem;
    --fs-base: 0.9375rem;
    --fs-md: 1.0625rem;
    --fs-lg: 1.25rem;
    --fs-xl: 1.5rem;
    --fs-2xl: 1.875rem;

    /* Radius */
    --r-sm: 8px;
    --r:    12px;
    --r-lg: 16px;
    --r-pill: 999px;

    /* Bayangan - halus dan berlapis, bukan satu blur pekat */
    --sh-sm: 0 1px 2px rgba(16, 24, 40, 0.05);
    --sh:    0 1px 3px rgba(16, 24, 40, 0.08), 0 1px 2px rgba(16, 24, 40, 0.04);
    --sh-md: 0 4px 8px -2px rgba(16, 24, 40, 0.08), 0 2px 4px -2px rgba(16, 24, 40, 0.04);
    --sh-lg: 0 12px 16px -4px rgba(16, 24, 40, 0.08), 0 4px 6px -2px rgba(16, 24, 40, 0.03);

    /* Alias lama. Aturan di bagian bawah file ini dan style lokal di
       kasbon.php/index.php masih memakai nama-nama ini. */
    --radius:  var(--r);
    --sentuh:  44px;
    --garis:   var(--border);
    --redup:   var(--text-muted);
    --card-bg: var(--surface);
    --sidebar-bg: var(--surface);
    --nav-bg:     var(--surface);
}

/* Mode gelap. Permukaan dinaikkan bertahap (bg < surface < surface-2) supaya
   kedalaman datang dari warna, bukan dari bayangan - bayangan hampir tidak
   terlihat di latar gelap. */
body.dark {
    --bg:        #0f1420;
    --surface:   #171d2b;
    --surface-2: #1e2534;
    --surface-3: #262f41;
    --border:    #2b3446;
    --border-2:  #3a4459;
    --text:      #e6e9ef;
    --text-2:    #b3bccc;
    --text-muted:#8b95a8;
    --accent:      #818cf8;
    --accent-hover:#a5b4fc;
    --accent-soft: rgba(129, 140, 248, 0.14);
    --ring: rgba(129, 140, 248, 0.32);

    --ok:   #34d399;  --ok-50:   rgba(52, 211, 153, 0.14);
    --warn: #fbbf24;  --warn-50: rgba(251, 191, 36, 0.14);
    --bad:  #f87171;  --bad-50:  rgba(248, 113, 113, 0.14);
    --info: #38bdf8;  --info-50: rgba(56, 189, 248, 0.14);

    --sh-sm: 0 1px 2px rgba(0, 0, 0, 0.3);
    --sh:    0 1px 3px rgba(0, 0, 0, 0.4);
    --sh-md: 0 4px 10px rgba(0, 0, 0, 0.45);
    --sh-lg: 0 14px 28px rgba(0, 0, 0, 0.5);
}

/* --------------------------------------------------------------------------
   JEMBATAN KE BOOTSTRAP

   Halaman memakai utility bawaan (.text-primary, .bg-success, .border-danger,
   .btn-link, ...) yang semuanya dihitung dari variabel --bs-*. Dengan
   memetakan variabel itu ke token di atas, ke-23 halaman ikut berubah warna
   tanpa satu pun class di markup diganti. File ini dimuat sesudah
   bootstrap.min.css, jadi deklarasi di sini yang menang.
   -------------------------------------------------------------------------- */
:root {
    --bs-body-font-family: var(--font);
    --bs-body-font-size: var(--fs-base);
    --bs-body-color: var(--text);
    --bs-body-bg: var(--bg);
    --bs-emphasis-color: var(--text);
    --bs-secondary-color: var(--text-muted);
    --bs-border-color: var(--border);
    --bs-border-radius: var(--r-sm);
    --bs-border-radius-lg: var(--r);
    --bs-border-radius-xl: var(--r-lg);

    --bs-primary: #4f46e5;   --bs-primary-rgb: 79, 70, 229;
    --bs-success: #059669;   --bs-success-rgb: 5, 150, 105;
    --bs-warning: #d97706;   --bs-warning-rgb: 217, 119, 6;
    --bs-danger:  #dc2626;   --bs-danger-rgb: 220, 38, 38;
    --bs-info:    #0284c7;   --bs-info-rgb: 2, 132, 199;
    --bs-secondary: #697586; --bs-secondary-rgb: 105, 117, 134;

    --bs-link-color: var(--accent);
    --bs-link-hover-color: var(--accent-hover);
    --bs-link-color-rgb: 79, 70, 229;
}

body.dark {
    --bs-primary: #818cf8;   --bs-primary-rgb: 129, 140, 248;
    --bs-success: #34d399;   --bs-success-rgb: 52, 211, 153;
    --bs-warning: #fbbf24;   --bs-warning-rgb: 251, 191, 36;
    --bs-danger:  #f87171;   --bs-danger-rgb: 248, 113, 113;
    --bs-info:    #38bdf8;   --bs-info-rgb: 56, 189, 248;
    --bs-link-color-rgb: 129, 140, 248;
}

/* Ikon validasi Bootstrap default (centang polos) diganti checkmark di
   dalam lingkaran hijau - dipakai form pendanaan (dana_inisialisasi.php,
   dana_setoran.php), tapi berlaku ke .form-control.is-valid mana pun.
   Warna SVG di-hardcode (tidak bisa var()), jadi dua versi untuk mode
   terang/gelap mengikuti --bs-success di atas. */
.form-control.is-valid {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23059669'%3E%3Cpath d='M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zm-3.97-3.03a.75.75 0 0 0-1.08.022L7.477 9.417 5.384 7.323a.75.75 0 0 0-1.06 1.06L6.97 11.03a.75.75 0 0 0 1.079-.02l3.992-4.99a.75.75 0 0 0-.01-1.05z'/%3E%3C/svg%3E") !important;
}
body.dark .form-control.is-valid {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%2334d399'%3E%3Cpath d='M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zm-3.97-3.03a.75.75 0 0 0-1.08.022L7.477 9.417 5.384 7.323a.75.75 0 0 0-1.06 1.06L6.97 11.03a.75.75 0 0 0 1.079-.02l3.992-4.99a.75.75 0 0 0-.01-1.05z'/%3E%3C/svg%3E") !important;
}

/* --------------------------------------------------------------------------
   2. DASAR
   -------------------------------------------------------------------------- */
body {
    font-family: var(--font);
    font-size: var(--fs-base);
    line-height: 1.55;
    background: var(--bg);
    color: var(--text);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

h1, h2, h3, h4, h5, h6 {
    font-weight: 650;
    letter-spacing: -0.011em;
    color: var(--text);
    line-height: 1.25;
}
h1 { font-size: var(--fs-2xl); }
h2 { font-size: var(--fs-xl); }
h3 { font-size: var(--fs-lg); }
h4 { font-size: var(--fs-md); }
h5 { font-size: var(--fs-base); }
h6 { font-size: var(--fs-sm); }

a { color: var(--accent); text-decoration: none; }
a:hover { color: var(--accent-hover); text-decoration: underline; }

hr { border-color: var(--border); opacity: 1; }

::selection { background: var(--accent-soft); color: var(--text); }

/* Fokus konsisten di seluruh aplikasi. Bootstrap memakai box-shadow tebal
   yang berbeda-beda per komponen; disatukan jadi satu cincin. */
:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}
/* Bootstrap memberi .form-control:focus latar var(--bs-body-bg), yang
   di-resolve di :root (selalu terang) - di mode gelap input yang difokus
   jadi putih dengan teks terang, tak terbaca. Dikunci ke token permukaan. */
.form-control:focus,
.form-select:focus {
    background-color: var(--surface);
    color: var(--text);
}
.btn:focus, .form-control:focus, .form-select:focus, .form-check-input:focus,
.page-link:focus {
    box-shadow: 0 0 0 3px var(--ring) !important;
    border-color: var(--accent) !important;
    outline: none;
}

/* --------------------------------------------------------------------------
   3. KOMPONEN: tombol

   Bootstrap menghitung warna tombol dari variabelnya sendiri (--bs-btn-*),
   jadi menimpanya lewat variabel itu lebih aman daripada menimpa
   background/border langsung - state hover/active/disabled ikut benar
   dengan sendirinya.
   -------------------------------------------------------------------------- */
.btn {
    --bs-btn-padding-y: 0.25rem;
    --bs-btn-padding-x: 0.75rem;
    --bs-btn-font-size: var(--fs-sm);
    --bs-btn-font-weight: 550;
    --bs-btn-border-radius: var(--r-sm);
    min-height: 34px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.4rem;
    letter-spacing: -0.006em;
    box-shadow: var(--sh-sm);
    transition: background-color .15s ease, border-color .15s ease,
                color .15s ease, box-shadow .15s ease, transform .06s ease;
}
.btn:active { transform: translateY(1px); }

.btn-sm {
    /* Kelas Bootstrap lama ini masih banyak dipakai markup. Dibuat identik
       dengan tombol standar agar aksi yang setara tidak berubah font/tinggi
       hanya karena satu halaman memakai btn-sm. */
    --bs-btn-padding-y: 0.25rem;
    --bs-btn-padding-x: 0.75rem;
    --bs-btn-font-size: var(--fs-sm);
    min-height: 34px;
}
.btn-lg {
    --bs-btn-padding-y: 0.25rem;
    --bs-btn-padding-x: 0.75rem;
    --bs-btn-font-size: var(--fs-sm);
    min-height: 34px;
}

.btn-primary {
    --bs-btn-bg: var(--accent);            --bs-btn-border-color: var(--accent);
    --bs-btn-hover-bg: var(--accent-hover);--bs-btn-hover-border-color: var(--accent-hover);
    --bs-btn-active-bg: var(--accent-hover);--bs-btn-active-border-color: var(--accent-hover);
    --bs-btn-disabled-bg: var(--accent);   --bs-btn-disabled-border-color: var(--accent);
    --bs-btn-color: #fff; --bs-btn-hover-color: #fff; --bs-btn-active-color: #fff;
}
.btn-success {
    --bs-btn-bg: var(--ok);            --bs-btn-border-color: var(--ok);
    --bs-btn-hover-bg: var(--ok-600);  --bs-btn-hover-border-color: var(--ok-600);
    --bs-btn-active-bg: var(--ok-600); --bs-btn-active-border-color: var(--ok-600);
    --bs-btn-color: #fff; --bs-btn-hover-color: #fff; --bs-btn-active-color: #fff;
}
.btn-warning {
    --bs-btn-bg: var(--warn);            --bs-btn-border-color: var(--warn);
    --bs-btn-hover-bg: var(--warn-600);  --bs-btn-hover-border-color: var(--warn-600);
    --bs-btn-active-bg: var(--warn-600); --bs-btn-active-border-color: var(--warn-600);
    --bs-btn-color: #fff; --bs-btn-hover-color: #fff; --bs-btn-active-color: #fff;
}
.btn-danger {
    --bs-btn-bg: var(--bad);            --bs-btn-border-color: var(--bad);
    --bs-btn-hover-bg: var(--bad-600);  --bs-btn-hover-border-color: var(--bad-600);
    --bs-btn-active-bg: var(--bad-600); --bs-btn-active-border-color: var(--bad-600);
    --bs-btn-color: #fff; --bs-btn-hover-color: #fff; --bs-btn-active-color: #fff;
}
.btn-info {
    --bs-btn-bg: var(--info);       --bs-btn-border-color: var(--info);
    --bs-btn-color: #fff; --bs-btn-hover-color: #fff; --bs-btn-active-color: #fff;
}

/* Di mode gelap aksennya sengaja dibuat terang supaya terbaca di latar
   gelap - tapi itu membuat teks putih di atasnya nyaris hilang. Tombol solid
   karena itu memakai tinta gelap, bukan putih. Hanya tombol berlatar penuh;
   varian bergaris tetap mengambil warna dari tokennya. */
body.dark .btn-primary,
body.dark .btn-success,
body.dark .btn-warning,
body.dark .btn-danger,
body.dark .btn-info {
    --bs-btn-color: var(--n-900);
    --bs-btn-hover-color: var(--n-900);
    --bs-btn-active-color: var(--n-900);
    --bs-btn-disabled-color: var(--n-900);
}
body.dark .btn-primary { --bs-btn-hover-bg: var(--brand-300); --bs-btn-hover-border-color: var(--brand-300); }
body.dark .btn-success { --bs-btn-hover-bg: #6ee7b7; --bs-btn-hover-border-color: #6ee7b7; }
body.dark .btn-warning { --bs-btn-hover-bg: #fcd34d; --bs-btn-hover-border-color: #fcd34d; }
body.dark .btn-danger  { --bs-btn-hover-bg: #fca5a5; --bs-btn-hover-border-color: #fca5a5; }

/* Tombol netral. Di aplikasi ini .btn-secondary hampir selalu berarti
   "batal"/"kembali", jadi dibuat tenang: permukaan biasa dengan garis. */
.btn-secondary,
.btn-light,
.btn-outline-secondary {
    --bs-btn-bg: var(--surface);          --bs-btn-border-color: var(--border-2);
    --bs-btn-color: var(--text-2);
    --bs-btn-hover-bg: var(--surface-3);  --bs-btn-hover-border-color: var(--border-2);
    --bs-btn-hover-color: var(--text);
    --bs-btn-active-bg: var(--surface-3); --bs-btn-active-border-color: var(--border-2);
    --bs-btn-active-color: var(--text);
}

.btn-outline-primary {
    --bs-btn-color: var(--accent);         --bs-btn-border-color: var(--border-2);
    --bs-btn-bg: var(--surface);
    --bs-btn-hover-bg: var(--accent-soft); --bs-btn-hover-border-color: var(--accent);
    --bs-btn-hover-color: var(--accent-hover);
    --bs-btn-active-bg: var(--accent-soft);--bs-btn-active-border-color: var(--accent);
    --bs-btn-active-color: var(--accent-hover);
}
.btn-outline-danger {
    --bs-btn-color: var(--bad);        --bs-btn-border-color: var(--border-2);
    --bs-btn-bg: var(--surface);
    --bs-btn-hover-bg: var(--bad);     --bs-btn-hover-border-color: var(--bad);
}
.btn-outline-success {
    --bs-btn-color: var(--ok);         --bs-btn-border-color: var(--border-2);
    --bs-btn-bg: var(--surface);
    --bs-btn-hover-bg: var(--ok);      --bs-btn-hover-border-color: var(--ok);
}

/* --------------------------------------------------------------------------
   4. KOMPONEN: kartu

   Kedalaman datang dari garis tipis + bayangan halus, bukan dari blur pekat
   seperti sebelumnya (0 3px 10px rgba(0,0,0,.08) di tiap kartu membuat
   halaman terlihat kotor saat kartunya banyak).
   -------------------------------------------------------------------------- */
.card,
.sb-card {
    background: var(--surface);
    color: var(--text);
    border: 1px solid var(--border);
    border-radius: var(--r-lg);
    box-shadow: var(--sh);
}
.sb-card { padding: 1.25rem; }

.card {
    --bs-card-bg: var(--surface);
    --bs-card-color: var(--text);
    --bs-card-border-color: var(--border);
    --bs-card-border-radius: var(--r-lg);
    --bs-card-inner-border-radius: calc(var(--r-lg) - 1px);
    --bs-card-spacer-x: 1.25rem;
    --bs-card-spacer-y: 1.25rem;
}
.card-header,
.card-footer {
    background: transparent;
    border-color: var(--border);
    font-weight: 600;
    color: var(--text);
}

/* Judul kartu. Halaman memakai <h5> polos di dalam .sb-card, jadi ditata
   di sini alih-alih menambah kelas ke 23 file. */
.sb-card > h5:first-child,
.sb-card > h5.mb-3 {
    font-size: var(--fs-sm);
    font-weight: 600;
    letter-spacing: 0.02em;
    text-transform: uppercase;
    color: var(--text-muted);
    margin-bottom: 0.5rem;
}
/* Angka besar di kartu statistik dashboard */
.sb-card > h2 {
    font-size: var(--fs-2xl);
    font-weight: 700;
    letter-spacing: -0.02em;
    margin-top: 0.25rem !important;
    font-variant-numeric: tabular-nums;
}

/* --------------------------------------------------------------------------
   5. KOMPONEN: form
   -------------------------------------------------------------------------- */
.form-label {
    font-size: var(--fs-sm);
    font-weight: 550;
    color: var(--text-2);
    margin-bottom: 0.3rem;
}
.form-control,
.form-select {
    min-height: 34px;
    /* 16px supaya Safari iOS tidak otomatis men-zoom saat input difokuskan.
       Nilai ini sengaja tidak diturunkan ke --fs-base. */
    font-size: var(--fs-sm);
    padding: 0.25rem 0.65rem;
    /* background-color, bukan shorthand `background`: shorthand ikut mereset
       background-image, dan panah dropdown .form-select justru berasal dari
       background-image itu - semua <select> jadi tampak seperti input teks. */
    background-color: var(--surface);
    color: var(--text);
    border: 1px solid var(--border-2);
    border-radius: var(--r-sm);
    box-shadow: none;
    transition: border-color .15s ease, box-shadow .15s ease;
}
.form-control::placeholder { color: var(--text-muted); opacity: 1; }
.form-control:disabled,
.form-select:disabled { background-color: var(--surface-3); color: var(--text-muted); }
/* TomSelect (select yang bisa dicari, mis. field "Karyawan" di form pengajuan)
   punya kotak ketik tersembunyi dengan min-width 7rem bawaan yang tetap ada
   sesudah satu opsi dipilih. Kalau teks opsi terpilih sudah memenuhi lebar
   kontainer, kotak ketik kosong itu tidak muat lagi di baris yang sama dan
   turun ke baris baru - terlihat seperti kursor "loncat" ke bawah. */
.ts-control > input { min-width: 0 !important; }
/* Opsi Karyawan (nama — rekening — admin) sering lebih panjang dari lebar
   kotaknya sendiri dan pecah ke baris kedua. Lebarkan dropdown sampai
   selebar isinya (bukan dikunci selebar kontrol) supaya tetap satu baris. */
.ts-dropdown.dropdown-karyawan { width: max-content !important; max-width: min(32rem, 90vw); }
.ts-dropdown.dropdown-karyawan .option { white-space: nowrap; }
/* TomSelect di dalam modal dipasang dengan dropdownParent:'body' supaya
   dropdown-nya tidak terpotong overflow .modal-dialog-scrollable (lihat
   pengajuan/index.php). Konsekuensinya dropdown itu jadi anak <body>, di
   LUAR .modal, sementara z-index bawaannya cuma 10 - kalah dari .modal
   (1055) dan .modal-backdrop (1050), jadi tampil di belakang popup.
   Selector diawali `body` supaya menang atas tom-select.bootstrap5.min.css
   yang dimuat sesudah app.css (lihat catatan tema di bawah). */
body .ts-dropdown { z-index: 1060; }
/* Tema TomSelect bawaan (tom-select.bootstrap5.min.css) sebagian besar warna
   teksnya di-hardcode (bukan lewat variabel --bs-*), dan link CSS-nya
   dimuat belakangan (di bawah halaman, sesudah app.css di <head>) - jadi
   kalaupun ditimpa dengan selector sespesifik yang sama, dialah yang
   menang karena datang belakangan. Override di sini dibuat lebih spesifik
   (diawali .dark) supaya menang terlepas dari urutan pemuatan. */
body.dark .ts-control,
body.dark .ts-wrapper.single .ts-control,
body.dark .ts-dropdown {
    background: var(--surface);
    color: var(--text);
    border-color: var(--border);
}
body.dark .ts-control > input,
body.dark .ts-control > div { color: var(--text); }
body.dark .ts-dropdown .option,
body.dark .ts-dropdown .optgroup-header { color: var(--text); background: var(--surface); }
body.dark .ts-dropdown .create { color: var(--text-muted); }
/* TomSelect memindahkan .active saat tombol ↑/↓ ditekan. Beri kontras
   yang jelas agar fokus keyboard terlihat di kedua tema, termasuk ketika
   stylesheet TomSelect dimuat sesudah app.css. */
body .ts-dropdown .option.active,
body .ts-dropdown .create.active,
body.dark .ts-dropdown .option.active,
body.dark .ts-dropdown .create.active {
    background: var(--accent-soft);
    color: var(--accent-hover);
    box-shadow: inset 3px 0 0 var(--accent);
}
.input-group-text {
    min-height: 34px;
    padding: 0.25rem 0.65rem;
    background: var(--surface-3);
    border-color: var(--border-2);
    color: var(--text-muted);
    font-size: 1rem;
}
.input-group-sm > .form-control,
.input-group-sm > .form-select,
.input-group-sm > .input-group-text,
.input-group-sm > .btn {
    min-height: 34px;
    font-size: var(--fs-sm);
}
.form-check-input { border-color: var(--border-2); background-color: var(--surface); }
.form-check-input:checked {
    background-color: var(--accent);
    border-color: var(--accent);
}
.form-text { color: var(--text-muted); font-size: var(--fs-xs); }

/* --------------------------------------------------------------------------
   6. KOMPONEN: badge, alert, modal, tabel dasar
   -------------------------------------------------------------------------- */
.badge {
    font-weight: 600;
    font-size: var(--fs-xs);
    letter-spacing: 0.01em;
    padding: 0.3em 0.6em;
    border-radius: var(--r-pill);
}
/* Badge status dibuat "soft" (latar tipis + teks pekat) - lebih mudah
   dibaca berderet di dalam tabel daripada blok warna penuh. */
.badge.bg-success { background: var(--ok-50) !important;   color: var(--ok-600); }
.badge.bg-warning { background: var(--warn-50) !important; color: var(--warn-600); }
.badge.bg-danger  { background: var(--bad-50) !important;  color: var(--bad-600); }
.badge.bg-primary { background: var(--accent-soft) !important; color: var(--accent-hover); }
.badge.bg-info    { background: var(--info-50) !important; color: var(--info); }
.badge.bg-secondary { background: var(--surface-3) !important; color: var(--text-2); }
body.dark .badge.bg-success { color: var(--ok); }
body.dark .badge.bg-warning { color: var(--warn); }
body.dark .badge.bg-danger  { color: var(--bad); }
body.dark .badge.bg-primary { color: var(--accent); }

.alert {
    border-radius: var(--r);
    border: 1px solid transparent;
    font-size: var(--fs-base);
    padding: 0.75rem 1rem;
}
/* Ikon umpan balik ditulis langsung sebelum pesan di beberapa halaman.
   Margin memastikan ikon tidak menempel pada huruf pertama, tanpa memaksa
   semua alert (yang tidak memiliki ikon) menjadi layout flex. */
.alert > .bi:first-child {
    display: inline-block;
    margin-right: 0.5rem;
    vertical-align: -0.1em;
}
.alert-success { background: var(--ok-50);   border-color: var(--ok);   color: var(--ok-600); }
.alert-warning { background: var(--warn-50); border-color: var(--warn); color: var(--warn-600); }
.alert-danger  { background: var(--bad-50);  border-color: var(--bad);  color: var(--bad-600); }
.alert-info    { background: var(--info-50); border-color: var(--info); color: var(--info); }
body.dark .alert-success { color: var(--ok); }
body.dark .alert-warning { color: var(--warn); }
body.dark .alert-danger  { color: var(--bad); }

/* Huruf yang cocok pada pencarian toleran-typo (substring atau typo) -
   lihat assets/fuzzy-search.js. */
.teks-cocok { color: var(--info); font-weight: 700; }

.modal-content {
    background: var(--surface);
    color: var(--text);
    border: 1px solid var(--border);
    border-radius: var(--r-lg);
    box-shadow: var(--sh-lg);
}
.modal-header, .modal-footer { border-color: var(--border); }
.modal-title { font-size: var(--fs-md); }
body.dark .btn-close { filter: invert(1) grayscale(100%) brightness(200%); }

.dropdown-menu {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--r);
    box-shadow: var(--sh-lg);
    padding: 0.3rem;
    font-size: var(--fs-base);
}
.dropdown-item { border-radius: var(--r-sm); color: var(--text); padding: 0.45rem 0.7rem; }
.dropdown-item:hover, .dropdown-item:focus { background: var(--surface-3); color: var(--text); }

.table {
    --bs-table-color: var(--text);
    --bs-table-bg: transparent;
    --bs-table-border-color: var(--border);
    --bs-table-striped-color: var(--text);
    --bs-table-striped-bg: var(--surface-2);
    --bs-table-hover-color: var(--text);
    --bs-table-hover-bg: var(--surface-3);
    font-size: var(--fs-base);
}
.table > thead th {
    font-size: var(--fs-xs);
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--text-muted);
    border-bottom: 1px solid var(--border);
}
/* Kolom angka sejajar per digit, supaya nominal mudah dibandingkan */
.table td.text-end, .table th.text-end { font-variant-numeric: tabular-nums; }

/* --------------------------------------------------------------------------
   7. Pagination + kontrol DataTables (tampilan saja; tata letak
      responsifnya diatur di bagian bawah file)
   -------------------------------------------------------------------------- */
.page-link {
    color: var(--text-2);
    background: var(--surface);
    border-color: var(--border);
    font-size: var(--fs-sm);
}
.page-link:hover { background: var(--surface-3); color: var(--text); border-color: var(--border); }
.page-item.active .page-link {
    background: var(--accent);
    border-color: var(--accent);
    color: #fff;
}
.page-item.disabled .page-link { background: var(--surface); color: var(--text-muted); border-color: var(--border); }

table.dataTable { color: var(--text); }
table.dataTable thead th.sorting,
table.dataTable thead th.sorting_asc,
table.dataTable thead th.sorting_desc { color: var(--text-2); }

/* Panah sort (naik/turun) di judul kolom. Bawaan DataTables cuma 12-30%
   opacity - nyaris tak terlihat, sehingga kolom yang sebenarnya bisa
   diurutkan tampak tidak punya sort. Dibuat jelas: kedua panah terlihat
   di kolom yang belum diurutkan, dan panah arah aktif memakai warna aksen.
   .th-sortable/.th-asc/.th-desc dipakai pengurut tabel statis (footer.php)
   supaya tampilannya sama dengan DataTables. */
table.dataTable > thead > tr > th.sorting,
table.dataTable > thead > tr > th.sorting_asc,
table.dataTable > thead > tr > th.sorting_desc,
th.th-sortable { cursor: pointer; user-select: none; }
table.dataTable > thead > tr > th.sorting::before,
table.dataTable > thead > tr > th.sorting::after,
table.dataTable > thead > tr > th.sorting_asc::before,
table.dataTable > thead > tr > th.sorting_asc::after,
table.dataTable > thead > tr > th.sorting_desc::before,
table.dataTable > thead > tr > th.sorting_desc::after { opacity: 0.4; color: var(--text-2); font-size: 0.8em; }
table.dataTable > thead > tr > th.sorting_asc::before,
table.dataTable > thead > tr > th.sorting_desc::after { opacity: 1; color: var(--accent); }

th.th-sortable { position: relative; padding-right: 1.6rem !important; white-space: nowrap; }
th.th-sortable::before,
th.th-sortable::after {
    position: absolute;
    right: 0.5rem;
    font-size: 0.8em;
    line-height: 1;
    opacity: 0.4;
    color: var(--text-2);
    display: block;
}
th.th-sortable::before { content: "\25B2"; bottom: 50%; }
th.th-sortable::after  { content: "\25BC"; top: 50%; }
th.th-sortable.th-asc::before,
th.th-sortable.th-desc::after { opacity: 1; color: var(--accent); }

/* Sisa penyesuaian mode gelap yang tidak tertutup token di atas */
body.dark .table > :not(caption) > * > * { color: var(--text); }

/* Baris peringatan (mis. hasil AI yang belum cocok ke karyawan/barang).
   .table-warning bawaan Bootstrap berlatar kuning terang; di mode gelap
   teks terang di atasnya jadi tak terbaca. Latar diganti kuning transparan
   di atas permukaan gelap, teks tetap --text. Pola sama untuk .table-success. */
body.dark .table-warning,
body.dark .table-success {
    --bs-table-color: var(--text);
    --bs-table-border-color: var(--border);
}
body.dark .table-warning { --bs-table-bg: var(--warn-50); }
body.dark .table-success { --bs-table-bg: var(--ok-50); }
body.dark .table-warning > * > * { color: var(--text); box-shadow: inset 0 0 0 9999px var(--warn-50); background-color: transparent; }
body.dark .table-success > * > * { color: var(--text); box-shadow: inset 0 0 0 9999px var(--ok-50); background-color: transparent; }
body.dark .table-warning .text-danger,
body.dark .table-warning .text-muted { color: var(--bad) !important; }
body.dark .table-warning .text-muted { color: var(--text-2) !important; }

/* Mode gelap: kontras teks form dan judul kolom dinaikkan. Nilai di kolom
   input (Skema Bantuan, Tarif Markup, dst.) dan label kolom yang kecil +
   huruf kapital sebelumnya memakai abu redup di atas latar gelap. */
body.dark .form-control,
body.dark .form-select { color: var(--text); }
body.dark .input-group-text { color: var(--text-2); }
body.dark .table > thead th,
body.dark .tabel-daftar thead th,
body.dark .data-table-card .tabel-daftar thead th { color: var(--text-2); }
body.dark .form-check-label { color: var(--text); }

/* --------------------------------------------------------------------------
   Pasangan label/nilai, untuk ringkasan data yang bukan daftar
   -------------------------------------------------------------------------- */
.ringkas-item {
    display: flex;
    justify-content: space-between;
    gap: 0.75rem;
    padding: 0.5rem 0;
    border-bottom: 1px solid var(--garis);
}
.ringkas-item:last-of-type { border-bottom: 0; }
.ringkas-item .label { color: var(--redup); min-width: 0; }

/* Header ringkasan karyawan (pengajuan_add.php): nama + info tambahan
   (admin/proyek) sebagai subjudul kecil, lalu angka-angka kunci
   (rekening, sisa limit) berdampingan - bukan ditumpuk 5 baris rata
   seperti .ringkas-item biasa, supaya yang penting (nama + limit)
   langsung kelihatan tanpa scroll, terutama di HP. */
.ringkas-header {
    display: flex;
    flex-direction: column;
    gap: 0.85rem;
    margin-bottom: 0.25rem;
}
.ringkas-header .ringkas-nama strong { font-size: 1.05rem; }
.ringkas-header .ringkas-sub {
    display: block;
    color: var(--redup);
    font-size: var(--fs-sm);
    margin-top: 0.15rem;
}
.ringkas-stats { display: flex; gap: 1.75rem; flex-wrap: wrap; }
.ringkas-stats .stat .label { display: block; color: var(--redup); font-size: var(--fs-sm); }
.ringkas-stats .stat .nilai { display: block; font-weight: 700; font-size: 1.05rem; white-space: nowrap; }

/* Desktop: layar cukup lebar, jadi nama+subjudul dan tiap label+nilai
   digabung satu baris (bukan ditumpuk seperti mobile). */
@media (min-width: 992px) {
    .ringkas-nama { display: flex; align-items: baseline; gap: 0.5rem; flex-wrap: wrap; }
    .ringkas-header .ringkas-sub { margin-top: 0; }
    .ringkas-stats .stat { display: flex; align-items: baseline; gap: 0.4rem; }
    .ringkas-stats .stat .label::after { content: ':'; }
}

.ringkas-item .nilai {
    font-weight: 600;
    text-align: right;
    white-space: nowrap;        /* "Rp 2.000.000" jangan pecah dua baris */
}

/* --------------------------------------------------------------------------
   Daftar: di HP tiap baris jadi kartu, di desktop kembali jadi tabel.
   Markup-nya satu. Tiap <td> cukup diberi data-label="Nama Kolom".
   -------------------------------------------------------------------------- */
.tabel-daftar {
    width: 100%;
    /* Bootstrap 5 memasang latar pada tiap SEL lewat --bs-table-bg, bukan pada
       baris. Dibuat transparan supaya latar kartu/wadah yang terlihat, dan
       mode gelap tidak menyisakan sel putih. */
    --bs-table-bg: transparent;
    --bs-table-color: inherit;
    /* Mode kartu tidak boleh punya lebar minimum: tabel yang dipaksa lebar
       akan mendorong nilai keluar layar dan menyisakan label saja. */
    min-width: 0;
}
body.dark .tabel-daftar {
    --bs-table-color: var(--text);
    --bs-table-striped-color: var(--text);
    --bs-table-striped-bg: rgba(255, 255, 255, 0.04);
}

.tabel-daftar thead {
    /* Disembunyikan dari mata, tetap terbaca pembaca layar */
    position: absolute;
    width: 1px; height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
}

.tabel-daftar tr {
    display: block;
    border: 1px solid var(--garis);
    border-radius: var(--radius);
    padding: 0.25rem 0.875rem;
    margin-bottom: 0.75rem;
    /* Diselesaikan di elemen ini, bukan di :root — --card-bg didefinisikan
       di body.dark, jadi indireksi lewat :root akan selalu jatuh ke putih. */
    background: var(--card-bg, #fff);
}

.tabel-daftar td {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 0.75rem;
    padding: 0.5rem 0;
    border: 0;
    border-bottom: 1px solid var(--garis);
    text-align: left !important;
    white-space: normal !important;   /* lawan kelas .nowrap milik DataTables */
}
.tabel-daftar tr td:last-child { border-bottom: 0; }

.tabel-daftar td::before {
    content: attr(data-label);
    flex: 0 0 auto;
    color: var(--redup);
    font-size: 0.8125rem;
}

/* Sel yang isinya tombol: biar tombolnya melebar, label tetap di kiri */
.tabel-daftar td.sel-aksi { flex-wrap: wrap; gap: 0.5rem; }
.tabel-daftar td.sel-aksi .btn { flex: 1 1 auto; }

/* Baris TOTAL di tfoot. colspan tidak bermakna saat baris jadi kartu, jadi
   selnya disembunyikan dan sisanya tampil sebagai kartu ringkasan. */
.tabel-daftar tr.baris-total {
    border-color: var(--border-2);
    background: var(--surface-2);
    font-weight: 600;
}
.tabel-daftar tr.baris-total td.sel-total {
    display: block;
    text-align: left;
    letter-spacing: .06em;
    font-size: .8125rem;
    color: var(--redup);
    border-bottom: 1px solid var(--garis);
}
.tabel-daftar tr.baris-total td.sel-total::before { content: none; }

/* Baris yang sedang dipilih (mis. untuk approve massal). box-shadow di sini
   berlaku untuk mode kartu (mobile-first, <tr> masih display:block - lihat
   .tabel-daftar tr di atas) - pada display:block, box-shadow melukis
   keempat sisi dengan benar. Begitu breakpoint desktop mengembalikan <tr>
   ke display:table-row, box-shadow ini TIDAK dilukis penuh oleh browser
   (cuma sisi atas & kiri yang tampak, ketahuan 2026-09-17) - table-row
   bukan kotak mandiri di model render tabel. Override per-<td> di bawah
   ("Desktop") yang menggantikannya untuk breakpoint itu. */
.tabel-daftar tr.terpilih {
    border-color: var(--accent);
    box-shadow: inset 0 0 0 1px var(--accent);
    background: var(--accent-soft);
}

/* Baris bertanda, mis. nilai tagihan melewati limit */
.tabel-daftar tr.lewat-limit {
    border-color: var(--bad);
    background: var(--bad-50);
}

/* --------------------------------------------------------------------------
   Kontrol DataTables

   Tata letaknya ditentukan opsi `dom` di tiap halaman, yang kini menghasilkan:

       .dt-toolbar  >  .dt-toolbar-kiri (tombol export + jumlah baris)
                       .dt-toolbar-kanan (pencarian)
       tabel
       .dt-kaki     >  info + paginasi

   Sebelumnya ketiganya adalah tiga baris .d-flex terpisah yang tidak pernah
   sejajar satu sama lain. Mobile-first: semuanya menumpuk penuh di layar
   kecil, dan baru menjadi baris sejajar mulai 992px.
   -------------------------------------------------------------------------- */
.dataTables_wrapper { font-size: var(--fs-base); color: var(--text); }

.dt-toolbar,
.dt-toolbar-kiri,
.dt-toolbar-kanan {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}
.dt-toolbar { margin-bottom: 0.875rem; }

/* Selektor sengaja lebih khusus (pakai div): CSS DataTables dimuat sesudah
   file ini dan memaksa float/text-align pada elemen-elemen ini. */
.dataTables_wrapper div.dt-buttons,
.dataTables_wrapper div.dataTables_length,
.dataTables_wrapper div.dataTables_filter,
.dataTables_wrapper div.dataTables_info,
.dataTables_wrapper div.dataTables_paginate {
    float: none !important;
    width: 100%;
    margin: 0;
    text-align: left;
}

/* Label "Show ... entries" dan "Search:" dirangkai sebaris dengan kontrolnya */
.dataTables_wrapper div.dataTables_length label,
.dataTables_wrapper div.dataTables_filter label {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin: 0;
    width: 100%;
    color: var(--text-muted);
    font-size: var(--fs-sm);
    white-space: nowrap;
}

/* Tombol export jadi satu kelompok tersegmen: satu garis mengelilingi,
   pembatas tipis di antara tombol. DataTables memaksa .btn-secondary ke
   setiap tombol (itu sebabnya tombol Excel yang diberi .btn-success tetap
   tampil abu), jadi warnanya diambil alih di sini dan dibuat seragam -
   dua tombol export berwarna-warni bersaing dengan data di bawahnya. */
.dataTables_wrapper div.dt-buttons {
    display: inline-flex;
    flex-wrap: wrap;
    gap: 0;
    width: auto;
}
.dataTables_wrapper div.dt-buttons .btn,
.dataTables_wrapper div.dt-buttons .btn.btn-secondary {
    --bs-btn-bg: var(--surface);
    --bs-btn-border-color: var(--border-2);
    --bs-btn-color: var(--text-2);
    --bs-btn-hover-bg: var(--surface-3);
    --bs-btn-hover-border-color: var(--border-2);
    --bs-btn-hover-color: var(--text);
    --bs-btn-active-bg: var(--surface-3);
    --bs-btn-active-color: var(--text);
    min-height: 34px;
    padding: 0.25rem 0.75rem;
    font-size: var(--fs-sm);
    font-weight: 550;
    border-radius: 0;
    box-shadow: none;
    margin: 0;
}
/* Hanya tepi terluar yang membulat, dan garis di antara tombol tidak dobel */
.dataTables_wrapper div.dt-buttons .btn:first-child {
    border-start-start-radius: var(--r-sm);
    border-end-start-radius: var(--r-sm);
}
.dataTables_wrapper div.dt-buttons .btn:last-child {
    border-start-end-radius: var(--r-sm);
    border-end-end-radius: var(--r-sm);
}
.dataTables_wrapper div.dt-buttons .btn + .btn { border-left-width: 0; }
.dataTables_wrapper div.dt-buttons .btn i { font-size: var(--fs-sm); opacity: 0.75; }

/* Pemilih jumlah baris: selebar isinya, bukan selebar kolom */
.dataTables_wrapper div.dataTables_length select.form-select {
    width: auto;
    min-width: 4.75rem;
    min-height: 34px;
    padding: 0.25rem 1.8rem 0.25rem 0.55rem;
    font-size: var(--fs-sm);
}

/* Kotak pencarian. Label "Search:" bawaan DataTables dipendekkan jadi ikon
   kaca pembesar lewat pseudo-element, supaya kotaknya bisa lebih lebar
   tanpa mendorong apa pun. */
.dataTables_wrapper div.dataTables_filter label { position: relative; font-size: 0; }
.dataTables_wrapper div.dataTables_filter label::before {
    content: "\F52A";                 /* bi-search */
    font-family: "bootstrap-icons";
    position: absolute;
    left: 0.7rem;
    top: 50%;
    transform: translateY(-50%);
    font-size: 0.9rem;
    color: var(--text-muted);
    pointer-events: none;
}
.dataTables_wrapper div.dataTables_filter input.form-control {
    width: 100%;
    min-height: 34px;
    margin: 0;
    padding-left: 1.9rem;
    font-size: var(--fs-sm);
    border-radius: var(--r-sm);
}

/* Baris kaki: jumlah data di kiri, paginasi di kanan */
.dt-kaki {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.75rem;
    margin-top: 0.875rem;
    padding-top: 0.875rem;
    border-top: 1px solid var(--border);
}
.dataTables_wrapper div.dataTables_info {
    color: var(--text-muted);
    font-size: var(--fs-sm);
    padding: 0;
    text-align: center;
}

/* 988 baris = 99 halaman. Deretan tombolnya harus boleh melipat, kalau
   tidak ia mendorong halaman melebihi lebar layar. */
.dataTables_wrapper div.dataTables_paginate ul.pagination {
    flex-wrap: wrap;
    justify-content: center;
    gap: 0.25rem;
    margin: 0;
}
.dataTables_wrapper div.dataTables_paginate .page-link {
    min-width: 34px;
    min-height: 34px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0 0.6rem;
    border-radius: var(--r-sm);
    border-color: var(--border);
    font-size: var(--fs-sm);
    font-weight: 550;
}
.dataTables_wrapper div.dataTables_paginate .page-item.active .page-link {
    background: var(--accent);
    border-color: var(--accent);
    color: #fff;
}
.dataTables_wrapper div.dataTables_paginate .page-item.disabled .page-link {
    opacity: 0.5;
}

/* --------------------------------------------------------------------------
   Desktop
   -------------------------------------------------------------------------- */
@media (min-width: 992px) {
    .dt-toolbar {
        flex-direction: row;
        align-items: center;
        justify-content: space-between;
        gap: 1rem;
    }
    .dt-toolbar-kiri {
        flex-direction: row;
        align-items: center;
        gap: 0.75rem;
    }
    .dt-toolbar-kanan { flex-direction: row; width: min(20rem, 40%); }

    .dataTables_wrapper div.dataTables_length,
    .dataTables_wrapper div.dataTables_filter { width: auto; }
    .dataTables_wrapper div.dataTables_filter { flex: 1 1 auto; }

    .dt-kaki {
        flex-direction: row;
        align-items: center;
        justify-content: space-between;
    }
    .dataTables_wrapper div.dataTables_info { text-align: left; }
    .dataTables_wrapper div.dataTables_paginate ul.pagination { justify-content: flex-end; }
}

/* --------------------------------------------------------------------------
   Desktop
   -------------------------------------------------------------------------- */
@media (min-width: 992px) {
    .ringkas-item { display: block; border-bottom: 0; padding: 0.125rem 0; }
    .ringkas-item .nilai { text-align: left; }
    .ringkas-item .label::after { content: ':\00a0'; }

    .tabel-daftar thead {
        position: static;
        width: auto; height: auto;
        overflow: visible;
        clip: auto;
    }
    .tabel-daftar thead th {
        border-bottom: 2px solid var(--garis);
        color: var(--redup);
        font-size: 0.875rem;
    }
    .tabel-daftar tr {
        display: table-row;
        border: 0;
        border-radius: 0;
        padding: 0;
        margin: 0;
        background: transparent;
    }
    .tabel-daftar td {
        display: table-cell;
        vertical-align: middle;
        padding: 0.5rem 0.4rem;
        border-bottom: 1px solid var(--garis);
    }
    .tabel-daftar td.text-end { text-align: right !important; }
    /* Tabel berkolom banyak tidak boleh dipaksa menyusut sampai tanggal,
       nama, dan nominal terpecah ke dua baris. Wadah tabel saja yang dapat
       digeser secara horizontal; halaman dan sidebar tetap diam. */
    .tabel-daftar.kolom-banyak { min-width: 1400px; }
    .tabel-daftar.kolom-banyak th,
    .tabel-daftar.kolom-banyak td { white-space: nowrap !important; }
    .tabel-daftar tr.baris-total td.sel-total {
        display: table-cell;
        text-align: center;
        font-size: inherit;
        letter-spacing: normal;
        color: inherit;
    }
    /* Dibatalkan di sini: tanpa garis pada sel terakhir, kolom Aksi tampak
       terputus dari barisnya saat tabel kembali berbentuk tabel. */
    .tabel-daftar tbody tr td:last-child { border-bottom: 1px solid var(--garis); }
    .tabel-daftar td.sel-aksi { white-space: nowrap !important; }
    .tabel-daftar td.sel-aksi .btn {
        --bs-btn-padding-y: 0.25rem;
        --bs-btn-padding-x: 0.75rem;
        --bs-btn-font-size: var(--fs-sm);
        flex: none;
        min-height: 34px;
    }
    .tabel-daftar td::before { content: none; }
    .tabel-daftar tr.lewat-limit { background: var(--bad-50); }

    /* Ganti box-shadow ber-<tr> (tidak dilukis penuh oleh browser di
       display:table-row - lihat catatan di .tabel-daftar tr.terpilih) dengan
       box-shadow per-<td>: tiap sel melukis sisi atas+bawahnya sendiri, dan
       sel pertama/terakhir menambahkan sisi kiri/kanan - hasilnya satu
       garis utuh mengelilingi baris, terlukis dengan benar di semua browser
       karena <td> adalah display:table-cell, kotak mandiri yang sah. */
    .tabel-daftar tr.terpilih { box-shadow: none; }
    .tabel-daftar tr.terpilih > td {
        box-shadow: inset 0 1px 0 0 var(--accent), inset 0 -1px 0 0 var(--accent);
    }
    .tabel-daftar tr.terpilih > td:first-child {
        box-shadow: inset 0 1px 0 0 var(--accent), inset 0 -1px 0 0 var(--accent), inset 1px 0 0 0 var(--accent);
    }
    .tabel-daftar tr.terpilih > td:last-child {
        box-shadow: inset 0 1px 0 0 var(--accent), inset 0 -1px 0 0 var(--accent), inset -1px 0 0 0 var(--accent);
    }
}

/* --------------------------------------------------------------------------
   Jaring pengaman: kalau tabel masih terlalu lebar, yang menggeser adalah
   wadahnya, bukan seluruh halaman.
   -------------------------------------------------------------------------- */
.tabel-bungkus { overflow-x: auto; -webkit-overflow-scrolling: touch; }

/* --------------------------------------------------------------------------
   Panel filter. Di HP dilipat supaya enam field tidak mendorong daftar jauh
   ke bawah; mulai 992px selalu terbuka dan tombol pelipatnya disembunyikan
   Bootstrap lewat .d-lg-none.
   -------------------------------------------------------------------------- */
@media (min-width: 992px) {
    #panelFilter {
        display: block !important;
        height: auto !important;
        visibility: visible !important;
    }
}

/* --------------------------------------------------------------------------
   Tombol aksi di dalam baris daftar

   Edit/Hapus muncul di setiap baris. Dengan gaya solid bawaannya, satu
   halaman berisi 20 blok oranye dan merah pekat yang menarik perhatian
   lebih dulu daripada datanya sendiri. Di sini keduanya diturunkan jadi
   tombol tenang bergaris, dan baru terisi penuh saat disentuh - warnanya
   tetap membedakan, bobotnya saja yang dikurangi.

   Dilakukan lewat selektor berkonteks, jadi class di markup (.btn-warning,
   .btn-danger) tidak perlu diubah di satu pun halaman.
   -------------------------------------------------------------------------- */
.tabel-daftar td.sel-aksi .btn,
.tabel-daftar td .btn-group .btn {
    box-shadow: none;
    font-weight: 550;
}

/* Edit dibuat biru, bukan oranye - supaya jelas beda dari Hapus tanpa harus
   ikut terkesan seperti tombol peringatan. */
.tabel-daftar td.sel-aksi .btn-warning {
    --bs-btn-bg: transparent;          --bs-btn-border-color: var(--border-2);
    --bs-btn-color: var(--info);
    --bs-btn-hover-bg: var(--info);    --bs-btn-hover-border-color: var(--info);
    --bs-btn-hover-color: #fff;
    --bs-btn-active-bg: var(--info);   --bs-btn-active-border-color: var(--info);
}
.tabel-daftar td.sel-aksi .btn-danger {
    --bs-btn-bg: transparent;          --bs-btn-border-color: var(--border-2);
    --bs-btn-color: var(--bad);
    --bs-btn-hover-bg: var(--bad);     --bs-btn-hover-border-color: var(--bad);
    --bs-btn-hover-color: #fff;
    --bs-btn-active-bg: var(--bad-600); --bs-btn-active-border-color: var(--bad-600);
}
.tabel-daftar td.sel-aksi .btn-primary,
.tabel-daftar td.sel-aksi .btn-info {
    --bs-btn-bg: transparent;          --bs-btn-border-color: var(--border-2);
    --bs-btn-color: var(--accent);
    --bs-btn-hover-bg: var(--accent);  --bs-btn-hover-border-color: var(--accent);
    --bs-btn-hover-color: #fff;
}
.tabel-daftar td.sel-aksi .btn-success {
    --bs-btn-bg: transparent;          --bs-btn-border-color: var(--border-2);
    --bs-btn-color: var(--ok-600);
    --bs-btn-hover-bg: var(--ok);      --bs-btn-hover-border-color: var(--ok);
    --bs-btn-hover-color: #fff;
}
body.dark .tabel-daftar td.sel-aksi .btn-warning { --bs-btn-color: var(--info); }
body.dark .tabel-daftar td.sel-aksi .btn-success { --bs-btn-color: var(--ok); }

/* Baris daftar jadi lebih mudah dilacak matanya saat disorot */
@media (min-width: 992px) {
    .tabel-daftar tbody tr { transition: background-color .12s ease; }
    .tabel-daftar tbody tr:hover { background: var(--surface-2); }
}

/* --------------------------------------------------------------------------
   10. Kerangka halaman dan daftar data modern

   Kelas ini dipakai bertahap oleh halaman master. Struktur lama tetap aman,
   sementara halaman yang sudah dimigrasikan mendapat hierarki yang lebih
   kuat daripada deretan utility Bootstrap.
   -------------------------------------------------------------------------- */
.page-shell {
    width: min(100%, 1480px);
    margin: 0 auto;
}

.page-heading {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 0.75rem;
    margin-bottom: 1rem;
}
/* Alur block biasa, BUKAN flex-wrap+flex-basis:100% (rapuh: div ini flex
   item shrink-to-fit dalam .page-heading (row, lihat breakpoint 768px di
   bawah), jadi flex-basis:100% pada .page-description diresolusi terhadap
   induk yang lebarnya kadang tidak pasti - kadang description ikut nempel
   satu baris dengan judul, tergantung persis panjang teks kombinasinya),
   dan BUKAN CSS Grid juga (dicoba, sama rapuhnya: description yang di-span
   penuh ikut menyumbang ke perhitungan lebar max-content kolom eyebrow/
   judul, jadi keduanya malah kedorong lebar/berantakan). Baru ketahuan
   2026-09-16 di halaman Ajukan Pengajuan.
   Elemen block (.page-description, <p> bawaan) SELALU mulai baris baru
   sendiri di alur normal - tidak butuh trik pengukuran lebar sama sekali.
   Eyebrow dan judul dibuat inline-block supaya sebaris satu sama lain. */
.page-eyebrow {
    display: inline-block;
    margin: 0 0.65rem 0 0;
    color: var(--accent);
    font-size: 0.6875rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    vertical-align: baseline;
}
.page-heading h1 {
    display: inline-block;
    margin: 0;
    font-size: clamp(1.5rem, 1.7vw, 1.75rem);
    font-weight: 700;
    letter-spacing: -0.035em;
    vertical-align: baseline;
}
.page-description {
    display: block;
    max-width: 42rem;
    margin: 0.15rem 0 0;
    color: var(--text-muted);
    font-size: var(--fs-sm);
    line-height: 1.45;
}
.page-primary-action {
    min-height: 34px;
    padding-inline: 0.85rem;
    align-self: flex-start;
    box-shadow: 0 7px 16px rgba(79, 70, 229, .18);
}

/* Ringkasan pendanaan di Pengajuan: satu kartu, tiga kolom (saldo / jumlah
   transaksi / CTA) dipisah garis - bukan tiga elemen lepas, supaya tidak
   ada ruang kosong terbuang (revamp 2026-09-20 mengikuti mockup). */
.pengajuan-summary {
    display: flex;
    flex-wrap: wrap;
    align-items: stretch;
    border: 1px solid color-mix(in srgb, var(--accent) 22%, var(--surface));
    border-radius: var(--r-lg);
    background: var(--accent-soft);
    overflow: hidden;
    margin-bottom: 1.25rem;
}
.pengajuan-summary-item {
    display: flex;
    align-items: center;
    gap: 0.9rem;
    flex: 1 1 260px;
    min-width: 0;
    padding: 1.1rem 1.5rem;
    border-top: 1px solid color-mix(in srgb, var(--accent) 18%, transparent);
}
.pengajuan-summary-item:first-child { border-top: 0; }
.pengajuan-summary-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    flex-shrink: 0;
    border-radius: var(--r);
    background: var(--surface);
    color: var(--accent);
    font-size: 1.2rem;
}
.pengajuan-summary-text { min-width: 0; }
.pengajuan-summary-text strong {
    display: block;
    font-size: 1.05rem;
    font-weight: 700;
    color: var(--text);
}
.pengajuan-summary-text p {
    margin: 0.15rem 0 0;
    color: var(--text-2);
    font-size: var(--fs-xs);
    line-height: 1.45;
}
.pengajuan-balance-label {
    color: var(--accent-hover);
    font-size: var(--fs-sm);
    font-weight: 600;
}
.pengajuan-balance-value {
    display: block;
    margin: 0.15rem 0 0.2rem;
    overflow-x: auto;
    color: var(--text);
    font-size: clamp(1.5rem, 3.5vw, 1.85rem);
    font-weight: 750;
    line-height: 1.2;
    letter-spacing: -0.035em;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}
.pengajuan-summary-cta {
    flex-direction: column;
    align-items: stretch;
    justify-content: center;
    gap: 0.55rem;
}
.pengajuan-summary-cta .btn {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
}
@media (min-width: 992px) {
    .pengajuan-summary-item {
        border-top: 0;
        border-left: 1px solid color-mix(in srgb, var(--accent) 18%, transparent);
    }
    .pengajuan-summary-item:first-child { border-left: 0; }
}

/* Kotak tips ringan - kalimat bantuan singkat di bawah konten, bukan
   peringatan (warnanya lembut, tidak bisa ditutup). */
.info-tip {
    display: flex;
    align-items: flex-start;
    gap: 0.75rem;
    margin-top: 1.25rem;
    padding: 0.9rem 1.1rem;
    border: 1px solid color-mix(in srgb, var(--accent) 20%, var(--surface));
    border-radius: var(--r);
    background: var(--accent-soft);
    color: var(--text-2);
}
.info-tip i {
    margin-top: 0.15rem;
    color: var(--accent);
    font-size: 1.05rem;
}
.info-tip p { margin: 0; font-size: var(--fs-sm); line-height: 1.5; }
.info-tip strong { color: var(--text); }

.page-shell > .alert {
    display: flex;
    align-items: center;
    gap: 0.65rem;
    margin-bottom: 1.25rem;
    border-color: color-mix(in srgb, var(--ok) 22%, transparent);
}
.page-shell > .alert .btn-close { margin-left: auto; }

.data-card {
    overflow: hidden;
    border-color: color-mix(in srgb, var(--border) 82%, transparent);
    border-radius: 18px;
    box-shadow: 0 1px 2px rgba(16, 24, 40, .03), 0 10px 32px rgba(16, 24, 40, .055);
}
.data-card-heading {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.85rem 1.35rem;
}
.data-card-heading > div {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.2rem 0.55rem;
}
.data-card-heading h2 {
    margin: 0;
    font-size: var(--fs-md);
    font-weight: 650;
    letter-spacing: -0.015em;
}
.data-card-heading p {
    margin: 0;
    color: var(--text-muted);
    font-size: var(--fs-sm);
}
.record-count {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    min-height: 34px;
    padding: 0.25rem 0.65rem;
    border: 1px solid var(--border);
    border-radius: var(--r-pill);
    background: var(--surface-2);
    color: var(--text-2);
    font-size: var(--fs-sm);
    font-weight: 600;
}

.data-card .dt-toolbar {
    margin: 0;
    padding: 0.65rem 1.35rem;
    background: var(--surface-2);
    border-top: 1px solid var(--border);
    border-bottom: 1px solid var(--border);
}
.data-card .dt-kaki {
    margin: 0;
    padding: 1rem 1.35rem;
    border-top: 1px solid var(--border);
}
.data-card .dataTables_wrapper div.dt-buttons .btn,
.data-card .dataTables_wrapper div.dt-buttons .btn.btn-secondary {
    min-height: 34px;
    padding-inline: 0.8rem;
    background: var(--surface);
}
.data-card .dataTables_wrapper div.dataTables_filter input.form-control {
    min-height: 34px;
    background-color: var(--surface);
}
.data-card .dataTables_wrapper div.dataTables_length select.form-select {
    min-height: 34px;
    background-color: var(--surface);
}

.page-users .tabel-daftar { table-layout: auto; }
.page-users .tabel-daftar thead th {
    padding: 0.85rem 1rem;
    border-bottom-width: 1px;
    background: var(--surface);
    font-size: 0.69rem;
    letter-spacing: 0.075em;
}
.page-users .tabel-daftar tbody td { padding: 0.55rem 0.85rem; }
.page-users .tabel-daftar tbody tr:last-child td { border-bottom: 0; }
.page-users .tabel-daftar tbody tr:hover { background: color-mix(in srgb, var(--accent-soft) 38%, var(--surface)); }

.user-cell { display: flex; align-items: center; gap: 0.75rem; min-width: 13rem; }
.user-avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 38px;
    height: 38px;
    border: 1px solid color-mix(in srgb, var(--accent) 15%, var(--border));
    border-radius: 11px;
    background: linear-gradient(145deg, var(--accent-soft), var(--surface));
    color: var(--accent-hover);
    font-size: var(--fs-xs);
    font-weight: 750;
    letter-spacing: .03em;
}
body.dark .user-avatar { color: var(--accent); }
.user-identity { display: block; min-width: 0; line-height: 1.35; }
.user-identity strong {
    display: block;
    overflow: hidden;
    color: var(--text);
    font-size: var(--fs-base);
    font-weight: 600;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.user-identity small {
    display: block;
    overflow: hidden;
    max-width: 22rem;
    color: var(--text-muted);
    font-size: var(--fs-sm);
    text-overflow: ellipsis;
    white-space: nowrap;
}
.username-value { color: var(--text-2); font-size: var(--fs-sm); font-weight: 500; }
.role-badge {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.3rem 0.6rem;
    border: 1px solid var(--border);
    border-radius: var(--r-pill);
    background: var(--surface-2);
    color: var(--text-2);
    font-size: var(--fs-xs);
    font-weight: 600;
}
.role-badge.is-admin { border-color: color-mix(in srgb, var(--accent) 18%, var(--border)); background: var(--accent-soft); color: var(--accent-hover); }
body.dark .role-badge.is-admin { color: var(--accent); }
.role-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--text-muted); box-shadow: 0 0 0 3px color-mix(in srgb, var(--text-muted) 12%, transparent); }
.role-badge.is-admin .role-dot { background: var(--accent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 13%, transparent); }
.date-value, .time-value { display: block; white-space: nowrap; }
.date-value { color: var(--text-2); font-size: var(--fs-sm); font-weight: 500; }
.time-value { margin-top: 0.1rem; color: var(--text-muted); font-size: var(--fs-xs); }

.page-users .row-actions { width: 4rem; text-align: right !important; }
.page-users .data-table-card,
.page-users .tabel-bungkus { overflow: visible; }
.row-menu-button {
    width: 34px;
    min-height: 34px;
    padding: 0;
    border-color: transparent;
    background: transparent;
    color: var(--text-muted);
    box-shadow: none;
}
.row-menu-button:hover,
.row-menu-button.show {
    border-color: var(--border);
    background: var(--surface-3);
    color: var(--text);
}
.row-menu-button i { font-size: 1.1rem; }
.row-actions .dropdown-menu { min-width: 11.5rem; }
.row-actions .dropdown-item { display: flex; align-items: center; gap: 0.6rem; font-size: var(--fs-sm); }
.row-actions .dropdown-item i { width: 1rem; text-align: center; }
.row-actions .dropdown-item.text-danger { color: var(--bad) !important; }
.row-actions .dropdown-item.text-danger:hover { background: var(--bad-50); }

@media (max-width: 991.98px) {
    .page-users .tabel-daftar tr { margin: 0.85rem; padding: 0.2rem 0.85rem; }
    .page-users .tabel-daftar td { padding: 0.65rem 0; }
    .page-users .tabel-daftar td[data-label="Pengguna"] { align-items: flex-start; }
    .page-users .tabel-daftar td[data-label="Pengguna"]::before { padding-top: 0.55rem; }
    .page-users .tabel-daftar td.row-actions { width: 100%; text-align: right !important; }
    .page-users .tabel-daftar td.row-actions .dropdown { margin-left: auto; }
    .data-card .dt-toolbar, .data-card .dt-kaki { padding-inline: 1rem; }
}

@media (min-width: 768px) {
    .page-heading { flex-direction: row; align-items: flex-end; justify-content: space-between; }
    .page-primary-action { align-self: auto; }
}

@media (min-width: 992px) {
    .page-users .tabel-daftar th:first-child,
    .page-users .tabel-daftar td:first-child { padding-left: 1.35rem; width: 38%; }
    .page-users .tabel-daftar th:last-child,
    .page-users .tabel-daftar td:last-child { padding-right: 1.35rem; }
    .data-card .dt-toolbar-kanan { width: auto; flex: 1 1 auto; justify-content: flex-end; }
    .data-card .dataTables_length { flex: 0 0 auto; }
    .data-card .dataTables_filter { flex: 0 1 22rem !important; }
}

/* --------------------------------------------------------------------------
   11. Sistem halaman admin
   -------------------------------------------------------------------------- */
.app-page {
    width: min(100%, 1480px);
    margin: 0 auto;
}
.app-page > .page-shell { width: 100%; }
.page-actions { display: flex; flex-wrap: wrap; flex-shrink: 0; align-items: center; gap: 0.6rem; }
.page-actions .btn { min-height: 34px; }
.page-actions .btn.btn-sm { min-height: 34px; }
.page-actions .btn:not(.btn-primary) { box-shadow: none; }

.section-heading {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem;
}
.section-heading h2 { margin: 0; font-size: var(--fs-md); font-weight: 650; }
.section-heading p { margin: 0.25rem 0 0; color: var(--text-muted); font-size: var(--fs-sm); }

.data-table-card {
    overflow: hidden;
    border-color: color-mix(in srgb, var(--border) 82%, transparent);
    border-radius: 18px;
    box-shadow: 0 1px 2px rgba(16, 24, 40, .03), 0 10px 32px rgba(16, 24, 40, .05);
}
.data-table-card > .data-card-heading { padding: 0.85rem 1.35rem; }
.data-table-card .dt-toolbar {
    margin: 0;
    padding: 0.65rem 1.35rem;
    background: var(--surface-2);
    border-top: 1px solid var(--border);
    border-bottom: 1px solid var(--border);
}
.data-table-card .dt-kaki { margin: 0; padding: 1rem 1.35rem; }
.data-table-card .tabel-daftar thead th {
    padding: 0.6rem 0.65rem;
    border-bottom-width: 1px;
    background: var(--surface);
    font-size: 0.69rem;
    letter-spacing: 0.07em;
}
.data-table-card .tabel-daftar tbody td { padding: 0.55rem 0.65rem; }
.data-table-card .tabel-daftar tbody tr:last-child td { border-bottom: 0; }
.data-table-card .tabel-daftar tbody tr:hover { background: color-mix(in srgb, var(--accent-soft) 32%, var(--surface)); }

.utility-panel,
.filter-panel {
    margin-bottom: 1.25rem;
    padding: 0.75rem;
    border: 1px solid var(--border);
    border-radius: var(--r);
    background: var(--surface);
    box-shadow: var(--sh-sm);
}
.utility-panel { border-style: dashed; }
.utility-panel form { display: flex; flex-wrap: wrap; align-items: end; gap: 0.75rem; }
.utility-panel label { display: block; color: var(--text-2); font-size: var(--fs-sm); font-weight: 600; }
.utility-panel input[type="file"] {
    max-width: 100%;
    padding: 0.45rem;
    border: 1px solid var(--border);
    border-radius: var(--r-sm);
    background: var(--surface-2);
    color: var(--text-2);
}
.utility-panel small { display: block; margin-top: 0.7rem; }
.filter-panel { padding-bottom: 0.75rem; }
.filter-panel > .row,
.filter-panel.row { margin-bottom: 0 !important; }
.filter-panel .form-select,
.filter-panel .form-control {
    min-height: 34px;
    padding-top: 0.25rem;
    padding-bottom: 0.25rem;
    font-size: 1rem;
}
.filter-panel .btn { min-height: 34px; }

/* Filter dan aksinya adalah satu proses. Pada ruang desktop yang cukup, buat
   ia satu baris agar tombol Filter tidak terpisah sendiri di bawahnya; pada
   tablet/ponsel grid Bootstrap tetap melipat secara natural.

   Lebar kolom TIDAK dihitung dari jumlah filter (dulu "repeat(6, ...)",
   di-hardcode pas buat 6 filter Data Bantuan) - halaman lain dengan filter
   lebih banyak memaksakan diri ke 6 kolom tetap itu dan tiap kolom jadi
   terlalu sempit, caret dropdown bawaan browser sampai tumpang tindih
   dengan teksnya (2026-09-16). auto-fit + minmax menyesuaikan sendiri ke
   jumlah filter berapa pun - kolom tidak pernah lebih sempit dari 150px,
   sisanya melipat ke baris berikutnya. */
@media (min-width: 1200px) {
    #panelFilter .filter-form {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
        align-items: end;
        gap: 0.5rem;
        margin: 0 !important;
    }
    #panelFilter .filter-form > [class*="col-"] {
        width: auto;
        max-width: none;
        margin: 0;
        padding: 0;
    }
    #panelFilter .filter-form .filter-submit .btn { white-space: nowrap; }
}

.inline-summary {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.45rem;
    margin: -0.75rem 0 1.2rem;
    color: var(--text-muted);
    font-size: var(--fs-sm);
}
.inline-summary strong { color: var(--text); font-weight: 650; }
.summary-dot { width: 4px; height: 4px; border-radius: 50%; background: var(--border-2); }

.metric-grid { margin-bottom: 1.5rem; }
.metric-card {
    position: relative;
    height: 100%;
    min-height: 132px;
    padding: 1.15rem 1.2rem;
    overflow: hidden;
    border: 1px solid var(--border);
    border-radius: 16px;
    background: var(--surface);
    box-shadow: 0 8px 24px rgba(16, 24, 40, .045);
}
.metric-card::after {
    content: "";
    position: absolute;
    right: -28px;
    bottom: -42px;
    width: 110px;
    height: 110px;
    border-radius: 50%;
    background: color-mix(in srgb, var(--metric-color, var(--accent)) 8%, transparent);
}
.metric-top { display: flex; align-items: center; justify-content: space-between; gap: 0.75rem; }
.metric-label { color: var(--text-muted); font-size: var(--fs-sm); font-weight: 550; }
.metric-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 38px;
    height: 38px;
    border-radius: 11px;
    background: color-mix(in srgb, var(--metric-color, var(--accent)) 11%, var(--surface));
    color: var(--metric-color, var(--accent));
}
.metric-value { margin-top: 0.65rem; color: var(--text); font-size: 1.65rem; font-weight: 720; letter-spacing: -0.035em; font-variant-numeric: tabular-nums; }
.metric-note { margin-top: 0.1rem; color: var(--text-muted); font-size: var(--fs-xs); }

.dashboard-grid { display: grid; grid-template-columns: 1fr; gap: 1rem; margin-bottom: 1.5rem; }
.dashboard-card {
    padding: 1.25rem;
    border: 1px solid var(--border);
    border-radius: 18px;
    background: var(--surface);
    box-shadow: 0 8px 28px rgba(16, 24, 40, .045);
}
.dashboard-card .section-heading { margin-bottom: 1rem; }
.chart-shell { position: relative; min-height: 300px; }
.chart-shell canvas { width: 100% !important; height: 300px !important; }
.dashboard-table { padding-bottom: 0.35rem; }
.dashboard-table .table { margin: 0; }
.dashboard-table .table > :not(caption) > * > * { padding: 0.72rem 0.55rem; }

.report-section { margin-bottom: 1.25rem; }
.report-section .card-header {
    padding: 1rem 1.25rem;
    font-size: var(--fs-base);
    font-weight: 650;
}
.report-section .card-header .text-muted { display: block; margin-top: 0.15rem; font-size: var(--fs-xs); font-weight: 400; }

/* Halaman formulir lama ikut mendapat komposisi yang rapi tanpa mengubah
   alur atau nama field-nya. */
.app-page > .d-flex:first-child,
.app-page > .d-md-flex:first-child,
.app-page > .mb-3:first-child {
    margin-bottom: 1.5rem !important;
}
.app-page > .d-flex:first-child h3,
.app-page > .d-md-flex:first-child h3,
.app-page > .mb-3:first-child h3 {
    font-size: 1.65rem;
    font-weight: 700;
    letter-spacing: -0.03em;
}
.app-page > .card.shadow-sm {
    max-width: 920px;
    padding: 0.35rem;
    border-radius: 18px;
    box-shadow: 0 8px 28px rgba(16, 24, 40, .05) !important;
}
.app-page > .card.shadow-sm .card-body { padding: clamp(1.1rem, 2.5vw, 1.6rem); }

.form-card {
    max-width: 860px;
    padding: 0.35rem;
    border-radius: 18px;
    box-shadow: 0 8px 28px rgba(16, 24, 40, .05);
}
.form-card-compact { max-width: 680px; }
.form-card-wide { max-width: 1040px; }
.batch-entry-card { max-width: none; }
.form-card > .card-header { padding: 1rem 1.3rem; }
.form-card .card-body { padding: clamp(1.1rem, 2.5vw, 1.65rem); }
.form-card form > .mb-3 { margin-bottom: 1.15rem !important; }
.form-card label:not(.form-check-label) {
    display: inline-block;
    margin-bottom: 0.35rem;
    color: var(--text-2);
    font-size: var(--fs-sm);
    font-weight: 600;
}
.form-card form > .btn { margin-top: 0.25rem; }
.form-card form > .btn + .btn { margin-left: 0.35rem; }

.rank-number {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border-radius: 8px;
    background: var(--surface-3);
    color: var(--text-2);
    font-size: var(--fs-xs);
    font-weight: 700;
}

@media (max-width: 991.98px) {
    /* Ruang sisi yang lebih rapat menjaga konten tetap layak pakai di layar
       320px, tanpa mengorbankan target sentuh tombol. */
    #main { padding-inline: 1rem; }

    .data-table-card { overflow: visible; }
    .data-table-card .dt-toolbar,
    .data-table-card .dt-kaki { padding-inline: 1rem; }
    .data-table-card .tabel-daftar tr { margin: 0.85rem; }

    /* Judul kartu kadang memiliki badge/jumlah data di kanan. Biarkan ia
       turun baris, bukan mempersempit judul atau mendorong kartu keluar. */
    .data-card-heading,
    .section-heading { align-items: flex-start; flex-wrap: wrap; }
    .data-card-heading > div,
    .section-heading > div { min-width: 0; }

    /* Nilai panjang, terutama nama dan nominal pada data lama, harus dapat
       menyusut di sebelah label. Default min-width:flex adalah sumber umum
       horizontal scroll yang sulit terlihat di desktop. */
    .tabel-daftar td { min-width: 0; align-items: flex-start; }
    .tabel-daftar td::before { max-width: 44%; white-space: normal; }
    .tabel-daftar td > :not(.btn):not(.dropdown) { min-width: 0; }
    .tabel-daftar td:not(.sel-aksi) > .input-group,
    .tabel-daftar td > .baris-nominal-persen {
        flex: 1 1 0;
        min-width: 0;
    }
    .tabel-daftar td .input-group .form-control { min-width: 0; }

    /* Konfigurasi cicilan memakai min-width untuk tabel desktop. Pada mode
       kartu aturan itu justru memaksa layar bergeser. */
    .sel-cicilan { min-width: 0 !important; }

    .page-shell > .alert { align-items: flex-start; overflow-wrap: anywhere; }
    .utility-panel input[type="file"] { width: 100%; }
}

@media (min-width: 992px) {
    .data-table-card .dt-toolbar-kanan { width: auto; flex: 1 1 auto; justify-content: flex-end; }
    .data-table-card .dataTables_filter { flex: 0 1 22rem !important; }
    .dashboard-grid { grid-template-columns: minmax(0, 1.35fr) minmax(320px, .65fr); }

    /* Tabel administrasi adalah area kerja padat. Sel dibuat ringkas agar
       lebih banyak data terbaca dalam satu layar, sementara aksi per baris
       sengaja lebih kecil dari tombol halaman agar tidak mendominasi data. */
    .table > :not(caption) > * > * {
        padding: 0.35rem 0.55rem;
        line-height: 1.35;
    }
    .data-table-card .tabel-daftar thead th { padding: 0.4rem 0.55rem; }
    .data-table-card .tabel-daftar tbody td { padding: 0.3rem 0.55rem; }
    .tabel-daftar td.sel-aksi .btn,
    table.dataTable td .btn:not(.row-menu-button) {
        --bs-btn-padding-y: 0.15rem;
        --bs-btn-padding-x: 0.5rem;
        --bs-btn-font-size: var(--fs-xs);
        min-height: 30px;
        font-weight: 500;
    }
    .row-menu-button {
        width: 30px;
        min-height: 30px;
    }
}

/* --------------------------------------------------------------------------
   SARAN NOMINAL RUPIAH (dropdown kustom di bawah input, mis. Jumlah Bantuan)
   Sama pola dengan .saran-barang di pengajuan_rokok.php - browser native
   <datalist> tidak bisa distyle dan tampilannya tidak konsisten antar
   browser, jadi dipakai list-group Bootstrap biasa di bawah field, hanya
   selebar kolom field-nya (parent perlu position:relative).
   -------------------------------------------------------------------------- */
.saran-rupiah {
    position: absolute;
    left: 0;
    right: 0;
    z-index: 20;
    margin-top: -1px;
    max-height: 12rem;
    overflow-y: auto;
    border: 1px solid var(--bs-border-color);
    border-top: 0;
    border-radius: 0 0 var(--r-sm) var(--r-sm);
    box-shadow: 0 6px 14px rgba(0, 0, 0, .12);
}
