/* gaya.css — sistem desain dashboard SIAGA.
 *
 * Dipakai oleh : pusat/web/ dan polda/web/ lewat /bersama/gaya.css
 * Berpasangan  : /bersama/huruf.css (harus dimuat lebih dulu)
 *
 * KENAPA DI bersama/, BUKAN DISALIN DUA KALI
 *
 * Superadmin pusat dan superadmin Polda sering orang yang sama, membuka kedua
 * layar berdampingan. Dua sistem desain yang perlahan berbeda membuat keduanya
 * terasa seperti dua aplikasi asing, dan yang paling merugikan bukan
 * keindahannya melainkan ingatan otot: tombol berbahaya yang letaknya berpindah
 * antar layar adalah tombol yang cepat atau lambat salah ditekan.
 *
 * BAHASA VISUALNYA MENERUSKAN admin/
 *
 * Dashboard lama sudah dipakai bertahun-tahun dan petugas hafal bentuknya.
 * Kertas hangat, tinta nyaris hitam, border 2px, bayangan keras tanpa blur,
 * aksen limau yang dipakai HEMAT. Sistem baru tidak memperkenalkan bahasa
 * baru; ia meneruskan yang sudah dikenal, lalu memperbaiki yang memang kurang
 * di sana - terutama layar kecil.
 *
 * DITULIS UNTUK LAYAR KECIL LEBIH DULU
 *
 * Aturan dasar di berkas ini berlaku untuk telepon. Layar lebar mendapat
 * tambahannya lewat media query ke ATAS. Urutan itu disengaja: yang ditulis
 * belakangan selalu yang paling sedikit diuji, dan telepon justru yang paling
 * sering dipakai di lapangan - petugas membuka dashboard sambil berdiri di
 * dekat radio, bukan sambil duduk di depan meja.
 */

/* ==========================================================================
   1. Nilai dasar
   ========================================================================== */

:root {
  --tinta: #15171C;
  --kertas: #F2F0E9;
  --permukaan: #FFFFFF;
  /* Kepala kartu sedikit lebih hangat dari badannya: itu yang memisahkan
     judul dari isi tanpa menambah satu garis pun. */
  --kepala: #FAFAF7;
  --senyap: #5F6371;
  --garis: #15171C;
  --garis-lembut: #E9E7E0;

  /* Tombol utama = tinta, bukan warna. Limau terlalu terang untuk menahan
     teks putih, dan terlalu berharga untuk dihabiskan di tombol biasa. */
  --utama: #15171C;
  --limau: oklch(0.88 0.21 125);
  --limau-lembut: oklch(0.95 0.1 125);
  --limau-tinta: #3F4A1A;

  --baik: oklch(0.88 0.21 125);
  --baik-latar: oklch(0.95 0.1 125);
  --awas: oklch(0.93 0.09 85);
  --awas-latar: oklch(0.96 0.06 85);
  --awas-tinta: #6B4E00;
  --buruk: oklch(0.68 0.19 30);
  --buruk-latar: oklch(0.94 0.05 30);
  --buruk-tinta: oklch(0.45 0.18 30);

  --lengkung: 14px;
  --lengkung-kecil: 9px;
  --lengkung-mini: 6px;

  /* Kartu 5px, tombol 2px yang menjadi 3px saat disentuh. Angkanya berbeda
     dengan sengaja: kartu berdiri diam, tombol bisa ditekan. */
  --bayang: 5px 5px 0 0 var(--tinta);
  --bayang-kecil: 2px 2px 0 0 var(--tinta);
  --bayang-naik: 3px 3px 0 0 var(--tinta);

  --mono: "IBM Plex Mono", "Cascadia Mono", Consolas, ui-monospace, monospace;
  --sans: "IBM Plex Sans", "Segoe UI", system-ui, -apple-system, sans-serif;
  --tampil: "Space Grotesk", "IBM Plex Sans", "Segoe UI", system-ui, sans-serif;

  /* Tinggi sentuh minimum. 44px adalah angka yang dipakai Apple dan Google,
     dan alasannya bukan selera: jari orang dewasa menutupi kira-kira selebar
     itu, jadi target yang lebih kecil ditekan tanpa bisa dilihat. */
  --sentuh: 44px;
}

/* [hidden] HARUS menang atas apa pun.
 *
 * Sudah terjadi: sebuah bagian diberi display: grid, lalu disembunyikan dengan
 * atribut hidden - dan ia tetap terlihat, karena display di kelasnya menimpa
 * display: none bawaan atribut itu. DOM bilang tersembunyi, layar bilang ada.
 * Ketahuan dengan melihat halamannya, bukan dengan membaca kodenya. */
[hidden] { display: none !important; }

* { box-sizing: border-box; }

html {
  /* Isian tidak boleh memicu zoom otomatis di iOS. Pemicunya ukuran huruf
     isian di bawah 16px, dan akibatnya halaman melompat setiap kali petugas
     menyentuh kotak isian. Lihat juga aturan input di bawah. */
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  min-height: 100dvh;
  background: var(--kertas);
  color: var(--tinta);
  font: 15px/1.55 var(--sans);
  -webkit-font-smoothing: antialiased;
  /* Tidak ada satu pun hal di dashboard ini yang layak digulung ke samping.
     Tabel lebar berubah bentuk menjadi kartu di layar kecil, bukan dipaksa
     muat lalu digeser. */
  overflow-x: hidden;
}

