/* Tukanggaji — komponen UI.
   RINTISAN (T0.1): baru memuat kerangka, menu, kartu, form, dan tombol —
   secukupnya agar login & beranda tampil benar.
   T0.3 memiliki file ini dan melengkapinya: tabel angka, chip status,
   panel peringatan, drawer kanan, fallback mobile (STANDARDS §4.2–4.3).
   Semua nilai HARUS mengacu ke var() dari tokens.css. */

*, *::before, *::after { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font);
  font-size: 14px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

a { color: inherit; text-decoration: none; }
a:hover { text-decoration: underline; }

.lemah { color: var(--muted); }

/* ================= KERANGKA ================= */

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

.samping {
  width: 200px;
  flex: 0 0 200px;
  border-right: 1px solid var(--border);
  background: var(--surface);
  padding: var(--sp-5) var(--sp-4);
  display: flex;
  flex-direction: column;
}

.merek {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  font-weight: 600;
  letter-spacing: -0.02em;
  margin-bottom: var(--sp-6);
}
.merek-logo {
  width: 28px; height: 28px;
  flex: none;
  border-radius: var(--radius-kecil);
  border: 1px solid var(--border);
}

/* Judul kelompok menu (Gajian / Master, 2026-08-17). Menu sebelumnya sembilan
   item datar tanpa hierarki — layar yang dipakai tiap bulan bercampur dengan
   master yang jarang disentuh. */
.menu-grup {
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  margin: var(--sp-4) var(--sp-3) var(--sp-2);
}
.menu-grup:first-of-type { margin-top: 0; }

.menu { list-style: none; margin: 0; padding: 0; }
.menu:last-of-type { flex: 1; }
.menu li { margin-bottom: var(--sp-1); }
.menu a {
  display: block;
  padding: var(--sp-2) var(--sp-3);
  border-radius: var(--radius-kecil);
  color: var(--muted);
  transition: background var(--transisi), color var(--transisi);
}
.menu a:hover { background: var(--surface-2); color: var(--ink); text-decoration: none; }
.menu a.aktif {
  background: var(--biru-bg);
  color: var(--biru-ink);
  font-weight: 700;
}

.samping-kaki {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--sp-2);
  padding-top: var(--sp-4);
  border-top: 1px solid var(--border);
  font-size: 13px;
}

.isi {
  flex: 1;
  min-width: 0;
  padding: var(--sp-7) var(--sp-6);
  max-width: 1200px;
}

.judul-halaman { margin-bottom: var(--sp-6); }
.judul-halaman h1 {
  margin: 0 0 var(--sp-1);
  font-size: 24px;
  font-weight: 600;
  letter-spacing: -0.02em;
}
.judul-halaman p { margin: 0; }

/* ================= KARTU ================= */

.bento {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: var(--sp-4);
}

.kartu {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: var(--sp-5);
  transition: box-shadow var(--transisi);
}
.kartu:hover { box-shadow: 0 2px 8px rgba(0,0,0,.04); }
.kartu h2 {
  margin: 0 0 var(--sp-3);
  font-size: 13px;
  font-weight: 500;
  color: var(--muted);
}

.angka-besar {
  margin: 0;
  font-family: var(--font-angka);
  font-variant-numeric: tabular-nums;
  font-size: 30px;
  letter-spacing: -0.02em;
}

/* ================= KABAR ================= */

.kabar {
  padding: var(--sp-3) var(--sp-4);
  border-radius: var(--radius-kecil);
  margin-bottom: var(--sp-4);
  font-size: 13px;
}
.kabar-info  { background: var(--biru-bg);   color: var(--biru-ink); }
.kabar-galat { background: var(--merah-bg);  color: var(--merah-ink); }
.kabar-oke   { background: var(--hijau-bg);  color: var(--hijau-ink); }
.kabar-awas  { background: var(--kuning-bg); color: var(--kuning-ink); }

/* ================= FORM & TOMBOL ================= */

label { display: block; margin-bottom: var(--sp-4); font-size: 13px; color: var(--muted); }

input[type=text], input[type=password], input[type=number], input[type=date],
input[type=search], textarea, select {
  display: block;
  width: 100%;
  margin-top: var(--sp-1);
  padding: var(--sp-2) var(--sp-3);
  font-family: var(--font);
  font-size: 14px;
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-kecil);
  transition: border-color var(--transisi);
}
input:focus, textarea:focus, select:focus { outline: none; border-color: var(--ink); }

/* Fokus keyboard harus terlihat tanpa mengubah bahasa visual input saat
   diklik. Ring luar dipakai agar field yang berada di atas tint kolom tabel
   tetap terbaca fokusnya, termasuk untuk navigasi Tab. */
input:focus-visible, textarea:focus-visible, select:focus-visible,
button:focus-visible, a:focus-visible {
  outline: 2px solid var(--biru-ink);
  outline-offset: 2px;
}

/* Semua field teks berbagi tinggi dan perilaku yang sama; textarea tetap
   boleh tumbuh vertikal untuk keterangan bonus dan catatan. */
textarea {
  min-height: 88px;
  resize: vertical;
}

.tombol {
  display: inline-block;
  padding: var(--sp-2) var(--sp-4);
  font-family: var(--font);
  font-size: 14px;
  border: 1px solid transparent;
  border-radius: var(--radius-kecil);
  cursor: pointer;
  transition: background var(--transisi), transform var(--transisi);
}
.tombol:active { transform: scale(.98); }
.tombol:disabled, .tombol-kecil:disabled {
  opacity: .55;
  cursor: not-allowed;
  transform: none;
}

.tombol-utama { background: var(--ink); color: #fff; }
.tombol-utama:hover { background: #333; }

/* Aksi berat (finalkan, hapus, buka kunci) sengaja TIDAK solid —
   tidak boleh terlihat seperti tombol bawaan (STANDARDS §4.1). */
.tombol-bahaya {
  background: transparent;
  color: var(--merah-ink);
  border-color: var(--merah-ink);
}
.tombol-bahaya:hover { background: var(--merah-bg); }

/* ================= LAYAR MASUK ================= */
/* Dirapikan 2026-08-23 (owner: "buat di login ... yg cantik") — sebelumnya
   cuma judul teks polos di atas kartu putih. Warna tambahannya SEMUA dari
   token netral yang sudah ada (bg/surface/surface-2/border) — tokens.css
   sendiri melarang memakai aksen pastel (merah/hijau/kuning/biru) sebagai
   hiasan, jadi kesan "cantik" datang dari gambar maskot + tipografi + ruang,
   bukan warna baru. */

.halaman-masuk {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100vh;
  padding: var(--sp-4);
  /* Latar bertingkat lembut, bukan warna rata — kedalaman tanpa menambah
     token warna baru: dua nada netral yang sudah ada, disusun radial. */
  background: radial-gradient(ellipse 900px 600px at 50% -10%, var(--surface-2), var(--bg) 70%);
}

.kartu-masuk {
  width: 100%;
  max-width: 340px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: var(--sp-6);
  text-align: center;
  /* Satu-satunya kartu di layar ini — satu bayangan lembut menegaskannya
     mengambang di atas latar, bukan menempel rata seperti kartu daftar. */
  box-shadow: 0 8px 32px rgba(0,0,0,.06);
}
.kartu-masuk-logo {
  display: block;
  width: 88px; height: 88px;
  margin: 0 auto var(--sp-4);
  border-radius: var(--radius);
  border: 1px solid var(--border);
}
.kartu-masuk .merek-besar {
  margin: 0;
  font-size: 22px;
  font-weight: 600;
  letter-spacing: -0.02em;
}
.kartu-masuk > p.lemah { margin: 0 0 var(--sp-5); font-size: 13px; }
.kartu-masuk label,
.kartu-masuk .kabar { text-align: left; }
.kartu-masuk .tombol { width: 100%; margin-top: var(--sp-2); }

/* ================= TOMBOL TAMBAHAN ================= */

.tombol-kecil {
  padding: var(--sp-1) var(--sp-3);
  font-size: 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-kecil);
  background: var(--surface);
  color: var(--ink);
  cursor: pointer;
  transition: background var(--transisi), border-color var(--transisi);
}
.tombol-kecil:hover { background: var(--surface-2); }

.tombol-sekunder {
  background: var(--surface);
  color: var(--ink);
  border-color: var(--border);
}
.tombol-sekunder:hover { background: var(--surface-2); }

/* ================= CHIP STATUS ================= */

.chip {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-1);
  padding: 2px var(--sp-2);
  border-radius: 999px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
  line-height: 1.8;
  white-space: nowrap;
}
.chip-draft { background: var(--kuning-bg); color: var(--kuning-ink); }
.chip-final,
.chip-lunas { background: var(--hijau-bg); color: var(--hijau-ink); }

/* Chip selisih (Δ) — hanya dipakai bila |Δ| > 20% (STANDARDS §4.3);
   selebihnya delta ditampilkan polos, tanpa chip. */
.chip-delta { font-family: var(--font-angka); font-variant-numeric: tabular-nums; }
.chip-delta-naik  { background: var(--hijau-bg); color: var(--hijau-ink); }
.chip-delta-turun { background: var(--merah-bg); color: var(--merah-ink); }

/* ================= PANEL PERINGATAN ================= */

.panel-peringatan {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  margin-bottom: var(--sp-5);
  overflow: hidden;
}
.panel-peringatan-judul {
  padding: var(--sp-3) var(--sp-4);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--kuning-ink);
  background: var(--kuning-bg);
}
.panel-peringatan ul { list-style: none; margin: 0; padding: 0; }
.panel-peringatan li + li { border-top: 1px solid var(--border); }
.panel-peringatan button {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  width: 100%;
  padding: var(--sp-3) var(--sp-4);
  font-family: var(--font);
  font-size: 13px;
  color: var(--ink);
  background: none;
  border: none;
  text-align: left;
  cursor: pointer;
  transition: background var(--transisi);
}
.panel-peringatan button:hover { background: var(--surface-2); }
.panel-peringatan button .lemah { font-size: 12px; }

/* ================= HEADER STICKY PERIODE ================= */

.header-periode {
  position: sticky;
  top: 0;
  z-index: 10;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4);
  padding: var(--sp-4) var(--sp-5);
  margin: calc(var(--sp-7) * -1) calc(var(--sp-6) * -1) var(--sp-5);
  background: var(--surface);
  border-bottom: 1px solid var(--border);
}
.header-periode-judul { display: flex; align-items: center; gap: var(--sp-3); flex-wrap: wrap; }
.header-periode-judul h1 { margin: 0; font-size: 18px; font-weight: 600; letter-spacing: -0.02em; }
.header-periode-total { display: flex; gap: var(--sp-6); }
.header-periode-total div { text-align: right; }
.header-periode-total .label {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--muted);
  margin-bottom: 2px;
}
.header-periode-total .nilai {
  font-family: var(--font-angka);
  font-variant-numeric: tabular-nums;
  font-size: 18px;
  font-weight: 600;
}

@media (max-width: 900px) {
  .header-periode {
    position: static;
    margin: 0 0 var(--sp-5);
    border-radius: var(--radius);
    border: 1px solid var(--border);
  }
}

/* ================= TABEL ANGKA ================= */
/* Komponen inti aplikasi (STANDARDS §4.2) — dikerjakan paling serius.
   Wadah scroll horizontal terpisah dari halaman, supaya halaman sendiri
   tidak ikut geser saat tabel lebar. */

.tabel-wadah {
  overflow-x: auto;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
}

.tabel-angka {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
  white-space: nowrap;
}

.tabel-angka th,
.tabel-angka td {
  padding: 0 var(--sp-3);
  height: 36px;
  border-bottom: 1px solid var(--border);
  text-align: left;
}

.tabel-angka thead th {
  position: sticky;
  top: 0;
  z-index: 1;
  background: var(--surface-2);
  color: var(--muted);
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .06em;
  white-space: nowrap;
}

.tabel-angka tbody tr:last-child td { border-bottom: none; }

/* Nominal: rata kanan, mono, sejajar lurus antar baris. */
.tabel-angka .num {
  text-align: right;
  font-family: var(--font-angka);
  font-variant-numeric: tabular-nums;
}

