/* Gaya klasik kantor, senada dengan aplikasi desktop Admin Kegiatan:
   palet abu-biru netral, sudut nyaris siku, tanpa bayangan, kerapatan tinggi. */

:root {
  --biru: #1f4e79;
  --biru-muda: #dce6f1;
  --latar: #f5f5f5;
  --permukaan: #ffffff;
  --garis: #c8c8c8;
  --garis-tipis: #e3e3e3;
  --teks: #1a1a1a;
  --teks-redup: #5a5a5a;
  --merah: #b00020;
  --hijau: #1e7d32;
  --kuning: #8a6100;
  --radius: 3px;
}

* { box-sizing: border-box; }

/* Atribut `hidden` harus menang atas display apa pun.
   Aturan bawaan browser (`[hidden] { display: none }`) kalah oleh selektor kelas
   seperti `.baris { display: flex }`, sehingga elemen yang disembunyikan tetap
   tampak — termasuk tombol yang semestinya tidak terlihat oleh peran guru. */
[hidden] { display: none !important; }

/* --- Gerbang muat: menutup halaman sampai sesi dan peran selesai diperiksa ---

   Tiap halaman mengirim isinya sebagai HTML statis, dan `<script type="module">`
   SELALU ditunda. Peramban karena itu selesai menggambar seluruh badan halaman
   sebelum baris pertama kode pemeriksaan berjalan — tabel kosong dan tulisan
   "Memuat…" sempat terlihat, lalu berkedip berganti isi. Kadang oleh orang yang
   ternyata tidak berhak melihatnya: seorang adminpresensi yang membuka
   masuk.html melihat seluruh antarmuka pemindai lengkap dengan kamera sebelum
   diberi tahu halaman itu bukan untuknya.

   Ditulis sebagai pseudo-element milik body, BUKAN <div> di tiap halaman:
   seluruh gerbang hidup di berkas ini saja, dan tiap halaman cukup menulis satu
   kelas di <html>. Dua belas salinan markah yang sama pasti menyimpang satu per
   satu — dan yang menyimpang di sini adalah penutup layar.

   `visibility: hidden` pada anak body, bukan sekadar tirai di atasnya: <dialog>
   yang terbuka tampil di lapisan teratas dan menang atas z-index berapa pun, dan
   tirai juga tidak menghalangi Tab, Ctrl+F, maupun pembaca layar. Untuk halaman
   yang justru belum tentu boleh dilihat, itu jaminan yang salah. Pseudo-element
   body sendiri tetap terlihat karena `body > *` hanya mencocokkan ELEMEN anak. */
html.memuat body > * { visibility: hidden; }

html.memuat body::before {
  content: '';
  position: fixed;
  inset: 0;
  /* .menu-profil memakai 30, .sisi 20, .tirai 10, .bilah 5. Angkanya sengaja
     jauh di atas semuanya supaya nilai baru tidak diam-diam melewatinya. */
  z-index: 1000;
  background: var(--latar);
}

html.memuat body::after {
  content: '';
  position: fixed;
  /* Dipusatkan lewat calc, bukan translate: transform disisakan untuk berputar. */
  top: calc(50% - 15px);
  left: calc(50% - 15px);
  width: 30px;
  height: 30px;
  z-index: 1001;
  border: 3px solid var(--garis);
  border-top-color: var(--biru);
  border-radius: 50%;
  animation: gerbang-putar .7s linear infinite;
}

@keyframes gerbang-putar { to { transform: rotate(360deg); } }

/* Putaran tanpa henti memicu mual pada sebagian orang, dan penanda muat adalah
   contoh baku animasi yang harus tunduk pada setelan ini. Penggantinya tetap
   bergerak — penanda yang diam tidak bisa dibedakan dari halaman yang macet. */
@media (prefers-reduced-motion: reduce) {
  html.memuat body::after { animation: gerbang-denyut 1.4s ease-in-out infinite; }
  @keyframes gerbang-denyut { 0%, 100% { opacity: .3 } 50% { opacity: 1 } }
}