::selection { background: var(--limau); color: var(--tinta); }

h1, h2, h3 { font-family: var(--tampil); font-weight: 600; letter-spacing: -0.01em; }
h1 { font-size: 1.3rem; margin: 0 0 6px; }
h2 { font-size: 1.05rem; margin: 0; }
h3 { font-size: .92rem; margin: 0 0 8px; }

p { margin: 0 0 12px; }
p:last-child { margin-bottom: 0; }

code, .mono { font-family: var(--mono); font-size: .88em; }
code {
  background: var(--kepala);
  border: 1px solid var(--garis-lembut);
  border-radius: var(--lengkung-mini);
  padding: 1px 5px;
  overflow-wrap: anywhere;
}

/* Tautan sewarna teks. Yang membedakan warna di halaman ini adalah KEADAAN
   sesuatu, bukan kemampuannya diklik. */
a { color: var(--tinta); font-weight: 600; text-underline-offset: 3px; }

.sunyi { color: var(--senyap); }
.kecil { font-size: .85rem; line-height: 1.5; }
.tebal { font-weight: 600; }
.galat {
  color: var(--buruk-tinta);
  background: var(--buruk-latar);
  border: 2px solid var(--buruk);
  border-radius: var(--lengkung-kecil);
  padding: 10px 12px;
  margin: 12px 0 0;
  font-size: .9rem;
}

/* ==========================================================================
   2. Kerangka halaman
   ========================================================================== */

.bilah {
  position: sticky;
  top: 0;
  z-index: 30;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 16px;
  /* Ponsel berponi memakan bagian atas layar. Tanpa ini, judul dashboard
     tertutup takik kamera pada telepon yang dipegang mendatar. */
  padding-top: max(10px, env(safe-area-inset-top));
  padding-left: max(16px, env(safe-area-inset-left));
  padding-right: max(16px, env(safe-area-inset-right));
  background: var(--kertas);
  border-bottom: 2px solid var(--tinta);
}

.merek { display: flex; align-items: center; gap: 10px; min-width: 0; }

/* Ubin merek: kotak tinta dengan titik limau. Satu-satunya tempat limau muncul
   tanpa menandakan keadaan, dan justru karena itu ia kecil. */
.merek-ubin {
  flex: none;
  width: 30px;
  height: 30px;
  border: 2px solid var(--tinta);
  border-radius: var(--lengkung-kecil);
  background: var(--utama);
  display: grid;
  place-items: center;
}
.merek-ubin::after {
  content: "";
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--limau);
}