/* Nol tampil sebagai en-dash lewat rp()/angka() — kelas ini hanya
   memastikan warnanya --muted, bukan mewarnai ulang teks berisi. */
.tabel-angka .nol { color: var(--muted); }

/* Nilai negatif / potongan. */
.tabel-angka .minus { color: var(--merah-ink); }

/* Baris total — sedikit lebih tegas, tanpa jadi berat. */
.tabel-angka tfoot td,
.tabel-angka tr.total td {
  border-top: 1px solid var(--ink);
  border-bottom: none;
  font-weight: 600;
  background: var(--surface-2);
}

/* Baris yang disorot dari panel peringatan (klik item → sorot baris). */
.tabel-angka tr.disorot td { background: var(--kuning-bg); }

/* Sel yang bisa diedit: polos sampai difokus, tanpa tombol Simpan. */
.tabel-angka .sel-edit {
  display: block;
  width: 100%;
  min-width: 64px;
  padding: var(--sp-1) var(--sp-2);
  margin: 0;
  font-family: var(--font-angka);
  font-variant-numeric: tabular-nums;
  font-size: 13px;
  text-align: right;
  color: var(--ink);
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--radius-kecil);
  transition: border-color var(--transisi), background var(--transisi);
}
.tabel-angka .sel-edit:hover { background: var(--surface-2); }
.tabel-angka .sel-edit:focus { outline: none; border-color: var(--ink); background: var(--surface); }

/* Kolom Nama & Unit dibekukan saat tabel digeser ke kanan (masukan owner,
   2026-07-30 malam): tabel input/review punya banyak kolom, dan tanpa ini
   nama karyawan hilang dari pandangan begitu digeser — sel yang sedang
   diketik jadi tidak jelas milik siapa. Lebar kedua kolom DIPATOK (bukan
   cuma min-width) supaya offset `left` kolom kedua bisa dihitung pasti. */
/* Baris judul kelompok (.kepala-grup) DIKECUALIKAN dari aturan nth-child di
   bawah. Sel pertamanya <th colspan="2">, jadi "kolom kedua" di baris itu
   bukan Unit melainkan judul kelompok berikutnya — dan itulah yang ikut
   dibekukan, menutupi kolom Unit saat tabel digeser (owner, 2026-08-22:
   "cabang ini kalo aku scroll kanan ikut geser"). Baris itu dibekukan
   terpisah di bawah, selebar dua kolom sekaligus. */
.tabel-beku tr:not(.kepala-grup) th:nth-child(1), .tabel-beku td:nth-child(1),
.tabel-beku tr:not(.kepala-grup) th:nth-child(2), .tabel-beku td:nth-child(2) {
  position: sticky;
  z-index: 2;
  background: var(--surface);
  overflow: hidden;
  text-overflow: ellipsis;
}
.tabel-beku thead tr:not(.kepala-grup) th:nth-child(1),
.tabel-beku thead tr:not(.kepala-grup) th:nth-child(2) {
  z-index: 3;
  background: var(--surface-2);
}
.tabel-beku tr:not(.kepala-grup) th:nth-child(1), .tabel-beku td:nth-child(1) {
  left: 0; width: 132px; min-width: 132px; max-width: 132px;
}
.tabel-beku tr:not(.kepala-grup) th:nth-child(2), .tabel-beku td:nth-child(2) {
  /* 84px supaya "BATLAS" (unit terpanjang) muat tanpa terpotong. */
  left: 132px; width: 84px; min-width: 84px; max-width: 84px;
  border-right: 1px solid var(--border);
}

/* Judul kelompok: satu sel selebar Nama+Unit (132+84), dibekukan utuh. */
.tabel-beku thead tr.kepala-grup th:first-child {
  position: sticky; left: 0; z-index: 3;
  width: 216px; min-width: 216px; max-width: 216px;
  background: var(--surface-2);
  border-right: 1px solid var(--border);
}
/* Baris disorot/total tetap terlihat di kolom beku juga, bukan cuma sisanya. */
.tabel-beku tr.disorot td:nth-child(1), .tabel-beku tr.disorot td:nth-child(2) { background: var(--kuning-bg); }
.tabel-beku tr.total td:nth-child(1), .tabel-beku tr.total td:nth-child(2),
.tabel-beku tfoot td:nth-child(1), .tabel-beku tfoot td:nth-child(2) { background: var(--surface-2); }

/* Varian satu-kolom-beku untuk tabel yang cuma punya satu kolom identitas
   (Kategori/Item/Penerima di layar Omset, bukan Nama+Unit) — owner,
   2026-07-30/31 malam: "judul primer kalau ada scroll jangan ikut scroll". */
.tabel-beku-1 th:nth-child(1), .tabel-beku-1 td:nth-child(1) {
  position: sticky;
  left: 0;
  z-index: 2;
  width: 132px; min-width: 132px; max-width: 132px;
  background: var(--surface);
  border-right: 1px solid var(--border);
  overflow: hidden;
  text-overflow: ellipsis;
}
.tabel-beku-1 thead th:nth-child(1) { z-index: 3; background: var(--surface-2); }
.tabel-beku-1 tr.total td:nth-child(1) { background: var(--surface-2); }
.tabel-balancing th:first-child,
.tabel-balancing td:first-child {
  width: 156px; min-width: 156px; max-width: 156px;
}
.tabel-balancing thead th:first-child { white-space: nowrap; text-overflow: clip; }
.form-tambah-balancing { max-width: 56rem; margin-top: var(--sp-4); }
.form-tambah-balancing h3 { font-size: 13px; }
.form-balancing-cabang {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--sp-4);
}
.form-balancing-detail {
  display: grid;
  grid-template-columns: minmax(140px, 0.75fr) minmax(0, 1.5fr) auto;
  gap: var(--sp-4);
  align-items: end;
}
.form-balancing .grup-field { min-width: 0; margin-bottom: var(--sp-3); }
.form-balancing .grup-field label { margin-bottom: var(--sp-2); }
@media (max-width: 700px) {
  .form-balancing-cabang,
  .form-balancing-detail { grid-template-columns: 1fr; }
  .form-balancing-detail > button { width: 100%; }
}

/* Baris pemisah unit/cabang (masukan owner: kelompokkan baris per unit,
   seperti blok "Unit: X" di xlsx eksekusi). Bukan baris data — cuma label. */
.tabel-angka tr.grup-unit td {
  background: var(--surface-2);
  color: var(--muted);
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .06em;
  height: 28px;
}
.tabel-beku tr.grup-unit td:nth-child(1), .tabel-beku tr.grup-unit td:nth-child(2) {
  background: var(--surface-2);
}
/* Totalan rupiah di kepala tiap cabang (owner, 2026-08-30: "di setiap
   header safari batlas dkk itu dikasi totalan rupiah") — teks polos
   normal-case menempel di sebelah nama cabang, tidak ikut huruf besar/
   letter-spacing baris judulnya supaya angka tetap gampang dibaca. */
.grup-unit-total {
  text-transform: none;
  letter-spacing: normal;
  font-weight: 400;
  margin-left: var(--sp-2);
}

/* Toolbar cari/saring di layar Karyawan (owner, 2026-08-30: "karyawan aku
   mau ada search nya by nama, bisa by unit"). */
.karyawan-alat {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  margin-bottom: var(--sp-3);
  flex-wrap: wrap;
}
.karyawan-cari {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-3);
  border: 1px solid var(--border);
  border-radius: var(--radius-kecil);
  background: var(--surface);
  color: var(--muted);
  flex: 1 1 240px;
  max-width: 320px;
}
.karyawan-cari input {
  border: none;
  outline: none;
  background: transparent;
  padding: 0;
  margin: 0;
  flex: 1;
  color: var(--ink);
  font-size: 13px;
}
#filter-unit-karyawan {
  padding: var(--sp-2) var(--sp-3);
  border: 1px solid var(--border);
  border-radius: var(--radius-kecil);
  background: var(--surface);
  color: var(--ink);
  font-size: 13px;
}
#karyawan-jumlah { font-size: 12px; }

/* Header kolom yang bisa diurutkan. Panahnya cuma muncul di kolom yang
   sedang aktif, supaya heading yang lain tidak berisik dengan simbol yang
   tidak berfungsi apa-apa untuknya saat ini. */
th.th-urut {
  cursor: pointer;
  user-select: none;
  white-space: nowrap;
}
th.th-urut:hover { color: var(--ink); }
th.th-urut .ikon-urut::after {
  content: '';
  display: inline-block;
  margin-left: var(--sp-1);
  width: 0;
  height: 0;
}
th.th-urut-aktif[data-arah="asc"] .ikon-urut::after {
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
  border-bottom: 5px solid currentColor;
}
th.th-urut-aktif[data-arah="desc"] .ikon-urut::after {
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
  border-top: 5px solid currentColor;
}

/* Pewarnaan kolom di layar Input (masukan owner, 2026-07-30 malam): kolom
   yang bisa diketik langsung dibedakan dari kolom hasil hitungan, dan di
   antara kolom yang bisa diketik, Bonus vs Bon dibedakan lagi — supaya mata
   langsung menangkap KATEGORI kolom sebelum membaca angkanya.
     kol-input → field masukan umum (masuk, lembur, telat, insentif)
     kol-bonus → bonus / ket bonus
     kol-bon   → potongan yang mengurangi Diterima: bayar bon, total bon,
                 dan nabung (2026-08-30) — digabung satu warna karena
                 keempat aksen pastel yang ada sudah habis dipakai kategori
                 lain, bukan karena bon & nabung artinya sama */
.tabel-angka th.kol-input,  .tabel-angka td.kol-input  { background: var(--biru-bg); }
.tabel-angka th.kol-bonus, .tabel-angka td.kol-bonus { background: var(--hijau-bg); }
.tabel-angka th.kol-bon,   .tabel-angka td.kol-bon   { background: var(--merah-bg); }
/* kol-kunci → layar Omset: persen Safari, bonus per ekor, porsi BASI. Ini
   ATURAN skema (memengaruhi periode berikutnya), bukan angka periode ini —
   kuning dipakai karena token itu sudah berarti "perlu perhatian" di seluruh
   aplikasi (STANDARDS §4.1: peringatan, draft). Ikon gembok di header
   memperjelas lagi (lihat .ikon-kunci di bawah). */
.tabel-angka th.kol-kunci, .tabel-angka td.kol-kunci { background: var(--kuning-bg); }
/* Kolom isian angka rupiah bisa 9 digit + titik ribuan ("8.889.890") — tanpa
   lebar minimum, tabel auto-layout kadang memberi kolom lebih sempit dari
   yang dibutuhkan input `width:100%`-nya, memotong tampilan angka SECARA
   DIAM-DIAM (mis. "900.000" tampil "900.00" — bisa terbaca salah, owner
   menyebutnya "bahaya"). Berlaku ke SEMUA kolom berwarna, bukan cuma dua —
   bug ini sempat lolos di kol-bon/kol-bonus karena hanya dua kelas pertama
   yang diberi lebar minimum. */
.tabel-angka td.kol-input, .tabel-angka td.kol-kunci,
.tabel-angka td.kol-bon, .tabel-angka td.kol-bonus { min-width: 132px; }
/* ...tapi tidak semua isian butuh selebar itu (owner, 2026-07-30 malam:
   "biru ini 4 digit aja isian nya maximal yg kuning itu 6 digit cukup...
   jangan kebesaran"). Qty/persen/tarif per item hanya beberapa digit — kotak
   isian selebar rupiah 9-digit di sebelahnya terlihat kosong dan longgar.
   Override lebih spesifik (2 kelas: kol-* + lebar-*) menang atas aturan
   lebar penuh di atas. */
/* width TETAP (bukan cuma min/max-width) supaya tabel auto-layout tidak
   melebarkan kolom ini memakai sisa ruang kosong saat kolom lain di tabel
   yang sama tidak butuh selebar itu — ditemukan 2026-07-31 di kolom qty OP:
   td tetap melebar sampai ~138px walau max-width 64px sudah dipasang. */