body {
  margin: 0;
  font-family: 'Segoe UI', Tahoma, Arial, sans-serif;
  font-size: 13px;
  color: var(--teks);
  background: var(--latar);
}

/* --- Kerangka: sidebar tetap di kiri, isi halaman di kanan --- */

.kerangka { display: flex; min-height: 100vh; }

.sisi {
  width: 220px;
  flex: 0 0 220px;
  background: var(--permukaan);
  border-right: 1px solid var(--garis);
  display: flex;
  flex-direction: column;
  position: sticky;
  top: 0;
  height: 100vh;
}

.sisi .merek {
  padding: 14px 16px;
  font-size: 16px;
  font-weight: 600;
  color: var(--biru);
  border-bottom: 1px solid var(--garis-tipis);
}

.sisi nav { flex: 1; overflow-y: auto; padding: 8px 0; }

.sisi a {
  display: block;
  padding: 7px 16px;
  color: var(--teks);
  text-decoration: none;
  border-left: 3px solid transparent;
}

.sisi a:hover { background: var(--latar); }

.sisi a.aktif {
  background: var(--biru-muda);
  color: var(--biru);
  font-weight: 600;
  border-left-color: var(--biru);
}

.sisi .grup > summary {
  padding: 7px 16px;
  cursor: pointer;
  color: var(--teks-redup);
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .04em;
  list-style: none;
}

.sisi .grup > summary::-webkit-details-marker { display: none; }
.sisi .grup > summary::before { content: '▸ '; }
.sisi .grup[open] > summary::before { content: '▾ '; }
.sisi .grup > summary:hover { background: var(--latar); }
.sisi a.anak { padding-left: 30px; }

/* --- Bilah atas: judul di kiri, profil di kanan --- */

.bilah {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 16px;
  background: var(--permukaan);
  border-bottom: 1px solid var(--garis);
  position: sticky;
  top: 0;
  z-index: 5;
}

/* Sidebar sudah menyebut "Presensi"; di layar lebar tidak perlu dua kali.
   Di layar sempit sidebar tersembunyi, jadi di sanalah merek ini berguna. */
.bilah .merek-bilah { display: none; }
.bilah .hanya-sempit { display: none; }
.bilah .profil { position: relative; margin-left: auto; }

.bilah .profil > button {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 4px 8px;
  border-color: transparent;
  background: transparent;
}

.bilah .profil > button:hover:not(:disabled) { background: var(--latar); }

.inisial {
  width: 28px;
  height: 28px;
  flex: 0 0 28px;
  border-radius: 50%;
  background: var(--biru);
  color: #fff;
  font-size: 11px;
  font-weight: 700;
  display: grid;
  place-items: center;
}

.inisial.berfoto { background: var(--garis); padding: 0; }
.inisial.berfoto img { width: 100%; height: 100%; object-fit: cover; }

/* Pemilih mode pada halaman pindai: QR atau catat manual */
.mode { display: flex; gap: 4px; margin-bottom: 12px; }

.mode button {
  padding: 8px 16px;
  border-bottom-width: 2px;
}

.mode button.aktif {
  background: var(--biru-muda);
  border-color: var(--biru);
  color: var(--biru);
  font-weight: 600;
}

.mode .jumlah {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 7px;
  border-radius: 9px;
  background: var(--garis);
  color: var(--teks-redup);
  font-size: 11px;
  font-weight: 700;
}

.mode button.aktif .jumlah { background: var(--biru); color: #fff; }

/* Satu panel tampak dalam satu waktu, jadi tidak ada lagi dua kolom. Kamera
   dibatasi lebarnya — video selebar layar tidak membuat QR lebih mudah terbaca,
   hanya membuat wajah petugas tampak besar. */
#panelQr { max-width: 520px; }
#panelManual { max-width: 640px; }

/* Hasil pencarian manual */
#daftarBelum { list-style: none; padding: 0; margin: 12px 0 0; max-height: 320px; overflow: auto; }

#daftarBelum li {
  display: flex;
  gap: 10px;
  align-items: center;
  padding: 6px 0;
  border-bottom: 1px solid var(--garis-tipis);
}

