/* =============================================================================
 *  perjadin.css — kelas yang TIDAK disediakan Tabler
 * =============================================================================
 *  Dipindahkan dari jembatan kontrak.css, hanya yang benar-benar masih dipakai:
 *  chip cakupan/tahun di topbar, judul di navbar, keadaan kosong, daftar kv,
 *  pohon unit organisasi, dan rantai audit.
 *
 *  Kelas yang sudah ada di Tabler (card, card-table, subheader, w-1,
 *  table-responsive, empty-*) SENGAJA tidak ikut — memakai milik tema berarti
 *  ia ikut berubah saat temanya diperbarui.
 *
 *  Berkas ini menyusut, bukan tumbuh: setiap halaman yang ditulis ulang dengan
 *  komponen Tabler asli membuang sebagian isinya.
 * =============================================================================
 */

/* --- Keadaan kosong ------------------------------------------------------
 * Muncul saat daftar tidak berisi apa pun ATAU saat pencarian tidak menemukan
 * hasil. Keduanya memakai blok yang sama dengan teks berbeda — perbedaannya
 * ada di template, bukan di sini.
 */
.kosong {
  padding: 3rem 1rem;
  text-align: center;
}

.kosong-header {
  margin-bottom: 1rem;
  font-size: 2.5rem;
  font-weight: 600;
  line-height: 1;
  color: var(--bs-secondary-color);
}

.kosong-title {
  margin-bottom: 0.5rem;
  font-size: 1.125rem;
  font-weight: 600;
}

.kosong-subtitle {
  margin-bottom: 0;
  color: var(--bs-secondary-color);
}

.kosong-action {
  margin-top: 1.5rem;
}

/* --- Judul halaman di topbar --------------------------------------------- */
.navbar-judul-utama {
  font-size: 1rem;
  font-weight: 600;
  line-height: 1.25;
  color: var(--bs-body-color);
}

.navbar-judul-sub {
  font-size: 0.75rem;
  line-height: 1.3;
  color: var(--bs-secondary-color);
}

/* --- Inisial pengguna di navbar ------------------------------------------ */
.avatar-inisial {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  border-radius: 50%;
  background: var(--bs-primary);
  color: #fff;
  font-size: 0.85rem;
  font-weight: 600;
}

/* --- Chip tahun anggaran -------------------------------------------------
 * Penyaring periode global (§5.5). Ia SELALU tampil karena penyaring yang
 * tidak terlihat adalah penyaring yang membuat orang bertanya "kenapa kontrak
 * saya hilang". Varian -tombol hanya dipasang bila memang ada tahun lain yang
 * bisa dipilih.
 */
.chip-tahun {
  display: inline-flex;
  flex-direction: column;
  padding: 0.25rem 0.75rem;
  border: 1px solid var(--bs-border-color);
  border-radius: 0.5rem;
  background: var(--bs-tertiary-bg);
  line-height: 1.15;
  text-decoration: none;
}

.chip-tahun-label {
  font-size: 0.625rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--bs-secondary-color);
}

.chip-tahun-nilai {
  font-size: 0.95rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--bs-body-color);
}

a.chip-tahun-tombol:hover {
  border-color: var(--bs-primary);
  background: var(--bs-primary-bg-subtle);
}

/* --- Chip cakupan unit ---------------------------------------------------
 * Bentuknya memakai kelas chip-tahun di atas — sengaja, keduanya penyaring
 * global yang mengunci sesi dan harus terlihat sama. Yang ditimpa hanya
 * nilainya: nama unit adalah teks panjang, bukan angka empat digit, jadi
 * tabular-nums tidak berlaku dan panjangnya harus dipotong supaya nama sepanjang
 * "Dinas PU dan Penataan Ruang" tidak mendorong menu akun keluar dari layar.
 */