.tabel-angka td.lebar-kecil  { width: 64px; min-width: 64px; max-width: 64px; }
.tabel-angka td.lebar-sedang { width: 84px; min-width: 84px; max-width: 84px; }
/* Kolom per-penerima Safari (persen + bonus per ekor + total): sel yang sama
   kadang menampilkan persen kecil ("2,5 %"), kadang nominal penuh
   ("Rp 109.747") di baris lain — 84px kepotong untuk nominalnya. 112px pas
   untuk nominal 6-7 digit tanpa melebar tak perlu seperti sebelum diperbaiki
   (kolom ini sempat ~215px, TEMUAN 2026-07-31). */
.tabel-angka td.lebar-penerima { width: 112px; min-width: 112px; max-width: 112px; }
/* "besar" (rupiah panjang, mis. Omset isi & Target harian sampai 9 digit)
   HARUS punya width tetap juga — sebelumnya cuma min-width:132px (aturan di
   atas) tanpa max-width/width, jadi ikut melebar mengisi sisa ruang tabel
   sama seperti lebar-kecil/sedang sebelum diperbaiki (owner, 2026-07-31:
   masih banyak yang oversize sesudah perbaikan pertama). */
.tabel-angka td.lebar-besar { width: 132px; min-width: 132px; max-width: 132px; }
/* Sel yang sedang difokus tetap harus terlihat jelas di atas tint kolomnya. */
.tabel-angka td.kol-input .sel-edit:focus,
.tabel-angka td.kol-bonus .sel-edit:focus,
.tabel-angka td.kol-bon .sel-edit:focus,
.tabel-angka td.kol-kunci .sel-kunci:focus { background: var(--surface); }

/* Field kunci (aturan skema) tampil sebagai TEKS POLOS sampai diklik, baru
   berubah jadi kotak isian (masukan owner, 2026-07-30 malam) — perbedaan
   visual antara "sedang menyisir angka" dan "sedang mengubah aturan" harus
   kentara, bukan cuma warna kolom. `readonly` dilepas/dipasang lewat skrip
   kecil di admin/omset.php saat fokus/blur. */
.tabel-angka .sel-kunci:read-only {
  border-color: transparent;
  background: transparent;
  cursor: pointer;
}
.tabel-angka .sel-kunci:read-only:hover { background: var(--surface-2); }
.tabel-angka .sel-kunci:not(:read-only) {
  border-color: var(--kuning-ink);
  background: var(--surface);
  cursor: text;
}

/* Ikon gembok — menandai field yang mengubah ATURAN skema (persen/porsi/
   bonus per ekor), bukan angka periode yang sedang dibuka. SVG inline
   sederhana (STANDARDS §4.1 melarang emoji & ikon library). */
.ikon-kunci { width: 12px; height: 12px; vertical-align: -1px; margin-left: 2px; color: var(--kuning-ink); }

/* Tanda "%" di samping angka persen, bukan di baris sendiri di bawahnya
   (owner, 2026-07-30 malam: "rapikan % disamping nya lebih bagus"). */
.isian-persen { display: inline-flex; align-items: baseline; gap: 2px; justify-content: flex-end; width: 100%; }
/* width:auto pada <input> TANPA batas eksplisit membuat tabel auto-layout
   memakai lebar bawaan peramban (~170-200px, ukuran default sebuah <input>
   tanpa atribut size) saat menghitung lebar kolom — walau tampilannya kecil
   karena flex-shrink, KOLOMNYA sudah kadung dilebarkan sebelum menyusut.
   Ditemukan 2026-07-31: kolom Ari/Ima/Nanda melebar sampai ~215px padahal
   isinya cuma "2,5 %". width tetap (bukan auto) menghilangkan akar masalahnya,
   bukan menambal lebar kolomnya (owner: "cm butuh 2 digit aja"). */
/* 34px kepotong untuk nilai berkoma seperti "0,35" (kategori Hewan) — hanya
   cukup untuk 2 digit bulat (owner, 2026-07-31: "yg koma malah kurang size").
   42px masih kepotong 8px (diukur scrollWidth 48 vs clientWidth 40) — teks
   rata-kanan jadi memotong digit TERAKHIR tanpa terlihat ("0,35" tampil
   "0,3"). 50px pas untuk 4 karakter terpanjang yang benar-benar dipakai. */
.isian-persen .sel-edit { width: 50px; min-width: 50px; flex: 0 0 auto; text-align: right; }

/* Baris selang-seling / zebra (masukan owner, 2026-07-30 malam, supaya baris
   panjang gampang disisir). Ini MEMBALIK keputusan lama STANDARDS §4.2
   ("tanpa zebra") — didokumentasikan di sana, bukan diam-diam.
   Kolom netral pakai --bg (krem sangat pudar) di baris genap — tiga lapis
   yang sudah ada: surface(ganjil)/bg(genap)/surface-2(header, total, pemisah
   unit), tidak ada nilai mentah baru.
   Kolom yang sudah berwarna sendiri (kol-input/kol-bonus/kol-bon/kol-kunci)
   TETAP ikut zebra (owner, koreksi berikutnya: "bon zebra merah juga, bonus
   zebra hijau") — tapi nadanya digelapkan sedikit dari warna aslinya lewat
   `color-mix()`, BUKAN warna baru: token yang sama, cuma nada genapnya
   sedikit lebih gelap. Ini menjaga dua hal sekaligus: pola selang-seling
   tetap terlihat DAN kategori warna kolom tetap konsisten di semua baris. */
.tabel-angka tbody tr:nth-child(even):not(.grup-unit):not(.total) td {
  background: var(--bg);
}
.tabel-angka tbody tr:nth-child(even):not(.grup-unit):not(.total) td.kol-input {
  background: color-mix(in srgb, var(--biru-bg), black 6%);
}
.tabel-angka tbody tr:nth-child(even):not(.grup-unit):not(.total) td.kol-bonus {
  background: color-mix(in srgb, var(--hijau-bg), black 6%);
}
.tabel-angka tbody tr:nth-child(even):not(.grup-unit):not(.total) td.kol-bon {
  background: color-mix(in srgb, var(--merah-bg), black 6%);
}
.tabel-angka tbody tr:nth-child(even):not(.grup-unit):not(.total) td.kol-kunci {
  background: color-mix(in srgb, var(--kuning-bg), black 6%);
}

/* Indikator autosave per baris — muncul sesaat setelah blur, di kolom sendiri. */
.status-simpan { font-size: 12px; white-space: nowrap; }
.status-simpan-oke   { color: var(--hijau-ink); }
.status-simpan-galat { color: var(--merah-ink); }
.status-simpan-tunggu { color: var(--muted); }

/* ================= DRAWER / PANEL KANAN =================

   Drawer BISA DITUTUP dan default-nya TERTUTUP (keputusan owner
   2026-07-29): saat menyisir angka, tabel butuh lebar penuh — di layar
   1440px, drawer terbuka membuat kolom BON terdorong keluar dan harus
   di-scroll, padahal prinsipnya review tanpa klik (STANDARDS §1.2).
   Drawer dibuka hanya ketika satu orang mau diperiksa slipnya.

   Markup:
     <div class="dua-kolom" data-drawer="tutup">   ← atau "buka"
       <div class="kolom-tabel"> … </div>
       <aside class="drawer"> … </aside>
     </div>
   Tombol pemicu cukup mengubah atribut data-drawer pada .dua-kolom. */

.dua-kolom {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-5);
}
.dua-kolom > .kolom-tabel { flex: 1; min-width: 0; }
.dua-kolom > .drawer { flex: 0 0 340px; }

.dua-kolom[data-drawer="tutup"] > .drawer { display: none; }
.dua-kolom[data-drawer="tutup"] { gap: 0; }

/* .tabel-rincian (rakitan tabel drawer di JS) dibuang 2026-08-29 — drawer
   sekarang <iframe> ke halaman lihat_pk yang sama dengan popup Kirim,
   lihat #drawer-bingkai di bawah. Aturan lebar kolomnya sudah tidak
   dipakai di mana pun. */

.drawer {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: var(--sp-5);
  position: sticky;
  top: var(--sp-5);
}
.drawer h2 {
  margin: 0 0 var(--sp-4);
  font-size: 13px;
  font-weight: 600;
}
.drawer-kosong { color: var(--muted); font-size: 13px; }
#drawer-bingkai {
  width: 100%;
  height: min(75vh, 760px);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface-2);
}

/* Kepala drawer: judul + tombol tutup */
.drawer-kepala {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sp-3);
  margin-bottom: var(--sp-4);
}
.drawer-kepala h2 { margin: 0; }

.drawer-tutup {
  border: none;
  background: none;
  padding: 0;
  font-family: var(--font);
  font-size: 12px;
  color: var(--muted);
  cursor: pointer;
}
.drawer-tutup:hover { color: var(--ink); text-decoration: underline; }

/* Nama karyawan di tabel: pemicu drawer, tapi tetap terbaca sebagai teks
   biasa — tabel angka tidak boleh terlihat penuh tautan biru. */
.tautan-baris {
  border: none;
  background: none;
  padding: 0;
  font-family: var(--font);
  font-size: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
}
.tautan-baris:hover { text-decoration: underline; }

@media (max-width: 900px) {
  .dua-kolom { flex-direction: column; }
  .dua-kolom > .drawer { flex: none; width: 100%; position: static; }
}

/* ================= FORM LANJUTAN ================= */

.grup-field { margin-bottom: var(--sp-5); }
.grup-field:last-child { margin-bottom: 0; }

/* Sumber data pegawai baru. Fieldset bertinta menandai langkah impor tanpa
   membuat kartu bertumpuk. Cabang hanya jadi petunjuk karena satu cabang
   Hybrida dapat dipakai oleh beberapa unit payroll. */
.ambil-hybrida {
  min-width: 0;
  margin: 0 0 var(--sp-6);
  padding: var(--sp-4);
  border: 1px solid color-mix(in srgb, var(--biru-ink) 24%, var(--border));
  border-radius: var(--radius);
  background: color-mix(in srgb, var(--biru-bg) 55%, var(--surface));
}
.ambil-hybrida legend {
  padding: 0 var(--sp-2);
  color: var(--biru-ink);
  font-weight: 700;
}
.ambil-hybrida > .bantuan { margin: 0 0 var(--sp-4); }
.ambil-hybrida .grup-field { margin-bottom: var(--sp-3); }
.kosong-hybrida { margin: 0; color: var(--muted); }
.hybrida-terpilih {
  display: grid;
  gap: 2px;
  padding-top: var(--sp-3);
  border-top: 1px solid color-mix(in srgb, var(--biru-ink) 18%, var(--border));
}
.hybrida-terpilih[hidden] { display: none; }
.hybrida-terpilih span,
.hybrida-terpilih small { color: var(--muted); }
.hybrida-terpilih small { margin-top: var(--sp-2); line-height: 1.45; }

.bantuan {
  margin: var(--sp-1) 0 0;
  font-size: 12px;
  color: var(--muted);
}

.galat-field {
  margin: var(--sp-1) 0 0;
  font-size: 12px;
  color: var(--merah-ink);
}
.grup-field.ada-galat input,
.grup-field.ada-galat select { border-color: var(--merah-ink); }

.baris-cek {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  margin-bottom: var(--sp-3);
}
.baris-cek label { margin: 0; color: var(--ink); font-size: 14px; }
.baris-cek input[type=checkbox],
.baris-cek input[type=radio] { width: auto; margin: 0; }

/* ================= KELENGKAPAN ================= */

kbd {
  display: inline-block;
  padding: 1px var(--sp-1);
  font-family: var(--font-angka);
  font-size: 11px;
  color: var(--muted);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 4px;
  line-height: 1.6;
}

.tab-daftar {
  display: flex;
  gap: var(--sp-5);
  border-bottom: 1px solid var(--border);
  margin-bottom: var(--sp-5);
}
.tab-daftar a {
  padding: var(--sp-2) 0;
  font-size: 13px;
  color: var(--muted);
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
}
.tab-daftar a:hover { color: var(--ink); text-decoration: none; }
.tab-daftar a.aktif { color: var(--ink); border-color: var(--ink); font-weight: 500; }