#daftarBelum li:last-child { border-bottom: none; }
#daftarBelum .nama-cari { flex: 1; }

/* Layar konfirmasi pindaian */
dialog.konfirmasi-pindai { min-width: 340px; max-width: calc(100vw - 32px); }
dialog.konfirmasi-pindai .orang { display: flex; gap: 14px; align-items: center; }
dialog.konfirmasi-pindai .wadah-wajah { flex: 0 0 auto; }
dialog.konfirmasi-pindai .nama { font-size: 19px; font-weight: 600; line-height: 1.2; }
dialog.konfirmasi-pindai .kelas { color: var(--teks-redup); margin-top: 2px; }
dialog.konfirmasi-pindai .akan { margin-top: 8px; }
dialog.konfirmasi-pindai .wajah { width: 84px; height: 84px; flex-basis: 84px; }
dialog.konfirmasi-pindai .aksi { display: flex; gap: 8px; justify-content: flex-end; }

/* Wajah santri. Dipakai di hasil pindaian maupun di layar konfirmasi, jadi
   aturan dasarnya sengaja tidak diikat ke salah satunya. */
.wajah {
  width: 64px;
  height: 64px;
  flex: 0 0 64px;
  border-radius: var(--radius);
  object-fit: cover;
  background: var(--permukaan);
  border: 1px solid var(--garis);
}

.wajah.kosong {
  display: grid;
  place-items: center;
  color: var(--teks-redup);
}

.hasil-pindai { display: flex; align-items: center; gap: 14px; }

.profil-teks { display: flex; flex-direction: column; line-height: 1.25; text-align: left; }
.profil-teks small { color: var(--teks-redup); font-size: 11px; }
.bilah .panah { color: var(--teks-redup); font-size: 10px; }

.menu-profil {
  position: absolute;
  right: 0;
  top: calc(100% + 4px);
  min-width: 220px;
  background: var(--permukaan);
  border: 1px solid var(--garis);
  border-radius: var(--radius);
  box-shadow: 0 2px 8px rgba(0, 0, 0, .12);
  z-index: 30;
  padding: 4px;
}

.menu-profil .kepala {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 10px 12px;
  border-bottom: 1px solid var(--garis-tipis);
  margin-bottom: 4px;
}

.menu-profil .kepala small { color: var(--teks-redup); font-size: 11px; }

.menu-profil > button {
  display: block;
  width: 100%;
  text-align: left;
  border-color: transparent;
  background: transparent;
  padding: 8px 12px;
}

.menu-profil > button:hover:not(:disabled) { background: var(--latar); }

/* min-width:0 supaya tabel lebar menggulir di dalam .gulir,
   bukan melebarkan seluruh halaman */
.kerangka > .isi { flex: 1; min-width: 0; }


.gulir { overflow-x: auto; }

/* Dipusatkan, seperti halaman kesehatan. Tanpa `margin: 0 auto` lebarnya
   memang dibatasi, tetapi isinya menempel ke tepi kiri — di layar lebar itu
   meninggalkan lahan kosong sepanjang sisi kanan dan membuat bilah atas
   seolah tidak sejajar dengan apa pun di bawahnya.

   Batasnya tetap 1100px, bukan 900px seperti di kesehatan: halaman rekap dan
   daftar presensi memuat tabel berkolom banyak, dan mempersempitnya hanya
   memindahkan masalah menjadi gulir mendatar. */
main { padding: 20px; max-width: 1100px; margin: 0 auto; }

@media (max-width: 860px) {
  .sisi {
    position: fixed;
    z-index: 20;
    left: 0;
    top: 0;
    transform: translateX(-100%);
    transition: transform .15s ease-out;
  }

  .sisi.buka { transform: none; }

  .tirai {
    position: fixed;
    inset: 0;
    z-index: 10;
    background: rgba(0, 0, 0, .35);
  }

  .bilah .merek-bilah {
    display: block;
    font-size: 15px;
    font-weight: 600;
    color: var(--biru);
  }

  .bilah .hanya-sempit {
    display: block;
    padding: 5px 10px;
    font-size: 15px;
    line-height: 1;
    border-color: #9e9e9e;
  }

  /* Di layar sempit nama memakan seluruh bilah; lingkaran inisialnya cukup */
  .bilah .profil-teks { display: none; }

  main { padding: 14px; }
  .baris > .kolom { flex: 1 1 100%; }
}