.chip-cakupan-nilai {
  max-width: 13rem;
  overflow: hidden;
  font-variant-numeric: normal;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* --- Pita alur lima langkah ----------------------------------------------
 * Sistem ini adalah urutan lima langkah, dan pengguna baru perlu melihat
 * urutan itu sebelum melihat angka. Diambil dari mockup, tapi ditulis dengan
 * komponen Bootstrap alih-alih warna yang dipatok.
 */
.pita-alur {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-bottom: 1.5rem;
}

.pita-alur-langkah {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex: 1 1 10rem;
  padding: 0.625rem 0.875rem;
  border: 1px solid var(--bs-border-color);
  border-radius: 0.5rem;
  background: var(--bs-body-bg);
  color: var(--bs-body-color);
  text-decoration: none;
  transition: border-color 0.15s ease, background 0.15s ease;
}

a.pita-alur-langkah:hover {
  border-color: var(--bs-primary);
  background: var(--bs-primary-bg-subtle);
}

.pita-alur-langkah.nonaktif {
  opacity: 0.55;
}

.pita-alur-nomor {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 1.6rem;
  height: 1.6rem;
  border-radius: 50%;
  background: var(--bs-primary);
  color: #fff;
  font-size: 0.75rem;
  font-weight: 700;
}

.pita-alur-langkah.nonaktif .pita-alur-nomor {
  background: var(--bs-secondary-bg);
  color: var(--bs-secondary-color);
}

.pita-alur-teks {
  font-size: 0.8125rem;
  font-weight: 600;
  line-height: 1.2;
}

.pita-alur-angka {
  font-size: 0.6875rem;
  font-weight: 400;
  color: var(--bs-secondary-color);
}

/* --- Kartu rantai anggaran -----------------------------------------------
 * Muncul di formulir paket, kontrak, dan tagihan begitu induknya dipilih.
 * Isinya jenjang di atas baris yang sedang dibuat, supaya operator melihat
 * pagu mana yang akan ia potong SEBELUM mengetik angkanya.
 */
.rantai {
  padding: 0.875rem 1rem;
  border: 1px solid var(--bs-border-color);
  border-radius: 0.5rem;
  background: var(--bs-tertiary-bg);
}

.rantai.kosong {
  color: var(--bs-secondary-color);
  font-style: italic;
}

.rantai-baris {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.25rem 0;
  font-size: 0.8125rem;
}

.rantai-baris+.rantai-baris {
  border-top: 1px dashed var(--bs-border-color);
}

.rantai-label {
  flex: 0 0 auto;
  font-weight: 600;
  color: var(--bs-secondary-color);
}

.rantai-nilai {
  text-align: right;
}

.rantai-angka {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
}

/* --- Daftar pasangan label/nilai pada halaman detail --------------------- */
.kv {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.5rem 0;
  border-bottom: 1px solid var(--bs-border-color);
}

.kv:last-child {
  border-bottom: 0;
}

.kv-label {
  flex: 0 0 auto;
  color: var(--bs-secondary-color);
  font-size: 0.8125rem;
}

.kv-nilai {
  text-align: right;
  font-weight: 500;
  /* min-width:0 supaya nilai panjang boleh membungkus, bukan mendorong
   * labelnya keluar. text-wrap:pretty menyeimbangkan baris terakhir sehingga
   * nama panjang seperti "Program Pengembangan Sistem Penyediaan Air Minum"
   * tidak menyisakan satu kata sendirian di baris kedua. */
  min-width: 0;
  text-wrap: pretty;
}

.kv-nilai.angka {
  font-variant-numeric: tabular-nums;
}

/* --- Penanda kolom terkunci pada formulir --------------------------------
 * Dipakai untuk nilai kontrak yang sudah punya tagihan disetujui (§5.7) dan
 * untuk nilai SP2D yang mengikuti nilai tagihan (§4.4). Input readonly saja
 * tidak cukup: tanpa penanda, kolom yang tidak bisa diketik terbaca sebagai
 * formulir yang rusak.
 */
.form-terkunci {
  background: var(--bs-secondary-bg) !important;
  cursor: not-allowed;
}

/* --- Batang kemajuan realisasi fisik -------------------------------------
 * Menggantikan .progress/.progress-bar Bootstrap KHUSUS untuk sel tabel.
 * Alasannya bukan selera: keduanya butuh tinggi dan lebar yang diatur per
 * pemakaian, dan satu-satunya cara ringkasnya — atribut style — diabaikan
 * browser karena CSP aplikasi ini melarang gaya sebaris. Tinggi dan lebar
 * minimum karena itu ditetapkan di sini sekali untuk semua; hanya lebar isian
 * yang tersisa untuk dipasang ui.js dari data-persen.
 */
.kemajuan {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.kemajuan-alur {
  flex: 1 1 auto;
  min-width: 72px;
  height: 6px;
  border-radius: 3px;
  /* Tabler versi ini TIDAK mengekspor variabel --bs-*; yang ada --tblr-*.
     Tanpa nilai cadangan, alur batangnya tidak tergambar sama sekali. */
  background: var(--tblr-bg-surface-secondary, #f1f3f5);
  overflow: hidden;
}

.kemajuan-isi {
  width: 0;
  /* ui.js yang mengisinya; nol = data belum terbaca */
  height: 100%;
  border-radius: 3px;
}

.kemajuan-angka {
  flex: 0 0 auto;
  font-size: 0.8125rem;
  font-family: var(--bs-font-monospace);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* ---------------------------------------------------------------------------
 * Pohon unit organisasi (rencana 28) — /admin/unit
 *
 * Dipakai HANYA oleh satu halaman, dan satu-satunya daftar di aplikasi ini yang
 * bukan DataTables. Alasan lengkapnya di UnitController::indexAction().
 *
 * Garis penghubungnya digambar dengan ::before/::after pada kotak selebar rel,
 * bukan dengan gambar atau karakter: ia harus ikut memanjang saat baris
 * meninggi karena nama unit yang membungkus.
 * ------------------------------------------------------------------------- */

.pohon-garis {
  display: flex;
  flex-shrink: 0;
  align-self: stretch;
}

.pohon-rel,
.pohon-siku {
  width: 1.125rem;
  flex-shrink: 0;
  position: relative;
}

/* Garis leluhur yang masih punya adik: diteruskan melewati baris ini. */
.pohon-rel.lanjut::before {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0.5rem;
  width: 1px;
  background: var(--bs-border-color);
}

/* Siku ke baris ini sendiri: turun separuh, lalu membelok ke kanan. */
.pohon-siku::before {
  content: "";
  position: absolute;
  top: 0;
  height: 50%;
  left: 0.5rem;
  width: 1px;
  background: var(--bs-border-color);
}

.pohon-siku::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 0.5rem;
  width: 0.625rem;
  height: 1px;
  background: var(--bs-border-color);
}

/* Masih punya adik di bawahnya: garisnya diteruskan melewati siku. */
.pohon-siku.lanjut::before {
  bottom: 0;
  height: auto;
}

.pohon-tombol {
  width: 1.25rem;
  height: 1.25rem;
  flex-shrink: 0;
  margin-right: 0.4rem;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--bs-border-color);
  border-radius: 0.25rem;
  background: var(--bs-body-bg);
  color: var(--bs-secondary-color);
  cursor: pointer;
}

.pohon-tombol:hover {
  color: var(--bs-body-color);
  background: var(--bs-tertiary-bg);
}

.pohon-tombol i {
  font-size: 0.625rem;
  transition: transform 0.14s ease;
}

.pohon-tombol[aria-expanded="true"] i {
  transform: rotate(90deg);
}

/* Baris daun: tempatnya tetap dipesan supaya nama unit sebidang dengan
   saudaranya yang punya tombol. */
.pohon-daun {
  visibility: hidden;
  border-color: transparent;
  background: none;
}

.pohon-tombol i { transition: none;
}

.pohon-nama mark {
  padding: 0 0.125rem;
  border-radius: 0.1875rem;
}

/* --- Dropdown Cakupan & Tahun anggaran (rencana 30) ----------------------
 * Chip yang sama, tapi menekannya membuka daftar di tempat, bukan pindah ke
 * /pilih-unit atau /pilih-tahun.
 *
 * Tanda panahnya dipasang lewat ::after pada chip, BUKAN lewat .dropdown-toggle:
 * chip ini flex-direction column, jadi caret bawaan Bootstrap akan jatuh sebagai
 * baris ketiga di bawah nilainya.
 */
.chip-pemicu {
  position: relative;
  padding-right: 1.75rem;
}

.chip-pemicu::after {
  content: "";
  position: absolute;
  right: 0.7rem;
  top: 50%;
  width: 0.4rem;
  height: 0.4rem;
  border-right: 1.5px solid var(--bs-secondary-color);
  border-bottom: 1.5px solid var(--bs-secondary-color);
  transform: translateY(-70%) rotate(45deg);
  transition: transform 0.15s ease;
}

.chip-pemicu[aria-expanded="true"] {
  border-color: var(--bs-primary);
  background: var(--bs-primary-bg-subtle);
}

.chip-pemicu[aria-expanded="true"]::after {
  border-color: var(--bs-primary);
  transform: translateY(-30%) rotate(225deg);
}

.chip-pemicu::after { transition: none;
}

.chip-menu {
  min-width: 18rem;
  max-width: 22rem;
}

.chip-menu-item {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  white-space: normal;
}

.chip-menu-cek {
  width: 1rem;
  flex-shrink: 0;
  color: var(--bs-primary);
}

/* Nama unit TIDAK dipotong di sini. Di chip ia berelipsis supaya menu akun tidak
   terdorong keluar layar; di dropdown pengguna membandingkan nama utuh. */
.chip-menu-nama {
  flex: 1;
  min-width: 0;
}

.chip-menu-item[aria-current="true"] .chip-menu-nama {
  font-weight: 600;
}

.chip-menu-tahun {
  font-variant-numeric: tabular-nums;
  font-weight: 700;
}

.chip-menu-kaki {
  padding: 0.25rem 1.5rem 0.5rem;
  font-size: 0.75rem;
  color: var(--bs-secondary-color);
  white-space: normal;
}

/* --- Kotak cari pohon unit (rencana 28, dibetulkan rencana 31) ------------
 * Lebarnya ditetapkan di sini, BUKAN lewat style="width: 15rem" di view seperti
 * versi pertama. CSP aplikasi ini `style-src 'self'` tanpa 'unsafe-inline',
 * jadi atribut style di HTML diblokir browser dan kotaknya jatuh ke lebar
 * bawaannya -- tanpa satu pun pesan di layar.
 */
.pohon-cari {
  width: 15rem;
  max-width: 100%;
}

/* =============================================================================
 *  Ikon Tabler sebagai mask CSS
 * =============================================================================
 *  <span class="ikon ikon-plus"></span>
 *
 *  Kenapa mask, bukan SVG sebaris: Volt meng-escape SELURUH {{ }} (services.php
 *  'autoescape' => true), jadi ikon sebaris harus dibungkus {% autoescape false %}
 *  di setiap tempat — 20-an blok yang gampang terlupa dan diam-diam mencetak
 *  markup sebagai teks.
 *
 *  Kenapa mask, bukan <img>: <img> tidak bisa mewarisi warna teks, jadi ikon di
 *  dalam tombol berwarna akan tetap hitam. background-color: currentColor
 *  membuatnya ikut warna induknya, persis seperti ikon SVG Tabler.
 *
 *  Nama kelas = nama berkas di /assets/tabler/icons. Nama menu di tabel `menus`
 *  memakai nama yang sama, jadi sidebar cukup menulis ikon-{{ item['icon'] }}.
 *  Ikon yang berkasnya tidak ada tidak menimbulkan galat — hanya ruang kosong.
 * =============================================================================
 */

.ikon {
  display: inline-block;
  width: 1.25rem;
  height: 1.25rem;
  vertical-align: -0.225em;
  background-color: currentColor;
  -webkit-mask: var(--ikon) center / contain no-repeat;
          mask: var(--ikon) center / contain no-repeat;
}

.ikon-sm { width: 1rem; height: 1rem; }

/* <span> bertopeng tidak punya lebar minimum seperti <svg>: di dalam wadah flex
   (.alert, .btn) ia ikut menyusut saat teks di sebelahnya panjang, dan ikonnya
   tinggal sebilah garis. */
.ikon { flex-shrink: 0; }

/* Di dalam tombol, ukuran dan jaraknya sama dengan `.btn .icon` milik Tabler
   (.btn Tabler berupa inline-flex tanpa gap, jadi spasi di teks tidak cukup). */
.btn .ikon {
  width: var(--tblr-btn-icon-size);
  min-width: var(--tblr-btn-icon-size);
  height: var(--tblr-btn-icon-size);
  margin: 0 calc(var(--tblr-btn-padding-x) / 2) 0 calc(var(--tblr-btn-padding-x) / -4);
}

/*
 * TOMBOL HANYA-IKON: margin di atas dinolkan.
 *
 * Margin asimetris itu benar untuk tombol BERLABEL — ikonnya merapat ke tepi
 * kiri lalu berjarak dari teksnya. Pada `.btn-icon` tidak ada label yang perlu
 * didekati, jadi yang tersisa hanya pergeseran: terukur sela kiri 4px lawan
 * sela kanan 16px di dalam kotak 40×40, ikon meleset 12px dari pusat. Tidak
 * terlihat selama tombolnya bening, langsung ketahuan begitu latar hovernya
 * menyala. Tabler menyelesaikan hal yang sama pada `.btn-icon .icon` miliknya.
 */
.btn-icon .ikon { margin: 0; }

.ikon-alert-circle { --ikon: url("/assets/tabler/icons/alert-circle.svg"); }
.ikon-alert-triangle { --ikon: url("/assets/tabler/icons/alert-triangle.svg"); }
.ikon-building { --ikon: url("/assets/tabler/icons/building.svg"); }
.ikon-building-bank { --ikon: url("/assets/tabler/icons/building-bank.svg"); }
.ikon-calculator { --ikon: url("/assets/tabler/icons/calculator.svg"); }
.ikon-calendar { --ikon: url("/assets/tabler/icons/calendar.svg"); }
.ikon-cash { --ikon: url("/assets/tabler/icons/cash.svg"); }
.ikon-chart-bar { --ikon: url("/assets/tabler/icons/chart-bar.svg"); }
.ikon-check { --ikon: url("/assets/tabler/icons/check.svg"); }
.ikon-chevron-right { --ikon: url("/assets/tabler/icons/chevron-right.svg"); }
.ikon-clipboard-check { --ikon: url("/assets/tabler/icons/clipboard-check.svg"); }
.ikon-copy { --ikon: url("/assets/tabler/icons/copy.svg"); }
.ikon-database { --ikon: url("/assets/tabler/icons/database.svg"); }
.ikon-download { --ikon: url("/assets/tabler/icons/download.svg"); }
.ikon-eye { --ikon: url("/assets/tabler/icons/eye.svg"); }
.ikon-eye-off { --ikon: url("/assets/tabler/icons/eye-off.svg"); }
.ikon-file-text { --ikon: url("/assets/tabler/icons/file-text.svg"); }
.ikon-folders { --ikon: url("/assets/tabler/icons/folders.svg"); }
.ikon-history { --ikon: url("/assets/tabler/icons/history.svg"); }
.ikon-id-badge-2 { --ikon: url("/assets/tabler/icons/id-badge-2.svg"); }
.ikon-info-circle { --ikon: url("/assets/tabler/icons/info-circle.svg"); }
.ikon-key { --ikon: url("/assets/tabler/icons/key.svg"); }
.ikon-layout-dashboard { --ikon: url("/assets/tabler/icons/layout-dashboard.svg"); }
.ikon-lock { --ikon: url("/assets/tabler/icons/lock.svg"); }
.ikon-logout { --ikon: url("/assets/tabler/icons/logout.svg"); }
.ikon-map-pin { --ikon: url("/assets/tabler/icons/map-pin.svg"); }
.ikon-menu-2 { --ikon: url("/assets/tabler/icons/menu-2.svg"); }
.ikon-moon { --ikon: url("/assets/tabler/icons/moon.svg"); }
.ikon-pencil { --ikon: url("/assets/tabler/icons/pencil.svg"); }
.ikon-plus { --ikon: url("/assets/tabler/icons/plus.svg"); }
.ikon-printer { --ikon: url("/assets/tabler/icons/printer.svg"); }
.ikon-receipt { --ikon: url("/assets/tabler/icons/receipt.svg"); }
.ikon-report-analytics { --ikon: url("/assets/tabler/icons/report-analytics.svg"); }
.ikon-search { --ikon: url("/assets/tabler/icons/search.svg"); }
.ikon-send { --ikon: url("/assets/tabler/icons/send.svg"); }
.ikon-settings { --ikon: url("/assets/tabler/icons/settings.svg"); }
.ikon-shield { --ikon: url("/assets/tabler/icons/shield.svg"); }
.ikon-stack-2 { --ikon: url("/assets/tabler/icons/stack-2.svg"); }
.ikon-sun { --ikon: url("/assets/tabler/icons/sun.svg"); }
.ikon-trash { --ikon: url("/assets/tabler/icons/trash.svg"); }
.ikon-upload { --ikon: url("/assets/tabler/icons/upload.svg"); }
.ikon-user { --ikon: url("/assets/tabler/icons/user.svg"); }
.ikon-users { --ikon: url("/assets/tabler/icons/users.svg"); }
.ikon-x { --ikon: url("/assets/tabler/icons/x.svg"); }

/* Indentasi opsi unit di dropdown tom-select (ui.js). Kelas, bukan atribut
 * style: CSP aplikasi mengirim style-src 'self' tanpa 'unsafe-inline'. */
/* Diawali `.ts-dropdown .option`: aturan tom-select itu (0,2,0) menimpa kelas
 * tunggal, dan indentasinya hilang tanpa galat. .75rem = padding dasarnya. */
.ts-dropdown .option.pilih-dalam-0 { padding-left: calc(.75rem + 0rem); }
.ts-dropdown .option.pilih-dalam-1 { padding-left: calc(.75rem + 1rem); }
.ts-dropdown .option.pilih-dalam-2 { padding-left: calc(.75rem + 2rem); }
.ts-dropdown .option.pilih-dalam-3 { padding-left: calc(.75rem + 3rem); }
.ts-dropdown .option.pilih-dalam-4 { padding-left: calc(.75rem + 4rem); }
.ts-dropdown .option.pilih-dalam-5 { padding-left: calc(.75rem + 5rem); }
.ts-dropdown .option.pilih-dalam-6 { padding-left: calc(.75rem + 6rem); }

/* =============================================================================
 *  tom-select di atas Tabler
 * =============================================================================
 *  tom-select.bootstrap5.css (resep libs.json Tabler) menulis warnanya lewat
 *  variabel --bs-*, sedangkan Tabler hanya mendefinisikan --tblr-*. Tanpa
 *  jembatan ini aturannya gugur diam-diam: min-height dan warna border hilang,
 *  dan kotaknya 35px sementara input Tabler 40px. Nilainya dipetakan ke
 *  variabel Tabler, jadi ikut mode gelap.
 */
.ts-wrapper,
.ts-dropdown {
  --bs-border-width: var(--tblr-border-width);
  --bs-border-color: var(--tblr-border-color);
  --bs-border-color-translucent: var(--tblr-border-color-translucent);
  --bs-border-radius: var(--tblr-border-radius);
  --bs-border-radius-sm: var(--tblr-border-radius-sm);
  --bs-border-radius-lg: var(--tblr-border-radius-lg);
  --bs-body-bg: var(--tblr-bg-forms);
  --bs-body-color: var(--tblr-body-color);
  --bs-secondary-bg: var(--tblr-secondary-bg);
  --bs-tertiary-bg: var(--tblr-tertiary-bg);
  --bs-secondary-color: var(--tblr-secondary);
  --bs-form-invalid-color: var(--tblr-form-invalid-color);
  --bs-form-valid-color: var(--tblr-form-valid-color);
  --bs-box-shadow-inset: var(--tblr-box-shadow-inset);
}

/* Metrik kotak sama dengan .form-control/.form-select Tabler (tinggi 40px). */
.ts-wrapper.form-select .ts-control,
.ts-wrapper.form-control .ts-control {
  padding: .5625rem 2.25rem .5625rem 1rem;
  line-height: 1.25rem;
}

.ts-wrapper.form-select.multi.has-items .ts-control,
.ts-wrapper.form-control.multi.has-items .ts-control {
  padding-top: calc(.5625rem - 2px);
  padding-bottom: calc(.5625rem - 2px);
}

/* --- SPT ------------------------------------------------------------------ */

/* Dasar & keperluan multi-baris: baris baru dari isian dipertahankan. */
.spt-teks { white-space: pre-line; }

/* Kolom Keperluan di daftar dipotong; teks lengkapnya di title. */
.spt-keperluan { max-width: 16rem; vertical-align: bottom; }
/* Antrian SPD punya sepuluh kolom (requirement): Keperluan lebih sempit. */
.spd-keperluan { max-width: 9rem; }

/* Keterangan pegawai di pilihan tom-select kartu D. */
.ts-dropdown .pegawai-meta,
.ts-control .pegawai-meta { display: block; font-size: .75rem; color: var(--tblr-secondary); }

/* --- SPJ ------------------------------------------------------------------ */

/*
  Tabel rincian SPJ digulir ke samping (12 kolom), dan kolom Komponen &
  SBU DIBEKUKAN di kiri — requirement: tanpa itu, isian di kanan tidak
  diketahui lagi milik komponen yang mana.
*/
.spj-rincian { max-height: 70vh; }
.spj-rincian .spj-beku {
  position: sticky;
  left: 0;
  z-index: 1;
  background: var(--tblr-bg-surface);
}

/*
 * LEBAR KOLOM KOMPONEN DIPATOK DI PEMBUNGKUSNYA, BUKAN DI SELNYA.
 *
 * Pada tabel `table-layout: auto`, `max-width` pada <td> diabaikan browser:
 * uraian SBU seperti "Uang Harian Perjalanan Dinas Dalam Negeri (Luar Kota)"
 * melebarkan kolomnya sendiri sampai 30rem, dan karena ia kolom pertama,
 * seluruh kolom sesudahnya terdorong keluar layar. Elemen blok berlebar tetap
 * di dalam sel tidak punya persoalan itu.
 *
 * Yang terpilih DIBUNGKUS, bukan dipotong: nama SBU yang terpotong "Uang Harian
 * Perjalanan Dina…" tidak bisa dibedakan dari saudaranya yang berbeda hanya di
 * ujung kalimat, dan tidak ada tempat untuk menaruh tooltip di dalam sel tabel
 * yang sudah padat.
 */
.spj-komponen { width: 15rem; white-space: normal; }
.spj-komponen .ts-control { flex-wrap: wrap; }
.spj-komponen .ts-control > .item {
  white-space: normal;
  overflow-wrap: anywhere;
}
.spj-rincian thead .spj-beku { z-index: 2; }
.spj-rincian .spj-beku { box-shadow: 1px 0 0 var(--tblr-border-color); }
.spj-rincian td, .spj-rincian th { white-space: nowrap; }
/* Judul kolom rata bawah dan berjarak: "Total" yang rata kanan tepat menempel
   pada "Penyedia" di sebelahnya terbaca sebagai satu judul, bukan dua. */
.spj-rincian th { vertical-align: bottom; }
.spj-rincian th, .spj-rincian td { padding-left: .5rem; padding-right: .5rem; }

/* Isian di dalam tabel rapat: angka tetap terbaca, teks tidak selebar layar. */
.spj-rincian input[type="number"] { min-width: 4.5rem; }
.spj-rincian input[type="text"] { min-width: 8.5rem; }
.spj-rincian input[type="file"] { min-width: 8rem; }

/*
 * Keterangan SBU di dalam sel Komponen: sifat · satuan · harga.
 *
 * Ketiganya baca-saja dan selalu mengikuti SBU yang dipilih, jadi sebagai tiga
 * kolom tersendiri ia hanya memakan lebar yang dibutuhkan kolom yang bisa
 * diketik — pada layar 1600 px itu berarti lima kolom terakhir tabel tersembunyi
 * di balik gulir mendatar yang tidak terlihat.
 */
.spj-ket {
  font-size: .75rem;
  color: var(--tblr-secondary, #667382);
  margin-top: .25rem;
  white-space: normal;
}

/* Peringatan di bawah isian: tidak memblokir, jadi bukan .invalid-feedback. */
.spj-pesan { font-size: .75rem; color: var(--tblr-warning); white-space: normal; }

/* --- Laporan -------------------------------------------------------------
 *
 * Lembar Audit BPK punya dua puluh kolom. Dibiarkan menyesuaikan lebar layar,
 * setiap kolom menyempit sampai isinya patah per huruf dan tabelnya tidak
 * terbaca. Lebar minimum memaksa .table-responsive menggulir mendatar —
 * menggulir masih bisa dibaca, teks yang patah per huruf tidak.
 */
/* Lebarnya ditentukan ISINYA, bukan angka yang ditebak: sel dan judul kolom
   sama-sama nowrap, jadi tabel melebar seperlunya dan .table-responsive yang
   menggulirnya. Satu-satunya yang dibatasi adalah kolom keperluan, yang
   kalimatnya bisa sangat panjang. */
.laporan-lebar td, .laporan-lebar th { white-space: nowrap; }
.laporan-lebar td .spd-keperluan { max-width: 22rem; }

/*
 * KOLOM IDENTITAS DIBEKUKAN, dan gulirnya DIBERI TANDA.
 *
 * Tabel Audit BPK selebar 2550px di jendela 1278px menyembunyikan 1272px —
 * separuh lebih. Dua hal yang membuatnya tetap terbaca:
 *
 *   1. Kolom pertama (No. SPT / Nama pegawai) tetap di tempatnya, jadi baris
 *      yang sedang dibaca tidak kehilangan identitasnya saat digulir. Tanpa
 *      itu, kolom "Harga/Malam" di ujung kanan tidak diketahui lagi milik siapa.
 *
 *   2. Bayangan di tepi kanan yang muncul HANYA saat masih ada isi di
 *      sebelahnya. Bilah gulir tipis bawaan browser mudah terlewat; bayangan
 *      yang hilang sendiri begitu digulir mentok adalah tanda yang jujur.
 *
 * Bayangannya murni CSS (`background-attachment: local` + `scroll`): lapisan
 * yang ikut tergulir menutupi lapisan yang diam, jadi ia padam sendiri di
 * ujung tanpa satu baris JavaScript pun.
 */
/*
 * SELEKTORNYA PANJANG KARENA HARUS MENGALAHKAN DataTables.
 *
 * DataTables menulis `table.dataTable thead>tr>th.dt-orderable-asc {
 * position: relative }` untuk menaruh panah urutnya — kekhususan (0,2,4),
 * lebih tinggi daripada `.laporan-lebar .laporan-beku` (0,2,0). Akibatnya
 * SELNYA membeku sementara JUDUL KOLOMNYA ikut tergeser: kolom yang isinya
 * diam tapi judulnya berjalan terbaca sebagai tabel yang rusak, bukan sebagai
 * kolom beku. Bentuk di bawah menyamai kekhususannya (0,2,4) dan perjadin.css
 * dimuat paling akhir, jadi ia yang menang — tanpa perlu !important.
 */
table.laporan-lebar thead > tr > th.laporan-beku,
table.laporan-lebar tbody > tr > td.laporan-beku {
  position: sticky;
  left: 0;
  background: var(--tblr-bg-surface);
}
table.laporan-lebar tbody > tr > td.laporan-beku { z-index: 1; }

/* Latar kepala tabel sekarang bernada (#CBDCEF, lihat `.table thead th`); sel
 * beku harus memakai nada yang SAMA, kalau tidak kolom pertama tampil putih di
 * tengah baris kepala yang bernada. */
table.laporan-lebar thead > tr > th.laporan-beku { z-index: 2; background: var(--mhl-kepala-tabel, #CBDCEF); }

/* Batas kanan kolom beku: tanpa itu, kolom yang dipatok tidak bisa dibedakan
   dari kolom yang sedang lewat di belakangnya. */
table.laporan-lebar .laporan-beku { box-shadow: 1px 0 0 var(--tblr-border-color); }

/* `:has()` dipakai karena pembungkus .table-responsive dibuat DataTables saat
   jalan — tidak ada tempat untuk menempelkan kelas dari server. */
.table-responsive:has(.laporan-lebar) {
  background:
    linear-gradient(to right, var(--tblr-bg-surface) 30%, rgba(255, 255, 255, 0)) left center,
    linear-gradient(to left, var(--tblr-bg-surface) 30%, rgba(255, 255, 255, 0)) right center,
    radial-gradient(farthest-side at 0 50%, rgba(0, 0, 0, .16), rgba(0, 0, 0, 0)) left center,
    radial-gradient(farthest-side at 100% 50%, rgba(0, 0, 0, .16), rgba(0, 0, 0, 0)) right center;
  background-repeat: no-repeat;
  background-size: 3rem 100%, 3rem 100%, 0.9rem 100%, 0.9rem 100%;
  background-attachment: local, local, scroll, scroll;
}

/* --- Tombol ciutkan menu samping ------------------------------------------
 *
 * `.btn-ghost-secondary` bawaan Tabler mengisi tombolnya ABU-ABU PENUH saat
 * disentuh kursor. Di bilah atas yang putih bersih, dengan judul navy dan chip
 * biru muda di sebelahnya, kotak abu-abu itu satu-satunya benda di layar yang
 * warnanya tidak berasal dari palet mana pun — terbaca seperti sisa komponen
 * yang belum disetel.
 *
 * Diganti latar redup dengan ikon yang justru MENGUAT: isyarat "bisa diklik"
 * tetap ada, tanpa menarik perhatian melebihi judul halaman di sebelahnya.
 */
.topbar-baris [data-ciut-sidebar] {
  --tblr-btn-bg: transparent;
  --tblr-btn-border-color: transparent;
  --tblr-btn-hover-border-color: transparent;
  --tblr-btn-active-border-color: transparent;
  /*
   * Hitam transparan, bukan warna permukaan Tabler.
   * `--tblr-bg-surface-secondary` hampir putih, dan bilah atas tema bawaan juga
   * hampir putih — isyarat hovernya lenyap. Lapisan gelap tipis selalu terlihat
   * di atas latar terang apa pun, dan ikut benar sendiri di mode gelap.
   */
  --tblr-btn-hover-bg: rgba(0, 0, 0, .06);
  --tblr-btn-hover-color: var(--tblr-body-color, #1e293b);
  --tblr-btn-active-bg: rgba(0, 0, 0, .1);
  --tblr-btn-active-color: var(--tblr-body-color, #1e293b);
  /*
   * BAYANGAN BENING, BUKAN `none`.
   *
   * Tabler menulis `.btn:focus-visible { box-shadow: var(--tblr-btn-box-shadow),
   * var(--tblr-btn-focus-box-shadow) }`. Dengan `none` di salah satu anggota
   * daftar, seluruh deklarasi itu menjadi tidak sah dan dibuang browser —
   * cincin fokus keyboardnya ikut hilang tanpa satu pun tanda. Bayangan bening
   * menghasilkan tampilan yang sama tanpa merusak daftarnya.
   */
  --tblr-btn-box-shadow: 0 0 #0000;
  /* Jaraknya ke judul 8px terasa mepet begitu latar hover muncul. */
  margin-right: .25rem;
}

.tema-mahulu .topbar-baris [data-ciut-sidebar] {
  --tblr-btn-color: #56708f;
  /*
   * Sekeluarga dengan chip Cakupan/Tahun di ujung kanan bilah yang sama, tapi
   * SETINGKAT LEBIH PEKAT dari warna chip (#eaf3fd). Chip punya garis tepi yang
   * membatasinya; tombol ini tidak, dan tanpa tepi warna seringan itu tenggelam
   * di atas putih — isyarat hover yang tidak terlihat sama saja dengan tidak ada.
   */
  --tblr-btn-hover-bg: #dbe9fa;
  --tblr-btn-hover-color: var(--mhl-navy);
  --tblr-btn-active-bg: #c5dcf6;
  --tblr-btn-active-color: var(--mhl-navy);
}

/* --- Menu samping yang diciutkan -----------------------------------------
 *
 * Saat ciut, sidebar hanya selebar 4rem. Kepala bagian ("Alur Perjalanan
 * Dinas", "Realisasi Anggaran", …) di lebar itu pecah menjadi tiga baris dan
 * memenuhi bilahnya — label yang sudah tidak terbaca tapi tetap memakan ruang.
 *
 * Teksnya disembunyikan, GARISNYA DIPERTAHANKAN: tanpa garis, dua belas ikon
 * berderet tanpa satu pun pemisah dan kelompoknya hilang sama sekali. Berlaku
 * di kedua tema karena tombol ciutnya memang bukan milik tema.
 */
.navbar-vertical.navbar-folded .hr-text {
  display: block;
  height: 1px;
  margin: .75rem;
  padding: 0;
  overflow: hidden;
  text-indent: -100em;
  background: rgba(255, 255, 255, .16);
}
.navbar-vertical.navbar-folded .hr-text::before,
.navbar-vertical.navbar-folded .hr-text::after { display: none; }

/*
 * MEREK SAAT SIDEBAR CIUT: LAMBANG SAJA.
 *
 * Sidebar yang diciutkan lebarnya 4rem. Nama sistem plus dua baris keterangan
 * tidak muat di situ dengan cara apa pun, dan yang tergambar sebelum ini
 * adalah satu huruf "S" yang menyembul terpotong di tepi kanan — tampilan
 * rusak, bukan singkatan.
 *
 * Teksnya disembunyikan seluruhnya. `.merek-teks` ber-`min-width: 0` sehingga
 * kotaknya menciut ke nol, tapi ISINYA tetap meluber keluar dan terlihat;
 * `display: none` yang benar-benar menghentikannya.
 *
 * Padding nol supaya lambangnya betul-betul di tengah bilah 4rem.
 */
.navbar-vertical.navbar-folded .navbar-brand {
  justify-content: center;
  padding-inline: 0;
}

.navbar-vertical.navbar-folded .merek-teks { display: none; }

/* Tanpa teks di sebelahnya, lambang dipusatkan pada bilah 4rem. */
.navbar-vertical.navbar-folded .merek-blok { justify-content: center; width: 100%; gap: 0; }

/* --- Grafik batang tegak dasbor (Pagu & Realisasi per Bidang) -------------
 *
 * Bukan pustaka grafik. Dua batang per bidang, tanpa sumbu dan tanpa tooltip,
 * tidak memerlukan 500 KB JavaScript — dan pustaka grafik akan jadi satu
 * dependensi lagi yang harus ikut diserahterimakan. Alasan yang sama dengan
 * .kemajuan berlaku di sini: tingginya data, jadi dipasang ui.js lewat CSSOM
 * (CSP melarang atribut style).
 */
.vbar-chart {
  display: flex;
  flex-wrap: wrap;
  gap: 1.5rem 2rem;
  align-items: flex-end;
  justify-content: center;
}

.vbar-col { flex: 0 0 auto; width: 10rem; text-align: center; }
.vbar-group { display: flex; justify-content: center; gap: 0.75rem; align-items: flex-end; }
.vbar-mini { display: flex; flex-direction: column; align-items: center; }

.vbar-alur {
  display: flex;
  align-items: flex-end;
  width: 1.75rem;
  height: 7rem;
  border-radius: 4px;
  background: var(--tblr-bg-surface-secondary, #f1f3f5);
  overflow: hidden;
}

.vbar-isi {
  width: 100%;
  /* ui.js yang mengisinya dari data-tinggi; nol = data belum terbaca */
  height: 0;
  border-radius: 4px 4px 0 0;
}

.vbar-sementara { background: var(--tblr-yellow, #f59f00); }
.vbar-definitif { background: var(--tblr-primary, #206bc4); }
.vbar-lewat     { background: var(--tblr-danger, #d63939); }

.vbar-angka {
  font-size: 0.8125rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  margin-bottom: 0.25rem;
}

.vbar-mini-label { font-size: 0.6875rem; color: var(--tblr-secondary, #667382); margin-top: 0.25rem; }
.vbar-label { font-weight: 600; margin-top: 0.5rem; }
.vbar-angka-kecil { font-size: 0.6875rem; color: var(--tblr-secondary, #667382); line-height: 1.4; }

.vbar-legenda {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 1rem;
  margin-top: 1rem;
  font-size: 0.75rem;
  color: var(--tblr-secondary, #667382);
}

.vbar-titik {
  display: inline-block;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  margin-right: 0.35rem;
}

/* --- Lebar isi halaman ----------------------------------------------------
 *
 * `.page-wrapper` sendiri tidak punya margin maupun padding; ruang kosong kiri
 * kanan seluruhnya datang dari `.container-xl` milik Bootstrap, yang dipatok
 * 1320px. Di layar 1920 itu menyisakan 172px terbuang di tiap sisi, dan di
 * 2560 sebanyak 492px — sementara aplikasi ini penuh tabel lebar (rincian SPJ,
 * Audit BPK, rekap laporan) yang justru kekurangan lebar.
 *
 * Batasnya dinaikkan, BUKAN dilepas sama sekali. Dengan `container-fluid`,
 * datagrid dan paragraf keperluan di layar 2560 akan terentang 2300px — baris
 * teks sepanjang itu sulit diikuti mata, dan kartu jadi didominasi ruang
 * kosong di dalamnya. 1760px membuat layar 1920 terpakai habis (page-wrapper
 * di sana 1664px) dan tetap menahan yang lebih lebar dari itu.
 *
 * Dipasang pada `.page` supaya kepala halaman dan isinya melebar bersamaan —
 * keduanya memakai .container-xl, dan kalau hanya salah satu yang berubah,
 * judul halaman tidak lagi lurus dengan kartunya.
 */
.page .container-xl { max-width: 1760px; }

/*
 * SELOKAN KIRI-KANAN ISI HALAMAN.
 *
 * Bawaan Bootstrap 16px, dan itu TETAP di lebar layar mana pun. Akibatnya
 * jarak isi ke tepi layar (16px) lebih sempit daripada padding di dalam
 * kartunya sendiri (20px) dan daripada irama vertikal halaman (24px: kepala ke
 * kartu, dan antar kartu). Halaman jadi terbaca menempel ke tepi sementara
 * segala sesuatu di dalamnya bernapas — dan justru di layar lebar, tempat isi
 * halaman kini memakai seluruh lebarnya, kesan itu paling terasa.
 *
 * Selokannya dinaikkan bertingkat, bukan satu angka untuk semua:
 *
 *   < 992px    16px  — di tablet dan layar sempit, ruang layar mahal dan
 *                      isi halaman lebih berharga daripada bingkainya
 *   >= 992px   24px  — sama dengan irama vertikal, jadi halaman terbaca
 *                      sebagai satu kisi, bukan dua ukuran yang bertabrakan
 *   >= 1200px  32px
 *   >= 1600px  48px  — layar lebar butuh bingkai yang lebih tegas; tanpa itu
 *                      tabel selebar 1600px terlihat seperti tumpah dari layar
 *
 * Empat tingkat, bukan dua: lompat langsung dari 24px ke 48px berarti selokan
 * berubah dua kali lipat hanya karena jendela digeser satu piksel melewati
 * 1600 — perubahan yang terlihat seperti halaman berganti tata letak.
 *
 * Semuanya dipasang pada `.page` supaya kepala halaman dan isinya bergerak
 * bersamaan — judul yang tidak lurus dengan kartunya lebih mengganggu
 * daripada selokan yang sempit.
 */
@media (min-width: 992px) {
  .page .container-xl { padding-left: 1.5rem; padding-right: 1.5rem; }
}

@media (min-width: 1200px) {
  .page .container-xl { padding-left: 2rem; padding-right: 2rem; }
}

@media (min-width: 1600px) {
  .page .container-xl { padding-left: 3rem; padding-right: 3rem; }
}

/* =========================================================================
 * PRATINJAU TEMA "MAHULU" — sementara, dinyalakan lewat ?tema=mahulu
 * =========================================================================
 *
 * Mengikuti mockup_perjadin/nomor_3.png baris ke-3: sidebar navy, topbar
 * putih dengan garis amber di bawahnya, aksen amber pada yang sedang aktif,
 * dan latar isi halaman biru muda. Warnanya diambil langsung dari piksel
 * mockup, bukan dikira-kira:
 *
 *     navy   #172e58     amber  #f9b313     latar isi  #daecfa
 *
 * SATU PENYIMPANGAN YANG DISENGAJA: tombol utama di mockup memakai teks PUTIH
 * di atas amber — rasio kontrasnya 1,9:1, jauh di bawah ambang WCAG AA 4,5:1,
 * dan pada layar laptop di ruang terang tulisannya praktis hilang. Di sini
 * teksnya navy di atas amber (8,4:1). Bentuk dan warnanya tetap sama; yang
 * berubah hanya warna tulisannya.
 */
.tema-mahulu {
  /*
   * NILAINYA DARI PALET RESMI (color pallet.png, nomor 01-06). Disamakan
   * 2026-09-18. Navy sebelumnya #172e58 — selisih satu nilai biru, tidak bisa
   * dilihat mata; disamakan supaya tidak ada dua angka yang dua-duanya
   * "benar" saat orang lain membaca berkas ini nanti.
   */
  --mhl-navy: #172E59;        /* 03 */
  --mhl-navy-muda: #24406f;
  --mhl-amber: #f9b313;       /* 02 */
  --mhl-amber-tua: #e0a00c;
  --mhl-kepala-tabel: #CBDCEF;/* 04 */
  /*
   * Kanvas isi halaman. Mockup memberi #daecfa — biru dengan saturasi 78%.
   * Di layar lebar, bagian halaman yang tidak terisi kartu menjadi bidang
   * biru besar, dan tepi kartu yang juga biru (#c6dcf0 dulu) membuat kartu
   * putih terbaca BERCINCIN, bukan terangkat. Saturasinya diturunkan ke 60%:
   * rona yang sama, identitas Mahulu-nya masih terbaca sebagai biru, tapi ia
   * berhenti bersaing dengan isi kartunya sendiri.
   */
  --mhl-latar: #E1EEFA;       /* 06 — dari palet; sebelumnya #e9f1fa */
}

/* --- Kepala tabel: latar dari palet (04) ----------------------------------
 *
 * DI SCOPE TEMA, bukan `.table thead th` polos. Tabler memasang DUA aturan
 * pada selektor yang sama persis:
 *
 *   .table thead th { background: var(--tblr-bg-surface-tertiary); ... }
 *   .table thead th { background: 0 0; }              <- yang kedua menang
 *
 * Keduanya berkekhususan (0,1,2) — sama dengan milik kita — jadi yang menentukan
 * tinggal urutan berkas, dan `background: 0 0` itu SHORTHAND: ia menghapus
 * `background-color` dari mana pun datangnya, termasuk dari
 * `--tblr-table-bg` yang dipakai Bootstrap di `.table > :not(caption) > * > *`.
 * Menyetel variabelnya saja karena itu tidak cukup; terukur tetap
 * `rgba(0,0,0,0)`.
 *
 * `.tema-mahulu` di depannya menjadikannya (0,2,2) dan persoalannya selesai
 * tanpa satu pun !important.
 */
.tema-mahulu .table thead th { background: var(--mhl-kepala-tabel, #CBDCEF); }

/*
 * SUDUTNYA DIPERSEGI. Tabler membulatkan sel kepala pertama dan terakhir pada
 * `.card-table` — masuk akal ketika tabel menempel di tepi atas kartu, karena
 * sudutnya lalu mengikuti sudut kartu.
 *
 * Di sini tabelnya TIDAK di tepi atas: di atasnya masih ada kepala kartu dan
 * bilah penyaring. Yang tergambar akibatnya bukan sudut kartu, melainkan pita
 * biru dengan dua takik di ujung atasnya — cacat yang baru terlihat setelah
 * latarnya berubah dari nyaris putih menjadi #CBDCEF.
 */
.tema-mahulu .table thead th:first-child { border-top-left-radius: 0; }
.tema-mahulu .table thead th:last-child  { border-top-right-radius: 0; }

/* Kolom beku di laporan lebar menyalin latar kepala — ia melayang di atas
 * sel lain, jadi latarnya harus buram. */
.tema-mahulu table.laporan-lebar thead > tr > th.laporan-beku {
  background: var(--mhl-kepala-tabel, #CBDCEF);
}

/* --- Blok merek: lambang + nama sistem ------------------------------------
 *
 * Lambang sendirian tidak menyebutkan instansi mana, dan judul di bilah atas
 * menyebut ISI halaman, bukan nama sistemnya.
 *
 * `min-width: 0` pada wadah teks WAJIB: tanpa itu anak flex tidak boleh
 * menyusut di bawah lebar isinya, dan nama dinas yang panjang melebarkan blok
 * merek melewati sidebar.
 */
.merek-blok { display: flex; align-items: center; gap: .625rem; min-width: 0; text-decoration: none; }
.merek-teks { min-width: 0; line-height: 1.2; }

.merek-nama {
  display: block;
  font-size: .875rem;
  font-weight: 700;
  color: var(--mhl-navy, #172E59);
  letter-spacing: -.01em;
  white-space: nowrap;
}

/* Dua baris keterangan: boleh terpotong dengan elipsis daripada melebarkan
 * blok atau membungkus jadi empat baris. Bentuk pendeknya sudah dipilih di
 * config supaya itu jarang terjadi. */
.merek-dinas,
.merek-wilayah {
  display: block;
  font-size: .6875rem;
  color: #55637a;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* --- Menu akun di kanan atas ---------------------------------------------
 *
 * Pindah dari dasar sidebar (komponen SidebarUser Tabler) ke kepala halaman,
 * berkumpul dengan chip Cakupan & Tahun Anggaran.
 */
.akun-pemicu {
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  padding: .3125rem .5rem .3125rem .3125rem;
  border: 1px solid transparent;
  border-radius: 999px;
  background: transparent;
  color: var(--mhl-navy, #172E59);
  text-decoration: none;
  font-size: .8125rem;
  font-weight: 600;
  line-height: 1;
}

.akun-pemicu:hover,
.akun-pemicu[aria-expanded="true"] { background: #f2f6fb; border-color: #dbe4ef; }
.akun-pemicu:focus-visible { outline: 2px solid var(--mhl-amber, #f9b313); outline-offset: 1px; }

/*
 * NAVY, bukan amber seperti waktu ia di sidebar. Di bilah atas yang putih,
 * amber sudah milik tombol aksi utama; lingkaran amber di sini akan bersaing
 * dengan tombol "Tambah" yang berjarak beberapa puluh piksel di bawahnya.
 */
.akun-avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  border-radius: 50%;
  flex-shrink: 0;
  background: var(--mhl-navy, #172E59);
  color: #fff;
  font-size: .8125rem;
  font-weight: 700;
}

.akun-nama { max-width: 11rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.akun-panah { width: .875rem; height: .875rem; color: #7b8a9e; transform: rotate(90deg); }
.akun-pemicu[aria-expanded="true"] .akun-panah { transform: rotate(-90deg); }

/* Di layar sempit namanya dibuang — avatar dan panahnya cukup. */
@media (max-width: 575.98px) { .akun-nama { display: none; } }

/* --- Pita batik + kaki halaman -------------------------------------------
 *
 * Batik BUKAN bagian dari kaki: ia pita hias di ATAS kaki, menutup pertemuan
 * kanvas dengan kaki halaman.
 *
 * `center bottom` + `repeat-x`: pada lebar layar berapa pun sumbu simetri
 * motifnya jatuh di tengah, jadi potongan yang terpotong seimbang kiri dan
 * kanan. Diulang dari kiri, yang terpotong selalu di kanan dan terbaca
 * seperti gambar yang kurang.
 *
 * `background-size: auto 100%`: tingginya yang dipatok, lebarnya mengikuti
 * rasio — motifnya tidak pernah melar.
 */
.pita-batik {
  height: 6.5rem;
  background-image: url("/assets/img/batik.png");
  background-repeat: repeat-x;
  background-position: center bottom;
  background-size: auto 100%;
  pointer-events: none;
}

/* Layar pendek: pita setinggi 104px memakan terlalu banyak dari yang tersisa. */
@media (max-height: 700px) { .pita-batik { height: 4rem; } }

/*
 * KAKI HALAMAN. Sebelumnya tanpa batas apa pun — teksnya mengambang di atas
 * kanvas yang sama dengan badan halaman, jadi tidak ada yang menandai bahwa
 * halaman sudah habis.
 *
 * Garis ambernya bukan hiasan baru: amber 3px adalah garis yang SAMA yang
 * memisahkan bilah atas dari isi halaman, jadi halaman jadi berbingkai amber
 * di atas dan di bawah.
 */
.tema-mahulu .footer {
  border-top: 3px solid var(--mhl-amber, #f9b313);
  background: #fff;
  padding: .875rem 0;
  margin-top: 0;
}

/* --- Sidebar ------------------------------------------------------------ */
.tema-mahulu .navbar-vertical { background: var(--mhl-navy); border-right: 0; }

/*
 * BILAH ATAS: SATU GARIS LURUS DARI MEREK SAMPAI CHIP.
 *
 * Inilah yang membuat tata letaknya menyambung seperti mockup. Kuncinya
 * TINGGI TETAP yang sama persis (--mhl-topbar) untuk dua elemen yang berbeda
 * induknya: blok merek di dalam sidebar, dan `.topbar-baris` di dalam
 * page-wrapper. Keduanya `box-sizing: border-box` dan sama-sama berbatas bawah
 * amber 3px, jadi garisnya jatuh pada baris piksel yang sama.
 *
 * Bisa demikian karena subjudul dan baris tab sudah dipindah ke
 * `.page-header-sub` di bawahnya (lihat index.volt). Selama keduanya masih di
 * dalam bilah, tingginya ikut isi halaman — 79px, 95px, atau 151px — dan
 * garisnya pasti bertangga.
 */
.tema-mahulu { --mhl-topbar: 4.5rem; }

.tema-mahulu .navbar-vertical .navbar-brand {
  display: flex;
  align-items: center;
  box-sizing: border-box;
  min-height: var(--mhl-topbar);
  /*
   * Margin NOL di semua sisi, dan lebarnya ikut wadah.
   *
   * Dengan `-1rem` di kiri-kanan, blok ini terukur membentang -16px sampai
   * 272px sementara sidebarnya 0 sampai 256px: 16px putih menumpuk di atas
   * bilah atas, dan garis tegak pemisahnya berdiri 16px terlalu ke kanan.
   * Wadah sidebar ternyata tidak berpadding sama sekali, jadi tidak ada yang
   * perlu ditiadakan.
   */
  margin: 0 0 0.75rem;
  padding: 0 1rem;
  background: #fff;
  border-bottom: 3px solid var(--mhl-amber);
}
/*
 * Lambang sedikit lebih besar dari bawaan Tabler (2rem): bilah atas di sini
 * setinggi 4,5rem, dan lambang 2rem di dalamnya terlihat hilang.
 *
 * `flex-shrink: 0` + `width: auto` WAJIB, bukan kehati-hatian. Sejak blok
 * merek jadi flex dengan teks di sebelahnya, lambang adalah anak flex — dan
 * anak flex BOLEH menyusut di bawah lebar isinya. Saat sidebar diciutkan ke
 * 4rem, terukur lambangnya menjadi 32 x 40 px: gepeng, rasionya 0,80 dari
 * yang seharusnya 1,00. Tingginya dipatok sementara lebarnya diperas.
 */
.tema-mahulu .navbar-vertical .navbar-brand-image {
  height: 2.5rem;
  /*
   * LEBARNYA DIPATOK, bukan `auto`. Lambangnya persegi (192 x 192 px), jadi
   * 2,5rem x 2,5rem adalah proporsi aslinya — bukan angka yang dikarang.
   *
   * `auto` saja tidak cukup: Bootstrap memasang `max-width: 100%` pada setiap
   * <img>, dan saat sidebar diciutkan induknya menyusut ke 32 px, jadi
   * lambangnya ikut diperas ke 32 x 40 px — rasio 0,80 dari yang seharusnya
   * 1,00. `max-width: none` yang melepasnya; `flex-shrink: 0` menjaga ia tidak
   * diperas lagi oleh flexbox.
   */
  width: 2.5rem;
  max-width: none;
  flex-shrink: 0;
}

/*
 * RUANG NAPAS DI DASAR DAFTAR MENU.
 *
 * Daftar menunya lebih panjang dari layar — terukur 1201 px di sidebar 800 px —
 * jadi ia menggulir. Selama menu akun masih di dasar sidebar, blok itulah yang
 * menutup daftarnya. Sejak ia pindah ke kanan atas, item terakhir berhenti
 * TEPAT di tepi bawah sidebar saat digulir habis: tidak ada yang menandai
 * bahwa daftarnya memang sudah selesai, dan yang terbaca justru seperti
 * terpotong.
 *
 * Nilainya disamakan dengan `pt-lg-3` (1rem) yang sudah ada di atas daftar,
 * supaya jarak atas dan bawahnya setara.
 */
.tema-mahulu .navbar-vertical .navbar-collapse .navbar-nav { padding-bottom: 1rem; }

/* Sisi kiri-kanan hanya .25rem: pil aktif butuh ruang, tapi 8px di tiap sisi
   membuat label terpanjang ("SPJ (Pertanggungjawaban)") mulai terpotong. */
.tema-mahulu .navbar-vertical .nav-link {
  color: rgba(255, 255, 255, .82);
  border-radius: .375rem;
  margin: .0625rem .25rem;
}
.tema-mahulu .navbar-vertical .nav-link:hover { background: var(--mhl-navy-muda); color: #fff; }

/*
 * Yang sedang dibuka: amber pekat dengan tulisan navy — kebalikan dari
 * sekitarnya, jadi posisi pengguna terbaca sekali lihat.
 *
 * Diawali `body` karena Tabler menulis `.navbar-expand-lg .navbar-nav
 * .nav-item.active>.nav-link { background: var(--tblr-navbar-active-bg) }`
 * dengan kekhususan (0,5,0) — sama dengan bentuk tanpa `body`, dan seri itu
 * dimenangkan siapa pun yang kebetulan dimuat belakangan. Satu elemen di depan
 * menjadikannya (0,5,1): menang pasti, bukan menang kebetulan.
 */
body.tema-mahulu .navbar-vertical .navbar-nav .nav-item.active > .nav-link,
body.tema-mahulu .navbar-vertical .navbar-nav .nav-link[aria-current="page"] {
  background: var(--mhl-amber);
  color: var(--mhl-navy);
  font-weight: 600;
}
body.tema-mahulu .navbar-vertical .navbar-nav .nav-item.active > .nav-link .ikon {
  background-color: var(--mhl-navy);
}

/* Kepala bagian ("Alur Perjalanan Dinas") memakai amber redup, bukan abu-abu:
   di atas navy, abu-abu jatuh ke bawah ambang keterbacaan. */
.tema-mahulu .navbar-vertical .hr-text {
  color: rgba(249, 179, 19, .85) !important;
  font-weight: 700;
}
.tema-mahulu .navbar-vertical .hr-text::after,
.tema-mahulu .navbar-vertical .hr-text::before { border-color: rgba(255, 255, 255, .14); }

.tema-mahulu .navbar-footer { border-top: 1px solid rgba(255, 255, 255, .12); }
.tema-mahulu .navbar-footer .nav-link { color: #fff; }
.tema-mahulu .navbar-footer .avatar { background: var(--mhl-amber); color: var(--mhl-navy); }

/* --- Bilah atas --------------------------------------------------------- */
.tema-mahulu .page-header { margin-top: 0; }

.tema-mahulu .topbar-baris {
  display: flex;
  align-items: center;
  box-sizing: border-box;
  min-height: var(--mhl-topbar);
  background: #fff;
  border-bottom: 3px solid var(--mhl-amber);
}
.tema-mahulu .topbar-baris > .container-xl { width: 100%; }

/*
 * BILAH ATAS DIPAKU (fixed), BUKAN SEKADAR LENGKET (sticky).
 *
 * `position: sticky` gagal di sini, dan bukan karena salah tulis: elemen
 * sticky tidak bisa keluar dari kotak induknya. Induknya `.page-header`, yang
 * tingginya hanya setinggi kepala halaman — begitu kepala itu tergulir habis,
 * bilahnya ikut terbawa. Terukur: pada gulir 300px bilahnya berada di -300
 * sementara blok merek tetap di 0, karena sidebar memang `position: fixed`.
 * Yang terlihat: sisi kanan tertarik naik, sisi kiri diam.
 *
 * Dipaku dari tepi kanan sidebar sampai tepi layar, jadi ia sebidang dengan
 * blok merek yang juga tidak pernah bergerak. Keduanya kini berhenti di baris
 * piksel yang sama pada gulir berapa pun.
 *
 * Hanya mulai 992px, yaitu titik Tabler menjadikan sidebar `fixed`. Di bawah
 * itu sidebarnya menciut jadi bilah atas biasa, dan bilah yang dipaku ke
 * `left: 16rem` akan menggantung entah di mana.
 */
@media (min-width: 992px) {
  .tema-mahulu .topbar-baris {
    position: fixed;
    top: 0;
    left: var(--tblr-sidebar-width, 16rem);
    right: 0;
    z-index: 1031;   /* di atas sidebar Tabler (1030) */
  }

  /* Ruang untuk bilah yang sudah keluar dari alur. */
  .tema-mahulu .page-wrapper { padding-top: var(--mhl-topbar); }
}

/* Subjudul & baris tab: di luar bilah, di atas latar biru isi halaman. */
.tema-mahulu .page-header-sub { padding-top: 1.25rem; }

.tema-mahulu .page-title { color: var(--mhl-navy); margin: 0; }
.tema-mahulu .page-pretitle { color: #6b7a90; }

/* Chip cakupan & tahun: biru muda seperti mockup, bukan abu-abu Tabler. */
.tema-mahulu .chip-tahun {
  background: #eaf3fd;
  border-color: #bcd6f0;
}
.tema-mahulu .chip-tahun-label { color: #56708f; }
.tema-mahulu .chip-tahun-nilai { color: var(--mhl-navy); }
.tema-mahulu a.chip-tahun-tombol:hover { border-color: var(--mhl-amber); background: #fdf3dd; }

/* --- Isi halaman -------------------------------------------------------- */
.tema-mahulu .page-wrapper { background: var(--mhl-latar); }
/*
 * INSET HALAMAN: 2rem, SAMA DENGAN KIRI-KANAN.
 *
 * Sempat 1.25rem (20 px) dan terasa terjepit — bukan karena 20 px kecil,
 * melainkan karena `.container-xl` sudah memberi 32 px di kiri dan kanan,
 * jadi atasnya satu-satunya sisi yang lebih rapat. Tepi atas juga dibatasi
 * bilah `fixed` + garis amber: batas yang berat membuat jarak yang sama
 * terasa lebih sempit daripada jarak ke kanvas kosong.
 *
 * 20 px juga satu-satunya nilai di luar grid 8 px aplikasi ini (16/24/32).
 * Ongkos naik ke 32 px: 12 px sekali per halaman, tidak menghilangkan baris
 * tabel yang berarti.
 */
.tema-mahulu .page-body { margin-top: 2rem; }
/*
 * Tepi netral + bayangan setipis satu piksel, bukan tepi biru: kartu diangkat
 * dari kanvas, tidak dibingkai olehnya. Lihat catatan --mhl-latar di atas.
 */
.tema-mahulu .card {
  border-color: #e3eaf3;
  box-shadow: 0 1px 2px rgba(23, 46, 88, .05), 0 2px 6px rgba(23, 46, 88, .04);
}
.tema-mahulu .card-title { color: var(--mhl-navy); }

/* --- Tombol utama -------------------------------------------------------
 *
 * Bentuknya menyalin `.btn-warning` milik Tabler apa adanya — tepi bening,
 * tulisan putih (`--tblr-warning-fg` di Tabler memang `--tblr-light`), dan
 * bayangan `--tblr-shadow-input` — hanya warnanya yang diganti amber Mahulu.
 *
 * Catatan yang perlu diketahui, bukan untuk diperdebatkan lagi: putih di atas
 * amber berjarak kontras 1,9:1, di bawah ambang WCAG AA 4,5:1. Ini keputusan
 * yang sudah diambil dan memang mengikuti mockup; ia dicatat di sini supaya
 * siapa pun yang membacanya nanti tahu itu pilihan, bukan kelalaian.
 */
.tema-mahulu .btn-primary {
  --tblr-btn-border-color: transparent;
  --tblr-btn-hover-border-color: transparent;
  --tblr-btn-active-border-color: transparent;
  --tblr-btn-color: #fff;
  --tblr-btn-bg: var(--mhl-amber);
  --tblr-btn-hover-color: #fff;
  --tblr-btn-hover-bg: var(--mhl-amber-tua);
  --tblr-btn-active-color: #fff;
  --tblr-btn-active-bg: var(--mhl-amber-tua);
  --tblr-btn-disabled-bg: var(--mhl-amber);
  --tblr-btn-disabled-color: #fff;
  --tblr-btn-box-shadow: var(--tblr-shadow-input);
  font-weight: 600;
}

/* Halaman aktif pada paginasi ikut amber (mockup). */
.tema-mahulu .page-item.active .page-link {
  background: var(--mhl-amber);
  border-color: var(--mhl-amber);
  color: var(--mhl-navy);
  font-weight: 700;
}

/* =============================================================================
 *  LAPISAN ISI — satu arti untuk satu warna
 * =============================================================================
 *  Tema Mahulu mengurus KERANGKA: sidebar, bilah atas, tombol utama. Di dalam
 *  kartu, warnanya dulu warisan Tabler apa adanya, dan satu baris daftar SPT
 *  memuat enam rona — biru "Ubah", biru "Cetak", merah "Hapus", ungu "Kadis",
 *  hijau "Disetujui", pil abu pada nomor — yang tidak satu pun berhubungan
 *  dengan temanya. Akibatnya mata jatuh ke TOMBOL, elemen paling kontras,
 *  padahal yang dicari orang di sebuah daftar adalah STATUS.
 *
 *  Aturan yang berlaku di seluruh bagian ini:
 *
 *    navy    struktur & identitas — judul, kepala kartu, kepala kolom, nomor
 *    amber   SATU aksi utama per layar, halaman aktif, cincin fokus
 *    hijau / merah / kuning / abu / navy-muda   STATUS saja
 *    netral  segala sisanya — aksi baris, keterangan, tepi, label isian
 *
 *  Biru dan ungu dikeluarkan dari lapisan isi: di tema navy-amber keduanya
 *  tidak menandakan apa pun.
 *
 *  TIDAK dibungkus `.tema-mahulu`. Ini bukan tema warna, ini sistemnya;
 *  ?tema=asal masih berguna untuk membandingkan KERANGKAnya, dan isi halaman
 *  sebaiknya tetap sama di kedua tampilan.
 * ========================================================================== */

/* --- Status ---------------------------------------------------------------
 *
 * Lima nada, satu tangga, SATU BENTUK. Perbedaan tinggi atau tebal antar
 * status membuat kolom Status bergerigi saat dibaca dari atas ke bawah.
 *
 * Titik 6px yang membawa ronanya, sehingga pilnya sendiri bisa tetap muda.
 * Itu juga yang membuat status tetap terbaca tanpa warna: bentuk + teks, bukan
 * warna saja — syarat WCAG 1.4.1 yang tidak dipenuhi pil berwarna polos.
 */
.status {
  display: inline-flex;
  align-items: center;
  gap: .4375rem;
  padding: .1875rem .5625rem .1875rem .5rem;
  border: 1px solid transparent;
  border-radius: 999px;
  font-size: .75rem;
  font-weight: 600;
  line-height: 1.3;
  white-space: nowrap;
}

.status::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
  flex-shrink: 0;
}

.status-draft  { background: #eef1f5; border-color: #e1e7ef; color: #5b6b80; }
.status-tunggu { background: #fdf5e3; border-color: #f4e2b6; color: #8a5d00; }
.status-jalan  { background: #eaf0f9; border-color: #d6e2f2; color: #2c4570; }
.status-setuju { background: #e8f6ee; border-color: #c8e8d6; color: #1a7f47; }
.status-tolak  { background: #fdedec; border-color: #f7d3d1; color: #b02a2a; }

/*
 * PERAN, BUKAN STATUS. "Kadis" dulu pil ungu — satu-satunya ungu di seluruh
 * aplikasi, dan bentuknya sama persis dengan pil status di kolom sebelahnya,
 * jadi ia terbaca sebagai status ketiga yang tidak ada di alur mana pun.
 * Persegi dan netral: penanda, bukan keadaan.
 */
.tag-peran {
  display: inline-block;
  padding: .0625rem .3125rem;
  border: 1px solid #d3dce8;
  border-radius: 4px;
  background: #fff;
  color: #3d5273;
  font-size: .6875rem;
  font-weight: 600;
  letter-spacing: .01em;
}

/* --- Nomor dokumen --------------------------------------------------------
 *
 * Dulu <code class="text-muted">: Tabler memberi <code> latar abu dan padding,
 * jadi nomor SPT tampil sebagai LENCANA — sejajar bobotnya dengan pil status,
 * padahal ia kolom identitas baris. Monospace dipertahankan (digit nomor harus
 * lurus antar baris), latarnya dilepas, warnanya naik ke navy.
 */
.nomor-dok {
  font-family: var(--tblr-font-monospace);
  font-size: .8125rem;
  font-weight: 600;
  color: #172e58;
  letter-spacing: -.01em;
  white-space: nowrap;
}

/* --- Aksi baris -----------------------------------------------------------
 *
 * IKON BERKOTAK, TANPA LABEL. Bentuk ini dipilih 2026-09-18 setelah enam
 * variasi diadu berdampingan di pratinjau.
 *
 * Yang digantikannya: campuran — aksi yang memulai pekerjaan baris itu
 * berlabel, aksi sekunder ikon saja. Aturan itu punya alasan yang masih benar
 * (menahan tangga tombol berbingkai di ujung kanan yang menyaingi kolom
 * Status), tapi akibatnya satu sel selebar 138 px memakai DUA tata bahasa
 * sekaligus: satu hal dibaca, sisanya ditebak. Mata harus berpindah mode di
 * dalam satu sel.
 *
 * Sekarang semuanya ikon, jadi tata bahasanya tinggal satu. Tepi tetap
 * mengembalikan apa yang hilang bersama labelnya: batas tombolnya terlihat
 * tanpa perlu disentuh lebih dulu — ikon telanjang menyerahkan pertanyaan
 * "ini bisa diklik atau tidak" kepada kursor. Terukur 94 px: 44 px lebih
 * sempit dari bentuk lama, dan hanya 4 px lebih lebar dari ikon tanpa tepi.
 *
 * LABELNYA TIDAK HILANG, ia pindah ke `aria-label` + `title`. Pembaca layar
 * tetap mendengar kalimatnya utuh, dan kursor yang diam memunculkannya.
 * Karena itu Tabel::tombol() sekarang mewajibkan teks — teksnya masih dipakai,
 * hanya tidak lagi digambar.
 */
.aksi-baris { display: inline-flex; gap: .25rem; align-items: center; }

.btn-aksi {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: .3125rem;
  border: 1px solid #e4ebf3;
  border-radius: 6px;
  background: #fff;
  color: #4a5c74;
  line-height: 1;
  text-decoration: none;
}

.btn-aksi .ikon { width: 1.0625rem; height: 1.0625rem; margin: 0; }
.btn-aksi:hover { background: #eef4fb; border-color: #c3d6e8; color: #172e58; }
.btn-aksi:focus-visible { outline: 2px solid var(--mhl-amber, #f9b313); outline-offset: 1px; }

/* Aksi yang MEMULAI pekerjaan baris itu — "Input SPJ", "Buat NPD",
 * "Lihat & Putuskan". Dulu dibedakan dengan huruf tebal; tanpa teks, tebal
 * tidak menggambar apa pun. Sekarang KOTAKNYA yang bernada navy — seperti
 * tombol yang sudah tersentuh — tanpa menambah satu rona pun ke lapisan isi. */
.btn-aksi-utama {
  border-color: #c3d6e8;
  background: #eef4fb;
  color: #1d3a6b;
}
.btn-aksi-utama:hover { border-color: #9fbfdd; background: #e2edf9; }

.btn-aksi-hapus:hover { background: #fdeceb; border-color: #f2c9c6; color: #b02a2a; }

/* Baris yang belum boleh dihapus tetap menampilkan tombolnya (lihat
 * Tabel::tombolHapus) — redup, dan tanpa latar hover yang menjanjikan klik. */
.btn-aksi:disabled,
.btn-aksi.disabled {
  color: #b4bdc9;
  border-color: #eef1f5;
  background: #fafbfc;
  pointer-events: none;
}

/* --- Kepala kartu ---------------------------------------------------------
 *
 * Tabler memaku tinggi kepala kartu 3,5rem dan memusatkan isinya. Dengan
 * subjudul isinya berdesakan; tanpa subjudul, 56px terpakai untuk satu baris
 * teks. Tingginya dibiarkan mengikuti isi, dan isinya dirata-ATAS supaya judul
 * tetap lurus dengan tombol di seberangnya saat subjudulnya dua baris.
 */
.card-header {
  min-height: 0;
  padding: .875rem 1.25rem;
  align-items: flex-start;
}

.card-title { font-size: .9375rem; font-weight: 700; color: #172e58; }

.card-subtitle {
  margin: .1875rem 0 0;
  font-size: .8125rem;
  font-weight: 400;
  color: #6b7a90;
  text-transform: none;
  letter-spacing: 0;
}

.card-header .card-actions { margin-top: 0; }

/* --- Huruf bagian A/B/C/D -------------------------------------------------
 *
 * Dulu `badge bg-primary-lt` — biru Tabler, rona yang tidak ada di tema ini
 * dan tidak berarti apa pun. Keping navy muda: penanda URUTAN, bukan status.
 */
.huruf-bagian {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.375rem;
  height: 1.375rem;
  margin-right: .5625rem;
  border-radius: 6px;
  background: #e7eef8;
  color: #2c4570;
  font-size: .75rem;
  font-weight: 700;
  line-height: 1;
}

/* --- Label datagrid -------------------------------------------------------
 *
 * `.datagrid-title` milik Tabler: 11px, SEMUA KAPITAL, berjarak huruf. Satu
 * dua buah terbaca; di kolom kanan detail SPT ada tujuh bertumpuk dan seluruh
 * kolom itu berdengung. Huruf kalimat, ukuran naik, warna turun — pembacanya
 * tahu mana label dan mana nilai dari KONTRAS, bukan dari huruf kapital.
 */
.datagrid-title {
  text-transform: none;
  letter-spacing: 0;
  font-size: .75rem;
  font-weight: 500;
  color: #6e7d93;
}

.datagrid-content { font-size: .875rem; font-weight: 500; color: #1d2b3f; }

/* --- Kepala kolom tabel ---------------------------------------------------
 *
 * #CBDCEF (palet 04), bukan #f7fafd yang nyaris putih. Terukur: teks navy di
 * atasnya 9,58 : 1 — jauh di atas ambang WCAG AA 4,5:1, dan lebih dari cukup
 * untuk huruf 11px tebal berspasi.
 *
 * Biru di sini TIDAK melanggar aturan "biru dibuang dari lapisan isi". Kepala
 * tabel bukan isi, ia STRUKTUR — dan navy/biru memang warna struktur di
 * aplikasi ini: sidebar, garis bilah atas. Di tabel dua belas kolom seperti
 * Rekap SPT, kepala yang tegas adalah yang memberi tahu mata di mana ia
 * berada setelah menggulir ke samping.
 *
 * Garis bawahnya dibuang: dengan latar sepekat ini, batasnya sudah digambar
 * oleh warnanya sendiri.
 */
.table thead th {
  border-bottom: 0;
  color: #172E59;
  font-size: .6875rem;
  font-weight: 700;
  letter-spacing: .05em;
}

.table tbody tr:hover > td { background: #f8fbfe; }

/* --- Bilah fakta ----------------------------------------------------------
 *
 * Di formulir SPT, Bidang / Pagu / Sisa Pagu bukan isian: ketiganya ikut paket
 * yang dipilih. Selama bentuknya sama persis dengan label isian di atasnya,
 * tidak ada yang memberi tahu itu, dan orang mencoba mengetiknya. Latar dan
 * tepi sendiri: sekali lihat jelas ini HASIL.
 */
.fakta {
  display: flex;
  flex-wrap: wrap;
  gap: 1.25rem 2rem;
  padding: .75rem 1rem;
  background: #f4f8fc;
  border: 1px solid #e3ecf5;
  border-radius: 8px;
}

.fakta-l { font-size: .75rem; color: #6e7d93; }

.fakta-v {
  font-size: .9375rem;
  font-weight: 600;
  color: #172e58;
  font-variant-numeric: tabular-nums;
}

.fakta-v-kecil { font-size: .8125rem; font-weight: 500; color: #3d5273; }

/* --- Formulir -------------------------------------------------------------
 *
 * Cincin fokus pindah dari biru Tabler ke amber: satu-satunya warna yang
 * bergerak mengikuti kursor sebaiknya warna tema, bukan warna kelima.
 */
.form-label { font-size: .8125rem; font-weight: 600; color: #2c4570; margin-bottom: .3125rem; }
.form-label.required::after { color: #c14a4a; }

.form-control:focus,
.form-select:focus,
.ts-control.focus {
  border-color: var(--mhl-amber, #f9b313);
  box-shadow: 0 0 0 3px rgba(249, 179, 19, .22);
}

.form-text, .form-hint { font-size: .75rem; color: #7b8a9e; }

/* --- Rel kanan: Status & Riwayat jadi satu kartu --------------------------
 *
 * Dulu dua kartu, dan "Diajukan 10:24 / Diputuskan 10:26" muncul di KEDUANYA —
 * sekali sebagai baris data, sekali lagi di garis waktu tepat di bawahnya.
 * Satu kartu: siapa & sekarang di mana, lalu garis waktunya.
 */
.rel-baris {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1rem;
  padding: .5rem 0;
}

.rel-baris + .rel-baris { border-top: 1px dashed #eaeff6; }
.rel-l { font-size: .8125rem; color: #6e7d93; white-space: nowrap; }
.rel-v { font-size: .8125rem; font-weight: 600; color: #1d2b3f; text-align: right; }
.rel-v-kecil { display: block; font-size: .75rem; font-weight: 400; color: #8493a6; }

/* Garis waktu. BUKAN `.steps` milik Tabler: steps menggambar penghubungnya
 * dengan pseudo-elemen selebar langkahnya, dan di kolom 4/12 itu patah. Di
 * sini penghubungnya satu garis mutlak, jadi lebarnya tidak jadi soal. */
.lini { list-style: none; margin: 0; padding: 0 0 0 1.125rem; position: relative; }

.lini::before {
  content: "";
  position: absolute;
  left: 4px;
  top: .45rem;
  bottom: .45rem;
  width: 2px;
  background: #e4ecf4;
}

.lini-item { position: relative; padding: 0 0 .875rem; }
.lini-item:last-child { padding-bottom: 0; }

.lini-item::before {
  content: "";
  position: absolute;
  left: -1.125rem;
  top: .3125rem;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: #fff;
  border: 2px solid #c2cedd;
}

.lini-item-ok::before    { border-color: #2f9e63; }
.lini-item-tolak::before { border-color: #b02a2a; }
.lini-item-kini::before  { border-color: var(--mhl-amber, #f9b313); box-shadow: 0 0 0 3px rgba(249, 179, 19, .2); }

.lini-judul { font-size: .8125rem; font-weight: 600; color: #1d2b3f; }
.lini-meta  { font-size: .75rem; color: #8493a6; margin-top: .0625rem; }

.lini-kutip {
  margin-top: .375rem;
  padding: .375rem .5rem;
  background: #f7f9fc;
  border-radius: 6px;
  font-size: .75rem;
  color: #52637c;
}

/* --- Tombol hening di kaki kartu -----------------------------------------
 *
 * Amber dijaga untuk SATU aksi utama per layar. Di halaman detail SPT, aksi
 * utamanya bukan "Cetak" — mencetak adalah tindakan SESUDAH selesai.
 */
.btn-netral {
  --tblr-btn-color: #33455f;
  --tblr-btn-bg: #fff;
  --tblr-btn-border-color: #d7e0ea;
  --tblr-btn-hover-bg: #f2f6fb;
  --tblr-btn-hover-border-color: #c3d0e0;
  --tblr-btn-hover-color: #172e58;
  font-weight: 600;
}

/* Tombol batal / mundur: paling hening dari tiga tombol di kaki formulir,
 * tapi TIDAK merah — membatalkan isian bukan tindakan merusak. */
.btn-hening {
  --tblr-btn-color: #5b6b80;
  --tblr-btn-bg: transparent;
  --tblr-btn-border-color: transparent;
  --tblr-btn-hover-bg: #eef2f7;
  --tblr-btn-hover-border-color: transparent;
  --tblr-btn-hover-color: #172e58;
  font-weight: 500;
}

/* --- Tombol merusak: hapus, tolak, nonaktifkan ----------------------------
 *
 * BENTUKNYA DIPILIH PEMAKAINYA 2026-09-19, sesudah enam varian diadu di
 * pratinjau: latar merah sangat muda, tepi merah lembut, tulisan merah, ikon
 * tong sampah. Letaknya tetap di kanan bersama Simpan.
 *
 * Yang digantikannya `btn-bahaya-hening` — abu tanpa tepi, merahnya baru
 * muncul saat disentuh. Ia terlalu sunyi: pemakainya menyebutnya "belum sreg",
 * dan alasannya masuk akal — tombol yang menghapus baris tidak seharusnya
 * perlu disentuh dulu untuk mengaku apa dirinya.
 *
 * KENAPA BERLATAR, BUKAN SEKADAR BERTEPI. Varian yang hanya bertepi lembut
 * (#f2c9c6) terukur 1,51 : 1 terhadap kaki kartu yang putih — kotaknya nyaris
 * tak bergaris. Bentuk ini lahir dari varian "zona bahaya" berlatar merah muda
 * yang memang bekerja; yang dipindah bukan hanya tombolnya, tapi juga sepetak
 * kecil latar merah mudanya.
 *
 * Terukur: tulisan #b02a2a di atas #fdf5f5 = 6,09 : 1, jauh di atas ambang
 * WCAG AA 4,5:1.
 *
 * INI TAMPILAN, BUKAN PENJAGA. Setiap tombol merusak di aplikasi ini tetap
 * melewati dialog konfirmasi (`data-konfirmasi` varian danger), jadi salah
 * klik memunculkan dialog — bukan menghapus.
 */
.btn-bahaya {
  --tblr-btn-color: #b02a2a;
  --tblr-btn-bg: #fdf5f5;
  --tblr-btn-border-color: #f2c9c6;
  --tblr-btn-hover-bg: #fbe3e1;
  --tblr-btn-hover-border-color: #e9a9a5;
  --tblr-btn-hover-color: #8f1f1f;
  --tblr-btn-active-bg: #f8d5d2;
  --tblr-btn-active-color: #8f1f1f;
  font-weight: 600;
}

/* --- Bilah penyaring ------------------------------------------------------
 *
 * Dulu TIGA baris kendali sebelum baris data pertama: penyaring modul,
 * "Tampilkan 25 baris", dan "Cari". ui.js kini menyuntikkan dua yang terakhir
 * KE DALAM bilah penyaring ini (lihat pasangRendererTabler), jadi seluruh
 * kendali yang mengubah isi tabel berada dalam satu bidang bernada.
 */
.strip-saring {
  padding: .8125rem 1.25rem;
  background: #f7fafd;
  border-top: 1px solid #eef3f8;
  border-bottom: 1px solid #eef3f8;
}

.strip-saring .form-label { margin-bottom: .25rem; font-size: .75rem; font-weight: 600; color: #52637c; }
.strip-saring + .strip-saring { border-top: 0; }
.strip-saring-kendali { margin-top: .75rem; }
.strip-saring-kendali:only-child { margin-top: 0; }

/* --- Keadaan kosong -------------------------------------------------------
 *
 * "Belum ada data" sebagai satu baris tabel kosong, di bawah tiga baris
 * kendali dan satu kepala tabel, terbaca seperti halaman yang GAGAL MEMUAT.
 * Antrian Verifikasi adalah layar yang paling sering dibuka penyetuju dan
 * paling sering kosong: keadaan kosongnya memang layar utamanya.
 */
.kosong { padding: 3rem 1.5rem; text-align: center; }

.kosong-ikon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 3rem;
  height: 3rem;
  margin-bottom: .875rem;
  border-radius: 50%;
  background: #eaf2fb;
  color: #7d93b2;
}

.kosong-ikon .ikon { width: 1.5rem; height: 1.5rem; }
.kosong-judul { font-size: .9375rem; font-weight: 600; color: #172e58; }
.kosong-ket { margin: .25rem auto 0; max-width: 42ch; font-size: .8125rem; color: #6e7d93; }

/* --- Sel paket di daftar SPT ---------------------------------------------
 *
 * "Perjalanan Dinas Pimpinan dan Sekretariat" pecah jadi empat baris karena
 * kolom Keperluan di sebelahnya sudah dipatok lebarnya. Tinggi baris lalu
 * ditentukan kolom terpanjang, dan tabel empat baris jadi setinggi delapan.
 * Satu baris terpotong + kode sub kegiatan di bawahnya; nama lengkapnya tetap
 * ada di `title`.
 */
.paket-sel {
  display: block;
  max-width: 11rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/*
 * Kendali DataTables di dalam bilah penyaring.
 *
 * "Tampilkan _MENU_ baris" adalah SATU kalimat dengan <select> di tengahnya;
 * begitu wadah flex-nya menyempit, kalimat itu patah jadi tiga baris dan
 * kata "baris" turun sendirian. Keduanya dipaku supaya tidak ikut menyusut,
 * dan kotak cari yang mengambil sisa ruangnya.
 */
.strip-saring-kendali > * { flex-shrink: 0; }
.strip-saring-kendali .dt-length label { display: inline-flex; align-items: center; gap: .375rem; margin: 0; white-space: nowrap; }
.strip-saring-kendali .dt-length select { width: auto; }
.strip-saring-kendali .dt-search { display: flex; justify-content: flex-end; }
.strip-saring-kendali .dt-search input { min-width: 14rem; }

/* =============================================================================
 *  SPJ — kartu pengisian per pegawai
 * =============================================================================
 *  Lihat 06-rencana-modul.md, bagian "Kartu pegawai SPJ". Ringkasnya: blok per
 *  pegawai dulu ITEM AKORDEON ber-`data-bs-parent`, jadi membuka pegawai B
 *  menutup pegawai A — padahal pekerjaan di layar ini adalah mengisi SEMUA
 *  orang dalam satu SPD, hampir selalu dengan melirik angka orang sebelumnya.
 * ========================================================================== */


/* --- Kartu pegawai -------------------------------------------------------
 *
 * KARTU, BUKAN ITEM AKORDEON. Dua alasan, keduanya perilaku:
 *
 *   1. `data-bs-parent` membuat membuka pegawai B MENUTUP pegawai A. Pekerjaan
 *      di layar ini adalah mengisi SEMUA orang dalam satu SPD, dan hampir
 *      selalu dengan menyalin angka dari orang sebelumnya. Akordeon dirancang
 *      untuk MEMBACA satu bagian, bukan untuk MENGISI beberapa.
 *   2. Tiap pegawai formulirnya sendiri dan disimpan sendiri. Controller sudah
 *      mengalihkan ke `#pegawai-{id}` sehingga halaman MENGGULIR ke orang yang
 *      tepat — tapi yang TERBUKA tetap `loop.first ? 'show'`, jadi yang
 *      mendarat di layar adalah kepala kartu yang tertutup.
 *
 * Bentuknya kartu supaya sama dengan seluruh halaman lain di aplikasi ini.
 */
.kartu-pegawai { margin-bottom: 1rem; }
.kartu-pegawai:last-child { margin-bottom: 0; }

.peg-kepala {
  display: flex; align-items: center; gap: 1rem;
  width: 100%; padding: .875rem 1.25rem;
  background: #fff; border: 0; border-radius: 10px 10px 0 0;
  text-align: left; cursor: pointer;
}
.peg-kepala:hover { background: #fbfdff; }
.peg-kepala[aria-expanded="true"] { border-bottom: 1px solid #eef2f7; border-radius: 10px 10px 0 0; }
.peg-kepala[aria-expanded="false"] { border-radius: 10px; }

/* Penanda buka/tutup di KIRI, bukan kanan: ia milik judulnya, dan saat di
 * kanan ia terpisah sejauh satu layar dari nama yang dibukanya. */
.peg-panah {
  flex-shrink: 0; width: 1rem; height: 1rem; color: #8493a6;
  transition: transform .15s ease;
}
.peg-kepala[aria-expanded="true"] .peg-panah { transform: rotate(90deg); }

.peg-identitas { min-width: 0; flex: 1 1 auto; }
.peg-nama { display: block; font-size: .9375rem; font-weight: 700; color: #172e58; line-height: 1.3; }
.peg-meta {
  font-size: .75rem; color: #6e7d93; margin-top: .125rem;
  display: flex; flex-wrap: wrap; gap: .25rem .5rem; align-items: center;
}
.peg-nip { font-family: var(--tblr-font-monospace); }

/*
 * ANGKA PEGAWAI ADA DI KEPALA KARTU, bukan hanya di Rekap paling bawah.
 *
 * Saat tertutup, kepala kartu dulu hanya memuat nama, satu lencana, dan
 * jabatan. Yang paling dicari orang yang memeriksa SPJ — berapa yang
 * dibayarkan kepada orang ini — baru terlihat sesudah menggulir melewati
 * seluruh kartu pegawai sampai tabel Rekap. Sekarang ia ada di barisnya.
 */
.peg-angka { flex-shrink: 0; text-align: right; }
.peg-total {
  display: block;
  font-family: var(--tblr-font-monospace); font-variant-numeric: tabular-nums;
  font-size: 1rem; font-weight: 700; color: #172e58; line-height: 1.2;
}
.peg-total-kosong { color: #a9b4c3; font-weight: 500; }
.peg-jml { display: block; font-size: .75rem; color: #6e7d93; margin-top: .125rem; }

.peg-isi { padding: 1.125rem 1.25rem; }

/* --- Bilah kemajuan seluruh pegawai --------------------------------------
 *
 * Menggantikan alert kuning "Masih ada yang belum lengkap" yang mendaftar
 * setiap kekurangan setiap orang di puncak halaman. Daftar itu benar, tapi ia
 * jauh dari tempat pekerjaannya: yang dibutuhkan di puncak halaman adalah
 * BERAPA LAGI, dan yang dibutuhkan di kartu orangnya adalah APA.
 */
.kemajuan-peg {
  display: flex; align-items: center; gap: 1rem;
  padding: .75rem 1.25rem; margin-bottom: 1rem;
  background: #f4f8fc; border: 1px solid #e3ecf5; border-radius: 10px;
}
.kemajuan-peg-teks { font-size: .875rem; color: #33455f; }
.kemajuan-peg-teks b { color: #172e58; }
.kemajuan-ruas { display: flex; gap: 3px; flex: 1 1 auto; max-width: 18rem; }
.kemajuan-ruas span { height: 6px; border-radius: 3px; flex: 1 1 0; background: #d7e2ee; }
.kemajuan-ruas .siap { background: #2f9e63; }
.kemajuan-peg-total {
  margin-left: auto; font-family: var(--tblr-font-monospace);
  font-weight: 700; color: #172e58; font-variant-numeric: tabular-nums;
}

/* --- Bagian A: unggah ----------------------------------------------------
 *
 * Dulu dua kolom 50/50: kiri satu isian berkas, kanan satu centang untuk
 * kasus BENCANA ALAM. Kasus yang muncul sekali dalam berapa tahun memakan
 * separuh lebar baris unggah, setiap kali, untuk semua orang.
 */
.unggah-kotak {
  display: flex; flex-wrap: wrap; align-items: center; gap: .75rem;
  padding: .75rem 1rem;
  background: #f7fafd; border: 1px dashed #cdddec; border-radius: 8px;
}
.unggah-ket { font-size: .75rem; color: #6e7d93; }

.berkas-cip {
  display: inline-flex; align-items: center; gap: .4375rem;
  padding: .25rem .5rem .25rem .5625rem;
  background: #fff; border: 1px solid #dde5ee; border-radius: 999px;
  font-size: .8125rem; color: #33455f;
}
.berkas-cip .ikon { width: .875rem; height: .875rem; color: #7d93b2; }
.berkas-cip-ukuran { font-size: .6875rem; color: #8493a6; }
.berkas-cip-hapus {
  border: 0; background: transparent; color: #a9b4c3; padding: 0 0 0 .125rem;
  line-height: 1; cursor: pointer;
}
.berkas-cip-hapus:hover { color: #b02a2a; }

/* Bencana alam: satu baris hening di bawah, bukan satu kolom di samping. */
.bencana-baris {
  margin-top: .75rem; padding-top: .75rem;
  border-top: 1px dashed #eaeff6;
}
.bencana-baris .form-check-label { font-size: .8125rem; color: #52637c; }

/* --- Bagian B: tabel rincian --------------------------------------------*/

/* Kaki tabel: SUBTOTAL PEGAWAI INI. Tabel rincian dulu tidak punya <tfoot>
 * sama sekali — lima baris angka tanpa jumlah di bawahnya, dan jumlahnya baru
 * muncul di kartu Rekap beberapa layar kemudian. */
.spj-rincian tfoot td {
  border-top: 2px solid #e4ecf4;
  font-weight: 700; color: #172e58;
  background: #f7fafd;
}

/* "tidak menginap (30%)" DIPINDAH dari sel Realisasi.
 *
 * Aturannya hanya berlaku untuk PENGINAPAN, tapi kotaknya digambar di setiap
 * baris — termasuk uang harian dan taksi, tempat ia tidak berarti apa-apa —
 * dan karena ia berada di dalam sel Realisasi, ia melebarkan kolom angka itu
 * untuk seluruh tabel. Sekarang ia cip di bawah komponennya, hanya pada baris
 * yang memang bisa memakainya. */
.aturan-cip {
  display: inline-flex; align-items: center; gap: .375rem;
  margin-top: .375rem; padding: .1875rem .5rem;
  background: #fdf5e3; border: 1px solid #f4e2b6; border-radius: 6px;
  font-size: .6875rem; color: #8a5d00; white-space: normal;
}
.aturan-cip input { margin: 0; }

/* Bukti: tombol, bukan <input type=file> di setiap baris.
 * Kotak berkas adalah kendali terlebar yang ada di HTML (8rem minimum di CSS
 * sekarang), dan ia digambar di tiap baris walaupun kebanyakan baris tidak
 * pernah diisi bukti. */
.bukti-sel { min-width: 7rem; }
.bukti-tambah {
  display: inline-flex; align-items: center; gap: .3125rem;
  padding: .1875rem .4375rem; border: 1px dashed #cdddec; border-radius: 6px;
  background: transparent; color: #52637c; font-size: .75rem; cursor: pointer;
}
.bukti-tambah:hover { background: #eef4fb; border-color: #a8c6e4; color: #172e58; }
.bukti-tambah .ikon { width: .875rem; height: .875rem; }

/* --- Kaki kartu pegawai --------------------------------------------------
 *
 * Tombol Simpan dulu berada di BARIS YANG SAMA dengan lima tombol "+ kategori"
 * dan didorong ke kanan dengan `ms-auto` — bobot visual yang sama dengan
 * tombol tambah baris, padahal ia satu-satunya yang menuliskan pekerjaan ke
 * basis data. Labelnya pun dipotong di tengah nama ("Simpan isian Ding Kue,
 * S.Hut., M.A."). Sekarang ia kaki kartu tersendiri.
 */
.peg-kaki {
  display: flex; flex-wrap: wrap; align-items: center; gap: .75rem;
  padding: .875rem 1.25rem;
  background: #f7fafd; border-top: 1px solid #eef2f7; border-radius: 0 0 10px 10px;
}
.peg-kaki-info { font-size: .8125rem; color: #6e7d93; }
.peg-kaki-info b { color: #172e58; font-family: var(--tblr-font-monospace); }

/* Tombol tambah baris: kelompok chip hening di bawah tabel, dengan label —
 * lima tombol sejajar tanpa label terbaca sebagai menu utama kartu itu. */
.tambah-baris { display: flex; flex-wrap: wrap; align-items: center; gap: .375rem; margin-top: .75rem; }
.tambah-baris-label { font-size: .75rem; color: #6e7d93; margin-right: .25rem; }
.tambah-cip {
  display: inline-flex; align-items: center; gap: .3125rem;
  padding: .25rem .5625rem; border: 1px dashed #cdddec; border-radius: 999px;
  background: transparent; color: #33455f; font-size: .8125rem; cursor: pointer;
}
.tambah-cip:hover { background: #eef4fb; border-color: #a8c6e4; color: #172e58; }
.tambah-cip .ikon { width: .875rem; height: .875rem; }

/* --- Daftar kekurangan di kepala kartu ---------------------------------- */
.kurang-daftar {
  display: flex; flex-wrap: wrap; gap: .25rem;
  margin-top: .375rem;
}
.kurang-cip {
  padding: .0625rem .375rem;
  background: #fdf5e3; border: 1px solid #f4e2b6; border-radius: 4px;
  font-size: .6875rem; color: #8a5d00;
}

/*
 * Isian berkas bukti: disembunyikan, dibuka lewat labelnya (.bukti-tambah).
 *
 * BUKAN `display: none` — isian yang tidak dirender tidak ikut terkirim pada
 * sebagian browser lama dan tidak bisa menerima fokus keyboard. Bentuk di
 * bawah menyembunyikannya secara visual tapi membiarkannya tetap ada di
 * formulir dan tetap bisa dijangkau Tab lewat labelnya.
 */
.bukti-isian {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* Label yang sedang memegang berkas terpilih: sudah bukan ajakan, tapi isi. */
.bukti-tambah.berisi {
  border-style: solid;
  border-color: #cfe0f0;
  background: #f2f7fd;
  color: #172e58;
}

/* Kartu pegawai memakai .card, jadi sudut kepala & kakinya harus menyatu
   dengan sudut kartunya — Tabler membulatkan .card, bukan anaknya. */
.kartu-pegawai { overflow: hidden; }

/* Tabel rincian yang belum berisi: kepala & kaki kolom disembunyikan, barisnya
   sendiri yang membawa pesan (lihat spj/form.volt). */
.tabel-kosong thead,
.tabel-kosong tfoot { display: none; }
.tabel-kosong .kosong { padding-top: 1.5rem; padding-bottom: 1.5rem; }

/* --- Kolom rata-kanan yang diikuti kolom rata-kiri ------------------------
 *
 * Kolom uang mendorong isinya ke tepi KANAN selnya; kolom berikutnya mendorong
 * isinya ke tepi KIRI selnya. Yang tersisa di antara keduanya hanya padding sel
 * — di daftar NPD terukur 8 px antara "3.840.000,00" dan "npd/01", kira-kira
 * dua spasi. Dua fakta yang berbeda lalu terbaca sebagai satu untai.
 *
 * Diperlakukan sebagai aturan umum, bukan tambalan satu tabel: susunan itu
 * muncul di mana pun kolom uang berdampingan dengan kolom teks.
 */
.table td.text-end + td:not(.text-end),
.table th.text-end + th:not(.text-end) { padding-left: 1.25rem; }

/* =============================================================================
 *  NPD — angka utama, kartu yang bisa diisi, dan rel kanan
 * =============================================================================
 *  Lihat 06-rencana-modul.md, bagian "Halaman NPD". Ringkasnya: halaman ini
 *  memuat dua kartu yang bentuknya sama persis, dan yang lebih panjang justru
 *  yang tidak bisa disentuh siapa pun — sementara satu-satunya angka yang
 *  menjadi alasan dokumen ini ada terselip di dalamnya sebagai sel biasa.
 * ========================================================================== */


/* --- Angka utama NPD -----------------------------------------------------
 *
 * NPD adalah dokumen PERMINTAAN PENCAIRAN: satu-satunya alasan ia ada adalah
 * menyebut berapa yang harus dibayarkan. Angka itu sekarang sel datagrid
 * dengan bobot yang sama persis dengan "Tahun anggaran 2026" — dan ia berada
 * di kartu B, kartu yang justru TIDAK bisa disentuh siapa pun.
 *
 * Dinaikkan ke kartu A, di atas dua isian yang memang diketik Keuangan:
 * yang dilihat lebih dulu adalah JUMLAHNYA, lalu nomor dan tanggal yang
 * diberikan untuknya.
 */
.npd-jumlah {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: .25rem 1.25rem;
  padding: 1rem 1.25rem;
  background: #f4f8fc; border: 1px solid #e3ecf5; border-radius: 8px;
}
.npd-jumlah-label {
  flex: 0 0 100%;
  font-size: .75rem; color: #6e7d93;
}
.npd-jumlah-nilai {
  font-family: var(--tblr-font-monospace); font-variant-numeric: tabular-nums;
  font-size: 1.75rem; font-weight: 700; color: #172e58; line-height: 1.15;
}
.npd-jumlah-terbilang {
  font-size: .8125rem; font-style: italic; color: #52637c;
}

/* Kartu yang BISA DIISI diberi tepi kiri amber.
 *
 * Di halaman ini ada dua kartu yang bentuknya sama persis, tapi hanya SATU
 * yang bisa disentuh — dan yang satunya justru lebih panjang, sehingga mata
 * membacanya sebagai kartu utama. Tepi 3px cukup untuk membedakan tanpa
 * menambah satu pun kotak atau lencana. Hilang sendiri saat terkunci.
 */
/*
 * `.card.kartu-isian`, BUKAN `.kartu-isian` saja — dan ini bukan gaya menulis.
 *
 * `.tema-mahulu .card { border-color: #e3eaf3 }` berkekhususan (0,2,0);
 * `.kartu-isian` hanya (0,1,0). Dengan bentuk pendek, LEBARNYA lolos (tema
 * tidak menyetel border-width) tapi WARNANYA ditimpa — terukur tepi 3px
 * berwarna rgb(227,234,243), persis warna tepi kartu biasa. Hasilnya penanda
 * yang digambar, memakan tempat, dan tidak terlihat.
 *
 * (0,2,0) menyamakan kekhususannya, dan blok ini berada sesudahnya di berkas
 * yang sama, jadi ia yang menang.
 */
.card.kartu-isian { border-left: 3px solid var(--mhl-amber, #f9b313); }

/* --- Rel kanan -----------------------------------------------------------
 *
 * `.datagrid` di kolom 405px jatuh ke SATU item per baris dengan jarak antar
 * item yang dirancang untuk kisi berkolom banyak. Hasilnya tangga panjang:
 * label, nilai, ruang kosong, label, nilai, ruang kosong.
 *
 * `.rel-baris` (sudah dipakai rel detail SPT) menaruh label di kiri dan nilai
 * di kanan pada baris yang sama — setengah tingginya, dan nilainya berbaris
 * lurus sehingga bisa dipindai ke bawah.
 */
.rel-blok { padding-top: .75rem; margin-top: .25rem; border-top: 1px dashed #eaeff6; }
.rel-blok-judul { font-size: .8125rem; color: #6e7d93; margin-bottom: .25rem; }
.rel-blok-isi { font-size: .8125rem; color: #1d2b3f; }
.rel-pegawai { list-style: none; margin: 0; padding: 0; }
.rel-pegawai li { padding: .3125rem 0; }
.rel-pegawai li + li { border-top: 1px dashed #eaeff6; }
.rel-pegawai-nama { font-size: .8125rem; font-weight: 600; color: #1d2b3f; }
.rel-pegawai-jabatan { font-size: .75rem; color: #8493a6; }

/* =============================================================================
 *  SPM & SP2D
 * =============================================================================
 *  Lihat 06-rencana-modul.md, bagian "SPM & SP2D".
 * ========================================================================== */


/* --- Angka utama SPM ------------------------------------------------------
 * Sama persis dengan `.npd-jumlah` yang sudah dipasang: SPM adalah PERINTAH
 * MEMBAYAR, dan totalnya sekarang sel datagrid di antara "Tahun anggaran" dan
 * "Terbilang". Kelasnya dipakai ulang, bukan dibuat kembar. */

/* --- Alur SPM ------------------------------------------------------------
 *
 * `.steps` milik Tabler memasang `.active` dengan benar, dan ia MEMANG
 * membedakan langkah sesudah yang aktif. Yang tidak dikenalnya: SELESAI vs
 * SEKARANG — keduanya digambar sama. Akibatnya habis di keadaan terakhir:
 * pada SPM yang SP2D-nya sudah terbit, terukur ketiga titiknya identik
 * (oklch(0.546 0.1724 254.2), 8px), jadi SPM yang sudah selesai sepenuhnya
 * terlihat persis seperti SPM yang baru sampai langkah ketiga. Titiknya pun
 * biru — rona yang sudah dikeluarkan dari lapisan isi.
 *
 * `.lini` (dipakai riwayat SPT) sudah mengenal tiga keadaan: selesai, sekarang,
 * dan belum. Di sini ia dipakai apa adanya, hanya ditambah nada "belum".
 */
.lini-item-belum::before { border-color: #dbe2ea; background: #f4f6f9; }
.lini-item-belum .lini-judul { color: #8493a6; font-weight: 500; }
.lini-item-belum .lini-meta  { color: #a9b4c3; }

/* --- Sel kegiatan di tabel SPJ -------------------------------------------
 *
 * `.spd-keperluan` (max-width 9rem) muncul lagi di sini — kelas sel tabel
 * Antrian SPD yang sepuluh kolom, dipakai di tabel tujuh kolom selebar 825px
 * yang justru lapang. Terukur: kotak 144 × 88 px, dan barisnya jadi 136 px.
 *
 * Nama paket dipotong satu baris (nama utuhnya di `title`), keperluannya
 * dibiarkan mengalir selebar selnya.
 */
/*
 * `display: block` WAJIB. `max-width` tidak berlaku pada elemen inline, dan
 * `.spm-kegiatan` sebuah <span>: tanpa ini keperluannya yang ber-`nowrap`
 * merentang sepanjang kalimatnya dan mendorong kolom Bidang, Total NPD, serta
 * kolom aksi keluar dari tabel. Jebakan yang sama sudah dicatat di
 * `.spj-komponen`.
 */
.spm-kegiatan { display: block; max-width: 17rem; }
.spm-kegiatan-nama {
  display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-weight: 500; color: #1d2b3f;
}
.spm-kegiatan-ket {
  display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: .75rem; color: #8493a6;
}

/* Kaki tabel SPJ: jumlah dibaca sebagai jumlah, bukan sebagai baris biasa. */
.card-table tfoot td { border-top: 2px solid #e4ecf4; background: #f7fafd; font-weight: 700; color: #172e58; }

/* --- Tanda jenis pencairan ----------------------------------------------
 * `badge bg-blue-lt` — satu-satunya biru tersisa di dua halaman ini, dan ia
 * JENIS, bukan status. `.tag-peran` sudah ada untuk persoalan yang sama
 * ("Kadis" di daftar SPT). */

/* --- Kartu rel: alur + tindakan jadi satu -------------------------------- */
.rel-tindakan { margin-top: 1rem; padding-top: 1rem; border-top: 1px dashed #eaeff6; }
.rel-tindakan .btn + .btn,
.rel-tindakan .btn + form { margin-top: .5rem; }
.rel-tindakan form { margin: 0; }

/* --- Hitungan antrian verifikasi ------------------------------------------
 *
 * Dulu `badge bg-red`. Merah di aplikasi ini berarti SATU hal — ada yang
 * salah: ditolak, gagal, bentrok. Hitungan antrian bukan kesalahan, ia beban
 * kerja, dan bagi Keuangan ia nyaris tidak pernah nol. Merah yang menyala
 * setiap hari berhenti berarti apa-apa, dan yang ikut mati bersamanya adalah
 * merah di tempat yang benar-benar membutuhkannya.
 *
 * Navy di atas biru muda: tetap terbaca dari jauh tanpa meminjam arti.
 */
.hitung-antrian {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.25rem;
  height: 1.25rem;
  margin-left: .375rem;
  padding: 0 .3125rem;
  border-radius: 999px;
  background: #dbe6f4;
  color: #23406e;
  font-size: .6875rem;
  font-weight: 700;
  line-height: 1;
}

/* Tab yang sedang dibuka sudah berlatar putih, jadi hitungannya dibalik
 * supaya kontrasnya tidak hilang. */
.nav-link.active .hitung-antrian { background: #172e58; color: #fff; }

/* --- Petunjuk memakai alat ------------------------------------------------
 *
 * "12 kolom — geser tabel ke samping" bukan keterangan ISI, ia petunjuk
 * MEKANIK: keterangan isi dibaca sekali lalu selesai, petunjuk mekanik
 * dibutuhkan setiap kali — bahkan oleh yang sudah hafal isinya. Digabung jadi
 * satu paragraf, keduanya sama-sama terlewat.
 */
.mekanik-baris {
  display: flex;
  align-items: center;
  gap: .4375rem;
  margin-top: .5rem;
  padding: .375rem .625rem;
  border-radius: 6px;
  background: #f1f6fc;
  color: #46586f;
  font-size: .75rem;
}

.mekanik-baris .ikon { width: .9375rem; height: .9375rem; flex-shrink: 0; color: #7b8a9e; }
.mekanik-baris strong { color: #172e58; }

/* --- Sel yang mengulang baris di atasnya ----------------------------------
 *
 * Daftar SBU memakai 312 px dari 1178 px — 26% lebar tabelnya — untuk dua
 * kolom yang isinya nyaris sama di semua baris. Nilainya digambar sekali di
 * baris pertama kelompoknya, lalu diam. Aman karena pengurutan tabel ini
 * dikerjakan SERVER (serverSide: true): yang dibandingkan selalu baris yang
 * benar-benar bersebelahan di layar, bukan urutan yang dibekukan saat render.
 */
.sel-ulang { color: transparent; user-select: none; }
.sel-ulang::before { content: "·"; color: #d3dceb; }

/* --- Kepala kartu daftar: kelompok aksi -----------------------------------
 *
 * Aksi sekunder dikelompokkan, aksi utama berdiri sendiri di paling kanan.
 * `btn-list` yang rata membungkus di titik yang salah begitu labelnya panjang:
 * di Daftar Program pada 1500 px, tombol amber jatuh ke baris bawah — posisi
 * paling lemah untuk aksi terpenting halaman itu. Sekarang yang turun lebih
 * dulu adalah kelompok sekundernya.
 */
.kepala-aksi { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; justify-content: flex-end; }
.kepala-aksi-lain { display: inline-flex; gap: .5rem; flex-wrap: wrap; }

/* Kolom yang isinya hanya digambar di baris pertama (MasterController::
 * kolomUlangan). DataTables menghitung lebar kolom dari isi tarikan PERTAMA
 * dan tidak tahu baris berikutnya akan diam, jadi lebarnya tetap sebesar teks
 * terpanjangnya walau 90% selnya kosong. Dipatok di sini; nilainya yang
 * sekali itu boleh membungkus. */
.kol-ulang { width: 7rem; max-width: 7rem; white-space: normal; }

/* Judulnya ikut membungkus — kelasnya dipasang di <th> juga (master/daftar.volt),
 * dan tanpa ini judul melebar melewati selnya lalu menabrak kolom sebelahnya.
 *
 * KEKHUSUSANNYA DINAIKKAN. `th.kol-ulang` (0,1,1) kalah dari
 * `table.dataTable thead > tr > th.dt-orderable-asc` (0,2,4) milik DataTables,
 * yang memasang `white-space: nowrap` pada setiap kepala kolom yang bisa
 * diurutkan. Terukur sebelum diperbaiki: sel 112 px, isinya 137 px, menjulur
 * menimpa judul kolom sebelahnya. Jebakan yang sama sudah tercatat untuk
 * `.laporan-beku`. */
table.dataTable thead > tr > th.kol-ulang,
table.dataTable thead > tr > th.kol-ulang.dt-orderable-asc,
table.dataTable thead > tr > th.kol-ulang.dt-orderable-desc { white-space: normal; }

/* Kode di dalam kolom sempit ini boleh patah. `.nomor-dok` ber-nowrap di mana
 * pun — benar untuk nomor dokumen di kolomnya sendiri, tapi di sini ia
 * menjulur keluar sel dan menimpa tombol aksinya. */
.kol-ulang .nomor-dok { white-space: normal; word-break: break-all; }


/* =============================================================================
 *  HALAMAN MASUK
 * =============================================================================
 *
 *  Dua kolom: identitas di kiri di atas foto Mahakam Ulu, kartu masuk di kanan.
 *
 *  OPSI 3 DARI TIGA YANG DISIAPKAN PERANCANGNYA — empat pojok sebagai empat
 *  berkas terpisah, bukan satu lembar bingkai selebar layar.
 *
 *  Alasannya terhitung, bukan selera. Lembar bingkai itu 1920 x 947 (rasio
 *  2,03); dipaksa mengisi wadah dengan `background-size: 100% 100%`, motifnya
 *  tergambar 87,7% dari lebar seharusnya pada layar 16:9, 65,8% pada 4:3, dan
 *  115% pada 21:9. Batik yang dipipihkan sepertiga bukan batik yang sama.
 *  Empat berkas terpisah tidak pernah diregangkan: yang berubah hanya jarak
 *  antar pojoknya.
 *
 *  Opsi 1 (satu foto utuh, judul ikut tercetak di dalamnya) ditolak karena
 *  judulnya lalu jadi GAMBAR: tidak terbaca pembaca layar, buram di layar
 *  beresolusi tinggi, dan mengganti satu kata berarti menggambar ulang.
 * ========================================================================== */

.masuk {
  position: relative;
  display: flex;
  align-items: center;
  min-height: 100vh;
  overflow: hidden;
  background: var(--mhl-navy, #172E59);
}

/*
 * `cover`, bukan `100% 100%`: fotonya memenuhi layar pada rasio apa pun dan
 * yang berlebih DIPOTONG — bukan dipipihkan. Untuk foto pemandangan, terpotong
 * sedikit di tepi tidak ada yang kehilangan; dipipihkan langsung terlihat.
 */
.masuk-latar {
  position: absolute;
  inset: 0;
  background-image: url("/assets/img/login/latar-hutan.jpg");
  background-size: cover;
  background-position: center;
}

/* Empat pojok, masing-masing dipaku ke pojoknya sendiri. `pointer-events: none`
 * karena ia hiasan: tanpa itu ia menutupi isian yang kebetulan berada di
 * bawahnya dan klik pemakainya tidak sampai. */
.masuk-pojok { position: absolute; pointer-events: none; }
.masuk-pojok img { display: block; width: 100%; height: auto; }

.masuk-pojok-ka        { top: 0;    left: 0;  width: 7rem; }
.masuk-pojok-kn-atas   { top: 0;    right: 0; width: 9rem; }
.masuk-pojok-kn-bawah  { bottom: 0; right: 0; width: 8.5rem; }
.masuk-pojok-kr-bawah  { bottom: 0; left: 0;  width: 26rem; }

/*
 * MARGIN KIRI-KANAN ADALAH KOLOM GRID, BUKAN PADDING.
 *
 * Keempat angkanya dibaca langsung dari piksel mockup (2132 x 1051):
 *
 *     10,5%  |  sisanya  |  25,9%  |  12,8%
 *      tepi     identitas   kartu     tepi
 *
 * Bentuk sebelumnya memakai padding `clamp(1.5rem, 4vw, 4.5rem)` di kedua
 * sisi — terukur 4,0% kiri dan 3,8% kanan, kurang dari separuh jarak mockup.
 * Judulnya nyaris menempel tepi layar dan kartu masuk menempel tepi kanan.
 *
 * DAN KENAPA BUKAN PADDING. Percobaan pertama memakai padding 10,5%/12,8%
 * dengan kolom kartu 25,9%; kartunya terukur 19,9%. Sebabnya persentase lebar
 * kolom grid dihitung terhadap kotak ISI — sesudah padding dipotong: 25,9%
 * dari 76,7% = 19,9%. Angka yang benar terhadap acuan yang salah. Dijadikan
 * kolom, keempatnya diukur terhadap lebar penuh dan jumlahnya persis 100%.
 *
 * Tidak ada `gap`: jaraknya sudah terkandung di lebar kolomnya sendiri.
 */
.masuk-isi {
  position: relative;
  width: 100%;
  display: grid;
  grid-template-columns: 10.5% minmax(0, 1fr) 25.9% 12.8%;
  align-items: center;
  padding: 2.5rem 0 4.5rem;
}

.masuk-hero  { grid-column: 2; }
.masuk-kartu { grid-column: 3; }

/* --- kiri: identitas ------------------------------------------------------ */

.masuk-merek { display: flex; align-items: center; gap: .875rem; margin-bottom: clamp(1.5rem, 5vh, 3.5rem); }
.masuk-merek img { width: 3rem; height: 3rem; flex-shrink: 0; }

.masuk-merek-teks {
  font-size: clamp(.8125rem, 1.1vw, 1rem);
  font-weight: 800;
  line-height: 1.25;
  letter-spacing: .01em;
  color: var(--mhl-navy, #172E59);
  text-transform: uppercase;
}

/*
 * `clamp()` di mana-mana, bukan titik henti bertingkat: judul setinggi 3,25rem
 * pada layar lebar harus turun mulus, bukan meloncat, karena di antara dua
 * titik henti ia akan membungkus di tempat yang tidak diinginkan.
 */
/*
 * 3,2vw, bukan 3,6vw.
 *
 * Sejak margin mengikuti proporsi mockup, kolom identitas menyempit dari
 * 840 px ke 694 px pada layar 1366 — ukuran laptop yang paling umum. Pada
 * 3,6vw baris ketiga ("KABUPATEN MAHAKAM ULU") tidak lagi muat dan pecah jadi
 * EMPAT baris di sana, sementara di 1600 ia tetap tiga.
 *
 * Kenapa bedanya hanya muncul di layar kecil: `clamp` memaku batas atasnya di
 * 3,25rem = 52 px. Pada 1600 ke atas ukurannya SUDAH terpotong batas itu, jadi
 * ada kelonggaran; pada 1366, 3,6vw = 49 px masih di bawah batas dan tumbuh
 * penuh mengikuti layar. Terhitung: baris terpanjangnya butuh lebar kolom
 * sekitar 15,6 kali ukuran hurufnya, dan 3,6vw hanya menyisakan 14,1.
 */
.masuk-judul {
  margin: 0 0 .75rem;
  font-size: clamp(1.75rem, 3.2vw, 3.25rem);
  font-weight: 800;
  line-height: 1.1;
  letter-spacing: -.01em;
  color: var(--mhl-navy, #172E59);
  text-transform: uppercase;
}

.masuk-judul .kuning { color: #FCB920; }

/*
 * 30rem, bukan 38ch.
 *
 * Kalimatnya 107 huruf — sama panjang dengan mockup, dan di mockup ia patah
 * jadi DUA baris. Dengan 38ch kotaknya terukur 328 px: 40% lebih sempit dari
 * mockup (33,7% lebar layar), dan kalimat yang sama pecah jadi TIGA baris.
 * Yang salah kotaknya, bukan kalimatnya.
 */
.masuk-ket {
  margin: 0;
  max-width: 30rem;
  font-size: clamp(.8125rem, 1.1vw, 1rem);
  line-height: 1.55;
  color: #203864;
}

.masuk-rute { margin-top: clamp(1.25rem, 4vh, 2.5rem); max-width: 26rem; }
.masuk-rute img { display: block; width: 100%; height: auto; }

/* --- kanan: kartu masuk --------------------------------------------------- */

/* Lebarnya ditentukan kolom gridnya (25,9%), bukan dipatok 26rem: dipatok,
 * ia memaksa kolom identitas menyempit di layar kecil alih-alih ikut mengecil
 * bersama layarnya. */
.masuk-kartu {
  width: 100%;
  background: #fff;
  border-radius: 1.25rem;
  padding: 2.25rem 2rem;
  box-shadow: 0 1.5rem 3rem rgba(23, 46, 89, .18);
}

.masuk-kartu-merek { display: block; width: 11rem; margin: 0 auto 1.25rem; }

.masuk-kartu h1 {
  margin: 0 0 .25rem;
  text-align: center;
  font-size: 1.625rem;
  font-weight: 800;
  color: var(--mhl-navy, #172E59);
}

.masuk-kartu-ket { margin: 0 0 1.5rem; text-align: center; font-size: .8125rem; color: #5b6b80; }

.masuk-isian { margin-bottom: .875rem; }
.masuk-isian .form-label { margin-bottom: .25rem; font-size: .75rem; font-weight: 600; color: #52637c; }

.masuk-kartu .form-control,
.masuk-kartu .form-select {
  padding: .625rem .875rem;
  border-radius: .625rem;
  border-color: #d7e0ea;
  font-size: .875rem;
}

.masuk-kartu .form-control:focus,
.masuk-kartu .form-select:focus {
  border-color: #FCB920;
  box-shadow: 0 0 0 .1875rem rgba(252, 185, 32, .25);
}

/* Tombol mata: input-group-flat milik Tabler menggambar tepinya sendiri, jadi
 * jari-jarinya perlu disamakan dengan isian lain. */
.masuk-kartu .input-group-flat .form-control { border-top-right-radius: 0; border-bottom-right-radius: 0; }
.masuk-kartu .input-group-flat .input-group-text {
  border-color: #d7e0ea;
  border-top-right-radius: .625rem;
  border-bottom-right-radius: .625rem;
  /*
   * TINGGI ISIAN SANDI DISAMAKAN DENGAN ISIAN LAIN.
   *
   * Terukur sebelum ini: username 42 px, kata sandi 60 px — selisih 18 px,
   * dan terlihat karena keduanya bersebelahan tegak.
   *
   * Penyebabnya BUKAN isiannya. `.input-group` meregangkan seluruh anaknya
   * setinggi anak TERTINGGI, dan yang tertinggi adalah sel ini: padding 9px
   * atas-bawah DITAMBAH tinggi bawaan `.btn` di dalamnya. Isian sandinya ikut
   * diregangkan, bukan tumbuh sendiri — jadi yang disetel sel pembungkusnya.
   */
  padding-top: 0;
  padding-bottom: 0;
}

.masuk-kartu .input-group-text .btn {
  display: flex;
  align-items: center;
  height: auto;
  min-height: 0;
  padding: 0;
  line-height: 1;
}

/*
 * NAVY DENGAN TULISAN AMBER, kebalikan tombol utama di dalam aplikasi.
 *
 * Di sini ia satu-satunya tombol di layar, dan latarnya foto berwarna — amber
 * penuh akan bersaing dengan langit senja di belakangnya. Navy pekat justru
 * yang paling terbaca di atas foto apa pun.
 *
 * Terukur: amber #FCB920 di atas navy #172E59 = 7,70 : 1, jauh di atas ambang
 * WCAG AA 4,5:1 — dan itu untuk huruf tebal 16px, yang ambangnya bahkan lebih
 * longgar.
 */
.masuk-tombol {
  width: 100%;
  margin-top: .75rem;
  padding: .75rem 1rem;
  border: 0;
  border-radius: .625rem;
  background: var(--mhl-navy, #172E59);
  color: #FCB920;
  font-size: 1rem;
  font-weight: 700;
}

.masuk-tombol:hover { background: #203864; }
.masuk-tombol:focus-visible { outline: 3px solid #FCB920; outline-offset: 2px; }

.masuk-bantuan { margin: 1rem 0 0; text-align: center; font-size: .75rem; color: #6e7d93; }

/* --- kaki ----------------------------------------------------------------- */

.masuk-kaki {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  /* Sejajar dengan judul dan kartu, bukan dengan tepi layar. */
  padding: .875rem 12.8% .875rem 10.5%;
  font-size: .75rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, .85);
  text-shadow: 0 1px 3px rgba(0, 0, 0, .35);
  pointer-events: none;
}

/* --- layar sempit ---------------------------------------------------------
 *
 * Di bawah 992px kolom kiri DIBUANG, bukan diciutkan. Dipaksa menyempit, judul
 * setinggi tiga baris bertabrakan dengan grafik rute dan baris kaki — terlihat
 * jelas pada bingkai 4:3 di pratinjau. Yang dibutuhkan orang di layar sempit
 * adalah kotak isiannya, bukan kalimat yang sudah ia baca kemarin.
 *
 * Pojok kiri-bawah ikut disembunyikan: lebarnya 26rem, dan di layar 360px ia
 * menutupi lebih dari separuh kartu.
 */
@media (max-width: 991.98px) {
  .masuk-isi { grid-template-columns: 1fr; justify-items: center; padding: 2rem 1rem 3.5rem; }
  .masuk-hero { display: none; }
  /* `grid-column: auto` WAJIB: kolom 3 tidak ada lagi di grid satu kolom, dan
   * tanpa ini kartunya tersorong ke baris ketiga — dua baris kosong di atasnya. */
  .masuk-kartu { grid-column: auto; width: 100%; max-width: 26rem; }
  .masuk-pojok-kr-bawah { display: none; }
  .masuk-pojok-ka { width: 4.5rem; }
  .masuk-pojok-kn-atas { width: 5.5rem; }
  .masuk-pojok-kn-bawah { width: 5rem; }
  .masuk-kaki { padding-left: 1rem; padding-right: 1rem; text-align: center; font-size: .6875rem; }
}

/* Layar sangat pendek: kartu tidak boleh dipaksa di tengah kalau isinya sudah
 * lebih tinggi dari layar — ia harus bisa digulir. */
@media (max-height: 640px) {
  .masuk { align-items: flex-start; }
}

/* --- Baris tab di kepala halaman ------------------------------------------
 *
 * `.page-header-sub` kini satu-satunya rumah baris tab (2026-09-19), dan
 * penggambarnya satu untuk kedua gaya — segmented dan bordered. Yang
 * bordered tidak lagi dibungkus <ul>/<li>.
 *
 * Tabler memasang jarak antar tabnya di `.nav-bordered .nav-item + .nav-item`,
 * yaitu pada PEMBUNGKUSNYA. Tanpa <li>, jaraknya hilang seluruhnya dan kelima
 * tab Laporan tercetak berdempetan: "Rekap SPTRekap SPDRekap SPJ…". Aturan di
 * bawah memindahkan jarak yang sama ke tautannya sendiri.
 *
 * `.nav-segmented` tidak ikut: ia memakai `gap` pada wadahnya, bukan margin
 * pada anaknya.
 */
.page-header-sub .nav-bordered .nav-link + .nav-link { margin-inline-start: 1.25rem; }

/* --- Sidebar ciut: gulirannya dikembalikan --------------------------------
 *
 * Tabler menyetel `.navbar-folded .navbar-collapse { overflow: visible }`,
 * dan alasannya masuk akal UNTUK TABLER: pada rel selebar 4rem, submenu
 * dimunculkan melayang ke samping, dan overflow yang memotong akan
 * menggunting flyout itu.
 *
 * SIDEBAR APLIKASI INI TIDAK PUNYA FLYOUT. Anak menu digambar sebagai item
 * biasa yang menjorok, bukan dropdown (lihat catatan di index.volt) —
 * satu-satunya `dropdown-menu` di kerangka ini milik chip Cakupan dan Tahun di
 * bilah atas. Jadi `overflow: visible` tidak membeli apa pun di sini, dan yang
 * dibayar mahal: GULIRANNYA MATI.
 *
 * Terukur pada layar 760 px: isi menu 933 px di dalam kotak 676 px, jadi
 * 257 px di bawahnya tidak bisa dijangkau sama sekali — `scrollTop` tetap 0
 * berapa kali pun digulir. Item menu paling bawah hilang, tanpa satu pun galat.
 *
 * `overflow-x: hidden` ditulis eksplisit: menyetel `overflow-y` saja membuat
 * sumbu X yang tadinya `visible` ikut dihitung sebagai `auto`, dan bilah gulir
 * mendatar muncul di rel selebar 4rem.
 */
/*
 * SELEKTORNYA MENCERMINKAN MILIK TABLER, bukan memakai !important.
 *
 * Aturan yang dikalahkan berbunyi:
 *
 *   .navbar-vertical.navbar-expand-sm:is(.navbar-folded,
 *     .navbar-folded-hover:not(:hover):not(:has(:focus-visible))) .navbar-collapse
 *
 * `:is()` mengambil kekhususan argumen TERKUATNYA, jadi totalnya (0,6,0).
 * Percobaan pertama saya `.tema-mahulu .navbar-vertical.navbar-folded
 * .navbar-collapse` hanya (0,4,0) dan kalah — tanpa satu pun galat, dan
 * pemindaian `document.styleSheets` pun tidak memperlihatkannya karena
 * aturannya bersarang di dalam @media `navbar-expand-lg`.
 *
 * Bentuk yang sama ditiru di sini lalu diberi awalan `.tema-mahulu`: (0,7,0),
 * menang telak, tetap terkurung di dalam tema.
 */
.tema-mahulu .navbar-vertical.navbar-expand-lg:is(.navbar-folded,
  .navbar-folded-hover:not(:hover):not(:has(:focus-visible))) .navbar-collapse {
  overflow-y: auto;
  overflow-x: hidden;
}

/* --- Kepala halaman tanpa baris tab ---------------------------------------
 *
 * `min-height: 2.25rem` bawaan Tabler dinolkan.
 *
 * Nilai itu menyediakan ruang untuk JUDUL halaman. Di aplikasi ini judulnya
 * sudah pindah ke `.topbar-baris` yang `position: fixed` — ia keluar dari alur
 * sama sekali. Yang tersisa 36 px yang tidak menampung apa pun, dan hanya di
 * halaman TANPA baris tab: di halaman bertab, `.page-header-sub` setinggi
 * 60 px sudah melebihi nilai itu sehingga ia tidak pernah aktif.
 *
 * Akibatnya iramanya pecah. Terukur, jarak dari garis amber ke benda pertama:
 *
 *     halaman bertab   : 20 px  -> baris tab -> 20 px -> kartu
 *     halaman tanpa tab: 36 px KOSONG + 20 px = 56 px -> kartu
 *
 * 20 px adalah satuan "kerangka ke isi" milik aplikasi ini, dipakai DUA KALI
 * di halaman bertab. Halaman tanpa tab sekarang memakai satuan yang sama.
 *
 * Bukan dikurangi separuh: ruang harus lahir dari sesuatu, bukan tertinggal
 * dari sesuatu yang sudah pindah. Kalau kelak 20 px terasa rapat, yang diubah
 * iramanya — untuk semua jenis halaman sekaligus — bukan sisa cadangan ini.
 *
 * Halaman bertab TIDAK berubah sedikit pun.
 */
.tema-mahulu .page-header { min-height: 0; }

/* Catatan di samping formulir ganti kata sandi. Kelas, bukan `style=`:
 * CSP `style-src 'self'` membuang atribut style tanpa satu pun galat. */
.catatan-akun { font-size: .8125rem; line-height: 1.7; color: #6e7d93; }
.catatan-akun li + li { margin-top: .5rem; }