.merek-teks { min-width: 0; }
.merek-nama {
  font: 600 14px/1.2 var(--tampil);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.merek-ket {
  font: 400 11px/1.3 var(--mono);
  color: var(--senyap);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.bilah-aksi { margin-left: auto; display: flex; gap: 8px; flex: none; }

.isi {
  width: 100%;
  max-width: 1100px;
  margin: 0 auto;
  padding: 16px;
  padding-left: max(16px, env(safe-area-inset-left));
  padding-right: max(16px, env(safe-area-inset-right));
  /* Ruang di bawah supaya kartu terakhir tidak menempel di bibir layar, dan
     supaya bilah bawah peramban ponsel tidak menutupi tombol terakhir. */
  padding-bottom: calc(48px + env(safe-area-inset-bottom));
  display: grid;
  gap: 16px;
}

/* Layar masuk berdiri sendiri, di tengah, tanpa bilah apa pun.
 *
 * Jalurnya diberi lebar sendiri, BUKAN place-items: center.
 *
 * Dengan place-items: center, lebar jalur grid ditentukan oleh isinya, lalu
 * width: 100% pada kartunya melingkar kembali ke lebar itu. Hasilnya kartu
 * masuk yang menciut ke lebar kalimat terpanjang di dalamnya - sekitar 180px
 * di telepon - dan terlihat seperti halaman yang gagal dimuat. */
.tengah {
  min-height: 100dvh;
  display: grid;
  grid-template-columns: minmax(0, 400px);
  justify-content: center;
  align-content: center;
  padding: 24px 16px;
  padding-bottom: calc(24px + env(safe-area-inset-bottom));
}
.tengah .kartu { width: 100%; }

/* ==========================================================================
   3. Kartu
   ========================================================================== */

.kartu {
  background: var(--permukaan);
  border: 2px solid var(--tinta);
  border-radius: var(--lengkung);
  box-shadow: var(--bayang);
  overflow: hidden;
}

.kartu-kepala {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  padding: 13px 16px;
  background: var(--kepala);
  border-bottom: 2px solid var(--tinta);
}
.kartu-kepala .sunyi { width: 100%; font-size: .85rem; }
.kartu-badan { padding: 16px; }
.kartu-badan > :first-child { margin-top: 0; }

/* Kartu peringatan. Warnanya hanya di kepala; badannya tetap kertas putih
   supaya teks panjang di dalamnya tetap enak dibaca. */
.kartu.bahaya { border-color: var(--buruk); box-shadow: 5px 5px 0 0 var(--buruk); }
.kartu.bahaya .kartu-kepala {
  background: var(--buruk-latar);
  border-bottom-color: var(--buruk);
  color: var(--buruk-tinta);
}

.kartu.awas { border-color: var(--awas-tinta); box-shadow: 5px 5px 0 0 var(--awas-tinta); }
.kartu.awas .kartu-kepala {
  background: var(--awas-latar);
  border-bottom-color: var(--awas-tinta);
  color: var(--awas-tinta);
}

/* ==========================================================================
   4. Tombol
   ========================================================================== */

button, .btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: var(--sentuh);
  font: 600 14px/1.2 var(--tampil);
  color: var(--tinta);
  background: var(--permukaan);
  border: 2px solid var(--tinta);
  border-radius: var(--lengkung-kecil);
  box-shadow: var(--bayang-kecil);
  padding: 10px 16px;
  cursor: pointer;
  text-decoration: none;
  transition: transform .12s ease, box-shadow .12s ease, background .12s ease;
}

/* Terangkat saat ditunjuk, tertekan penuh saat disentuh. Yang membuatnya terasa
   seperti tombol fisik bukan bayangannya, melainkan bayangan yang HILANG saat
   ditekan - seolah tombolnya benar-benar turun menyentuh kertas. */
@media (hover: hover) {
  button:hover, .btn:hover { transform: translate(-1px, -1px); box-shadow: var(--bayang-naik); }
}
button:active, .btn:active { transform: translate(2px, 2px); box-shadow: 0 0 0 0 var(--tinta); }

button.utama { background: var(--utama); color: var(--kertas); }
button.limau { background: var(--limau); color: var(--tinta); }
button.bahaya { background: var(--buruk-latar); color: var(--buruk-tinta); border-color: var(--buruk); }
button.datar { background: var(--permukaan); }

button.mungil {
  min-height: 38px;
  padding: 7px 12px;
  font-size: 12.5px;
  border-radius: 7px;
}

button.lebar, .btn.lebar { width: 100%; }

button:disabled {
  opacity: .45;
  cursor: not-allowed;
  transform: none;
  box-shadow: var(--bayang-kecil);
}

button:focus-visible, a:focus-visible, summary:focus-visible {
  outline: 3px solid var(--limau);
  outline-offset: 2px;
}

/* ==========================================================================
   5. Isian
   ========================================================================== */

label {
  display: block;
  font: 600 12px/1.3 var(--tampil);
  letter-spacing: .03em;
  text-transform: uppercase;
  color: var(--senyap);
  margin: 0 0 6px;
}

input, select, textarea {
  width: 100%;
  /* 16px, bukan 14px, DAN ITU BUKAN SELERA.
     Safari di iOS memperbesar seluruh halaman begitu isian yang disentuh
     berukuran huruf di bawah 16px, lalu tidak mengecilkannya kembali. Petugas
     yang mengisi formulir pendaftaran di telepon akan terlempar keluar dari
     tata letaknya di isian pertama. */
  font: 400 16px/1.4 var(--sans);
  color: var(--tinta);
  background: var(--permukaan);
  border: 2px solid var(--tinta);
  border-radius: var(--lengkung-kecil);
  padding: 11px 13px;
  min-height: var(--sentuh);
}
textarea { min-height: 96px; resize: vertical; font-family: var(--mono); font-size: 13px; }
input::placeholder, textarea::placeholder { color: #9A9DA8; }

/* Cincin limau, bukan border yang menebal: border sudah 2px, dan menebalkannya
   lagi menggeser seluruh baris satu piksel setiap kali difokus. */
input:focus, select:focus, textarea:focus {
  outline: none;
  box-shadow: 0 0 0 3px var(--limau);
}

input[type="checkbox"] {
  width: 22px;
  height: 22px;
  min-height: 0;
  accent-color: var(--limau-tinta);
}

.isian { margin: 0 0 14px; }
.isian:last-of-type { margin-bottom: 0; }
.isian .kecil { margin-top: 6px; }

/* Satu kolom di telepon. Selalu. Formulir dua kolom di layar selebar 360px
   menghasilkan isian selebar 150px, dan nama Polda tidak muat di sana. */
.baris-isian { display: grid; gap: 14px; }

/* Kotak centang DAN labelnya dijadikan satu bidang yang terlihat bisa diketuk.
 *
 * Kotak centangnya sendiri cuma 22px, jauh di bawah 44px yang bisa ditekan jari
 * tanpa melihat. Labelnya memang sudah menjadi target lewat atribut for, tetapi
 * sebelum diberi bingkai ia tidak terlihat seperti bagian dari kendali yang
 * sama - jadi orang tetap membidik kotak kecilnya. */
.saklar {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: var(--sentuh);
  padding: 10px 13px;
  border: 2px solid var(--tinta);
  border-radius: var(--lengkung-kecil);
  background: var(--kepala);
  cursor: pointer;
}
.saklar label {
  margin: 0;
  flex: 1;
  cursor: pointer;
  text-transform: none;
  letter-spacing: 0;
  font-family: var(--sans);
  font-size: 14px;
  line-height: 1.4;
  color: var(--tinta);
}
.saklar:focus-within { box-shadow: 0 0 0 3px var(--limau); }

/* ==========================================================================
   6. Angka besar
   ========================================================================== */

/* Yang harus terbaca sekilas dari seberang meja diberi ubin sendiri. Di layar
   kecil dua per baris; kuota dan sisa hari adalah dua hal yang paling sering
   ditanyakan orang, dan keduanya angka. */
.angka-petak {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
  margin: 0 0 16px;
}
.angka {
  border: 2px solid var(--tinta);
  border-radius: var(--lengkung-kecil);
  background: var(--kepala);
  padding: 11px 13px;
  min-width: 0;
}
.angka-nilai {
  font: 600 24px/1.1 var(--tampil);
  font-variant-numeric: tabular-nums;
  overflow-wrap: anywhere;
}
.angka-nama {
  font: 600 10.5px/1.3 var(--tampil);
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--senyap);
  margin-top: 4px;
}
.angka.baik { background: var(--baik-latar); }
.angka.awas { background: var(--awas-latar); }
.angka.buruk { background: var(--buruk-latar); color: var(--buruk-tinta); }

/* ==========================================================================
   7. Pil keadaan
   ========================================================================== */

.pil {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font: 600 11.5px/1 var(--tampil);
  letter-spacing: .02em;
  text-transform: uppercase;
  border: 2px solid var(--tinta);
  border-radius: 999px;
  padding: 5px 10px;
  background: var(--permukaan);
  white-space: nowrap;
}
.pil::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: currentColor;
  flex: none;
}
.pil.baik { background: var(--baik-latar); }
.pil.awas { background: var(--awas-latar); color: var(--awas-tinta); }
.pil.buruk { background: var(--buruk-latar); color: var(--buruk-tinta); border-color: var(--buruk); }
.pil.mati { background: var(--kepala); color: var(--senyap); }