/* Tanda progres di bilah langkah (2026-08-23). Tiga keadaan, bukan dua:
   ✓ = selesai penuh, "3/21" = sebagian, tanpa tanda = belum disentuh.
   Yang sebagian pakai warna peringatan, BUKAN warna selesai — dulu ambangnya
   "lebih dari nol" sehingga satu slip terkirim dari 21 sudah membuat langkah
   Kirim tampak hijau, tepat di keadaan yang paling perlu dikhawatirkan.
   Angka dibuat mono supaya "3/21" dan "12/21" tidak menggeser label di
   sebelahnya tiap kali nilainya berubah. */
.langkah-tanda {
  margin-left: var(--sp-1);
  font-size: 11px;
  font-weight: 500;
}
.langkah-penuh { color: var(--hijau-ink); }
.langkah-sebagian {
  padding: 1px var(--sp-1);
  border-radius: var(--radius-kecil);
  background: var(--kuning-bg);
  color: var(--kuning-ink);
  font-family: var(--font-angka);
  font-variant-numeric: tabular-nums;
}

/* Tombol "lanjut ke langkah berikutnya" di kaki layar periode (2026-08-17).
   Sebelumnya tiap selesai satu langkah owner harus balik ke menu samping. */
.lanjut-langkah { margin: var(--sp-6) 0 var(--sp-4); }

.remah {
  display: flex;
  align-items: center;
  gap: var(--sp-1);
  font-size: 13px;
  color: var(--muted);
  margin-bottom: var(--sp-4);
}
.remah a { color: var(--muted); }
.remah a:hover { color: var(--ink); }
.remah span.pemisah { color: var(--border); }

.kosong {
  padding: var(--sp-7) var(--sp-4);
  text-align: center;
  color: var(--muted);
  font-size: 13px;
}
.kosong strong { display: block; color: var(--ink); font-size: 14px; margin-bottom: var(--sp-1); font-weight: 500; }

/* ================= LAYAR SEMPIT ================= */

@media (max-width: 900px) {
  .kerangka { flex-direction: column; }
  .samping {
    width: auto;
    flex: none;
    border-right: none;
    border-bottom: 1px solid var(--border);
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    align-items: center;
    column-gap: var(--sp-3);
    row-gap: var(--sp-1);
    padding: var(--sp-3) var(--sp-4);
  }
  .merek {
    grid-column: 1 / -1;
    margin-bottom: var(--sp-1);
  }
  /* Setiap kelompok mendapat jalur sendiri. Dahulu Gajian dan Master berebut
     satu flex-row; rangkaian Periode yang panjang mendorong seluruh menu
     Master ke luar viewport saat jendela menyempit. Label kelompok sengaja
     tetap tampak agar dua jalur mendatar ini tidak tertukar. */
  .menu-grup {
    display: block;
    grid-column: 1;
    margin: 0;
    align-self: center;
  }
  .menu {
    grid-column: 2;
    display: flex;
    min-width: 0;
    gap: var(--sp-1);
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scrollbar-width: thin;
  }
  .menu:last-of-type { flex: none; }
  .menu li { margin-bottom: 0; }
  .menu a, .menu-belum { white-space: nowrap; }
  /* Sub-langkah ikut mendatar; garis kiri & nomor jadi mubazir di sini. */
  .menu-anak { display: flex; gap: var(--sp-1); margin: 0 0 0 var(--sp-2); padding-left: var(--sp-2); }
  .menu-konteks { display: none; }
  .samping-kaki {
    grid-column: 1 / -1;
    border-top: none;
    padding-top: var(--sp-1);
  }
  .isi { padding: var(--sp-5) var(--sp-4); }
}

/* HP (2026-08-17). Sebelumnya breakpoint berhenti di 900px — padahal layar
   Kirim justru yang paling mungkin dibuka dari HP saat owner mentransfer
   sambil mengirim slip. */
@media (max-width: 600px) {
  /* Isian di bawah 16px memicu auto-zoom iOS setiap kali sel difokus, dan
     halaman tidak pernah kembali ke skala semula — bukan soal selera. */
  input, select, textarea, .sel-edit { font-size: 16px; }

  .isi { padding: var(--sp-4) var(--sp-3); }
  .judul-halaman h1 { font-size: 20px; }
  .bento { grid-template-columns: 1fr; }
  .header-periode { gap: var(--sp-2); }
  .header-periode-total { gap: var(--sp-4); }
  .tab-daftar { gap: var(--sp-4); overflow-x: auto; }
  .tab-daftar a { white-space: nowrap; }
  .lanjut-langkah .tombol { display: block; text-align: center; }
}

/* Menu yang layarnya belum dibuat: tampak redup dan tidak bisa diklik.
   Lebih baik jelas belum ada daripada tautan yang membawa ke 404. */
.menu-belum {
  display: block;
  padding: var(--sp-2) var(--sp-3);
  color: var(--border);
  cursor: not-allowed;
}

/* Zona tarik-lepas bukti transfer (owner, 2026-08-17: "aku suka nya drag
   and drop") — admin/cetak.php, seksi "Kirim ke pegawai".

   Kotaknya sengaja dibuat SEGI EMPAT (owner, 2026-08-30: "kotak nya
   dibuat square aja ato ada cara lain biar gampang") — dulu cuma strip
   tipis setinggi teksnya, target yang sangat sempit untuk menjatuhkan
   berkas hasil drag dari Finder/Explorer/galeri. Target persegi jauh
   lebih gampang "ditembak" oleh penunjuk mouse maupun jari.

   Ikon + satu-dua kata, BUKAN kalimat penuh (owner, sama hari: "tulisannya
   ya didalam kotak dong ga rapi.. bisa dirapikan dan di minimize lg") —
   "tarik berkas ke sini, atau pilih berkas" tidak muat di kotak sekecil
   ini dan meluber ke kolom sebelah. Kalimat lengkapnya pindah ke atribut
   title (tersedia lewat hover), isi kotaknya cuma ikon panah unggah +
   label pendek. */
/* margin:0 auto — sel-bukti (2026-08-30) sekarang lebih lebar (120px) dari
   kotaknya sendiri (64px) supaya seimbang dengan kolom lain di tabel
   Kirim; tanpa auto-margin kotaknya menempel rata kiri sel, bukan
   di tengah. */
.zona-bukti { position: relative; display: flex; flex-direction: column; align-items: center; width: 64px; margin: 0 auto; }
.zona-bukti-lepas {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  width: 100%;
  aspect-ratio: 1 / 1;
  padding: 4px;
  font-size: 10px;
  line-height: 1.2;
  color: var(--muted);
  text-align: center;
  border: 1px dashed var(--border);
  border-radius: var(--radius-kecil);
  cursor: pointer;
  overflow: hidden;
  transition: border-color var(--transisi), background var(--transisi);
}
.zona-bukti-lepas:hover { background: var(--surface-2); }

/* Status "belum ada"/"sudah ada" digabung KE DALAM kotaknya sendiri
   (2026-08-30, owner: "tulisan belum ada dan sudah ada di dalam pilih
   berkas nya gimana?") — bukan lagi baris teks terpisah di atasnya.
   Kalau sudah ada, kotaknya jadi thumbnail bukti transfer sungguhan
   (gambar asli untuk jpg/png, ikon+label "PDF" untuk pdf); diklik
   langsung membuka buktinya di tab baru (owner: "kl sudah ada dikasi
   tumbnail jd kl dipencet keluar bukti e"), TIDAK lagi memicu pemilih
   berkas — mengganti berkas pindah ke ikon pensil kecil di sudut. */
.zona-bukti-lihat {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 2px;
  width: 100%;
  aspect-ratio: 1 / 1;
  border: 1px solid var(--border);
  border-radius: var(--radius-kecil);
  overflow: hidden;
  color: var(--muted);
  font-size: 10px;
  transition: border-color var(--transisi);
}
.zona-bukti-lihat:hover { border-color: var(--ink); }
.zona-bukti-lihat img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* Ikon "ganti berkas": lencana bulat kecil di sudut kanan-atas thumbnail,
   bukan menimpa seluruh kotak — supaya area thumbnail tetap sepenuhnya
   bisa diklik untuk MELIHAT, bukan berebut dengan area GANTI. */
.zona-bukti-ganti {
  position: absolute;
  top: -6px;
  right: -6px;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 50%;
  color: var(--muted);
  cursor: pointer;
  transition: color var(--transisi), border-color var(--transisi);
}
.zona-bukti-ganti:hover { color: var(--ink); border-color: var(--ink); }

/* Kata-kata zona unggah mengikuti cara yang benar-benar tersedia di layar itu
   (2026-08-23). Di layar lebar: seret atau klik ("pilih berkas"). Di layar
   sempit: tidak ada seret sama sekali, jadi yang ditawarkan hanya ketuk
   ("ambil foto") — bukti transfer di HP hampir selalu tangkapan layar atau
   foto, bukan berkas yang sudah tersimpan rapi. */
.zona-bukti-cara-ketuk { display: none; }
@media (max-width: 700px) {
  .zona-bukti-cara-seret { display: none; }
  .zona-bukti-cara-ketuk { display: inline; }
}
.zona-bukti-hover .zona-bukti-lepas { border-color: var(--ink); background: var(--surface-2); }
.zona-bukti-hover .zona-bukti-lihat { border-color: var(--ink); }

/* Bendera "dibawa dari bulan lalu" (2026-08-21). Owner: "apabila sesi baru
   membawa variable dari bulan sebelumnya tp dikasi tanda misal bendera
   kecil". Segitiga kecil di sudut kiri-atas sel, BUKAN warna latar penuh:
   sel-sel ini sudah berwarna sendiri menurut kategorinya (kol-bonus hijau,
   kol-bon merah), dan menimpanya akan menghapus arti warna yang sudah
   dipakai owner selama ini untuk menyisir tabel.

   Tandanya sengaja tidak mencolok — ini bukan galat, cuma "belum kamu
   periksa". Hilang sendiri begitu selnya diketik ulang. */
.tabel-angka td.sel-bawaan {
  position: relative;
}
.tabel-angka td.sel-bawaan::before {
  content: "";
  position: absolute;
  top: 0; left: 0;
  border-width: 7px 7px 0 0;
  border-style: solid;
  border-color: var(--kuning-ink) transparent transparent transparent;
  opacity: .75;
  pointer-events: none;
}

/* ================= MENU BERTINGKAT & RAPAT (2026-08-21) =================
   Owner: "bole ga kalo periode ini merupakan awal mula kita buka absensi
   sampe kirim ini sebagai sub nya ditulis lebih condong... di periode ga
   bisa di klik (karena ga keliatan si ketutupan windows ku pendek)".

   Dua masalah sekaligus: (1) keenam layar gajian sederet sama rata, jadi
   tidak kelihatan mana induk mana tahapan; (2) tinggi barisnya boros,
   sehingga di laptop berlayar pendek daftarnya terpotong dan item paling
   bawah tidak bisa diklik sama sekali.

   Perbaikannya bukan mengecilkan huruf sampai sulit dibaca, tapi memangkas
   RUANG: line-height menu diturunkan (teks menu tidak butuh 1.6 seperti
   paragraf), padding vertikal dipotong, dan jarak antar item dihapus. */

.samping { padding: var(--sp-4) var(--sp-3); }
.merek { margin-bottom: var(--sp-4); }

.menu-grup { margin: var(--sp-3) var(--sp-2) var(--sp-1); }
.menu li { margin-bottom: 0; }
.menu a, .menu-belum {
  padding: 5px var(--sp-2);
  line-height: 1.35;
}

/* Periode = induk. Ditebalkan sedikit supaya kelihatan sebagai pangkal
   alur, bukan salah satu dari enam item setara. */
.menu > li > a { font-weight: 500; }

/* Tahapan di dalam satu periode: menjorok, bernomor, sedikit lebih kecil.
   Garis tipis di kiri menegaskan keenamnya satu rangkaian. */
