/* Penyesuaian di atas tema Porto Admin, khusus utk aplikasi Serah Terima ID Card */

/* ============================================================
   HEADER
   Porto memberi .header tinggi 60px, .header .logo float kiri, dan
   .header-right float kanan setinggi 56px. Aturan di bawah menyesuaikan
   brand teks & avatar huruf (pengganti <img> logo/foto profil Porto)
   supaya pas di dalam geometri itu.
   ============================================================ */
.header .logo{display:flex;align-items:center;height:40px;}
.porto-brand{
  display:inline-flex;align-items:center;gap:9px;
  font-weight:700;font-size:15px;line-height:1;color:#fff;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  max-width:min(46vw,320px);
}
.porto-brand i{color:#5c6bc0;font-size:19px;flex-shrink:0;}

/* Pengganti <img> foto profil: lingkaran berisi inisial nama petugas.
   Ukurannya disamakan dengan .userbox .profile-picture img (35px). */
.userbox .profile-picture .avatar-circle{
  width:35px;height:35px;border-radius:50%;
  background:#5c6bc0;color:#fff;
  display:inline-flex;align-items:center;justify-content:center;
  font-weight:700;font-size:15px;line-height:1;
}
.userbox .profile-info{max-width:170px;}
.userbox .name,
.userbox .role{
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  line-height:1.25;
}
.userbox .name{font-size:13px;font-weight:600;}
.userbox .role{font-size:11px;}
html.dark .userbox .role{color:var(--adm-muted);}

/* Di layar sempit Porto menyembunyikan .separator; teks profil ikut
   disembunyikan agar avatar saja yang tersisa dan header tidak berdesakan. */
@media (max-width:767px){
  .userbox .profile-info{display:none;}
  .porto-brand{font-size:13px;max-width:52vw;}
  .porto-brand i{font-size:17px;}
}

/* Badge status antrian - dipetakan ke warna Bootstrap yang relevan */
.status-badge{display:inline-block;padding:.35em .7em;border-radius:.35rem;font-size:12px;font-weight:700;color:#fff;white-space:nowrap;}
.status-waiting{background:#6c757d;}
.status-kurasi_gagal{background:#dc3545;}
.status-kurasi_berhasil{background:#8e5bd0;}
.status-in_progress{background:#3b8ef3;}
.status-selesai_cetak{background:#28a745;}
.status-sudah_diambil{background:#17706a;}
.status-dibatalkan{background:#8a8fa3;}
/* Dipakai lewat status_badge_class() di scanner & lookup pengambilan */
.badge-kurasi{background:#8e5bd0;}

.table-actions .btn{margin:2px;}

.modal .modal-body label{font-weight:600;font-size:13px;}


/* ============================================================
   DARK LAYOUT
   Porto sudah punya aturan html.dark untuk komponen (card, tabel,
   form, alert, header). Yang TIDAK dicakup adalah chrome layout-nya:
   sidebar, content-body, inner-wrapper, dan nav-main. Bagian itulah
   yang dilengkapi di bawah ini.
   ============================================================ */
html.dark{
  --adm-bg:#1b1e28;         /* latar halaman */
  --adm-panel:#242834;      /* sidebar & panel */
  --adm-line:#333846;       /* garis pemisah */
  --adm-text:#d7dae2;       /* teks utama */
  --adm-muted:#8b93a5;      /* teks sekunder */
  --adm-accent:#5c6bc0;     /* aksen (sama dgn brand) */

  /* Alias nama variabel dari stylesheet sisi pengunjung.
     Markup admin lama masih memakai var(--muted), var(--border), dsb di
     atribut style="". Variabel itu dulu datang dari assets/style.css yang
     sudah tidak dimuat admin, sehingga tanpa alias ini nilainya kosong dan
     teks "muted" tampil sewarna teks biasa / border jadi tak terlihat. */
  --muted:var(--adm-muted);
  --border:var(--adm-line);
  --primary:var(--adm-accent);
  --warning:#e0a44b;
  --success:#28a745;
  --danger:#dc3545;
}

html.dark body,
html.dark .inner-wrapper,
html.dark section.body{background:var(--adm-bg);color:var(--adm-text);}

html.dark .content-body{background:var(--adm-bg);}

/* --- Sidebar --- */
html.dark .sidebar-left,
html.dark .sidebar-left .nano-content,
html.dark .sidebar-left .sidebar-header{background:var(--adm-panel);}
html.dark .sidebar-left .sidebar-header .sidebar-title{color:var(--adm-muted);}
html.dark .sidebar-left .sidebar-header .sidebar-toggle{background:transparent;}
html.dark .sidebar-left .sidebar-header .sidebar-toggle i{color:var(--adm-muted);}

html.dark .nav-main a,
html.dark .nav-main .nav-link{color:var(--adm-text);}
html.dark .nav-main a i,
html.dark .nav-main .nav-link i{color:var(--adm-muted);}
html.dark .nav-main a:hover,
html.dark .nav-main .nav-link:hover{background:rgba(255,255,255,.05);color:#fff;}
html.dark .nav-main li.nav-active > a,
html.dark .nav-main a.active-link{
  background:rgba(92,107,192,.18);
  color:#fff;
  box-shadow:inset 3px 0 0 var(--adm-accent);
}
html.dark .nav-main li.nav-active > a i,
html.dark .nav-main a.active-link i{color:var(--adm-accent);}

/* --- Header & breadcrumb --- */
/* .header punya border-top 3px; Porto menyamakan warnanya dengan latar header
   versi mereka (#1D2127). Karena latar di sini diganti, warna border-top ikut
   disamakan - kalau tidak, tersisa garis 3px yang warnanya beda di paling atas. */
html.dark .header{
  background:var(--adm-panel);
  border-top-color:var(--adm-panel);
  border-bottom:1px solid var(--adm-line);
}
html.dark .header .logo-container,
html.dark .header .header-right{background:var(--adm-panel);}
/* PENTING: di layout "fixed", Porto memasang position:fixed pada .page-header
   (html.fixed .page-header { position:fixed; top:60px; left:300px; right:0 }).
   Jadi latarnya WAJIB solid — kalau transparent, seluruh isi halaman yang
   di-scroll terlihat menembus judul & breadcrumb.
   Padding & box-shadow sengaja TIDAK disentuh: .page-header h2 sudah punya
   padding sendiri (0 22px 0 20px), dan Porto sudah menyediakan box-shadow
   versi gelap. */
html.dark .page-header{
  background:var(--adm-bg);
  border-left-color:var(--adm-bg);
  z-index:1001;
}
/* Garis 4px di bawah judul bawaan Porto berwarna #CCC dan tidak ikut diubah di
   mode gelap, sehingga tampak seperti batang terang yang mengambang. */
html.dark .page-header h2{
  color:var(--adm-text);
  border-bottom-color:var(--adm-accent);
}
html.dark .breadcrumbs li,
html.dark .breadcrumbs li a,
html.dark .breadcrumbs li span{color:var(--adm-muted);}
html.dark .profile-info .name{color:var(--adm-text);}
html.dark .profile-info .role{color:var(--adm-muted);}

/* --- Card & tabel --- */
html.dark .card{background:var(--adm-panel);border-color:var(--adm-line);}
html.dark .card-header{background:rgba(255,255,255,.03);border-bottom-color:var(--adm-line);}
html.dark .card-title{color:var(--adm-text);}
html.dark .table{color:var(--adm-text);}
html.dark .table > :not(caption) > * > *{
  background-color:transparent;color:var(--adm-text);border-bottom-color:var(--adm-line);
}
html.dark .table thead th{color:var(--adm-muted);border-bottom-color:var(--adm-line);}
html.dark .table-hover > tbody > tr:hover > *{background-color:rgba(255,255,255,.04);color:#fff;}

/* --- Form --- */
html.dark .form-control,
html.dark .form-select{
  background:#1f2330;border-color:var(--adm-line);color:var(--adm-text);
}
html.dark .form-control:focus,
html.dark .form-select:focus{
  background:#1f2330;border-color:var(--adm-accent);color:#fff;
  box-shadow:0 0 0 .2rem rgba(92,107,192,.2);
}
html.dark .form-control::placeholder{color:#69708090;}
html.dark .input-group-text{background:#1f2330;border-color:var(--adm-line);color:var(--adm-muted);}

/* --- Tabs --- */
html.dark .nav-tabs{border-bottom-color:var(--adm-line);}
html.dark .nav-tabs .nav-link{color:var(--adm-muted);border-color:transparent;}
html.dark .nav-tabs .nav-link:hover{border-color:var(--adm-line);color:var(--adm-text);}
html.dark .nav-tabs .nav-link.active{
  background:var(--adm-panel);color:#fff;
  border-color:var(--adm-line) var(--adm-line) var(--adm-panel);
}

/* --- Modal --- */
html.dark .modal-content{background:var(--adm-panel);color:var(--adm-text);}
html.dark .modal-header,
html.dark .modal-footer{border-color:var(--adm-line);}
html.dark .btn-close{filter:invert(1) grayscale(100%) brightness(200%);}

/* --- Teks bantu --- */
html.dark .text-muted{color:var(--adm-muted) !important;}
html.dark hr{border-color:var(--adm-line);}
html.dark code{background:#1f2330;color:#e0a44b;}


/* ============================================================
   DATATABLES — penyesuaian agar menyatu dgn dark layout
   ============================================================ */
.dataTables_wrapper{padding-top:4px;}
.dataTables_wrapper .row:first-child{margin-bottom:10px;}
.dataTables_wrapper .row:last-child{margin-top:10px;}

html.dark .dataTables_wrapper,
html.dark .dataTables_wrapper .dataTables_info,
html.dark .dataTables_wrapper .dataTables_length,
html.dark .dataTables_wrapper .dataTables_filter{color:var(--adm-muted);}
html.dark .dataTables_wrapper .dataTables_length select,
html.dark .dataTables_wrapper .dataTables_filter input{
  background:#1f2330;border:1px solid var(--adm-line);color:var(--adm-text);
  border-radius:4px;padding:4px 8px;
}
html.dark .dataTables_wrapper .page-link{
  background:#1f2330;border-color:var(--adm-line);color:var(--adm-text);
}
html.dark .dataTables_wrapper .page-link:hover{background:#2b3040;color:#fff;}
html.dark .dataTables_wrapper .page-item.active .page-link{
  background:var(--adm-accent);border-color:var(--adm-accent);color:#fff;
}
html.dark .dataTables_wrapper .page-item.disabled .page-link{
  background:#1c202b;border-color:var(--adm-line);color:#5b6172;
}
html.dark table.dataTable thead th.sorting:after,
html.dark table.dataTable thead th.sorting_asc:after,
html.dark table.dataTable thead th.sorting_desc:after{color:var(--adm-muted);}


/* ============================================================
   WIDGET SUMMARY — kartu statistik dengan ikon berwarna
   Memakai struktur bawaan Porto (card-featured-left + widget-summary),
   di sini hanya dirapikan ukurannya & dibuat konsisten di dark layout.
   ============================================================ */
.widget-summary .summary-icon{
  width:56px;height:56px;border-radius:10px;
  display:flex;align-items:center;justify-content:center;
  font-size:22px;color:#fff;margin-right:14px;
}
.widget-summary .summary .title{
  font-size:12px;font-weight:600;text-transform:uppercase;
  letter-spacing:.4px;margin:0 0 2px;color:var(--adm-muted,#8b95a5);
}
.widget-summary .summary .amount{font-size:26px;font-weight:800;line-height:1.1;}
.widget-summary .summary-footer{margin-top:4px;}
.widget-summary .summary-footer a{font-size:11px;font-weight:700;text-decoration:none;}

html.dark .widget-summary .summary .amount{color:#fff;}
html.dark .widget-summary .summary-footer a{color:var(--adm-muted);}
html.dark .widget-summary .summary-footer a:hover{color:var(--adm-accent);}

/* Warna ikon widget — dipakai lewat class .summary-icon.bg-* */
.summary-icon.bg-primary{background:#5c6bc0 !important;}
.summary-icon.bg-secondary{background:#6c757d !important;}
.summary-icon.bg-warning{background:#e67e22 !important;}
.summary-icon.bg-info{background:#3b8ef3 !important;}
.summary-icon.bg-success{background:#28a745 !important;}
.summary-icon.bg-tertiary{background:#17706a !important;}
.summary-icon.bg-quaternary{background:#8a8fa3 !important;}

/* Kartu statistik yg bisa diklik utk memfilter tabel */
a.stat-link{text-decoration:none;display:block;color:inherit;}
a.stat-link:hover .card{border-color:var(--adm-accent,#5c6bc0);}
a.stat-link .card{transition:border-color .15s ease,transform .1s ease;}
a.stat-link:active .card{transform:scale(.99);}


/* ============================================================
   LAPISAN KOMPATIBILITAS
   Halaman admin selain dashboard dulunya memakai ../assets/style.css
   (stylesheet sisi pengunjung). Setelah semuanya dipindah ke layout
   Porto, stylesheet itu tidak lagi dimuat di admin — komponen yang
   masih dipakai markup-nya didefinisikan ulang di sini, langsung
   dalam nuansa dark.
   ============================================================ */

/* Ukuran dasar SVG hasil icon().
   PENTING: tanpa aturan ini SVG tidak punya batas ukuran sama sekali dan akan
   melar memenuhi lebar kolom induknya. Dulu ukurannya datang dari
   assets/style.css (stylesheet sisi pengunjung) yang sudah tidak dimuat admin. */
.icon{width:18px;height:18px;flex-shrink:0;}
.icon-inline{width:14px;height:14px;display:inline-block;vertical-align:-2px;margin-right:2px;flex-shrink:0;}
h1 > .icon-inline,
h2 > .icon-inline{width:18px;height:18px;vertical-align:-3px;margin-right:6px;}

/* Tombol ikon */
.icon-btn{
  display:inline-flex;align-items:center;gap:6px;
  padding:7px 12px;border-radius:6px;border:none;cursor:pointer;
  font-size:12px;font-weight:700;text-decoration:none;line-height:1;
  color:#fff;background:#5c6bc0;
}
.icon-btn .icon{width:15px;height:15px;flex-shrink:0;}
.icon-btn:hover{filter:brightness(1.12);color:#fff;}
.icon-btn.success{background:#28a745;}
.icon-btn.warning{background:#e67e22;}
.icon-btn.danger{background:#dc3545;}
.icon-btn.outline{background:transparent;border:1px solid #5c6bc0;color:#8f9cdb;}
.icon-btn.outline:hover{background:rgba(92,107,192,.14);color:#fff;}
.icon-btn:disabled{opacity:.55;cursor:default;filter:none;}

.action-row{display:flex;gap:8px;flex-wrap:wrap;margin-top:14px;}

/* Tabel key-value pada halaman detail/lookup */
.data-list{width:100%;border-collapse:collapse;font-size:14px;}
.data-list td{
  padding:9px 4px;border-bottom:1px solid var(--adm-line,#333846);
  vertical-align:top;color:var(--adm-text,#d7dae2);
}
.data-list td:first-child{color:var(--adm-muted,#8b93a5);width:42%;}
.data-list tr:last-child td{border-bottom:0;}

/* Tabel daftar bergaya lama (petugas.php) */
table.recap{width:100%;border-collapse:collapse;font-size:13px;color:var(--adm-text,#d7dae2);}
table.recap th,table.recap td{padding:10px 8px;border-bottom:1px solid var(--adm-line,#333846);text-align:left;}
table.recap th{color:var(--adm-muted,#8b93a5);font-weight:700;white-space:nowrap;}
.table-wrap{overflow-x:auto;}

/* Badge non-status */
.badge{display:inline-block;padding:4px 11px;border-radius:999px;font-size:11px;font-weight:700;color:#fff;}
.badge-success{background:#28a745;}
.badge-default{background:#6c757d;}
.badge-warning{background:#e67e22;}
.badge-danger{background:#dc3545;}

/* Alert: markup lama memakai .alert-error, Bootstrap memakai .alert-danger */
.alert-error{
  position:relative;padding:1rem 1rem;margin-bottom:1rem;
  border:1px solid #842029;border-radius:.375rem;
  background:#2c1618;color:#ea868f;
}

small.hint,.hint{color:var(--adm-muted,#8b93a5);font-size:12px;display:block;margin-top:4px;}

/* Pratinjau foto & kotak QR */
.foto-preview{margin-top:8px;border-radius:8px;overflow:hidden;border:1px solid var(--adm-line,#333846);max-width:220px;}
.foto-preview img{display:block;width:100%;height:auto;}
.qr-box{
  text-align:center;padding:12px;background:#fff;
  border:1px solid var(--adm-line,#333846);border-radius:8px;
}
.qr-box img{max-width:220px;width:100%;}

/* Modal bergaya lama (scanner.php) */
.modal-bg{
  position:fixed;inset:0;background:rgba(8,10,16,.7);
  display:flex;align-items:center;justify-content:center;z-index:1050;padding:16px;overflow-y:auto;
}
.modal-bg > .modal{
  position:relative;display:flex;flex-direction:column;
  background:var(--adm-panel,#242834);color:var(--adm-text,#d7dae2);
  border-radius:10px;padding:20px;max-width:420px;width:100%;
  /* height:auto WAJIB: kelas .modal milik Bootstrap menyetel height:100%,
     sehingga panel modal ikut setinggi layar dan menyisakan ruang kosong
     besar di bawah isinya. */
  height:auto;
  max-height:calc(100dvh - 32px);margin:auto;overflow-y:auto;
}

#reader{width:100%;max-width:420px;margin:0 auto;}
.footer-note{color:var(--adm-muted,#8b93a5);font-size:12px;text-align:center;margin-top:18px;}

/* Markup halaman admin lama memakai <div class="card"> tanpa .card-body, jadi
   Bootstrap tidak memberinya padding sama sekali. Kartu Porto yang ditulis
   ulang memakai <section class="card">, sehingga selektor div.card di bawah
   ini hanya mengenai markup lama dan tidak mengganggu kartu Porto. */
div.card{padding:20px;}
div.card > h1:first-child,
div.card > h2:first-child,
div.card > h3:first-child{margin-top:0;}
div.card h1{font-size:20px;}
div.card h2{font-size:17px;}
html.dark div.card h1,
html.dark div.card h2,
html.dark div.card h3{color:var(--adm-text);}

/* Label & input pada markup lama (dulu dari style.css sisi pengunjung) */
html.dark div.card label{
  display:block;font-size:13px;font-weight:600;margin:14px 0 6px;color:var(--adm-text);
}
/* Field pada markup lama (form kurasi, pengambilan, petugas, dsb) */
html.dark div.card input[type=text],
html.dark div.card input[type=tel],
html.dark div.card input[type=number],
html.dark div.card input[type=url],
html.dark div.card input[type=password],
html.dark div.card input[type=file],
html.dark div.card textarea,
html.dark div.card select{
  width:100%;padding:9px 12px;border-radius:6px;
  background:#1f2330;border:1px solid var(--adm-line);color:var(--adm-text);
  font-size:14px;
}
html.dark div.card input:focus,
html.dark div.card textarea:focus,
html.dark div.card select:focus{
  outline:none;border-color:var(--adm-accent);
  box-shadow:0 0 0 .2rem rgba(92,107,192,.2);
}

/* Kontrol DataTables dikembalikan ke ukuran wajarnya.
   Aturan div.card di atas memberi width:100% ke SEMUA input & select di dalam
   kartu — termasuk kotak "Tampilkan N baris" dan kotak Cari milik DataTables,
   yang akibatnya melar selebar kartu dan saling menimpa. Selektor di sini lebih
   spesifik, jadi menang tanpa perlu !important. */
.dataTables_wrapper .dataTables_length,
.dataTables_wrapper .dataTables_filter{display:flex;align-items:center;gap:8px;}
.dataTables_wrapper .dataTables_filter{justify-content:flex-end;}
.dataTables_wrapper .dataTables_length label,
.dataTables_wrapper .dataTables_filter label{
  display:flex;align-items:center;gap:8px;margin:0;font-weight:500;white-space:nowrap;
}
html.dark div.card .dataTables_wrapper select,
html.dark div.card .dataTables_wrapper input[type=search],
html.dark div.card .dataTables_wrapper input{
  width:auto;display:inline-block;padding:5px 10px;font-size:13px;margin:0;
}
html.dark div.card .dataTables_wrapper select{min-width:74px;}
html.dark div.card .dataTables_wrapper input[type=search]{min-width:170px;}

/* Badge status versi lama (dipakai scanner.php & cari_pengambilan.php lewat
   status_badge_class()). Dulu didefinisikan di stylesheet sisi pengunjung. */
.badge-waiting{background:#6c757d;}
.badge-progress{background:#3b8ef3;}
.badge-done{background:#17706a;}
.badge-cancel{background:#8a8fa3;}

/* ============================================================
   HALAMAN LOGIN
   ============================================================ */
body.login-page{background:var(--adm-bg,#1b1e28);min-height:100vh;}
.login-wrap{
  min-height:100vh;display:flex;flex-direction:column;
  align-items:center;justify-content:center;padding:24px 16px;
}
.login-card{width:100%;max-width:390px;margin:0;}
.login-brand{
  display:flex;align-items:center;justify-content:center;gap:9px;
  font-weight:700;font-size:14px;color:var(--adm-muted,#8b93a5);
  margin-bottom:6px;text-align:center;
}
.login-brand i{color:var(--adm-accent,#5c6bc0);font-size:20px;}
.login-title{
  font-size:20px;font-weight:700;text-align:center;
  margin:0 0 20px;color:var(--adm-text,#d7dae2);
}
.login-page .form-label{font-size:13px;font-weight:600;color:var(--adm-muted,#8b93a5);margin-bottom:5px;}
.login-footer{margin-top:18px;font-size:12px;color:var(--adm-muted,#8b93a5);}

/* ============================================================
   HALAMAN KURASI
   ============================================================ */
/* Kondisi awal modul kamera: kamera mati, menunggu ditekan "Aktifkan Kamera" */
.reader-placeholder{
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:10px;
  min-height:190px;margin-top:4px;padding:18px;
  border:1px dashed var(--adm-line,#333846);border-radius:10px;
  color:var(--adm-muted,#8b93a5);font-size:13px;text-align:center;
}
.reader-placeholder > .icon{width:30px;height:30px;opacity:.6;}
.reader-placeholder .icon-btn{margin-top:4px;padding:10px 18px;font-size:13px;}

/* Baris tombol di bawah pratinjau kamera (Ganti / Matikan) */
#reader-actions{gap:8px;flex-wrap:wrap;margin-top:10px;}

/* Kotak pratinjau kamera dari html5-qrcode */
#reader{width:100%;max-width:380px;margin:10px auto 0;border-radius:10px;overflow:hidden;}
#reader video{display:block;width:100%;height:auto;}

/* Tombol keputusan kurasi: hijau & merah berdampingan, sama lebar */
#form-kurasi .action-row .btn{
  display:inline-flex;align-items:center;justify-content:center;gap:8px;
  padding:11px 16px;font-size:14px;font-weight:700;
}

/* Judul kartu pada markup lama agar tidak terlalu besar di layout admin */
div.card h1{font-size:19px;display:flex;align-items:center;gap:8px;}

/* ==== Kepala kartu dengan tombol aksi di kanan (mis. "Tambah Peran") ==== */
.judul-aksi{
  display:flex;align-items:center;justify-content:space-between;
  gap:12px;flex-wrap:wrap;margin-bottom:6px;
}

/* ==== Isi modal .modal-bg ====
   Modal ini bukan <div class="card">, jadi aturan div.card label/input di atas
   tidak mengenainya dan field-nya tampil dengan gaya bawaan Bootstrap yang
   terang di atas panel gelap. Ditegaskan di sini. */
.modal-bg > .modal label{
  display:block;font-size:13px;font-weight:600;margin:14px 0 6px;color:var(--adm-text);
}
.modal-bg > .modal h3{margin:0 0 4px;font-size:17px;color:var(--adm-text);}
.modal-bg > .modal input[type=text],
.modal-bg > .modal input[type=password],
.modal-bg > .modal input[type=number],
.modal-bg > .modal textarea,
.modal-bg > .modal select{
  width:100%;padding:9px 12px;border-radius:6px;
  background:#1f2330;border:1px solid var(--adm-line);color:var(--adm-text);
  font-size:14px;
}
.modal-bg > .modal input:focus,
.modal-bg > .modal textarea:focus,
.modal-bg > .modal select:focus{
  outline:none;border-color:var(--adm-accent);
  box-shadow:0 0 0 .2rem rgba(92,107,192,.2);
}
.modal-bg > .modal input[readonly]{
  background:#171a24;color:var(--adm-muted);cursor:not-allowed;
}
.modal-bg > .modal .hint{
  display:block;font-size:12px;color:var(--adm-muted);margin-top:5px;line-height:1.5;
}

/* ==== Daftar centang modul di modal Kelola Peran ====
   Selektor diberi kelas supaya menang atas "div.card label" yang memaksa
   display:block — tanpa itu kotak centang dan teksnya tampil di baris berbeda. */
.pilihan-modul{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(165px,1fr));
  gap:8px 14px;margin-top:6px;
}
html.dark div.card .pilihan-modul-item,
.modal-bg > .modal .pilihan-modul-item,
.pilihan-modul-item{
  display:flex;align-items:center;gap:8px;margin:0;
  font-size:13px;font-weight:500;color:var(--adm-text);cursor:pointer;
}
.pilihan-modul-item input[type=checkbox]{
  width:auto;margin:0;flex:0 0 auto;accent-color:var(--adm-accent);
}
.pilihan-modul-item input[type=checkbox]:disabled{cursor:not-allowed;}
.pilihan-modul-item input[type=checkbox]:disabled + span{color:var(--adm-muted);}

/* ==== Tombol di dalam modal .modal-bg ====
   html.dark .btn-default memberi latar #282d36 — nyaris sama dengan panel
   modalnya sendiri (#242834), sehingga tombol "Batal" tampak menghilang jadi
   kotak rata tanpa tepi. Garis tepi di bawah mengembalikannya sebagai tombol.

   Catatan: kelas "btn success"/"btn outline"/"btn warning" adalah gaya sisi
   PENGUNJUNG (assets/style.css) dan TIDAK berlaku di sini — di halaman admin
   .btn polos berarti latar transparan + teks warna body, praktis tak terlihat
   di atas panel gelap. Pakai btn-success / btn-warning / btn-default. */
html.dark .modal-bg > .modal .btn-default{
  border-color:var(--adm-line);
}
.modal-bg > .modal .action-row .btn{
  display:inline-flex;align-items:center;justify-content:center;gap:6px;
}

/* ==== Modal Konfirmasi Pengambilan ID Card ====
   Foto bukti diambil lewat kamera langsung (tema sama dengan scanner):
   dua slot foto berdampingan + satu panel kamera bersama. */
.modal-bg > .modal.modal-ambil{max-width:560px;}
.ambil-kepala{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:2px;}
.ambil-kepala h3{margin:0;font-size:17px;display:flex;align-items:center;gap:8px;}
.ambil-kepala h3 i{color:var(--adm-accent);}
.ambil-tutup{background:transparent;border:0;color:var(--adm-muted);font-size:26px;line-height:1;cursor:pointer;padding:0 4px;}
.ambil-tutup:hover{color:var(--adm-text);}

.ambil-slot-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;margin-top:10px;}
@media (max-width:460px){.ambil-slot-grid{grid-template-columns:1fr;}}
.ambil-slot{border:1px solid var(--adm-line);border-radius:10px;padding:10px;background:rgba(255,255,255,.02);transition:border-color .15s ease, box-shadow .15s ease;}
/* slot yang sedang dipotret kamera */
.ambil-slot.aktif{border-color:var(--adm-accent);box-shadow:0 0 0 .2rem rgba(92,107,192,.2);}
.ambil-slot-judul{font-size:13px;font-weight:600;margin-bottom:8px;color:var(--adm-text);}
.ambil-slot.terisi .ambil-slot-judul::after{content:" \2713";color:#28a745;}
.ambil-slot-kotak{position:relative;aspect-ratio:4/3;border:1px dashed var(--adm-line);border-radius:8px;overflow:hidden;display:flex;align-items:center;justify-content:center;background:#1f2330;}
.ambil-slot.terisi .ambil-slot-kotak{border-style:solid;}
.ambil-slot-kotak img{width:100%;height:100%;object-fit:cover;display:block;}
.ambil-slot-kosong{display:flex;flex-direction:column;align-items:center;gap:6px;color:var(--adm-muted);font-size:12px;text-align:center;padding:6px;}
.ambil-slot-kosong i{font-size:26px;opacity:.55;}
/* display:flex/block di atas mengalahkan atribut [hidden] */
.ambil-slot-kotak img[hidden],.ambil-slot-kosong[hidden],.ambil-kamera[hidden]{display:none;}
.ambil-slot-aksi{display:flex;gap:6px;margin-top:8px;}
.ambil-slot-aksi .icon-btn{flex:1;justify-content:center;padding:8px 10px;}

.ambil-kamera{margin-top:14px;border:1px solid var(--adm-accent);border-radius:10px;padding:10px;background:rgba(92,107,192,.06);}
.ambil-kamera-kepala{display:flex;align-items:center;justify-content:space-between;gap:8px;flex-wrap:wrap;margin-bottom:8px;font-size:13px;}
.ambil-kamera-kepala .icon-inline{width:14px;height:14px;vertical-align:-2px;}
.modal-bg > .modal .ambil-kamera-kepala select{width:auto;max-width:230px;padding:5px 8px;font-size:12px;}
.ambil-kamera-bingkai{border-radius:8px;overflow:hidden;background:#000;aspect-ratio:4/3;max-height:50vh;}
.ambil-kamera-bingkai video{width:100%;height:100%;object-fit:cover;display:block;}
.ambil-kamera .action-row{margin-top:10px;}

.ambil-kaki{display:flex;justify-content:flex-end;gap:8px;margin-top:16px;padding-top:14px;border-top:1px solid var(--adm-line);}
.ambil-kaki .btn{display:inline-flex;align-items:center;gap:6px;}

/* ---- Kelola Syarat & Ketentuan: unggah drag & drop + editor WYSIWYG ---- */
/* Porto sudah menata .dropzone & .note-editor termasuk mode gelapnya; di sini
   hanya penyesuaian ukuran dan warna agar menyatu dengan kartu admin. */
.dropzone-terms{
  background:var(--adm-input);border:2px dashed var(--adm-line);border-radius:10px;
  min-height:130px;padding:14px;display:flex;flex-wrap:wrap;align-items:center;justify-content:center;
}
.dropzone-terms:hover{border-color:var(--adm-accent);}
.dropzone-terms .dz-message{margin:0;text-align:center;color:var(--adm-muted);font-size:13px;}
.dropzone-terms .dz-message i{display:block;font-size:26px;margin-bottom:6px;opacity:.7;}
.dropzone-terms.dz-started{display:block;}
.dropzone-terms .dz-preview{margin:8px;}
.dropzone-terms .dz-preview .dz-image{border-radius:8px;}
.dropzone-terms .dz-remove{color:var(--adm-muted);font-size:12px;}

/* Kotak ganti gambar per blok lebih ringkas daripada kotak tambah blok. */
.dropzone-ganti{min-height:86px;padding:10px;margin-top:8px;}
.dropzone-ganti .dz-message{font-size:12px;}
.dropzone-ganti .dz-message i{font-size:18px;margin-bottom:4px;}

.terms-admin-kiri{width:190px;flex-shrink:0;}
.terms-admin-kiri .terms-admin-thumb{width:100%;}
/* Editor menggantikan textarea lama; lebarnya mengikuti kolom isi blok. */
.terms-admin-desc .note-editor{margin-bottom:0;}
.note-editor.note-frame{border-color:var(--adm-line);border-radius:8px;}
html.dark .note-editor .note-editable a{color:#8c9aff;}
html.dark .note-editor .note-placeholder{color:var(--adm-muted);}
@media (max-width:720px){
  .terms-admin-kiri{width:100%;}
}

/* ============================================================
   TABEL DAFTAR YANG RAPI (.tabel-rapi)
   ------------------------------------------------------------
   Dipakai di Kelola Petugas (tabel Peran & tabel Petugas). Tujuannya
   menyeragamkan: tinggi baris, garis pemisah, perataan tengah, dan kolom
   aksi yang tetap satu baris.
   ============================================================ */
.tabel-rapi { margin-bottom: 0; }

.table.tabel-rapi > thead > tr > th {
  padding: 10px 12px;
  font-size: 11.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em;
  white-space: nowrap; vertical-align: middle;
  border-bottom: 1px solid var(--adm-line, #333846);
}

/* Selektor memakai .table.tabel-rapi (dua kelas): aturan tema gelap
   "html.dark .table > :not(caption) > * > *" lebih spesifik daripada satu kelas,
   dan tanpa ini warna garis pemisahnya ikut warna tema yang nyaris tak terlihat. */
.table.tabel-rapi > tbody > tr > td {
  padding: 11px 12px;
  /* Isi sel disejajarkan di tengah supaya badge, tombol, dan teks satu baris
     tidak lagi menggantung di posisi yang berbeda-beda. */
  vertical-align: middle;
  /* !important karena tabel Bootstrap memakai border-collapse: warna garis
     bawaan tema (hampir sewarna latar) tetap menang tanpa penegasan ini. */
  border-bottom: 1px solid rgba(255, 255, 255, .08) !important;
}
.table.tabel-rapi > tbody > tr:last-child > td { border-bottom: 0 !important; }

/* Kolom aksi: rata kanan dan TIDAK boleh turun ke baris baru - sebelumnya
   tombol Hapus jatuh ke bawah tombol Edit sehingga barisnya jadi tinggi. */
/* Kolom Aksi berada di KIRI tabel, jadi isinya dirapatkan ke kiri juga.
   width:1% membuat kolomnya hanya selebar tombol-tombolnya. */
.tabel-rapi .kol-aksi { width: 1%; white-space: nowrap; text-align: left; }
.tabel-rapi .kol-aksi .action-row {
  margin-top: 0; gap: 6px; flex-wrap: nowrap; justify-content: flex-start; align-items: center;
}
.tabel-rapi .kol-aksi .icon-btn { padding: 6px 10px; white-space: nowrap; }

.tabel-rapi .kol-tengah { text-align: center; }
.tabel-rapi .kol-angka { white-space: nowrap; color: var(--adm-muted, #8b93a5); }
.tabel-rapi .teks-lemah { color: var(--adm-muted, #8b93a5); font-size: 12px; white-space: nowrap; }

/* Kumpulan chip (modul per peran, event per petugas): jarak seragam dan
   boleh turun baris tanpa merusak jarak antar barisnya. */
.tabel-rapi .chip-baris { display: flex; flex-wrap: wrap; gap: 5px; align-items: center; }
.tabel-rapi .chip-baris .badge { margin: 0; padding: 3px 9px; font-size: 10.5px; }
.tabel-rapi .chip-baris .icon-btn { padding: 5px 9px; }

.tabel-rapi .form-select { width: 100%; min-width: 0; }
.tabel-rapi code { font-size: 12px; }

/* Di layar sempit tabelnya digulir mendatar (pembungkus .table-responsive),
   jadi kolomnya tidak saling menghimpit. */
.tabel-rapi { min-width: 760px; }

/* ---- Pilihan modul dalam dua grup (modal Tambah/Edit Peran) ---- */
.modul-grup-wadah { display: flex; flex-direction: column; gap: 10px; margin-top: 6px; }
.grup-modul {
  border: 1px solid var(--adm-line, #333846); border-radius: 8px;
  padding: 9px 12px 11px; background: rgba(255, 255, 255, .02);
}
.grup-modul-judul {
  font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .06em;
  color: var(--adm-muted, #8b93a5); margin-bottom: 7px;
}
.grup-modul .pilihan-modul { margin-top: 0; gap: 7px 14px; }

/* Modal peran dirapatkan: jarak label bawaan modal (14px) membuat isinya
   terlihat renggang padahal pilihannya sudah dikelompokkan. */
#modal-peran label { margin: 11px 0 5px; }
#modal-peran .grup-modul label { margin: 0; }
#modal-peran .hint { margin-top: 4px; }
#modal-peran .action-row { margin-top: 14px !important; }

/* ============================================================
   RECAP ANTRIAN — baris filter, widget rekap, tombol ikon
   Disusun mengikuti Data Pendaftar badge-app (.filter-pendaftar di
   app/badge-app/assets/css/style.css): seluruh penyaring adalah combo-box
   pilih-banyak yang berjajar dalam satu baris dan boleh membungkus.
   ============================================================ */
.filter-antrian {
  display: flex; flex-wrap: wrap; gap: 10px 12px; align-items: flex-end;
  padding: 12px 14px; border: 1px solid var(--adm-line, #333846); border-radius: 8px;
  background: rgba(255, 255, 255, .02);
}
/* flex-basis 200px, bukan lebar tetap: lima penyaring pada layar 1280px muat
   satu baris, dan pada layar sempit ikut menyusut sebelum membungkus. */
.filter-antrian .form-group { flex: 0 1 200px; min-width: 0; margin-bottom: 0; }
/* Porto memberi GARIS PEMISAH di atas setiap .form-group yang bersebelahan
   (".form-group + .form-group" di theme.css) - masuk akal untuk formulir yang
   bertumpuk ke bawah, tapi pada baris filter mendatar garisnya muncul melayang
   di atas empat kotak terakhir, dan padding-nya menambah tinggi yang tidak
   perlu. */
.filter-antrian .form-group + .form-group { border-top: 0; padding-top: 0; }
.filter-antrian .filter-cari { flex: 1 1 240px; }
/* Alasan ">" yang sama seperti pada isian di bawah: daftar pilihan combo-box
   digambar di dalam .filter-antrian juga, dan tiap pilihannya sebuah <label>.
   Tanpa pembatasan ini, nama pilihan ikut jadi HURUF BESAR TEBAL KECIL-KECIL -
   gaya untuk judul kolom penyaring, bukan untuk isi daftar yang harus dibaca. */
.filter-antrian > .form-group > label {
  display: block;
  font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .05em;
  color: var(--adm-muted, #8b93a5); margin-bottom: 5px;
}
/* Hanya ISIAN di baris filter itu sendiri - perhatikan tanda ">".
   Daftar pilihan combo-box digambar DI DALAM .filter-antrian juga, dan di
   dalamnya ada satu <input type=checkbox> per pilihan. Dengan pemilih tanpa ">"
   (".filter-antrian input"), kotak centang itu ikut dilebarkan 100% sehingga
   memenuhi barisnya sebagai kotak putih besar dan mendorong nama pilihannya
   keluar dari panel. */
.filter-antrian > .form-group > select,
.filter-antrian > .form-group > input { width: 100%; min-width: 0; }
/* Ketiga jenis kotak disamakan bentuknya: <input> biasa, <select> biasa, dan
   tombol combo-box. Baris filter bisa memuat ketiganya sekaligus, dan dengan
   ukuran bawaan masing-masing, tiga kotak bersebelahan berakhir dengan tiga
   tinggi yang berbeda (41 / 38 / 36 px) padahal fungsinya setara.

   ".form-control" ikut ditulis di pemilihnya, bukan hanya "input": Porto punya
   aturan ".form-control:not(.form-control-sm):not(.form-control-lg)" yang
   spesifisitasnya TIGA kelas, sehingga pemilih tanpa kelas di elemennya kalah
   dan hanya sebagian deklarasi yang berlaku - padding ikut, ukuran huruf
   tidak. Itu sebabnya line-height & min-height juga ditegaskan di sini:
   keduanya diatur aturan Porto yang sama. */
.filter-antrian > .form-group > input.form-control,
.filter-antrian > .form-group > select.form-select,
.filter-antrian > .form-group > select,
.filter-antrian > .form-group > input,
.filter-antrian .multiselect {
  font-size: 13px; line-height: 22px; min-height: 0;
  padding-top: 7px; padding-bottom: 7px;
}
/* Tombol sejajar dengan dasar kotak di kirinya (label + tinggi input). */
.filter-antrian .filter-aksi { flex: 0 0 auto; display: flex; gap: 8px; align-items: center; }
.filter-antrian .filter-info {
  flex: 1 1 100%; font-size: 12px; color: var(--adm-muted, #8b93a5);
}
.filter-antrian .filter-info:empty { display: none; }

/* ---- Combo-box pilih-banyak (bootstrap-multiselect) ---- */
/* Pluginnya mengganti <select> dengan <button class="multiselect"> + dropdown
   Bootstrap, keduanya dirancang untuk latar TERANG. Tanpa aturan di bawah,
   tombol dan daftarnya menyala putih di tengah baris filter yang gelap - dan
   tulisan pilihannya putih di atas putih. */
.filter-antrian .btn-group { display: block; width: 100%; }
/* border-style ditulis di sini, bukan hanya warnanya di aturan html.dark:
   elemennya <button>, dan gaya bawaan browser untuk tombol adalah "2px outset"
   - tanpa penegasan ini kotak filternya bertepi timbul seperti tombol Windows
   lama, bukan sedatar isian di sebelahnya. */
.filter-antrian .multiselect {
  width: 100%; text-align: left; position: relative; padding: 7px 26px 7px 12px;
  border: 1px solid transparent; border-radius: 6px; font-size: 13px;
}
.filter-antrian .multiselect .multiselect-selected-text {
  display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.filter-antrian .multiselect::after { position: absolute; right: 10px; top: 45%; }
/* Panel daftarnya selebar ISINYA, minimal selebar tombolnya.
   Dikunci 100% (selebar tombol), nama kategori terpanjang - "Gagal Cek Data /
   Tidak Hadir" - terpotong di tepi panel. Batas atasnya tetap ada supaya nama
   event yang panjang tidak menarik panelnya melintasi layar; kalau lebih
   panjang lagi, tulisannya turun baris. */
.multiselect-container {
  min-width: 100%; width: max-content; max-width: 320px; padding: 6px;
}
.multiselect-container .form-check { padding: 4px 8px 4px 28px; border-radius: 6px; }
.multiselect-container .multiselect-filter { padding: 4px 4px 8px; }
.multiselect-container .multiselect-option { font-size: 13px; }
.multiselect-container .form-check-label { white-space: normal; }

html.dark .filter-antrian .multiselect {
  background: #1f2330; border-color: var(--adm-line); color: var(--adm-text);
}
html.dark .filter-antrian .multiselect:focus,
html.dark .filter-antrian .btn-group.show .multiselect {
  border-color: var(--adm-accent); box-shadow: 0 0 0 .2rem rgba(92, 107, 192, .2);
  color: var(--adm-text);
}
/* Daftarnya digambar di luar .filter-antrian (dipindahkan Bootstrap ke ujung
   body pada sebagian kasus), jadi aturannya TIDAK dibatasi ke baris filter. */
html.dark .multiselect-container { background: var(--adm-panel); border-color: var(--adm-line); }
html.dark .multiselect-container .form-check-label,
html.dark .multiselect-container .multiselect-group label { color: var(--adm-text); }
/* Baris yang sedang disorot papan ketik atau tetikus. Bawaan Bootstrap memberi
   latar terang dengan tulisan gelap - di tema gelap jadi nyaris tak terbaca. */
html.dark .multiselect-container .multiselect-option:hover,
html.dark .multiselect-container .multiselect-option:focus,
html.dark .multiselect-container .multiselect-option.active,
html.dark .multiselect-container .dropdown-item:hover,
html.dark .multiselect-container .dropdown-item:focus,
html.dark .multiselect-container .dropdown-item.active {
  background: var(--adm-accent); color: #fff;
}
html.dark .multiselect-container .multiselect-option:hover .form-check-label,
html.dark .multiselect-container .multiselect-option:focus .form-check-label,
html.dark .multiselect-container .multiselect-option.active .form-check-label { color: #fff; }
html.dark .multiselect-container .multiselect-filter input {
  background: #1f2330; border-color: var(--adm-line); color: var(--adm-text);
}
html.dark .multiselect-container .multiselect-filter input::placeholder { color: var(--adm-muted); }

/* ---- Widget rekap per kategori ---- */
/* Grid mandiri, bukan kolom Bootstrap, supaya jarak & tinggi kartunya seragam.
   Jumlah kolomnya DITENTUKAN, tidak auto-fit: kartunya ada delapan (total + 7
   kategori), dan auto-fit pada layar lebar menghasilkan lima kolom - baris
   keduanya lalu menyisakan dua lubang kosong di ujung. Empat dan dua membagi
   delapan dengan rata; tiga dipakai di lebar menengah, di mana satu baris
   ganjil lebih baik daripada kartu yang terlalu sempit. */
.recap-grid {
  display: grid; gap: 10px; margin-bottom: 14px;
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
@media (min-width: 768px) { .recap-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 1100px) { .recap-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.recap-grid .card-body { padding: 12px 14px; }
/* Porto memberi .summary min-height 65px (untuk widget dasbor yang isinya jauh
   lebih banyak) dan word-break:break-all. Keduanya salah di sini: tingginya
   menyisakan ruang kosong sepertiga kartu, dan break-all memotong nama kategori
   di tengah kata ("KURASI BERHA-SIL") alih-alih di spasinya. */
.recap-grid .summary { min-height: 0; word-break: normal; overflow-wrap: anywhere; }
/* Ikon & angka dikecilkan dari ukuran bawaan .widget-summary: delapan kartu
   seukuran aslinya mendorong tabelnya jauh ke bawah layar. */
.recap-grid .summary-icon { width: 42px; height: 42px; font-size: 17px; margin-right: 11px; border-radius: 9px; }
.recap-grid .summary .title { font-size: 10.5px; letter-spacing: .05em; }
.recap-grid .summary .amount { font-size: 21px; }
.recap-grid .summary-footer span { font-size: 9.5px; font-weight: 700; letter-spacing: .06em; color: var(--adm-muted, #8b93a5); }
/* Kartu yang sedang menjadi penyaring aktif: tepinya menyala dan keterangan
   bawahnya ikut berwarna, supaya terlihat tanpa harus membaca tulisannya. */
.recap-grid .stat-aktif .card { border-color: var(--adm-accent, #5c6bc0); background: rgba(92, 107, 192, .10); }
.recap-grid .stat-aktif .summary-footer span { color: var(--adm-accent, #5c6bc0); }

/* Seluruh butir grid setinggi barisnya, apa pun jenis elemennya. Tanpa ini,
   butir yang bentuknya berbeda (mis. <section> telanjang di antara <a>) tidak
   ikut meregang dan kartunya menggantung di ujung baris. */
.recap-grid { align-items: stretch; }
.recap-grid > * { height: 100%; }
.recap-grid > * > .card, .recap-grid > .card { height: 100%; margin-bottom: 0; }

/* Kartu keterangan: bentuknya sama dengan kartu penyaring, tapi memang tidak
   bisa diklik - jadi tidak ada isyarat bahwa ia bisa. */
.recap-grid .stat-mati { cursor: default; }
.recap-grid .stat-mati .summary-footer span { opacity: .55; }
@media (max-width: 575px) {
  .recap-grid .summary-icon { width: 34px; height: 34px; font-size: 14px; margin-right: 9px; }
  .recap-grid .summary .amount { font-size: 18px; }
  .recap-grid .card-body { padding: 10px; }
  /* Keterangan kaki dibuang di HP: "SEDANG DITAMPILKAN" tidak muat satu baris
     di kartu selebar setengah layar, dan begitu ia membungkus, satu kartu jadi
     lebih tinggi daripada tetangganya sehingga barisnya terlihat miring.
     Yang hilang hanya tulisannya - kartu yang sedang aktif tetap dikenali dari
     tepi & latarnya yang menyala, dan namanya tetap terbaca pembaca layar
     lewat aria-label. */
  .recap-grid .summary-footer { display: none; }
}

/* ---- Tombol aksi ikon saja ---- */
/* Lebarnya dipaksa sama supaya kolom Aksi tidak bergerigi: tanpa ini lebar
   tombol mengikuti lebar ikonnya, dan ikon WhatsApp lebih sempit daripada
   ikon printer. */
.tabel-rapi .table-actions .btn-ikon {
  width: 30px; padding: 5px 0; text-align: center; line-height: 1.35;
}
.tabel-rapi .table-actions .btn-ikon i { margin: 0; }

/* Kolom tabel Recap. Dulu diatur lewat td:nth-child(), yang menunjuk kolom
   yang salah sejak urutan kolomnya bergeser - komentarnya menyebut "kode" dan
   "waktu" padahal yang kena Aksi dan Petugas. Sekarang lewat kelas, jadi
   penambahan kolom tidak pernah menggeser aturannya lagi. */
/* Baris tombol di kepala halaman Detail: tombol kembali dan tombol alur kerja
   berjajar, dan boleh membungkus di layar sempit tanpa saling menempel. */
.baris-aksi-detail { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }

/* ---- Laporan WhatsApp ---- */
/* Lima kartu, bukan delapan seperti Recap: 5 dan 3 membaginya dengan rapi,
   sedangkan 4 menyisakan satu kartu sendirian di baris kedua. */
.recap-grid.recap-grid-3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (min-width: 768px) { .recap-grid.recap-grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 1200px) { .recap-grid.recap-grid-3 { grid-template-columns: repeat(5, minmax(0, 1fr)); } }

/* Kolom isi pesan: satu baris dengan titik-titik di ujungnya. Dibiarkan
   membungkus, satu pesan panjang membuat barisnya setinggi lima baris dan
   tabelnya tidak bisa dipindai sekilas lagi - isi penuhnya ada di title. */
.tabel-wa .kol-pesan { max-width: 320px; }
.tabel-wa .kol-pesan span {
  display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: 12.5px; color: var(--adm-muted, #8b93a5);
}
.tabel-wa .kol-pesan span:hover { color: var(--adm-text, #d7dae2); }

/* Laporan Email memakai DUA baris di kolom itu - subjek di atas, potongan
   isinya di bawah - jadi aturan di atas yang hanya mengenai <span> tidak
   mengikatnya, dan kalimat panjang menimpa kolom Hasil & Petugas di
   sebelahnya. */
.tabel-email .kol-pesan { max-width: 340px; }
.tabel-email .kol-pesan > strong,
.tabel-email .kol-pesan > div {
  display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.tabel-email .kol-pesan > div { font-size: 12.5px; }


.wa-navigasi {
  display: flex; flex-wrap: wrap; gap: 10px 14px;
  align-items: center; justify-content: space-between; margin-top: 12px;
}
.wa-navigasi .wa-navigasi-tombol { display: flex; gap: 8px; align-items: center; }

.table.tabel-rapi .kol-kode { white-space: nowrap; }
.table.tabel-rapi .kol-waktu { white-space: nowrap; font-size: 12.5px; }
.table.tabel-rapi .table-actions .btn { margin: 0 0 0 4px; }

/* Padding sel & tombol aksi dirapatkan sedikit supaya tabel Recap (9 kolom)
   muat tanpa gulir mendatar; tabel lain ikut terlihat lebih padat. */
.table.tabel-rapi > thead > tr > th,
.table.tabel-rapi > tbody > tr > td { padding-left: 9px; padding-right: 9px; }
.table.tabel-rapi .table-actions .btn { padding: 5px 9px; font-size: 12px; }
.table.tabel-rapi .status-badge { padding: 4px 9px; font-size: 11px; }

/* ---- Role Management ----
   Dua kolom: daftar peran di kiri, matriks haknya di kanan. Daftar peran
   sengaja terlihat terus, bukan tersembunyi di dropdown: "peran apa saja yang
   ada" adalah pertanyaan yang paling sering diajukan panitia. */
.role-tata{display:grid;grid-template-columns:260px 1fr;gap:16px;align-items:start;}
@media (max-width:900px){.role-tata{grid-template-columns:1fr;}}
.role-daftar .card-judul{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-bottom:10px;}
.role-daftar .card-judul h2{margin:0;font-size:15px;}
.role-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:6px;}
.role-list-item{padding:9px 11px;border:1px solid var(--adm-line,#333846);border-radius:8px;cursor:pointer;}
.role-list-item:hover{border-color:var(--adm-primary,#5c6bc0);}
.role-list-item.aktif{border-color:var(--adm-primary,#5c6bc0);background:rgba(92,107,192,.12);}
.role-list-nama{display:block;font-weight:700;font-size:13.5px;color:var(--adm-text,#d7dae2);}
.role-list-ket{display:block;font-size:11.5px;color:var(--adm-muted,#8b93a5);margin-top:2px;}

.role-kepala{display:grid;grid-template-columns:1fr 1fr;gap:12px;}
@media (max-width:640px){.role-kepala{grid-template-columns:1fr;}}

.role-alat{display:flex;align-items:center;justify-content:space-between;gap:10px;flex-wrap:wrap;margin:18px 0 8px;padding-top:14px;border-top:1px solid var(--adm-line,#333846);}
.role-alat-judul{font-weight:700;font-size:13.5px;color:var(--adm-text,#d7dae2);}
.role-alat-tombol{display:flex;gap:6px;flex-wrap:wrap;}

.role-grup{margin-bottom:14px;}
.role-grup-judul{font-size:11.5px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--adm-muted,#8b93a5);margin-bottom:6px;}
/* Tabelnya digulir menyamping di layar sempit, bukan diciutkan: kolom hak yang
   hilang dari layar sama saja dengan hak yang tidak bisa disetel. */
.role-tabel{width:100%;border-collapse:collapse;font-size:13px;}
.role-tabel th,.role-tabel td{padding:6px 8px;border-bottom:1px solid var(--adm-line,#333846);color:var(--adm-text,#d7dae2);}
.role-tabel thead th{font-size:11px;text-transform:uppercase;letter-spacing:.06em;color:var(--adm-muted,#8b93a5);text-align:center;font-weight:700;}
.role-tabel thead th:first-child{text-align:left;}
.role-modul-nama{width:100%;color:var(--adm-text,#d7dae2);}
.role-kol-centang{text-align:center;width:64px;}
/* Sasaran sentuh yang layak: matriks ini disetel di laptop, tetapi kadang
   juga di tablet saat acara sudah berjalan. */
.role-kol-centang input{width:17px;height:17px;cursor:pointer;}
.role-kol-centang input:disabled{cursor:not-allowed;opacity:.35;}

.role-kaki{display:flex;gap:8px;justify-content:flex-end;margin-top:16px;padding-top:14px;border-top:1px solid var(--adm-line,#333846);}
.role-kaki .btn-danger{margin-right:auto;}

/* ---- Kelola Petugas: tab & data login petugas baru ---- */
.tabs-petugas{border-bottom:1px solid var(--adm-line,#333846);margin:0 0 16px;padding:0;
  display:flex;flex-wrap:wrap;gap:2px;list-style:none;}
.tabs-petugas .nav-link{background:none;border:0;border-bottom:2px solid transparent;
  color:var(--adm-muted,#8b93a5);padding:9px 14px;font-size:13.5px;font-weight:600;
  cursor:pointer;display:flex;align-items:center;gap:7px;white-space:nowrap;}
.tabs-petugas .nav-link:hover{color:var(--adm-text,#d7dae2);}
.tabs-petugas .nav-link.active{color:var(--adm-text,#d7dae2);
  border-bottom-color:var(--adm-accent,#5c6bc0);}
/* Jumlah kunci login yang sedang aktif - satu-satunya tab yang isinya mendesak,
   dan satu-satunya yang perlu menarik perhatian tanpa dibuka. */
.tab-lencana{background:#dc3545;color:#fff;border-radius:100px;font-size:10.5px;
  font-weight:700;padding:1px 7px;line-height:1.5;}

.kol-kontak{font-size:12px;line-height:1.5;}
.kol-kontak span{display:block;color:var(--adm-muted,#8b93a5);white-space:nowrap;}
.kol-kontak i{width:12px;opacity:.7;}

/* Kotak data login. Dibedakan tajam dari sisa formulir: isinya hanya bisa
   dibaca sekali, dan yang terlewat membacanya harus mereset sandinya. */
.kredensial{margin-top:18px;border:1px solid #28a745;border-radius:10px;
  background:rgba(40,167,69,.08);padding:14px 16px;}
.kredensial-kepala{display:flex;align-items:center;justify-content:space-between;
  gap:10px;flex-wrap:wrap;font-weight:700;font-size:13.5px;color:#28a745;margin-bottom:10px;}
.kredensial-isi{display:grid;grid-template-columns:150px 1fr;gap:6px 12px;margin:0 0 10px;
  font-size:13px;}
@media (max-width:560px){.kredensial-isi{grid-template-columns:1fr;gap:2px 0;}
  .kredensial-isi dd{margin-bottom:8px;}}
.kredensial-isi dt{color:var(--adm-muted,#8b93a5);}
.kredensial-isi dd{margin:0;color:var(--adm-text,#d7dae2);word-break:break-all;}
/* Sandi & username dibaca lalu diketik ulang orang lain - huruf berjarak tetap
   membedakan 0 dari O dan 1 dari l, yang justru paling sering salah dengar. */
.kredensial-isi code{font-family:ui-monospace,"Courier New",monospace;font-size:14px;
  font-weight:700;letter-spacing:.04em;background:rgba(0,0,0,.25);padding:2px 7px;border-radius:5px;}
.kredensial-catatan{font-size:12px;color:var(--adm-muted,#8b93a5);margin:0 0 12px;line-height:1.6;}
.kredensial-aksi{display:flex;gap:8px;flex-wrap:wrap;}
.kred-ok{color:#28a745;}
.kred-gagal{color:#dc3545;}