/* ==========================================================================
   8. Rincian
   ========================================================================== */

.rincian { margin: 0; display: grid; gap: 0; }
.rincian > div {
  display: grid;
  gap: 2px;
  padding: 11px 0;
  border-bottom: 1px solid var(--garis-lembut);
}
.rincian > div:last-child { border-bottom: 0; padding-bottom: 0; }
.rincian > div:first-child { padding-top: 0; }
.rincian dt {
  font: 600 11px/1.3 var(--tampil);
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--senyap);
}
.rincian dd { margin: 0; overflow-wrap: anywhere; }

/* ==========================================================================
   9. Tabel yang berubah menjadi kartu
   ========================================================================== */

/* Di telepon, tabel BUKAN tabel.
 *
 * Tabel tujuh kolom di layar 360px cuma punya dua jalan keluar: digulung ke
 * samping, atau diperkecil sampai tidak terbaca. Keduanya buruk, dan yang
 * pertama lebih buruk karena kolom keadaan - satu-satunya yang benar-benar
 * dicari orang - justru yang paling kanan dan tidak pernah terlihat.
 *
 * Jadi tiap baris menjadi kartunya sendiri, dan nama kolomnya ikut turun
 * sebagai label di sebelah kiri tiap nilai lewat data-label. */
.tabel { width: 100%; border-collapse: collapse; }
.tabel th, .tabel td { text-align: left; }
.tabel th {
  font: 600 10.5px/1.3 var(--tampil);
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--senyap);
  padding: 0 10px 8px;
  border-bottom: 2px solid var(--tinta);
}
.tabel tr.perhatian td { background: var(--awas-latar); }
.tabel tr.mati td { opacity: .55; }

.tabel thead {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
.tabel, .tabel tbody, .tabel tr, .tabel td { display: block; width: 100%; }
.tabel tr {
  border: 2px solid var(--tinta);
  border-radius: var(--lengkung-kecil);
  box-shadow: var(--bayang-kecil);
  background: var(--permukaan);
  margin: 0 0 12px;
  padding: 3px 0;
}
.tabel tbody tr:last-child { margin-bottom: 0; }
.tabel td {
  display: grid;
  grid-template-columns: minmax(84px, 34%) minmax(0, 1fr);
  gap: 12px;
  align-items: baseline;
  padding: 10px 13px;
  border-bottom: 1px solid var(--garis-lembut);
  overflow-wrap: anywhere;
}
.tabel td::before {
  content: attr(data-label);
  font: 600 10.5px/1.4 var(--tampil);
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--senyap);
}
.tabel td.aksi::before, .tabel td:not([data-label])::before { content: none; }
.tabel td.aksi, .tabel td:not([data-label]) { grid-template-columns: minmax(0, 1fr); }
.tabel tbody tr td:last-child { border-bottom: 0; }
.tabel td.aksi { padding-top: 12px; padding-bottom: 8px; display: flex; flex-wrap: wrap; gap: 8px; }
.tabel td.aksi button { margin: 0; flex: 1 1 auto; }

.kosong { color: var(--senyap); font-size: .9rem; padding: 6px 0; }

/* Angka berpasangan seperti "0 / 50" tidak boleh putus di tengah garis
   miringnya: yang terbaca kemudian adalah dua angka tanpa hubungan. */
.tanpa-putus { white-space: nowrap; }