.menu-anak {
  list-style: none;
  margin: 2px 0 var(--sp-2);
  padding: 0 0 0 var(--sp-3);
  border-left: 1px solid var(--border);
  margin-left: var(--sp-3);
}
.menu-anak a {
  display: flex;
  align-items: baseline;
  gap: var(--sp-2);
  font-size: 13px;
  font-weight: 400;
}
.menu-no {
  display: inline-block;
  min-width: 1em;
  font-family: var(--font-angka);
  font-size: 11px;
  color: var(--border);
}
.menu-anak a.aktif .menu-no { color: var(--muted); }

/* Periode yang sedang dikerjakan — supaya jelas semua langkah di bawahnya
   mengikuti periode ini, bukan bertanya ulang tiap kali dibuka. */
.menu-konteks {
  margin: 0 var(--sp-2) var(--sp-2);
  padding: 3px var(--sp-2);
  font-size: 11px;
  color: var(--biru-ink);
  background: var(--biru-bg);
  border-radius: var(--radius-kecil);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Kaki sidebar tidak boleh ikut mendorong menu keluar layar. */
.samping-kaki { padding-top: var(--sp-3); font-size: 12px; }

/* Normalisasi mode bilah diletakkan sesudah aturan menu bertingkat agar
   margin sidebar desktop di atas tidak mengambil alih tata letak sempit. */
@media (max-width: 900px) {
  .samping { padding: var(--sp-3) var(--sp-4); }
  .merek { margin-bottom: var(--sp-1); }
  .menu-grup { margin: 0; }
  .menu-anak {
    margin: 0 0 0 var(--sp-2);
    padding-left: var(--sp-2);
    border-left: none;
  }
  .samping-kaki { padding-top: var(--sp-1); }
}

/* ================= TATA LETAK LAYAR LEBAR (2026-08-21) =================
   Owner: "windows nya besar jg layarnya ga responsive kartunya macet di
   lebar segitu" + "baiknya halaman utama dibuat ga scroll kebawah aja kan di
   kartu uda scroll" + "pita ini mengganggu. harusnya diatas sekalian seperti
   header".

   PERCOBAAN PERTAMA GAGAL dan pelajarannya layak dicatat: saya menjadikan
   .isi flex-column + overflow:hidden lalu berharap `.isi > .tabel-wadah`
   yang menggulir. Tabelnya ternyata berada DI DALAM <form>, bukan anak
   langsung .isi — jadi aturannya tidak pernah kena, tidak ada yang bisa
   menggulir, dan seluruh isi di bawah lipatan terpotong. Menyusun tata letak
   dengan asumsi tentang struktur HTML yang tidak diperiksa dulu.

   Pendekatan sekarang tidak bergantung struktur sama sekali: wadah tabel
   diberi tinggi maksimum, dan HANYA dia yang menggulir. Berlaku di mana pun
   letaknya, termasuk di dalam form atau drawer. */

@media (min-width: 901px) {
  /* Tabel angka butuh selebar mungkin; patokan 1200px masuk akal untuk teks
     (baris terlalu panjang sulit dibaca), tidak untuk tabel. */
  .isi { max-width: none; }

  /* SEMUA BARIS TAMPIL, tanpa gulir vertikal di dalam kartu (owner,
     2026-08-21: "dikartu table untuk view vertical nya munculkan semua aja
     biar ga usa ada scroll kebawah"). Yang tersisa cuma gulir mendatar untuk
     tabel lebar.

     Dua gulir bersarang — halaman DAN kartu — memang membingungkan: roda
     mouse mengenai yang mana bergantung posisi kursor. Sekarang cukup satu:
     halamannya. Judul kolom tetap terlihat karena thead-nya sticky. */
  .tabel-wadah { overflow-x: auto; overflow-y: visible; }

  /* Header periode BUKAN pita mengambang. Ia sticky dulu karena halamannya
     yang menggulir; sekarang cukup jadi baris pertama yang tidak ikut
     tergulir bersama tabel. Margin atas negatif dibuang — itu yang membuatnya
     tertarik ke atas dan menimpa kabar peringatan di atasnya. */
  .header-periode {
    position: static;
    z-index: auto;
    margin-top: 0;
  }
}
/* Total & Diterima sekarang di depan (dekat Unit): diberi latar netral supaya
   terbaca sebagai HASIL, bukan kolom yang bisa diketik seperti tetangganya. */
.tabel-angka th.kol-hasil,
.tabel-angka td.kol-hasil {
  background: var(--surface-2);
  width: 104px; min-width: 104px;
}
.tabel-angka tr:nth-child(even) td.kol-hasil { background: var(--surface-2); }

/* Kolom Simpan "terbang": menempel di tepi kanan supaya indikator tersimpan
   selalu terlihat, tidak perlu menggeser tabel dulu untuk memastikan angka
   sudah masuk (owner: "untuk simpan ini baiknya jg modelnya terbang jadi
   selalu terlihat"). Pola sama dengan kolom Nama/Unit yang dibekukan di kiri. */
.tabel-angka th.kol-simpan,
.tabel-angka td.kol-simpan {
  position: sticky;
  right: 0;
  z-index: 2;
  width: 76px; min-width: 76px;
  background: var(--surface);
  border-left: 1px solid var(--border);
}
.tabel-angka thead th.kol-simpan { z-index: 4; background: var(--surface-2); }
.tabel-angka tr:nth-child(even) td.kol-simpan { background: var(--bg); }
.tabel-angka tr.grup-unit td.kol-simpan { background: var(--surface-2); }

/* Tombol "ambil dari bulan lalu" di layar Input. */
.aksi-warisan {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  flex-wrap: wrap;
  margin-bottom: var(--sp-4);
}
.aksi-warisan .bantuan { margin: 0; }

/* ================= LEBAR KOLOM MENGIKUTI ISI (2026-08-21) =================
   Owner: "masuk itu kan max 30 hari jadi digitnya cukup 2 ato mungkin 3. ini
   besar banget sehingga lebar nya tidak efisien. periksa semua kolom dan
   rapikan."

   Sebelumnya SEMUA kolom berwarna dipatok min-width 132px. Angka itu benar
   untuk rupiah 9 digit ("2.723.710") dan dipasang justru untuk memperbaiki
   bug pemotongan diam-diam ("900.000" tampil "900.00", 2026-07-30) — tapi
   dipukul rata ke setiap kolom, termasuk yang isinya "26". Akibatnya tabel
   melebar tanpa alasan dan kolom penting terdorong keluar layar.

   Sekarang lebarnya diturunkan dari ISI TERPANJANG YANG MUNGKIN per satuan,
   dengan cadangan untuk label headernya. Diletakkan sesudah aturan kol-*
   supaya menang (kekhususan sama, yang belakangan menang). */

.tabel-angka th.w-hari,  .tabel-angka td.w-hari  { width: 56px;  min-width: 56px;  max-width: 56px;  }
.tabel-angka th.w-menit, .tabel-angka td.w-menit { width: 64px;  min-width: 64px;  max-width: 64px;  }
.tabel-angka th.w-jam,   .tabel-angka td.w-jam   { width: 68px;  min-width: 68px;  max-width: 68px;  }
.tabel-angka th.w-qty,   .tabel-angka td.w-qty   { width: 68px;  min-width: 68px;  max-width: 68px;  }
.tabel-angka th.w-rp,    .tabel-angka td.w-rp    { width: 108px; min-width: 108px; max-width: 108px; }
.tabel-angka th.w-teks,  .tabel-angka td.w-teks  { width: 180px; min-width: 140px; max-width: 220px; }

/* .sel-edit punya min-width 64px bawaan — itu lebih lebar dari kolom Masuk,
   dan akan memaksa kolomnya melar lagi lewat perhitungan lebar tabel. */
.tabel-angka td.w-hari .sel-edit,
.tabel-angka td.w-menit .sel-edit,
.tabel-angka td.w-jam .sel-edit,
.tabel-angka td.w-qty .sel-edit { min-width: 0; }

/* Keterangan bonus itu teks bebas: rata kiri, boleh melipat. */
.tabel-angka td.w-teks .sel-edit { text-align: left; }

/* ================= UMPAN BALIK SIMPAN DI SEL ITU SENDIRI =================
   Kolom "Simpan" dibuang (owner: "ga berguna, hilangkan saja"). Ia memakan
   lebar tetap di SETIAP baris demi sesuatu yang hanya berarti sepersekian
   detik sesudah mengetik — dan letaknya jauh dari sel yang baru disentuh.

   Penggantinya: selnya sendiri yang berkedip. Informasinya tetap ada (dan
   tetap wajib ada — autosave tanpa konfirmasi adalah cara kehilangan data
   tanpa sadar), tapi muncul persis di tempat mata sedang tertuju. */
.tabel-angka .sel-edit.sel-tunggu { border-color: var(--border); background: var(--surface-2); }
.tabel-angka .sel-edit.sel-oke    { border-color: var(--hijau-ink); background: var(--hijau-bg); }
.tabel-angka .sel-edit.sel-galat  { border-color: var(--merah-ink); background: var(--merah-bg); }

/* Induk menu yang cabangnya boleh dibuka tapi induknya tidak (2026-08-21).
   Bedakan dari .menu-belum (layar yang memang belum dibuat): ini bukan
   "belum ada", tapi "bukan bagianmu" — jadi tetap terbaca jelas sebagai
   judul kelompok, bukan tautan mati yang bikin penasaran. */
.menu-induk-mati {
  display: block;
  padding: 5px var(--sp-2);
  line-height: 1.35;
  font-weight: 500;
  color: var(--muted);
  cursor: default;
}

/* Header dua tingkat pada tabel perbandingan absensi (2026-08-21): baris
   pertama menamai KELOMPOKNYA, baris kedua menyebut sumber tiap kolom. */
.tabel-angka thead tr.kepala-grup th {
  border-bottom: none;
  padding-bottom: 0;
  color: var(--ink);
  font-size: 11px;
}
.tabel-angka thead tr.kepala-grup th[colspan="2"] {
  border-left: 1px solid var(--border);
  text-align: center;
}

/* Kolom aksi di layar Periode: menempel di tepi kanan supaya "Buka" selalu
   terlihat tanpa menggeser tabel (owner: "dibuat terbang aja"). */
.tabel-angka th.kol-aksi,
.tabel-angka td.kol-aksi {
  position: sticky;
  right: 0;
  z-index: 2;
  width: 132px; min-width: 132px;
  text-align: right;
  white-space: nowrap;
  background: var(--surface);
  border-left: 1px solid var(--border);
}
.tabel-angka thead th.kol-aksi { z-index: 4; background: var(--surface-2); }
.tabel-angka tr:nth-child(even) td.kol-aksi { background: var(--bg); }

/* Hapus = aksi berat: outline merah, tidak pernah terlihat seperti tombol
   bawaan (STANDARDS §4.1). */
.tombol-hapus {
  color: var(--merah-ink);
  border-color: var(--merah-ink);
  background: transparent;
  margin-left: var(--sp-1);
}
.tombol-hapus:hover { background: var(--merah-bg); }
/* ================= SIDEBAR DIAM, ISI YANG MENGGULIR (2026-08-21) ==========
   Owner: "pencetan ganti sandinya ga keliatan, di buat yg menu itu ga scroll
   aja yg scroll sebelah nya (halaman utama) karena aneh jg menu kok hilang".

   Begitu halaman yang menggulir (supaya semua baris tabel tampil tanpa gulir
   bersarang), sidebar ikut naik keluar layar — termasuk kaki sidebar yang
   memuat "Kata sandi" dan "Keluar". Navigasi yang hilang saat menyisir data
   memang aneh: menu itu justru dipakai untuk berpindah SESUDAH selesai
   membaca.

   position:sticky, bukan fixed: sticky tetap ikut aliran flex jadi lebarnya
   dihitung otomatis dan isi di sebelahnya tidak perlu diberi margin kiri
   manual. */
@media (min-width: 901px) {
  .samping {
    position: sticky;
    top: 0;
    align-self: flex-start;
    height: 100vh;
    overflow-y: auto;
  }
}

/* ================= CADANGAN TANPA JAVASCRIPT (2026-08-21) =================
   Layar Input dan Omset menyimpan otomatis saat pindah sel. Tombol "Simpan
   semua" / "Simpan Safari" dst. tetap dirender karena tanpa JS itulah
   satu-satunya jalan menyimpan (STANDARDS §2: form harus tetap berfungsi
   tanpa JS) — tapi begitu JS hidup, tombol itu bukan cuma mubazir, ia
   MENYESATKAN: orang mengira perubahannya belum tersimpan sampai ditekan
   (owner: "ini kan perubahan tersimpan otomatis kok masi pake simpan semua").

   Penandanya dipasang di <head> sebelum body dirender, jadi tombolnya tidak
   pernah sempat berkedip muncul. */
.js .hanya-tanpa-js { display: none; }
html:not(.js) .hanya-dengan-js { display: none; }

/* ================= PAPAN PENGELUARAN & CENTANG TRANSFER (2026-08-21) ======
   Owner: "untuk kirim harus ada centangan bahwa sudah di eksekusi sehingga
   tidak menimbulkan human eror kirim 2x" + "ini perlu dibesarin karena ini
   bagus untuk dia cek pengeluaran".

   Dibuat MENCOLOK, beda dari penanda halus lain di aplikasi ini: yang dicegah
   bukan salah ketik, tapi uang keluar dua kali. */

.papan-transfer {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1px;
  margin-bottom: var(--sp-5);
  background: var(--border);          /* jadi garis pemisah antar blok */
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
}
.papan-blok {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: var(--sp-4) var(--sp-5);
  background: var(--surface);
}
.papan-label {
  font-size: 11px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--muted);
}
.papan-angka {
  font-size: 20px;
  font-weight: 600;
  letter-spacing: -0.01em;
}
.papan-rp {
  font-family: var(--font-angka);
  font-variant-numeric: tabular-nums;
  font-size: 15px;
  color: var(--muted);
}
/* Warna hanya pada dua blok yang bisa berubah; Total sengaja netral supaya
   tidak ikut berteriak. */