h1 { font-size: 19px; font-weight: 600; margin: 0 0 4px; }
/* 66ch — sekitar satu baris yang nyaman dibaca. Dibiarkan selebar 1100px,
   kalimat penjelas menjadi satu garis panjang yang sulit dilacak matanya
   saat berpindah baris. Sama dengan halaman kesehatan. */
p.keterangan { color: var(--teks-redup); margin: 0 0 18px; max-width: 66ch; }

.panel {
  background: var(--permukaan);
  border: 1px solid var(--garis);
  border-radius: var(--radius);
  padding: 16px;
  margin-bottom: 16px;
}

.baris { display: flex; gap: 10px; align-items: flex-end; flex-wrap: wrap; }
.kolom { display: flex; flex-direction: column; gap: 4px; }
label { font-size: 12px; color: var(--teks-redup); }

input, select, textarea, button {
  font-family: inherit;
  font-size: 13px;
  padding: 8px 10px;
  border: 1px solid #9e9e9e;
  border-radius: 2px;
  background: var(--permukaan);
  color: var(--teks);
}

input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--biru);
  box-shadow: inset 0 0 0 1px var(--biru);
}

button {
  cursor: pointer;
  border-radius: var(--radius);
  border-color: #9e9e9e;
}

button:hover:not(:disabled) { background: var(--latar); }
button:disabled { opacity: .5; cursor: default; }

button.utama {
  background: var(--biru);
  border-color: var(--biru);
  color: #fff;
  font-weight: 500;
}

button.utama:hover:not(:disabled) { background: #18406a; }

table { width: 100%; border-collapse: collapse; }
th, td { text-align: left; padding: 7px 10px; border-bottom: 1px solid var(--garis-tipis); }
th { background: #e8e8e8; font-size: 12.5px; font-weight: 700; }
tbody tr:hover { background: #fafafa; }

.lencana {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 10px;
  font-size: 11px;
  font-weight: 600;
}

.lencana.hadir, .lencana.tepat_waktu { background: #e3f1e5; color: var(--hijau); }
.lencana.terlambat { background: #fbf0dc; color: var(--kuning); }
.lencana.alfa { background: #fbe3e6; color: var(--merah); }
.lencana.izin, .lencana.sakit { background: #e6ecf4; color: var(--biru); }
.lencana.manual { background: #eeeeee; color: var(--teks-redup); }

.pesan { padding: 10px 12px; border-radius: var(--radius); margin-bottom: 12px; }
.pesan.galat { background: #fbe3e6; color: var(--merah); border: 1px solid #e8b4bb; }
.pesan.sukses { background: #e3f1e5; color: var(--hijau); border: 1px solid #b6ddbd; }
.pesan.info { background: var(--biru-muda); color: var(--biru); border: 1px solid #b9cde4; }

.ringkas { display: flex; gap: 18px; flex-wrap: wrap; margin-bottom: 14px; }
.ringkas b { font-size: 15px; }

video {
  width: 100%;
  background: #000;
  border: 1px solid var(--garis);
  border-radius: var(--radius);
}

.hasil-besar { font-size: 22px; font-weight: 600; margin: 6px 0; }
.kosong { color: var(--teks-redup); padding: 18px; text-align: center; }

dialog {
  border: 1px solid var(--garis);
  border-radius: var(--radius);
  padding: 0;
  min-width: 380px;
}

dialog .isi { padding: 16px; }
dialog .aksi { padding: 12px 16px; border-top: 1px solid var(--garis-tipis); text-align: right; }
dialog::backdrop { background: rgba(0, 0, 0, .3); }


@media (max-width: 860px) {
  dialog { min-width: 0; width: calc(100vw - 32px); }
}