/* ==========================================================================
   10. Lipatan
   ========================================================================== */

details.lipat { border-top: 2px solid var(--garis-lembut); margin-top: 16px; padding-top: 4px; }
details.lipat > summary {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: var(--sentuh);
  font: 600 13.5px/1.2 var(--tampil);
  cursor: pointer;
  list-style: none;
  padding: 10px 0;
}
details.lipat > summary::-webkit-details-marker { display: none; }
details.lipat > summary::before {
  content: "+";
  font: 600 16px/1 var(--mono);
  width: 22px;
  height: 22px;
  border: 2px solid var(--tinta);
  border-radius: var(--lengkung-mini);
  display: grid;
  place-items: center;
  flex: none;
}
details.lipat[open] > summary::before { content: "−"; background: var(--limau); }

/* ==========================================================================
   11. Kotak dialog
   ========================================================================== */

/* Di telepon ia lembar yang naik dari bawah; di layar lebar ia kotak di tengah.
 *
 * Keduanya menggantikan window.prompt, window.confirm, dan window.alert yang
 * dipakai sebelumnya. Tiga hal itu ditinggalkan bukan karena jelek: sebagian
 * peramban dan hampir semua tampilan tertanam MEMBLOKIRNYA diam-diam, jadi
 * tombolnya tampak tidak melakukan apa-apa. Sudah terjadi saat menguji layar
 * pusat - tombol Kuota ditekan dan tidak ada yang terjadi sama sekali. */
dialog {
  border: 2px solid var(--tinta);
  border-radius: var(--lengkung) var(--lengkung) 0 0;
  box-shadow: var(--bayang);
  background: var(--permukaan);
  color: var(--tinta);
  padding: 0;
  width: 100%;
  max-width: 100%;
  max-height: 92dvh;
  margin: auto auto 0;
  overflow: hidden;
}
dialog::backdrop { background: rgba(21, 23, 28, .45); }

.dlg-kepala {
  padding: 15px 18px;
  background: var(--kepala);
  border-bottom: 2px solid var(--tinta);
}
.dlg-kepala h2 { margin: 0; }
.dlg-kepala .sunyi { margin: 5px 0 0; font-size: .87rem; }
.dlg-badan { padding: 16px 18px; overflow-y: auto; max-height: 52dvh; }
.dlg-badan > :first-child { margin-top: 0; }
.dlg-kaki {
  display: grid;
  gap: 10px;
  padding: 14px 18px;
  padding-bottom: calc(14px + env(safe-area-inset-bottom));
  background: var(--kepala);
  border-top: 2px solid var(--tinta);
}

/* Di layar kecil tombol paling bawah yang paling mudah dijangkau ibu jari, dan
   yang paling mudah dijangkau harus yang paling aman. Jadi Batal digambar di
   bawah, walaupun di dalam kode ia datang lebih dulu. */
.dlg-kaki .batal { order: 2; }

/* ==========================================================================
   12. Roti panggang
   ========================================================================== */

/* Pesan sekilas yang menggantikan window.alert. Muncul di bawah supaya tidak
   menutupi apa pun yang sedang dibaca, dan hilang sendiri. */
.roti-wadah {
  position: fixed;
  left: 50%;
  bottom: calc(18px + env(safe-area-inset-bottom));
  transform: translateX(-50%);
  z-index: 60;
  display: grid;
  gap: 8px;
  width: min(440px, calc(100% - 32px));
  pointer-events: none;
}
.roti {
  border: 2px solid var(--tinta);
  border-radius: var(--lengkung-kecil);
  box-shadow: var(--bayang-naik);
  background: var(--permukaan);
  padding: 12px 14px;
  font-size: .92rem;
  animation: roti-masuk .18s ease-out;
}
.roti.baik { background: var(--baik-latar); }
.roti.buruk { background: var(--buruk-latar); color: var(--buruk-tinta); border-color: var(--buruk); }
@keyframes roti-masuk { from { opacity: 0; transform: translateY(10px); } }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

/* ==========================================================================
   13. Papan operasi
   ========================================================================== */

/* Satu grup = satu kotak; sub-grup bersarang di dalamnya, menjorok sedikit.
   Unit yang hadir di grup itu berbaris di bawah kepalanya. Di telepon tombol
   tiap unit menumpuk ke bawah dan selebar kotaknya; di layar lebar mereka
   berjajar di kanan. */
.grup {
  border: 2px solid var(--tinta);
  border-radius: var(--lengkung-kecil);
  background: var(--permukaan);
  margin: 0 0 10px;
  overflow: hidden;
}
.grup .grup { margin: 8px 0 8px 10px; border-left-width: 4px; }
.grup-kepala {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  padding: 9px 12px;
  background: var(--kepala);
  border-bottom: 1px solid var(--garis-lembut);
}
.grup-nama { font: 600 14px/1.3 var(--tampil); overflow-wrap: anywhere; }
.grup-jumlah { font: 500 12px/1 var(--mono); color: var(--senyap); }
.grup-aksi { display: flex; gap: 6px; flex-wrap: wrap; margin-left: auto; }
.grup-kosong { padding: 8px 12px; color: var(--senyap); font-size: .85rem; }