.papan-blok.sudah .papan-angka, .papan-blok.sudah .papan-rp { color: var(--hijau-ink); }
.papan-blok.belum .papan-angka, .papan-blok.belum .papan-rp { color: var(--kuning-ink); }
.papan-transfer.lunas .papan-blok.belum .papan-angka,
.papan-transfer.lunas .papan-blok.belum .papan-rp { color: var(--muted); }

@media (max-width: 700px) { .papan-transfer { grid-template-columns: 1fr; } }

/* ================= VIEW INPUT & KIRIM: TABEL ADAPTIF =====================
   Kedua layar memakai satu pola identitas yang sama. Nama dan aksi berada
   dalam grid terpisah sehingga ikon tidak pernah ditindih teks. Input tetap
   berupa lembar kerja horizontal dengan satu kolom identitas beku. Kirim
   berubah menjadi kartu per karyawan saat ruangnya sempit. */

.pegawai-identitas {
  display: grid;
  gap: 3px;
  min-width: 0;
}
.pegawai-nama-baris {
  display: grid;
  grid-template-columns: minmax(0, max-content) auto;
  align-items: center;
  justify-content: start;
  gap: var(--sp-2);
  min-width: 0;
}
.pegawai-nama {
  display: block;
  min-width: 0;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 13px;
  font-weight: 600;
}
.pegawai-aksi {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-1);
  flex: none;
}
.pegawai-meta {
  display: inline-flex;
  align-items: baseline;
  gap: var(--sp-1);
  color: var(--biru-ink);
  font-size: 11px;
  white-space: nowrap;
}
.pegawai-meta > span { color: var(--muted); }
.pegawai-meta > .pegawai-pangkat { color: var(--ink); }
.pegawai-peringatan {
  display: flex;
  gap: var(--sp-2);
  margin-top: var(--sp-1);
  color: var(--merah-ink);
  font-size: 11px;
}
.pegawai-peringatan a { color: inherit; font-weight: 600; }

.ikon-tombol-mini {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 26px;
  height: 26px;
  padding: 0;
  border: 1px solid transparent;
  border-radius: var(--radius-kecil);
  background: var(--biru-bg);
  color: var(--biru-ink);
  cursor: pointer;
  transition: border-color var(--transisi), background var(--transisi), transform var(--transisi);
}
.ikon-tombol-mini:hover {
  border-color: var(--biru-ink);
  background: var(--surface);
  color: var(--biru-ink);
  text-decoration: none;
}
.ikon-tombol-mini:active { transform: translateY(1px); }

/* Input adalah lembar angka: tabel boleh lebih lebar dari wadah dan digeser,
   tetapi identitas karyawan selalu tinggal di kiri. Unit digabung ke dalam
   identitas agar tidak ada lagi offset sticky kedua yang rapuh. */
.tabel-input-gaji {
  width: max-content;
  min-width: 100%;
  table-layout: auto;
}
.tabel-input-gaji th.kol-identitas,
.tabel-input-gaji td.kol-identitas {
  position: sticky;
  left: 0;
  z-index: 2;
  width: 1%;
  min-width: 260px;
  padding-top: var(--sp-2);
  padding-bottom: var(--sp-2);
  background: var(--surface);
  border-right: 1px solid var(--border);
}
.tabel-input-gaji thead th.kol-identitas {
  z-index: 4;
  background: var(--surface-2);
}
.tabel-input-gaji tbody tr:nth-child(even):not(.grup-unit) td.kol-identitas { background: var(--bg); }
.tabel-input-gaji tr.disorot td.kol-identitas { background: var(--kuning-bg); }
.tabel-input-gaji .pegawai-nama-baris { grid-template-columns: max-content auto; }

/* Kirim selebar isi, bukan selebar halaman. Empat kolom punya ukuran kerja
   yang stabil; pembungkusnya membatasi tabel agar tidak pernah mendorong
   layout halaman. Saat ruang komponen tidak cukup, baris berubah jadi kartu. */
.tabel-wadah-kirim {
  width: fit-content;
  max-width: 100%;
}
.tabel-kirim-adaptif {
  width: auto;
  min-width: 0;
  table-layout: auto;
}
.tabel-kirim-adaptif th.sel-karyawan,
.tabel-kirim-adaptif td.sel-karyawan {
  width: 260px;
  min-width: 260px;
  max-width: 260px;
  white-space: normal;
}
.tabel-kirim-adaptif th.sel-dibayar,
.tabel-kirim-adaptif td.sel-dibayar { width: 150px; min-width: 150px; max-width: 150px; }
.tabel-kirim-adaptif th.sel-status,
.tabel-kirim-adaptif td.sel-status { width: 132px; min-width: 132px; max-width: 132px; text-align: left; }
.tabel-kirim-adaptif th.sel-bukti,
.tabel-kirim-adaptif td.sel-bukti { width: 120px; min-width: 120px; max-width: 120px; text-align: center; }
.tabel-kirim-adaptif td { height: auto; padding-top: var(--sp-3); padding-bottom: var(--sp-3); }
.tabel-kirim-adaptif tbody tr:not(.grup-unit):hover td { background: var(--surface-2); }
.tabel-kirim-adaptif tbody tr.baris-ditransfer:hover td { background: color-mix(in srgb, var(--hijau-bg), black 4%); }
.sel-dibayar strong { display: block; font-size: 14px; }
.sel-dibayar span { display: block; margin-top: 2px; font-size: 11px; font-family: var(--font); font-variant-numeric: normal; }
.sel-status .centang-transfer { margin-bottom: var(--sp-1); }
.sel-status .sel-terkirim { display: block; font-size: 11px; }

.grup-unit td {
  white-space: normal;
}
.tabel-input-gaji tr.baris-grup td,
.tabel-kirim-adaptif tr.baris-grup td {
  position: static;
  width: auto;
  min-width: 0;
  max-width: none;
  overflow: visible;
}
.tabel-input-gaji .grup-unit-ringkas,
.tabel-kirim-adaptif .grup-unit-ringkas {
  position: sticky;
  left: 0;
  z-index: 1;
  display: inline-flex;
  align-items: baseline;
  padding-right: var(--sp-3);
  background: var(--surface-2);
}
.grup-unit-nama { display: inline-block; }
.grup-unit-total {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-3);
  margin-left: var(--sp-3);
}

/* Satu warna lembut per cabang. Warna hanya menandai blok pembacaan;
   kolom input yang sudah punya arti semantik (biru/hijau/merah/kuning)
   dan baris yang disorot tidak ditimpa. Status transfer tetap dibaca dari
   centang/chip, bukan dengan mengganti warna seluruh baris. */
.tabel-zebra-cabang > tbody:nth-of-type(5n + 1) { --warna-cabang: var(--biru-bg); }
.tabel-zebra-cabang > tbody:nth-of-type(5n + 2) { --warna-cabang: var(--hijau-bg); }
.tabel-zebra-cabang > tbody:nth-of-type(5n + 3) { --warna-cabang: var(--kuning-bg); }
.tabel-zebra-cabang > tbody:nth-of-type(5n + 4) { --warna-cabang: var(--merah-bg); }
.tabel-zebra-cabang > tbody:nth-of-type(5n + 5) {
  --warna-cabang: color-mix(in srgb, var(--biru-bg) 50%, var(--hijau-bg));
}
.tabel-zebra-cabang > tbody {
  --warna-cabang-baris: color-mix(in srgb, var(--warna-cabang) 42%, var(--surface));
  --warna-cabang-selang: color-mix(in srgb, var(--warna-cabang) 58%, var(--surface));
  --warna-cabang-kepala: color-mix(in srgb, var(--warna-cabang) 76%, var(--surface));
}
.tabel-zebra-cabang > tbody > tr:not(.grup-unit):not(.disorot) > td:not(.kol-input):not(.kol-bonus):not(.kol-bon):not(.kol-kunci) {
  background: var(--warna-cabang-baris);
}
.tabel-zebra-cabang > tbody > tr:nth-child(odd):not(.grup-unit):not(.disorot) > td:not(.kol-input):not(.kol-bonus):not(.kol-bon):not(.kol-kunci) {
  background: var(--warna-cabang-selang);
}
.tabel-zebra-cabang > tbody > tr.grup-unit > td,
.tabel-zebra-cabang > tbody > tr.grup-unit .grup-unit-ringkas {
  background: var(--warna-cabang-kepala);
}

/* Kartu hanya untuk layar kecil sungguhan, bukan karena drawer mengurangi
   lebar kolom tabel pada desktop. */
@media (max-width: 760px) {
  .tabel-wadah-kirim {
    overflow: visible;
    border: none;
    border-radius: 0;
    background: transparent;
  }
  .tabel-kirim-adaptif,
  .tabel-kirim-adaptif tbody {
    display: block;
    width: 100%;
    min-width: 0;
  }
  .tabel-kirim-adaptif thead {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
  }
  .tabel-kirim-adaptif tr:not(.grup-unit) {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 104px;
    gap: 0 var(--sp-4);
    margin-bottom: var(--sp-3);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--warna-cabang-baris, var(--surface));
    overflow: hidden;
  }
  .tabel-kirim-adaptif tr.grup-unit {
    display: block;
    margin: var(--sp-5) 0 var(--sp-2);
  }
  .tabel-kirim-adaptif tr.grup-unit:first-child { margin-top: 0; }
  .tabel-kirim-adaptif tr.grup-unit td {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: var(--sp-3);
    width: 100%;
    height: auto;
    padding: var(--sp-2) 0;
    border: none;
    background: transparent;
  }
  .tabel-kirim-adaptif .grup-unit-ringkas {
    position: static;
    justify-content: space-between;
    width: 100%;
    padding-right: 0;
    background: transparent;
  }
  .tabel-kirim-adaptif td {
    display: block;
    width: auto;
    min-width: 0;
    border: none;
    background: transparent;
  }
  .tabel-kirim-adaptif td::before {
    content: attr(data-label);
    display: block;
    margin-bottom: var(--sp-1);
    color: var(--muted);
    font-size: 10px;
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
  }
  .tabel-kirim-adaptif td.sel-karyawan {
    grid-column: 1 / -1;
    width: auto;
    min-width: 0;
    padding: var(--sp-3) var(--sp-4);
    border-bottom: 1px solid var(--border);
  }
  .tabel-kirim-adaptif td.sel-karyawan::before { display: none; }
  .tabel-kirim-adaptif td.sel-dibayar {
    grid-column: 1;
    grid-row: 2;
    width: auto;
    min-width: 0;
    padding: var(--sp-3) var(--sp-4) var(--sp-2);
    text-align: left;
  }
  .tabel-kirim-adaptif td.sel-status {
    grid-column: 1;
    grid-row: 3;
    width: auto;
    min-width: 0;
    padding: 0 var(--sp-4) var(--sp-3);
    text-align: left;
  }
  .tabel-kirim-adaptif td.sel-bukti {
    grid-column: 2;
    grid-row: 2 / 4;
    width: auto;
    min-width: 0;
    padding: var(--sp-3) var(--sp-4) var(--sp-3) 0;
    align-self: center;
  }
  .tabel-kirim-adaptif .pegawai-nama-baris { grid-template-columns: minmax(0, 1fr) auto; }
  .grup-unit-total { margin-left: 0; }
}