.unit {
  display: grid;
  gap: 8px;
  padding: 10px 12px;
  border-bottom: 1px solid var(--garis-lembut);
}
.unit:last-child { border-bottom: 0; }
.unit.asing { background: var(--awas-latar); }
.unit-nama { font: 600 14px/1.3 var(--mono); overflow-wrap: anywhere; }
.unit-ket { color: var(--senyap); font-size: .82rem; }
.unit-lencana { display: flex; flex-wrap: wrap; gap: 6px; }
.unit-aksi { display: flex; flex-wrap: wrap; gap: 6px; }
.unit-aksi button { flex: 1 1 auto; }

/* Lencana kecil di samping nama: keadaan, bukan hiasan. */
.lencana {
  display: inline-flex;
  align-items: center;
  font: 600 10.5px/1 var(--tampil);
  letter-spacing: .03em;
  text-transform: uppercase;
  border: 1.5px solid var(--tinta);
  border-radius: 999px;
  padding: 4px 8px;
  background: var(--permukaan);
  white-space: nowrap;
}
.lencana.baik { background: var(--baik-latar); }
.lencana.awas { background: var(--awas-latar); color: var(--awas-tinta); border-color: var(--awas-tinta); }
.lencana.buruk { background: var(--buruk-latar); color: var(--buruk-tinta); border-color: var(--buruk); }
.lencana.mati { background: var(--kepala); color: var(--senyap); }

/* Daftar centang di dalam kotak dialog: grup yang boleh dimasuki, misalnya. */
.daftar-centang { display: grid; gap: 8px; }
.daftar-centang .saklar { min-height: 40px; padding: 7px 12px; }

/* ==========================================================================
   13b. Kerangka konsol: menu samping + halaman
   ========================================================================== */

/* Dipakai dashboard Polda, yang bentuknya MENERUSKAN konsol dispatch lama:
   menu gelap di kiri, satu halaman per urusan, bilah atas dengan keadaan
   server dan jam. Petugas sudah hafal letaknya bertahun-tahun; yang berubah
   hanya isinya. Di telepon menu menjadi laci, dan bilah tab mendatar di bawah
   bilah atas membuat tiap halaman tetap satu ketukan jauhnya. */
.kerangka { display: grid; grid-template-columns: minmax(0, 1fr); min-height: 100dvh; }

.sisi {
  background: var(--tinta);
  color: var(--kertas);
  padding: 18px 14px;
  padding-top: max(18px, env(safe-area-inset-top));
  display: flex;
  flex-direction: column;
  gap: 3px;
  /* Laci di telepon. */
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  width: min(280px, 86vw);
  z-index: 40;
  overflow-y: auto;
  overscroll-behavior: contain;
  transform: translateX(-102%);
  transition: transform .18s ease;
  border-right: 2px solid var(--tinta);
}
.sisi.buka { transform: none; }
.tirai { position: fixed; inset: 0; background: rgba(21, 23, 28, .45); z-index: 39; }
.tirai[hidden] { display: none; }