.centang-transfer {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-1);
  margin: 0;
  padding: 2px var(--sp-2);
  border-radius: 999px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--muted);
  background: var(--surface-2);
  cursor: pointer;
  white-space: nowrap;
}
.centang-transfer input { margin: 0; cursor: pointer; accent-color: var(--hijau-ink); }
.centang-transfer.sudah { color: var(--hijau-ink); background: var(--hijau-bg); }

/* Baris yang uangnya sudah keluar. Tipis saja — cukup untuk dilewati mata,
   tidak sampai menutupi angkanya. */
.tabel-angka:not(.tabel-zebra-cabang) tr.baris-ditransfer > td { background: var(--hijau-bg); }
.tabel-angka:not(.tabel-zebra-cabang) tr.baris-ditransfer > td.kol-simpan,
.tabel-angka:not(.tabel-zebra-cabang) tr.baris-ditransfer > td.kol-aksi { background: var(--hijau-bg); }

/* Jabatan: isinya pendek ("Keeper", "Ai Specialist") tapi tanpa batas ia ikut
   menyerap ruang sisa tabel dan mendorong kolom lain keluar layar
   (owner, 2026-08-21: "jabatan lebar nya masi terlalu gede"). */
.tabel-angka th.w-jabatan,
.tabel-angka td.w-jabatan {
  /* 132px → 104px (owner, 2026-08-22: "lebar nya aku lihat jabatan masi
     banyak space"). Jabatan terpanjang "Ai Specialist" masih muat; sisanya
     dipotong dengan elipsis dan tetap utuh di popup ubah. */
  width: 104px; min-width: 104px; max-width: 104px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* ================= POPUP (dialog bawaan peramban) ================= */
.popup {
  width: min(560px, calc(100vw - 2rem));
  max-height: calc(100vh - 4rem);
  padding: 0;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--ink);
  overflow: auto;
}
.popup::backdrop { background: rgba(0, 0, 0, .32); }
.popup-kepala {
  position: sticky;
  top: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4);
  padding: var(--sp-4) var(--sp-5);
  background: var(--surface);
  border-bottom: 1px solid var(--border);
}
.popup #popup-isi { padding: var(--sp-5); }
/* Kartu & drawer di dalam popup tidak perlu bingkai lagi — popupnya sendiri
   sudah jadi bingkai. */
.popup .kartu { border: none; padding: 0; max-width: none; }
.popup .dua-kolom { display: block; }
.popup .drawer {
  position: static;
  width: auto;
  border: none;
  margin: 0;
  padding: 0;
}

/* ================= KOLOM PROSES: SAKLAR + IKON (2026-08-21) ===============
   Owner: "status dan aksi itu jadikan satu aja (namanya proses) pake icon
   button ijo abu (status aktif ga aktif) dan icon edit", lalu: "gunakan toggle
   button yg bagus ini aku ga suka dan kenapa besar sekali lebar kolom nya".

   Percobaan pertama memakai tombol bulat ber-ikon titik — itu bukan saklar,
   cuma tombol yang kebetulan berwarna, dan tidak memberi tahu bahwa ia BISA
   DIGESER antara dua keadaan. Sekarang saklar sungguhan: rel + knop yang
   bergeser, mengikuti aria-checked sehingga tampilan dan maknanya mustahil
   berbeda.

   Kolomnya juga tidak lagi menumpang .kol-aksi (132px, ukuran untuk tombol
   "Buka"+"Hapus" di layar Periode). Isinya cuma saklar 34px + ikon 28px. */

.tabel-angka th.kol-proses,
.tabel-angka td.kol-proses {
  width: 88px; min-width: 88px; max-width: 88px;
  text-align: right;
  white-space: nowrap;
}

.proses { display: inline-flex; gap: var(--sp-2); align-items: center; }

/* ---- Saklar ---- */
.saklar {
  position: relative;
  flex: none;
  width: 34px; height: 20px;
  padding: 0;
  border: none;
  border-radius: 999px;
  background: var(--border);
  cursor: pointer;
  transition: background var(--transisi);
}
.saklar::after {
  content: "";
  position: absolute;
  top: 2px; left: 2px;
  width: 16px; height: 16px;
  border-radius: 50%;
  background: var(--surface);
  box-shadow: 0 1px 2px rgba(0,0,0,.2);
  transition: transform var(--transisi);
}
.saklar[aria-checked="true"] { background: var(--hijau-ink); }
.saklar[aria-checked="true"]::after { transform: translateX(14px); }
.saklar:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }

/* ---- Ikon ubah ---- */
.ikon-tombol {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 26px; height: 26px;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: var(--radius-kecil);
  background: var(--surface);
  color: var(--muted);
  cursor: pointer;
  transition: background var(--transisi), color var(--transisi), border-color var(--transisi);
}
.ikon-tombol:hover { background: var(--surface-2); color: var(--ink); text-decoration: none; }

/* ================= POPUP: DIRAPIKAN ================= */
.popup-isi { padding: var(--sp-5); }
.popup-sempit { width: min(420px, calc(100vw - 2rem)); }

/* Form di dalam popup: label rapat dengan isiannya, jarak antar kelompok
   konsisten, dan tombol simpan berdiri sendiri di bawah. */
.popup .grup-field { margin-bottom: var(--sp-4); }
.popup label { margin-bottom: var(--sp-1); }
.popup .bantuan { margin: var(--sp-1) 0 0; }
.popup .tombol-utama, .popup .tombol-bahaya { margin-top: var(--sp-2); }
.popup form > .popup-isi > .tombol { width: 100%; }

/* Dua kolom di dalam popup jadi satu aliran; drawer tarif menyusul di bawah
   form, dipisah garis — bukan berdampingan seperti di halaman penuh. */
.popup .drawer-kepala { padding: 0 0 var(--sp-3); border-bottom: 1px solid var(--border); margin-bottom: var(--sp-4); }
.popup .drawer-kepala h2 { font-size: 14px; margin: 0; }
.popup .drawer-tutup { display: none; }

/* Geser dua jari di dalam tabel lebar TIDAK boleh memicu "kembali" di
   peramban (owner, 2026-08-21). Tabel gaji digulir mendatar terus-menerus;
   sekali gesernya kelewat di tepi kiri, Chrome menganggapnya perintah mundur
   dan halaman ditinggalkan — di layar Input itu berarti kehilangan posisi
   dan harus mencari baris yang sedang dikerjakan lagi.

   overscroll-behavior-x: contain menahan gerakannya di dalam tabel: gulir
   mendatarnya tetap normal, tapi kelebihannya tidak diteruskan ke peramban.
   Ini melindungi walau setelan trackpad di Mac tidak diubah, dan berlaku
   untuk siapa pun yang memakai sistem ini, bukan cuma di Mac owner. */
.tabel-wadah { overscroll-behavior-x: contain; }

/* Halaman secara keseluruhan juga tidak perlu efek pantul horizontal. */
body { overscroll-behavior-x: none; }

/* Periode yang pernah disahkan lalu dibuka kunci (2026-08-21). Statusnya
   kembali "draft", jadi tanpa tanda ini ia terlihat persis seperti periode
   yang belum pernah disahkan sama sekali — padahal slipnya mungkin sudah
   dibagikan dan uangnya mungkin sudah ditransfer. */
.chip-dibuka { background: var(--kuning-bg); color: var(--kuning-ink); }

/* Angka negatif yang HARUS terlihat, bukan cuma bertanda minus di antara
   deretan angka lain — mis. kolom Pegawai di Peruntukan dana salary, yang
   minus berarti setoran manajemen melebihi kas gaji cabang itu. */
.tabel-angka td.sel-minus { color: var(--merah-ink); background: var(--merah-bg); }

/* Dua ikon berdampingan di kolom Proses (ubah + hapus). Gap kecil supaya
   keduanya terbaca sebagai satu kelompok aksi, bukan dua kolom terpisah. */
.grup-ikon { display: inline-flex; gap: 2px; align-items: center; }

/* Hapus memakai ikon yang sama bentuknya dengan tombol lain, dibedakan hanya
   saat disentuh — merah permanen di 14 baris membuat tabel terlihat seperti
   daftar galat. */
button.ikon-tombol { background: none; cursor: pointer; font: inherit; }
.ikon-bahaya:hover { background: var(--merah-bg); color: var(--merah-ink); border-color: var(--merah-ink); }

/* Baris tombol di kaki popup. */
.popup-aksi { display: flex; gap: var(--sp-2); justify-content: flex-end; margin-top: var(--sp-4); }

/* Chip merah untuk keadaan yang MENGHALANGI, bukan sekadar mencatat — mis.
   "belum ada tarif" di daftar Karyawan, yang berarti orangnya tidak akan ikut
   saat periode dibuka. Dibedakan dari .chip-draft (kuning = perlu diperiksa). */
.chip-galat { background: var(--merah-bg); color: var(--merah-ink); }

/* ================= PENANDA "MASIH ADA KOLOM DI KANAN" =================
 *
 * Tabel lebar hanya menyisakan tepi terpotong di kanan, dan itu tidak terbaca
 * sebagai "geser untuk lihat lagi" — owner, 2026-08-22: "kasi icon -> biar tau
 * kalo layarnya masi ada urutan belakangnya".
 *
 * SATU penanda saja: panah kecil yang bisa diklik.
 *
 * Versi pertama menambah pita gradasi di tepi kanan sebagai lapis kedua.
 * Niatnya memberi tahu "ada isi yang terpotong", tapi yang sampai ke owner
 * justru pertanyaan: "ini maksud nya apa si?" (2026-08-22). Bayangan yang
 * harus ditebak artinya bukan penanda — ia cuma kotoran visual di tepi tiap
 * tabel. Panahnya sendiri sudah menjawab pertanyaannya, dan bisa diklik.
 *
 * Panah hilang begitu tabel digeser mentok kanan. Tanpa JS ia tidak pernah
 * muncul — dan itu memang benar: tanpa JS ia tidak bisa tahu kapan harus
 * hilang, dan penanda yang bohong lebih buruk daripada tidak ada.
 */
.tabel-wadah { position: relative; }

.penanda-geser {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 5;
  display: none;
  align-items: center;
  justify-content: center;
  width: 24px; height: 24px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface);
  color: var(--ink);
  box-shadow: 0 1px 3px rgba(0, 0, 0, .10);
  cursor: pointer;
  padding: 0;
}
/* Arah kanan & kiri dipisah: masing-masing muncul HANYA kalau ada yang bisa
   dilihat ke arah itu. Panah kiri baru berguna sesudah tabel digeser, dan
   menampilkannya sejak awal akan membuat keduanya jadi hiasan yang diabaikan
   (owner minta panah balik, 2026-08-22). */
.penanda-geser-kanan { right: 8px; }
.penanda-geser-kiri  { left: 8px; }
.tabel-wadah.bisa-geser  .penanda-geser-kanan { display: inline-flex; }
.tabel-wadah.bisa-balik  .penanda-geser-kiri  { display: inline-flex; }
.penanda-geser:hover { background: var(--surface-2); }

/* Kolom Proses di layar Karyawan ikut "terbang" di tepi kanan — owner,
   2026-08-22: "aku mau proses kolom ini terbang bisa geser2 jadi walau layar
   kecil tetap user bisa pencet". Tombolnya aksi utama layar ini; kalau untuk
   menekannya harus menggeser tabel dulu, ia praktis hilang di layar kecil. */
.tabel-angka th.kol-proses,
.tabel-angka td.kol-proses {
  position: sticky;
  right: 0;
  z-index: 2;
  background: var(--surface);
  border-left: 1px solid var(--border);
}
.tabel-angka thead th.kol-proses { z-index: 4; background: var(--surface-2); }
.tabel-angka tr:nth-child(even) td.kol-proses { background: var(--bg); }

/* Baris JUDUL KELOMPOK (YOG, SMR, PIK …) di tabel berkolom-beku.
 *
 * Selnya <td colspan> selebar seluruh tabel. Sel selebar itu tidak punya ruang
 * untuk "menempel": position:sticky hanya menahan elemen di dalam kotak
 * induknya, dan kotak induknya sama lebarnya dengan seluruh tabel — jadi
 * labelnya ikut hanyut ke kiri saat digeser (owner, 2026-08-22: "cabang Yog
 * yang diatas amelia ini masi gerak2").
 *
 * Yang dipatok karena itu LABELNYA, bukan selnya: sel dibiarkan mengalir
 * normal, span di dalamnya yang menempel di tepi kiri.
 *
 * .baris-grup sengaja kelas tersendiri, bukan menumpang .grup-unit: di layar
 * Absensi .grup-unit dipakai untuk arti yang sama sekali lain (baris yang
 * akan dilewati karena tidak punya baris periode), dan aturan di bawah akan
 * merusak pembekuan kolom di sana. */
.tabel-beku tr.baris-grup td {
  position: static;
  width: auto; min-width: 0; max-width: none;
  overflow: visible;
}
.tabel-beku tr.baris-grup td > span {
  position: sticky;
  left: 0;
  display: inline-block;
}

/* Aksi WhatsApp tetap memakai biru yang sama dengan pratinjau/edit agar
   seluruh aksi di sebelah nama terbaca sebagai satu kelompok. */
.ikon-wa:hover { background: var(--biru-bg); color: var(--biru-ink); border-color: var(--biru-ink); }
/* Tempat kosong untuk yang belum punya no HP: ruangnya tetap dipakai supaya
   kolomnya tidak melompat-lompat antar baris. */
.ikon-mati { opacity: .35; cursor: default; }

/* ---- Popup pratinjau slip ---- */
.popup-lebar { width: min(860px, calc(100vw - 2rem)); }
.popup-kepala {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--sp-3); margin-bottom: var(--sp-3);
}
/* .popup-bingkai (2026-08-30): dulu cuma #popup-slip-bingkai, dialog "Lihat
   slip" yang sekarang sudah dihapus (diganti drawer, admin/cetak.php) —
   #popup-bukti-bingkai (dialog "Lihat bukti transfer") kebetulan tidak
   ikut memakai aturan ukurannya, jadi ukurannya jatuh ke bawaan iframe
   (~300×150px), gambarnya kepotong rata tepi tanpa cara menggulungnya
   (owner: "kepotong pak"). Diganti kelas bersama supaya SEMUA iframe di
   dalam popup otomatis dapat ukuran yang sama, bukan menunggu ketahuan
   satu per satu tiap ada popup baru. */
.popup-bingkai {
  width: 100%;
  height: min(70vh, 700px);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface-2);
}

/* Popup yang isinya form langsung (tanpa #popup-isi) tidak punya jarak tepi
   sama sekali — .popup sengaja padding:0 karena beberapa popup memuat
   pembungkusnya sendiri. Akibatnya isian menempel ke garis tepi dan tombol
   Simpan menggantung di sudut (owner, 2026-08-22: "pop up edit nya jelek
   terlalu mepet"). */
.popup > form { padding: var(--sp-5); }
.popup-lebar  { padding: var(--sp-5); }

/* Jarak antar isian di dalam popup dilonggarkan: di layar sempit satu popup
   bisa memuat lima isian beserta bantuannya, dan tanpa jarak semuanya
   terbaca sebagai satu blok teks. */
.popup .grup-field { margin-bottom: var(--sp-4); }
.popup .grup-field:last-of-type { margin-bottom: var(--sp-2); }
.popup .bantuan { margin-top: var(--sp-1); }

/* Kolom centangan "pakai setoran tetap" — sempit, isinya cuma satu kotak. */
.tabel-angka th.w-pakai, .tabel-angka td.w-pakai { width: 72px; min-width: 72px; text-align: center; }

/* Tombol berisi angka: pilihan DAN tindakan sekaligus — yang ditekan adalah
   angka yang mau dipakai. Dibuat seperti angka, bukan seperti tombol besar,
   supaya tabel tetap terbaca sebagai tabel angka. */
.tombol-nilai {
  font-family: var(--font-angka);
  font-variant-numeric: tabular-nums;
  font-size: 13px;
  font-weight: 600;
  padding: 3px 8px;
  border: 1px solid var(--hijau-ink);
  border-radius: var(--radius-kecil, 6px);
  background: var(--hijau-bg);
  color: var(--hijau-ink);
  cursor: pointer;
}
.tombol-nilai:hover { filter: brightness(.97); }
.tombol-nilai:active { transform: translateY(1px); }
.tombol-nilai:disabled { opacity: .5; cursor: progress; }
/* Sesudah dipakai, tombolnya menawarkan nilai LAMA — warnanya netral supaya
   tidak terus-menerus mengajak ditekan. */
.tombol-nilai-kembali {
  border-color: var(--border);
  background: var(--surface-2);
  /* `var(--lemah, #6b6b6b)` sampai 2026-08-23 — token itu tidak pernah ada
     (namanya --muted), jadi yang benar-benar terpakai selalu hex cadangannya:
     satu warna abu-abu liar yang tidak ikut berubah kalau paletnya diubah,
     dan tidak terlihat salah karena kebetulan mirip. Fallback hex di dalam
     var() memang begitu — ia menyembunyikan salah ketik nama token. */
  color: var(--muted);
  font-weight: 400;
}

/* ================= SLIP PUBLIK (slip.php) ================= */
/* Dipindah dari <style> inline di slip.php, 2026-08-23. Nilainya dulu
   ditulis mentah di sana (420px, 14px, 15px) — melanggar STANDARDS §4.1 yang
   di seluruh berkas lain dipatuhi ketat, dan membuat satu-satunya halaman
   yang dilihat orang luar jadi satu-satunya halaman di luar sistem desain. */

.halaman-slip { background: var(--bg); font-family: var(--font); color: var(--ink); margin: 0; }

/* Selebar kartu nota, dipusatkan: slip ini hampir selalu dibuka di HP, dan di
   layar lebar kolom teks yang melar bikin angka kanan-kiri berjauhan. */
.slip-wadah { max-width: 420px; margin: 0 auto; padding: var(--sp-5) var(--sp-4); }
.slip-kartu {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: var(--sp-5);
}

/* Logo perusahaan (2026-08-24) — kecil, di tengah, di atas nama perusahaan.
   Lebar dipatok, tinggi ikut proporsi asli gambarnya (height:auto). */
.slip-logo { display: block; width: 72px; height: auto; margin: 0 auto var(--sp-2); }

.slip-merek { font-size: 16px; margin: 0 0 2px; text-align: center; }
.slip-motto { margin: 0 0 var(--sp-4); text-align: center; font-style: italic; color: var(--muted); }
.slip-pratinjau { margin-bottom: var(--sp-4); text-align: center; }
.slip-nama { margin: 0; }
.slip-nik { color: var(--hijau-ink); font-size: 0.8em; font-weight: 400; }
.slip-identitas { margin: 0 0 var(--sp-4); }
.slip-rentang { font-variant-numeric: tabular-nums; }

.slip-baris {
  display: flex;
  justify-content: space-between;
  gap: var(--sp-3);
  padding: var(--sp-2) 0;
  border-bottom: 1px solid var(--border);
  font-family: var(--font-angka);
  font-variant-numeric: tabular-nums;
  font-size: 14px;
}
.slip-baris:last-of-type { border-bottom: none; }
.slip-baris.minus { color: var(--merah-ink); }

/* Keterangan dalam kurung (bonus_ket, Cust·Reflexy INSENTIF Origin) — lebih
   kecil & pudar daripada label utamanya, supaya baris tetap satu baris dan
   keterangannya terbaca sebagai TAMBAHAN, bukan bagian sama pentingnya
   dengan nama komponennya (owner, 2026-08-24). */
.slip-baris-ket { font-size: 11px; color: var(--muted); }
.slip-total { font-weight: 600; font-size: 15px; }

/* Diterima = jawaban atas pertanyaan yang membuat orang membuka slipnya.
   Diberi latar sendiri supaya tidak perlu membaca label untuk menemukannya. */
.slip-diterima {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--sp-3);
  margin-top: var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
  background: var(--surface-2);
  border-radius: var(--radius-kecil);
}
.slip-diterima-label { font-size: 13px; color: var(--muted); }
.slip-diterima-nilai {
  font-family: var(--font-angka);
  font-variant-numeric: tabular-nums;
  font-size: 19px;
  letter-spacing: -0.02em;
}

.slip-tujuan { margin: var(--sp-4) 0 0; }
.slip-bukti { margin-top: var(--sp-4); }
.slip-bukti-judul { display: flex; justify-content: space-between; gap: var(--sp-2); margin: 0 0 2px; font-size: 13px; }
.bukti-gambar {
  display: block;
  width: 100%;
  border-radius: var(--radius-kecil);
  border: 1px solid var(--border);
  margin-top: var(--sp-2);
}

.slip-unduh { display: block; text-align: center; margin-top: var(--sp-5); }
.slip-kaki { margin: var(--sp-4) 0 0; padding: 0 var(--sp-2); font-size: 12px; text-align: center; }

/* Link review semua slip: hanya dibuat owner di Kirim, dibuka tanpa akun. */
.review-link-box { margin: var(--sp-5) 0; padding: var(--sp-4); border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); }
.review-link-box h2 { margin: 0 0 var(--sp-2); font-size: 15px; }
.review-link-box p { margin: 0 0 var(--sp-3); font-size: 13px; }
.review-link-baris, .review-link-aksi { display: flex; gap: var(--sp-2); align-items: center; flex-wrap: wrap; }
.review-link-baris input { flex: 1 1 280px; min-width: 0; padding: 9px; border: 1px solid var(--border); border-radius: var(--radius-kecil); font-size: 13px; }
.review-link-aksi { margin-top: var(--sp-3); }
.review-link-aksi form { margin: 0; }

/* Satu kartu per layar. Scroll snap menangani sapuan sentuh tanpa JS;
   tombol dan panah keyboard hanya memindahkan posisi untuk desktop. */
.halaman-review-slip { min-height: 100vh; }
.review-slip-kepala { display: flex; justify-content: space-between; align-items: center; gap: var(--sp-3); padding: var(--sp-3) var(--sp-4); border-bottom: 1px solid var(--border); background: var(--surface); }
.review-slip-kepala > div:first-child { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.review-slip-kepala strong { font-size: 15px; }
.review-slip-kepala span { font-size: 12px; color: var(--muted); }
.review-slip-navigasi { display: flex; align-items: center; gap: var(--sp-2); white-space: nowrap; }
.review-slip-navigasi #review-posisi { color: var(--ink); font-family: var(--font-angka); font-variant-numeric: tabular-nums; }
.review-slip-track { display: flex; overflow-x: auto; scroll-snap-type: x mandatory; scrollbar-width: none; }
.review-slip-track::-webkit-scrollbar { display: none; }
.review-slip-slide { flex: 0 0 100%; box-sizing: border-box; scroll-snap-align: start; padding: var(--sp-4) var(--sp-4) 0; }
.review-slip-slide .slip-kartu { max-width: 420px; margin: 0 auto; }
.review-slip-petunjuk, .review-slip-kosong { text-align: center; color: var(--muted); font-size: 12px; padding: var(--sp-3); }
@media (max-width: 520px) {
  .review-slip-kepala { align-items: flex-start; }
  .review-slip-kepala > div:first-child span { max-width: 38vw; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .review-slip-navigasi { gap: 4px; }
}