.sisi .merek { padding: 0 6px 16px; }
.sisi .merek-ubin { background: var(--limau); border-color: var(--kertas); }
.sisi .merek-ubin::after { background: var(--tinta); }
.sisi .merek-nama { color: var(--kertas); font-size: 16px; }
.sisi .merek-nama span { color: var(--limau); }
.sisi .merek-ket { color: #9A9DA8; letter-spacing: .12em; }

.sisi .pil-server {
  display: flex;
  align-items: center;
  gap: 8px;
  background: #1E2027;
  border: 1.5px solid #3A3D46;
  border-radius: 9px;
  padding: 8px 10px;
  margin: 0 2px 14px;
  font: 600 11px/1 var(--mono);
  letter-spacing: .06em;
  text-transform: uppercase;
}
.sisi .pil-server::before { content: ""; width: 8px; height: 8px; border-radius: 50%; background: #6B7079; flex: none; }
.sisi .pil-server.baik::before { background: var(--limau); }
.sisi .pil-server.buruk::before { background: var(--buruk); }

.nav-grup {
  font: 400 10px/1 var(--mono);
  letter-spacing: .16em;
  text-transform: uppercase;
  color: #7C808C;
  margin: 16px 0 8px 12px;
}
.nav-item {
  display: flex;
  align-items: center;
  /* Tombol umum merapatkan isinya ke tengah; di menu tiap butir harus
     berjajar rata kiri, kalau tidak nama halamannya berdiri di posisi yang
     berbeda-beda dan menu terlihat berantakan. */
  justify-content: flex-start;
  gap: 10px;
  width: 100%;
  min-height: 40px;
  transition: none;
  background: transparent;
  border: 0;
  border-radius: 9px;
  box-shadow: none;
  padding: 9px 12px;
  font: 600 13.5px/1.2 var(--tampil);
  color: var(--kertas);
  text-align: left;
}
.nav-item:hover, .nav-item:active, .nav-item:focus-visible { background: #22252D; transform: none; box-shadow: none; outline-offset: -3px; }
.nav-item.aktif { background: var(--limau); color: var(--tinta); }
/* Penanda persegi kecil: penunjuk posisi yang tidak bersaing dengan namanya. */
.nav-item::before { content: ""; flex: none; width: 7px; height: 7px; border-radius: 2px; background: #4A4E58; }
.nav-item.aktif::before { background: var(--tinta); }
.nav-item .hitung {
  margin-left: auto;
  font: 600 11px/1.4 var(--mono);
  color: #9A9DA8;
  padding: 1px 7px;
  border-radius: 6px;
  background: #22252D;
  font-variant-numeric: tabular-nums;
}
.nav-item .hitung:empty { display: none; }
.nav-item.aktif .hitung { color: var(--tinta); background: rgba(21, 23, 28, .16); }
/* Angka merah hanya kalau memang ada yang perlu disentuh. */
.nav-item .hitung.alarm, .nav-item.aktif .hitung.alarm { background: var(--buruk); color: #fff; border-radius: 999px; padding: 1px 8px; }

.nav-kaki {
  margin-top: auto;
  position: sticky;
  bottom: 0;
  background: var(--tinta);
  padding: 14px 12px 2px;
  border-top: 1.5px solid #2B2E36;
  font: 400 11px/1.7 var(--mono);
  color: #9A9DA8;
  overflow-wrap: anywhere;
}
.nav-kaki b { color: var(--kertas); font-weight: 400; }

/* Bilah atas: keadaan server di kiri, jam dan tombol di kanan. Di telepon
   keterangan server disembunyikan - ia tetap ada di kaki laci menu - dan
   bilah tab turun ke baris kedua. */
.kerangka .bilah { flex-wrap: wrap; }
.bilah .meta { font: 400 12.5px/1.4 var(--mono); color: var(--senyap); }
.bilah .meta b { color: var(--tinta); font-weight: 600; }
.bilah .jam {
  font: 600 14px/1 var(--mono);
  font-variant-numeric: tabular-nums;
  border: 2px solid var(--tinta);
  border-radius: 9px;
  padding: 9px 11px;
  box-shadow: var(--bayang-kecil);
  background: var(--permukaan);
}
.bilah .hp-sembunyi { display: none; }
.bilah .galat-server { color: var(--buruk-tinta); font-weight: 600; font-size: 12.5px; }
.bilah .galat-server:empty { display: none; }

/* Bilah tab mendatar, hanya di telepon: isinya sama dengan menu kiri. */
.tab-bar {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  scrollbar-width: none;
  flex-basis: 100%;
  padding-bottom: 2px;
}
.tab-bar::-webkit-scrollbar { display: none; }
.tab-bar .tab {
  flex: none;
  min-height: 36px;
  padding: 6px 12px;
  border-radius: 999px;
  font-size: 12.5px;
  box-shadow: none;
}
.tab-bar .tab.aktif { background: var(--limau); }
.tab-bar .tab .hitung { font: 600 11px/1 var(--mono); padding: 2px 6px; border-radius: 999px; background: var(--kepala); }
.tab-bar .tab .hitung:empty { display: none; }
.tab-bar .tab .hitung.alarm { background: var(--buruk); color: #fff; }

.halaman { display: grid; gap: 16px; min-width: 0; }
.judul-halaman { display: flex; align-items: baseline; flex-wrap: wrap; gap: 6px 14px; }
.judul-halaman h2 { font: 700 24px/1.1 var(--tampil); letter-spacing: -.01em; }
.judul-halaman h2::before {
  content: attr(data-grup);
  display: block;
  font: 400 10.5px/1 var(--mono);
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--senyap);
  margin-bottom: 7px;
}
.judul-halaman p { margin: 0; flex: 1 1 42ch; color: var(--senyap); font-size: 13.5px; max-width: 78ch; }

.dua-kolom { display: grid; gap: 16px; align-items: start; grid-template-columns: minmax(0, 1fr); }

/* Kotak angka besar papan operasi. Kotak pertama limau: berapa radio yang
   hidup adalah pertanyaan pertama orang yang baru duduk di meja ini. */
.stat-petak { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
.stat {
  background: var(--permukaan);
  border: 2px solid var(--tinta);
  border-radius: var(--lengkung);
  box-shadow: var(--bayang);
  padding: 14px 15px;
  min-width: 0;
}
.stat:first-child { background: var(--limau); }
.stat .k { font: 600 10.5px/1.3 var(--mono); letter-spacing: .12em; text-transform: uppercase; color: var(--senyap); }
.stat:first-child .k, .stat:first-child .s { color: var(--limau-tinta); }
.stat .v { font: 700 34px/1 var(--tampil); margin: 8px 0 4px; font-variant-numeric: tabular-nums; }
.stat .s { font-size: 12.5px; color: var(--senyap); }
.stat.alarm .k, .stat.alarm .v { color: var(--buruk-tinta); }

/* Daftar "perlu ditangani" / "sedang offline". */
ul.perhatian { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
ul.perhatian li {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px 10px;
  padding: 9px 12px;
  background: var(--permukaan);
  border: 2px solid var(--tinta);
  border-radius: var(--lengkung-kecil);
  box-shadow: var(--bayang-kecil);
}
ul.perhatian li.parah { background: var(--buruk-latar); }
ul.perhatian li.judul {
  background: none;
  border: 0;
  box-shadow: none;
  padding: 10px 0 2px;
  font: 700 12px/1.3 var(--tampil);
  text-transform: uppercase;
  letter-spacing: .06em;
}
ul.perhatian li.judul.sepi { color: var(--senyap); }
ul.perhatian li.judul .sunyi { font-weight: 400; text-transform: none; letter-spacing: 0; }
ul.perhatian .n { font-weight: 700; font-family: var(--mono); font-size: 13px; }
ul.perhatian .ket { color: var(--senyap); font-size: 12px; margin-left: auto; }
ul.perhatian .titik { width: 9px; height: 9px; border-radius: 50%; background: #9A9DA8; flex: none; }
ul.perhatian .titik.baik { background: var(--limau); }
ul.perhatian .titik.buruk { background: var(--buruk); }

/* ==========================================================================
   14. Layar lebar
   ========================================================================== */

@media (min-width: 560px) {
  /* Empat, bukan auto-fit.
     Kedua dashboard memang menampilkan empat angka, dan auto-fit di layar lebar
     membuat tujuh jalur untuk empat ubin - empat ubin sempit menggerombol di
     kiri dengan sepertiga kartu dibiarkan kosong di kanannya. */
  .angka-petak { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .dlg-kaki { grid-auto-flow: column; justify-content: end; }
  .dlg-kaki .batal { order: 0; }
  .dlg-kaki button { min-width: 116px; }
}

@media (min-width: 760px) {
  .bilah { padding: 12px 24px; }
  .merek-nama { font-size: 15px; }
  .isi { padding: 24px; gap: 20px; }
  .kartu-kepala, .kartu-badan { padding-left: 20px; padding-right: 20px; }

  .baris-isian { grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); align-items: end; }
  .baris-isian .selebar { grid-column: 1 / -1; }
  .baris-isian button { min-width: 120px; }

  /* Tabel kembali menjadi tabel. */
  .tabel thead { position: static; width: auto; height: auto; clip-path: none; }
  .tabel { display: table; }
  .tabel tbody { display: table-row-group; }
  .tabel tr {
    display: table-row;
    border: 0;
    border-radius: 0;
    box-shadow: none;
    background: transparent;
    margin: 0;
    padding: 0;
  }
  .tabel td {
    display: table-cell;
    padding: 12px 10px;
    border-bottom: 1px solid var(--garis-lembut);
    vertical-align: top;
    /* anywhere HANYA untuk mode kartu di telepon.
       Ia tidak cuma memutus kata panjang; ia juga mengecilkan lebar minimum
       sel menjadi satu huruf, dan algoritma tabel mempercayainya. Akibatnya
       kolom Nama tergencet sampai "Polda Kalimantan Selatan" turun satu huruf
       per baris sementara sepertiga tabel dibiarkan kosong. break-word memutus
       kata yang sama panjangnya tanpa berbohong soal lebar minimumnya. */
    overflow-wrap: break-word;
  }
  .tabel td::before { content: none; }
  .tabel tbody tr:last-child td { border-bottom: 0; }
  /* Lebih khusus daripada .tabel td, jadi ia harus dikembalikan sendiri -
     kalau tidak, sel tindakan tetap flex dan tombolnya menumpuk ke bawah. */
  /* Boleh melipat ke baris kedua: baris akun punya delapan tombol, dan
     delapan tombol dalam satu baris memakan separuh lebar tabel. */
  .tabel td.aksi { display: table-cell; text-align: right; width: 1%; min-width: 300px; }
  .tabel td.aksi button { margin: 0 0 6px 6px; flex: none; }

  .unit { grid-template-columns: minmax(0, 1fr) auto; align-items: center; }
  .unit-aksi { justify-content: flex-end; }
  .unit-aksi button { flex: none; }
  .grup .grup { margin-left: 16px; }

  /* Kolom yang isinya pendek tidak perlu ikut melebar. Tanpa ini, lebar dibagi
     rata dan kolom Nama - satu-satunya yang isinya kalimat - kebagian paling
     sedikit. */
  .tabel th:first-child, .tabel td:first-child { width: 1%; white-space: nowrap; }

  .rincian { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 24px; }
  .rincian > div:nth-child(2) { padding-top: 0; }

  dialog {
    width: min(560px, calc(100% - 48px));
    border-radius: var(--lengkung);
    margin: auto;
  }
  .dlg-badan { max-height: 60dvh; }
}

@media (min-width: 980px) {
  .rincian { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .rincian > div:nth-child(3) { padding-top: 0; }

  /* Menu kiri selalu terlihat; laci, tirai, dan bilah tab tidak ada. */
  .kerangka { grid-template-columns: 250px minmax(0, 1fr); }
  .sisi { position: sticky; top: 0; height: 100dvh; width: auto; transform: none; transition: none; z-index: 1; }
  .tirai { display: none !important; }
  .tab-bar, #tombol-menu { display: none; }
  .bilah .hp-sembunyi { display: inline; }
  .stat-petak { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .stat { padding: 18px 20px; }
  .stat .v { font-size: 44px; margin: 10px 0 6px; }
  .judul-halaman h2 { font-size: 28px; }
  .halaman { gap: 20px; }
}

@media (min-width: 1180px) {
  .dua-kolom { grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr); gap: 20px; }
}
