:root{
  --bg:#E4E7EE;
  --surface:#F3F4F8;
  --surface-2:#EBEDF3;
  --sidebar-1:#1E1B4B;
  --sidebar-2:#312E81;
  /* Sidebar memakai variabelnya sendiri: dinaikkan terang & diturunkan
     saturasinya agar tidak terlalu pekat, tanpa mengubah latar layar login
     yang masih memakai --sidebar-1/2. */
  --nav-1:#332F69;
  --nav-2:#3E3A84;
  --primary:#4F46E5;
  --primary-600:#4338CA;
  --primary-tint:#E7E9F9;
  --accent:#EBA23A;
  --ink:#1E293B;
  --ink-soft:#334155;
  --muted:#64748B;
  --muted-2:#94A3B8;
  --line:#D7DBE4;
  /* Tepi dua warna untuk kisi tabel: putih di sisi atas-kiri, abu di sisi
     bawah-kanan. Satu arah cahaya untuk seluruh sel. */
  --tepi-terang:#FFFFFF;
  --tepi-gelap:#CBD1DC;
  --head-h:62px;
  --success:#10B981; --success-tint:#E7F7F0;
  --warn:#F59E0B;    --warn-tint:#FEF3E2;
  --danger:#EF4444;  --danger-tint:#FDECEC;
  --info:#3B82F6;    --info-tint:#E8F1FE;
  --violet:#8B5CF6;  --violet-tint:#F1ECFE;
  --r-card:8px; --r-btn:6px; --r-input:6px;
  --shadow-sm:0 1px 2px rgba(16,24,40,.05);
  /* Kesan timbul: bayangan hitam BERLAPIS — satu tipis rapat di tepi untuk
     ketegasan garis, satu lebar & kabur di bawah sebagai "jarak" dari halaman.
     Satu bayangan besar saja terbaca sebagai kabut; yang tipis itulah yang
     membuat tepinya terasa punya ketebalan.
     Dijadikan token karena dipakai kartu statistik dasbor DAN seluruh .card —
     dua tempat dengan nilai yang sedikit berbeda adalah cacat yang baru
     ketahuan saat keduanya kebetulan bersebelahan di layar. */
  --shadow-3d:0 1px 2px rgba(15,23,42,.08), 0 10px 22px -8px rgba(15,23,42,.30);
  --shadow-3d-naik:0 2px 4px rgba(15,23,42,.10), 0 18px 34px -10px rgba(15,23,42,.38);
  /* Garis tepi ikut digelapkan; --line terlalu pucat untuk bersanding dengan
     bayangan segelap ini dan membuat kartunya tampak mengambang tanpa sisi. */
  --line-3d:rgba(15,23,42,.10);
  --shadow-md:0 8px 24px -8px rgba(30,27,75,.18);
  --shadow-lg:0 24px 48px -16px rgba(30,27,75,.30);
  --sidebar-w:264px;
  /* Tinggi baris & header tabel dikunci agar batas "tepat 10 baris" bisa
     dihitung pasti, bukan ditebak. */
  --dt-row:30px;
  --dt-head:32px;
}

*{box-sizing:border-box;margin:0;padding:0}
/* Atribut `hidden` HARUS menang atas display milik elemen sendiri.
   Aturan [hidden]{display:none} bawaan peramban berasal dari lembar gaya UA,
   jadi ia kalah dari aturan kelas mana pun — dan di berkas ini hampir setiap
   elemen yang disembunyikan JS punya display sendiri (.btn inline-flex,
   .layout flex, .dt-card block). Sebelumnya itu ditambal satu per satu setiap
   kali ketahuan; satu aturan di sini menutup seluruhnya, termasuk yang belum
   ketahuan. */
[hidden]{display:none!important}
/* Dokumen sendiri TIDAK PERNAH menggulir. Satu-satunya yang menggulir adalah
   .content di dalam .main — dengan begitu topbar (judul halaman, tombol
   catatan, menu akun) mustahil ikut terdorong keluar layar, di halaman mana
   pun dan seberapa pun panjang isinya.
   Dikunci di html DAN body: sebagian peramban memindahkan gulir dokumen ke
   salah satunya saja, jadi mengunci satu belum tentu cukup.
   Layar login tidak terpengaruh — ia position:fixed dengan overflow-y sendiri. */
html,body{height:100%;overflow:hidden}
body{
  font-family:'Source Sans 3','Source Sans Pro',system-ui,-apple-system,'Segoe UI',Arial,sans-serif;
  background:var(--bg);
  color:var(--ink);
  font-size:14px;
  line-height:1.5;
  -webkit-font-smoothing:antialiased;
}
a{color:inherit;text-decoration:none}
button{font-family:inherit;cursor:pointer;border:none;background:none}
::-webkit-scrollbar{width:10px;height:10px}
::-webkit-scrollbar-thumb{background:#cbd3e1;border-radius:20px;border:3px solid transparent;background-clip:content-box}
::-webkit-scrollbar-thumb:hover{background:#aeb9cc;background-clip:content-box}

/* ============ LAYOUT ============ */
/* 100dvh, bukan 100vh: di peramban ponsel yang bilah alamatnya menyusut-membesar,
   100vh bernilai TINGGI TERBESAR yang mungkin — layout jadi lebih tinggi
   daripada yang benar-benar terlihat, dan yang pertama terdorong keluar adalah
   topbar di ujung atas. 100vh tetap ditulis lebih dulu sebagai cadangan untuk
   peramban yang belum mengenal dvh. */
.layout{display:flex;height:100vh;height:100dvh;overflow:hidden}

/* ---- Sidebar ---- */
.sidebar{
  width:var(--sidebar-w);
  background:linear-gradient(185deg,var(--nav-2),var(--nav-1));
  color:#E4E5EC;
  position:fixed;inset:0 auto 0 0;
  display:flex;flex-direction:column;
  z-index:60;
  transition:transform .28s cubic-bezier(.4,0,.2,1);
}
.brand{
  display:flex;align-items:center;gap:12px;
  height:var(--head-h);padding:0 18px;flex:none;
  border-bottom:1px solid rgba(255,255,255,.10);
}
.brand .logo{
  width:38px;height:38px;border-radius:22.4%;
  display:block;flex:none;
  box-shadow:0 6px 16px -4px rgba(0,0,0,.45);
}
.brand .txt{min-width:0}
.brand h1{color:#fff;font-size:16px;font-weight:800;letter-spacing:-.2px;line-height:1.2}
.brand span{
  display:block;font-size:10.5px;color:#9a9dd8;font-weight:500;
  line-height:1.25;text-wrap:balance;
}

.nav{flex:1;overflow-y:auto;padding:6px 10px 12px}
button:not(:disabled),.chip,.toggle,select,[data-goto],[data-page],[data-act]{cursor:pointer}
.nav::-webkit-scrollbar-thumb{background:rgba(255,255,255,.15);background-clip:content-box}
/* Label grup dan garis pemisahnya dihapus: sidebar jadi satu daftar rata. */
.nav-sep{margin-top:4px}
.nav-item{
  display:flex;align-items:center;gap:11px;
  cursor:pointer;
  padding:7px 12px;border-radius:8px;
  color:#E4E5EC;font-weight:500;font-size:13px;
  margin-bottom:1px;position:relative;
  /* Dulu tiap item berupa "kartu" bergaris dan berbayang. Itu membuat sidebar
     terasa pekat dan tiap item terbaca sebagai blok terpisah. Kini rata,
     sehingga menunya menyatu dan jaraknya bisa dirapatkan. */
  background:transparent;
  transition:background .15s,color .15s;
}
.nav-item i{width:19px;text-align:center;font-size:14.5px;flex:none}
.nav-item:hover{background:rgba(255,255,255,.085);color:#fff}
.nav-item.active{background:rgba(255,255,255,.145);color:#fff}
.nav-item.active::before{
  content:"";position:absolute;left:-10px;top:50%;transform:translateY(-50%);
  width:3px;height:18px;border-radius:0 3px 3px 0;background:var(--accent);
}
.nav-item .badge-count{
  margin-left:auto;background:var(--accent);color:#3b2606;
  font-size:10.5px;font-weight:800;padding:2px 7px;border-radius:20px;
}
/* submenu */
.nav-item .caret{width:auto;margin-left:auto;font-size:10px;opacity:.75;transition:transform .22s}
.nav-item.has-sub.open .caret{transform:rotate(180deg)}
.nav-sub{overflow:hidden;max-height:0;transition:max-height .28s ease;margin:1px 0 3px 10px;
  border-left:1px solid rgba(255,255,255,.14);padding-left:7px}
/* Cukup untuk kelompok terpanjang (6 butir) plus ruang kalau menunya
   ditata ulang; nilainya hanya batas transisi, bukan tinggi tetap. */
.nav-sub.open{max-height:600px}
.nav-item.sub{
  background:transparent;
  color:#C6C8D6;font-size:12.5px;padding:6px 10px;margin-bottom:0;
}
.nav-item.sub i{width:auto;font-size:5px;opacity:.5;margin:0 3px}
.nav-item.sub:hover{background:rgba(255,255,255,.06);color:#fff;transform:none;box-shadow:none}
.nav-item.sub.active{background:rgba(255,255,255,.1);color:#fff;box-shadow:none}
.nav-item.sub.active::before{display:none}
/* ---- Tab halaman terbuka ---- */
/* min-width:0 WAJIB pada anak flex yang menggulir: tanpa itu lebarnya dipaksa
   seluas isinya dan topbar ikut melar sampai tombol akun terdorong keluar. */
.tabbuka{
  display:flex;align-items:center;gap:6px;flex:1;min-width:0;
  overflow-x:auto;overflow-y:hidden;scrollbar-width:thin;padding:4px 2px;
}
.tabbuka::-webkit-scrollbar{height:5px}
.tabbuka:empty{display:none}
.tabbuka-item{
  display:inline-flex;align-items:center;gap:6px;flex:none;max-width:190px;
  padding:5px 7px 5px 11px;border-radius:9px;cursor:pointer;
  border:1px solid var(--line);background:var(--surface);
  font-family:inherit;font-size:12px;font-weight:600;color:var(--ink-soft);
  transition:background .15s,color .15s,border-color .15s;
}
.tabbuka-item:hover{background:var(--surface-2);color:var(--ink)}
.tabbuka-item.aktif{background:var(--primary-tint);border-color:var(--primary);color:var(--primary)}
.tabbuka-item>span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* Tab Home tak punya tombol tutup → bantalan kanannya disamakan dengan kiri
   supaya tidak terlihat gompal. */
.tabbuka-item.tabbuka-tetap{padding-right:11px}
.tabbuka-tutup{
  flex:none;width:17px;height:17px;display:grid;place-items:center;border:0;border-radius:5px;
  background:transparent;color:inherit;opacity:.55;font-size:10px;cursor:pointer;
}
.tabbuka-tutup:hover{opacity:1;background:rgba(192,57,43,.14);color:var(--danger)}
/* Di layar sempit topbar sudah penuh oleh judul dan tombol akun; tabnya
   disembunyikan, bukan dipaksa berdesakan. Halamannya tetap bisa dicapai lewat
   menu, jadi tidak ada yang hilang. */
@media (max-width:980px){ .tabbuka{display:none} }

/* ---- Main ---- */
.main{flex:1;margin-left:var(--sidebar-w);display:flex;flex-direction:column;min-width:0}

.topbar{
  position:sticky;top:0;z-index:40;
  min-height:var(--head-h);
  background:rgba(243,244,248,.9);backdrop-filter:blur(10px);
  border-bottom:1px solid rgba(10,12,35,.22);
  box-shadow:0 6px 18px -6px rgba(12,14,40,.32),inset 0 1px 0 rgba(255,255,255,.6);
  display:flex;align-items:center;gap:14px;
  padding:0 24px;
}
.hamburger{display:grid;place-items:center;font-size:16px;color:var(--ink-soft);width:38px;height:38px;border-radius:11px;border:1px solid var(--line);background:var(--surface);transition:.15s;flex:none}
.hamburger:hover{background:var(--surface-2);color:var(--primary)}
.page-head{margin-right:auto}
.page-head h2{font-size:15.5px;font-weight:800;letter-spacing:-.3px;line-height:1.15}
.page-head p{color:var(--muted);font-size:11.5px;line-height:1.2}
/* flex:none — topbar adalah flex container, dan tanpa ini tombol ikonnya ikut
   menyusut saat judul halaman panjang; yang terlihat lalu bukan tombol bulat
   melainkan lonjong yang makin gepeng tiap ada tombol baru. */
.icon-btn{
  width:38px;height:38px;flex:none;border-radius:11px;color:var(--ink-soft);
  display:grid;place-items:center;font-size:15px;position:relative;
  border:1px solid var(--line);background:var(--surface);transition:.15s;
}
.icon-btn:hover{background:var(--surface-2);color:var(--primary)}
.icon-btn .dot{position:absolute;top:9px;right:10px;width:8px;height:8px;border-radius:50%;background:var(--danger);border:2px solid #fff}
/* Pintasan ikon header: satu tombol, panel berisi ketiga tindakannya. */
.ikon-wrap{position:relative;flex:none}
.ikon-menu{
  position:absolute;right:0;top:calc(100% + 8px);min-width:206px;
  background:var(--surface);border:1px solid var(--line);border-radius:10px;
  box-shadow:var(--shadow-md);padding:6px;display:none;z-index:60;
}
.ikon-wrap.open .ikon-menu{display:block;animation:fade .16s ease both}
/* Di dalam panel, tombolnya berhenti jadi kotak ikon dan menjadi baris menu —
   bentuknya disamakan dengan .user-menu supaya dua panel bersebelahan di sudut
   yang sama tidak terlihat berasal dari dua aplikasi berbeda.
   Disasar lewat `.topbar .ikon-menu` (bukan `.ikon-menu` saja) KARENA aturan
   `.topbar .icon-btn{width:31px…}` di bawah punya kekhasan yang sama: dengan
   kekhasan seri, yang menang adalah yang ditulis belakangan — dan itu akan
   mengubah baris menunya kembali jadi kotak 31px. */
.topbar .ikon-menu .icon-btn{
  width:100%;height:auto;border:none;background:transparent;border-radius:7px;
  display:flex;align-items:center;gap:10px;padding:9px 11px;margin-left:0;
  font-family:inherit;font-size:13px;color:var(--ink-soft);text-align:left;
}
/* Margin negatif antar-ikon header dibatalkan di dalam panel: di sana mereka
   baris menu yang bertumpuk, bukan ikon yang dirapatkan. Kekhasannya sengaja
   0,4,0 supaya menang atas `.topbar .icon-btn+.icon-btn` yang ditulis
   belakangan, termasuk salinannya di dalam media query layar sempit. */
.topbar .ikon-menu .icon-btn+.icon-btn{margin-left:0}
.topbar .ikon-menu .icon-btn:hover{background:var(--surface-2);color:var(--ink)}
.topbar .ikon-menu .icon-btn i{width:16px;text-align:center;font-size:13px}
.topbar .ikon-menu .icon-btn > span:not(.dot){flex:1}
/* Titik di dalam panel kembali ke tepi kanan barisnya, bukan menempel di sudut
   kotak ikon yang sudah tidak ada. */
.topbar .ikon-menu .icon-btn .dot{position:static;width:7px;height:7px;border:none;flex:none;
  top:auto;right:auto}
/* Angka tab di butir "Close All Tab". */
.um-jml{margin-left:auto;font-size:11px;font-weight:700;color:var(--muted);
        background:var(--surface-2);border-radius:20px;padding:1px 7px;min-width:20px;text-align:center}
.user-menu button:disabled{opacity:.45;cursor:default}
.user-menu button:disabled:hover{background:transparent}

/*
 * Tiga ikon di header (layar penuh, catatan, notifikasi) dibuat lebih kecil
 * dan dirapatkan. Jaraknya TIDAK diatur lewat .topbar{gap} — gap itu juga
 * memisahkan judul halaman, tab, dan kartu akun, dan merapatkannya akan
 * merapatkan semuanya. Yang dipakai margin negatif antar-ikon saja, sehingga
 * jarak ke tetangga kiri-kanannya tetap 14px.
 */
.topbar .icon-btn{width:31px;height:31px;border-radius:9px;font-size:13px}
.topbar .icon-btn+.icon-btn{margin-left:-9px}
/* Titik notifikasi ikut mengecil dan bergeser — pada tombol 31px, posisi
   lamanya jatuh nyaris di tengah ikonnya. */
.topbar .icon-btn .dot{top:6px;right:6px;width:7px;height:7px;border-width:1.5px}
@media (max-width:560px){
  .topbar{gap:9px}
  .topbar .icon-btn{width:29px;height:29px;font-size:12.5px}
  .topbar .icon-btn+.icon-btn{margin-left:-5px}
}

/* Show/Hide sidebar (desktop) */
.sidebar{transition:transform .22s ease}
.main{transition:margin-left .22s ease}
.layout.collapsed .sidebar{transform:translateX(-100%)}
.layout.collapsed .main{margin-left:0}

/* Menu user */
.user-wrap{position:relative;flex:none}
.user-btn{display:flex;align-items:center;gap:9px;padding:5px 9px 5px 6px;border:1px solid var(--line);background:var(--surface);border-radius:11px;cursor:pointer;transition:.15s}
.user-btn:hover{background:var(--surface-2)}
.user-av{width:30px;height:30px;border-radius:9px;background:var(--primary);color:#fff;display:grid;place-items:center;font-size:12px;font-weight:700;flex:none}
.user-meta{display:flex;flex-direction:column;line-height:1.12;text-align:left}
.user-meta b{font-size:12.5px;color:var(--ink)}
.user-meta small{font-size:10.5px;color:var(--muted)}
.user-btn .fa-chevron-down{font-size:10px;color:var(--muted-2);transition:transform .2s}
.user-wrap.open .fa-chevron-down{transform:rotate(180deg)}
.user-menu{position:absolute;right:0;top:calc(100% + 8px);min-width:196px;background:var(--surface);border:1px solid var(--line);border-radius:10px;box-shadow:var(--shadow-md);padding:6px;display:none;z-index:60}
.user-wrap.open .user-menu{display:block;animation:fade .16s ease both}
.user-menu button{width:100%;display:flex;align-items:center;gap:10px;padding:9px 11px;border:none;background:transparent;border-radius:7px;cursor:pointer;font-family:inherit;font-size:13px;color:var(--ink-soft);text-align:left}
.user-menu button:hover{background:var(--surface-2)}
.user-menu button.danger{color:#d15b60}
.user-menu button.danger:hover{background:rgba(209,91,96,.12)}
.user-menu i{width:16px;text-align:center;font-size:13px}
.user-menu .divider{height:1px;background:var(--line);margin:5px 4px}

/* container-type membuat lebar wadah ini bisa ditanya @container.
   SELURUH tata letak di dalam .content memakai @container, bukan @media:
   menutup sidebar menambah 264px ruang TANPA mengubah lebar layar, jadi media
   query berbasis layar tidak akan pernah tahu ruangnya sudah berubah — dan
   sebaliknya, layar 1366px dengan sidebar terbuka hanya menyisakan ~1050px
   padahal aturan berbasis layar mengira ruangnya 1366px.
   Ambang @container = ambang @media lama dikurangi 316px (264 sidebar + 52
   padding), sehingga perilakunya saat sidebar terbuka tetap sama seperti
   sebelumnya dan hanya keadaan sidebar tertutup yang jadi benar.
   Yang TETAP @media hanyalah yang berada di LUAR wadah ini — sidebar, topbar,
   dan modal — karena lebarnya memang tidak ditentukan .content. */
.content{padding:26px;flex:1;min-height:0;overflow-y:auto;container-type:inline-size;container-name:isi}
.page{display:none;animation:fade .35s ease both}
.page.active{display:block}
@keyframes fade{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
/* Placeholder halaman yang belum berisi (mis. Bonus SLA/Motor, Deduksi Klien). */
.page-kosong{display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:10px;min-height:46vh;text-align:center;color:var(--muted);
  border:1px dashed var(--line);border-radius:14px;background:var(--surface);padding:40px 20px}
.page-kosong i{font-size:34px;color:var(--muted-2)}
.page-kosong h4{font-size:15px;font-weight:800;color:var(--ink);letter-spacing:-.2px}
.page-kosong p{font-size:12.5px;max-width:360px;line-height:1.5}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}

/* ---- Stat cards ---- */
.stat-grid{
  display:grid;
  /* Sepuluh kartu dalam SATU baris. minmax(0,1fr) penting: tanpanya kolom
     menolak menyusut di bawah lebar kontennya dan barisnya akan meluber. */
  grid-template-columns:repeat(10,minmax(0,1fr));
  gap:12px;margin-bottom:20px;
}
.stat{
  background:var(--surface);border-radius:var(--r-card);padding:16px 12px;
  border:1px solid var(--line-3d);
  box-shadow:var(--shadow-3d);
  display:flex;flex-direction:column;align-items:center;text-align:center;
  gap:9px;transition:transform .18s,box-shadow .18s;min-width:0;
}
.stat:hover{
  transform:translateY(-3px);
  box-shadow:var(--shadow-3d-naik);
}
.stat .top{display:flex;align-items:center;justify-content:center;width:100%}
.stat .ic{width:36px;height:36px;border-radius:11px;display:grid;place-items:center;font-size:15px;flex:none}
.stat .trend{font-size:11.5px;font-weight:700;padding:3px 8px;border-radius:20px;display:flex;align-items:center;gap:4px}
.stat .num{font-size:22px;font-weight:800;letter-spacing:-.5px;color:var(--ink);line-height:1.15}
.stat .lbl{color:var(--muted);font-size:11.5px;font-weight:500;line-height:1.3;overflow-wrap:anywhere}
.ic.ind{background:var(--primary-tint);color:var(--primary)}
.ic.grn{background:var(--success-tint);color:var(--success)}
.ic.amb{background:var(--warn-tint);color:var(--warn)}
.ic.vio{background:var(--violet-tint);color:var(--violet)}
.ic.red{background:var(--danger-tint);color:var(--danger)}
.ic.blu{background:var(--info-tint);color:var(--info)}

/* Area isi ≤1.280px (layar sempit DAN laptop 1366px + sidebar): sepuluh kolom
   menyisakan ≤94px — label "Total Karyawan", "Absen Lebih Jarak", "Tidak Absen
   3 Hari" terlipat janggal. Barisnya tetap SATU baris, digulir mendatar dengan
   snap per kartu (permintaan user 15 Okt 2026: "scroll kesamping, snap-x");
   lebar kartu ≥142px supaya semua label muat satu baris. */
@container isi (max-width:1280px){
  .stat-grid{
    grid-template-columns:none;
    grid-auto-flow:column;
    grid-auto-columns:minmax(142px,1fr);
    overflow-x:auto;
    scroll-snap-type:x mandatory;
    /* Wadah gulir MEMOTONG apa pun di luar batasnya — termasuk bayangan kartu
       (±24px ke bawah, ±14px ke samping). Diberi ruang bayangan: 12px kiri-kanan
       (diimbangi margin negatif → kartu tetap sejajar bagian lain; area isi
       ber-padding ≥12px jadi halaman tak ikut meluber) dan 26px bawah (margin
       bawah 2px → jarak kartu ke bagian berikutnya tetap 28px). Tepi kiri-kanan
       memudar di ruang 12px itu supaya tidak ada potongan tajam. */
    margin:0 -12px 2px;
    padding:4px 12px 26px;
    scroll-padding-inline:12px;
    -webkit-mask-image:linear-gradient(to right,transparent 0,#000 12px,#000 calc(100% - 12px),transparent 100%);
    mask-image:linear-gradient(to right,transparent 0,#000 12px,#000 calc(100% - 12px),transparent 100%);
  }
  /* Scrollbar tipis, hanya tampak saat di-hover (ruangnya tetap → tak bergeser).
     scrollbar-width/scrollbar-color HANYA untuk Firefox: Chrome 121+ yang melihat
     keduanya memakai scrollbar bawaan Windows (tebal, ada panah ◀ ▶) dan
     mengabaikan gaya ::-webkit-scrollbar di bawah. */
  @supports (-moz-appearance:none){
    .stat-grid{scrollbar-width:thin;scrollbar-color:transparent transparent}
    .stat-grid:hover{scrollbar-color:#cbd3e1 transparent}
  }
  .stat{scroll-snap-align:start}
  /* Bayangan hover di dalam wadah gulir dibuat muat (±21px ke bawah setelah
     terangkat 3px) — bayangan hover bawaan (±42px) akan terpotong rata. */
  .stat-grid .stat:hover{box-shadow:0 2px 4px rgba(15,23,42,.10),0 12px 20px -8px rgba(15,23,42,.32)}
  .stat-grid::-webkit-scrollbar{height:7px;background:transparent}
  .stat-grid::-webkit-scrollbar-track{background:transparent}
  .stat-grid::-webkit-scrollbar-button{display:none;width:0;height:0}
  .stat-grid::-webkit-scrollbar-thumb{background:transparent;border-radius:20px}
  .stat-grid:hover::-webkit-scrollbar-thumb{background:#cbd3e1}
}
.trend.up{background:var(--success-tint);color:var(--success)}
.trend.down{background:var(--danger-tint);color:var(--danger)}
.trend.flat{background:var(--surface-2);color:var(--muted)}

/* ---- Panels / cards ---- */
.grid-2{display:grid;grid-template-columns:1.55fr 1fr;gap:16px;margin-bottom:22px}
/* Tiga kartu ringkasan sejajar, sama lebar dan sama tinggi. Tingginya
   ditentukan daftar di dalamnya yang dibatasi sekitar tujuh baris, jadi ketiganya
   berakhir di garis yang sama tanpa perlu dipatok angka. */
.home-tiga{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:16px;margin-bottom:22px}
.home-tiga>.card{display:flex;flex-direction:column;min-width:0}
.home-tiga>.card>.card-body{flex:1;min-height:0;display:flex;flex-direction:column}
/* Tiga kolom butuh lebar; di bawah itu jadi dua, lalu satu. Ambangnya diukur
   dari wadah isinya (@container), sama seperti .home-dua — sidebar yang
   terbuka mempersempit isi tanpa mempersempit jendela. */
@container isi (max-width:1100px){ .home-tiga{grid-template-columns:repeat(2,minmax(0,1fr))} }
@container isi (max-width:764px){ .home-tiga{grid-template-columns:minmax(0,1fr)} }
/* Tab jenis pengajuan di dalam kartu Pengajuan. */
.pgj-tab{display:flex;gap:2px;border-bottom:1px solid var(--line);margin-bottom:8px;flex:none}
.pgj-tab .note-tab{padding:7px 10px;font-size:11.5px}
/* Lencana jumlah pada tiap tab — angka pengajuan jenis itu di rentang filter. */
.pgj-n{display:inline-flex;align-items:center;justify-content:center;min-width:17px;height:17px;
       padding:0 5px;margin-left:3px;border-radius:999px;background:var(--surface-2);
       border:1px solid var(--line);color:var(--muted);font-size:10px;font-weight:800;
       font-variant-numeric:tabular-nums;line-height:1;vertical-align:middle}
.pgj-n:empty,.pgj-n.nol{opacity:.5}
/* Tab aktif: lencananya ikut menonjol. */
.pgj-tab .note-tab.active .pgj-n{background:var(--primary);border-color:var(--primary);color:#fff;opacity:1}
.kartu-jml{flex:none;padding:2px 9px;border-radius:999px;background:var(--surface-2);
           border:1px solid var(--line);color:var(--muted);font-size:11px;font-weight:700;
           font-variant-numeric:tabular-nums;white-space:nowrap}
.kartu-jml:empty{display:none}
/* Tren Kehadiran dan Peta Cabang berdampingan. Grafiknya butuh lebar untuk
   batang per hari; petanya cukup persegi. */
/* align-items:stretch (bawaan grid), BUKAN start: kedua kartu memanjang sama
   tinggi, dan isinya yang menyesuaikan. Dengan start, tinggi tiap kartu
   ditentukan isinya masing-masing dan tepi bawahnya tidak pernah sejajar. */
.home-dua{display:grid;grid-template-columns:4fr 8fr;gap:16px;margin-bottom:22px}
@container isi (max-width:1000px){ .home-dua{grid-template-columns:minmax(0,1fr)} }
.home-dua>.card{display:flex;flex-direction:column;min-width:0}
.home-dua>.card>.card-body{flex:1;min-height:0;display:flex;flex-direction:column}
/* Peta mengisi sisa tinggi kartunya, bukan dipatok angka tetap — itulah yang
   membuat tingginya mengikuti kartu grafik di sebelahnya. */
.home-dua .chart-wrap{flex:1;min-height:280px;overflow:hidden;display:flex;flex-direction:column}
/* SVG mengisi kotak ini secara ABSOLUT — tingginya tidak ikut menentukan tinggi
   kartu, jadi menggambar ulang tidak bisa membuat kartunya memanjang (putaran
   ResizeObserver). Tinggi plot murni dari layout kisi (mengikuti kartu peta). */
.chart-wrap .chart-plot{position:relative;flex:1;min-height:0;width:100%;align-self:stretch}
.chart-wrap .chart-plot>svg{position:absolute;inset:0;width:100%;height:100%;display:block}
.chart-legend{margin-top:4px;flex:none;width:100%}
/* Kartu grafik diperbesar: sama polanya dengan peta — menutupi area isi, SVG-nya
   dilepas dari batas tinggi supaya batang & angkanya ikut membesar. */
.card.chart-besar{position:fixed;inset:12px;z-index:70;margin:0;max-width:none}
.card.chart-besar>.card-body{min-height:0}
.card.chart-besar .chart-wrap{flex:1;min-height:0}
.chart-maks{flex:none;margin-left:auto}
/*
 * isolation:isolate WAJIB di sini. Leaflet menumpuk panel-panelnya dengan
 * z-index 100-1000 (ubin 200, penanda 600, popup 700, kendali 800, sudut 1000).
 * Tanpa konteks penumpukan sendiri, angka-angka itu bersaing di tingkat
 * HALAMAN — dan karena modal hanya z-index 80, petanya menggambar DI ATAS
 * modal catatan yang sedang terbuka, seolah mengambang lepas dari halamannya.
 * Dengan isolate, seluruh angka itu terkurung di dalam kotak ini.
 */
.peta-wrap{flex:1;min-height:230px;border-radius:10px;overflow:hidden;
           border:1px solid var(--line);background:var(--surface-2);
           position:relative;z-index:0;isolation:isolate}
/* Diperbesar: kartunya menutupi seluruh area isi, petanya ikut memanjang.
   Memakai posisi tetap, bukan Fullscreen API — peta yang menutupi layar penuh
   menyembunyikan menu dan filter yang justru sering dipakai bersamanya. */
.card.peta-besar{position:fixed;inset:12px;z-index:70;margin:0;max-width:none}
.card.peta-besar .peta-wrap{min-height:0}
.peta-maks{flex:none;margin-left:auto}
/* Peta mengisi kartunya sampai ke pinggir; sudut bawahnya mengikuti sudut
   kartu supaya tidak ada tepi lurus yang menonjol di dalam sudut membulat. */
.peta-badan{padding:0;overflow:hidden;border-radius:0 0 var(--r-card) var(--r-card)}
.peta-badan .peta-wrap{border:0;border-radius:0}
/* Tab di dalam kartu peta. Barisnya rapat karena ia berada DI DALAM kartu,
   bukan di kepalanya. */
/* Kotak tanggal dd-mm-yyyy. Kotak bawaan peramban tetap ada di belakangnya
   sebagai pemilik nilai dan pembuka kalender — hanya tampilannya yang diganti. */
.tgl-kotak{position:relative;display:inline-flex;align-items:center}
.tgl-tampil{width:128px;padding-right:30px!important}
.tgl-picu{position:absolute;right:4px;width:24px;height:24px;border:none;border-radius:6px;
          background:transparent;color:var(--muted);cursor:pointer;font-size:12px;
          display:grid;place-items:center}
.tgl-picu:hover{background:var(--surface-2);color:var(--primary)}
.tgl-picu:focus-visible{outline:2px solid var(--primary);outline-offset:1px}
/* Kotak aslinya tidak terlihat tapi tetap ada: display:none membuat
   showPicker() ditolak peramban. */
.tgl-asli{position:absolute;right:6px;bottom:0;width:1px;height:1px;opacity:0;
          pointer-events:none;border:0;padding:0}
.tgl-tampil.salah{border-color:#C0392B!important}

.peta-tab{display:flex;gap:2px;padding:0 12px;border-bottom:1px solid var(--line);flex:none;align-items:center}
.peta-tab .note-tab{padding:8px 12px;font-size:11.5px}
/* Rekap total cabang per status di ujung kanan baris tab. */
.peta-rekap{margin-left:auto;display:flex;gap:8px;align-items:center;flex-wrap:wrap}
.pr-chip{display:inline-flex;align-items:center;gap:5px;padding:3px 10px;border-radius:999px;
         font-size:11px;font-weight:600;border:1px solid var(--line);background:var(--surface);
         cursor:pointer;transition:background .15s,border-color .15s,box-shadow .15s}
.pr-chip:hover{border-color:currentColor}
.pr-chip:focus-visible{outline:2px solid var(--primary);outline-offset:1px}
.pr-chip b{font-variant-numeric:tabular-nums;font-weight:800}
.pr-chip .pr-dot{width:8px;height:8px;border-radius:50%;flex:none}
/* Aktif = biru, sama dengan titik aktif di peta. */
.pr-aktif{color:#2563eb} .pr-aktif .pr-dot{background:#2563eb}
.pr-nonaktif{color:var(--danger)} .pr-nonaktif .pr-dot{background:var(--danger)}
/* Chip yang sedang menyaring: isian berwarna, teks putih. */
.pr-chip[aria-pressed="true"]{color:#fff}
.pr-chip[aria-pressed="true"] .pr-dot{background:#fff}
.pr-aktif[aria-pressed="true"]{background:#2563eb;border-color:#2563eb}
.pr-nonaktif[aria-pressed="true"]{background:var(--danger);border-color:var(--danger)}
/*
 * min-height DI SINI, bukan hanya di .peta-wrap.
 *
 * Dulu lantai 230px itu milik petanya saja, jadi tinggi kartunya ditentukan
 * peta saat tab Peta terbuka dan ditentukan ISI TABEL saat tab List Cabang
 * terbuka — 210 baris cabang membuat kartunya (dan kartu grafik di
 * sebelahnya, karena keduanya satu baris kisi) memanjang jauh ke bawah.
 *
 * Dengan min-height di panelnya, dua hal sekaligus beres: kedua tab berbagi
 * lantai yang sama sehingga tinggi kartunya tidak berubah saat tab berganti,
 * dan min-height yang bukan `auto` membuat panelnya boleh lebih pendek
 * daripada isinya — syarat supaya .peta-daftar benar-benar menggulir dan
 * bukan sekadar berhak menggulir.
 */
.peta-panel{display:none;flex:1;min-height:230px;position:relative}
.peta-panel.show{display:flex;flex-direction:column}
.card.peta-besar .peta-panel{min-height:0}
/* Daftar cabang: 144 baris TIDAK boleh menentukan tinggi kartu (kisi align
   stretch → kartu ikut memanjang, kartu grafik di sebelahnya ikut terseret).
   `flex:1;min-height:0;overflow:auto` saja tak cukup: tinggi baris kisi dihitung
   dari isi, jadi masih sirkular. Dibikin ABSOLUT inset:0 — keluar dari alur,
   jadi tak pernah menyumbang tinggi; ia mengisi panel (min 230 / mengikuti kartu
   grafik) dan menggulir di dalamnya. Pola sama dgn SVG grafik. */
.peta-daftar{position:absolute;inset:0;overflow:auto}
.peta-daftar table{width:100%;border-collapse:collapse;font-size:11.5px}
.peta-daftar th{position:sticky;top:0;background:var(--surface-2);text-align:left;
                padding:7px 12px;font-size:10px;text-transform:uppercase;letter-spacing:.04em;
                color:var(--muted);border-bottom:1px solid var(--line)}
.peta-daftar td{padding:6px 12px;border-bottom:1px solid var(--line)}
.peta-daftar tr:last-child td{border-bottom:0}
.peta-daftar .pd-n{margin-left:5px;padding:1px 6px;border-radius:999px;background:var(--surface);
                   border:1px solid var(--line);color:var(--muted);font-size:9.5px;font-weight:700;
                   letter-spacing:0;text-transform:none;font-variant-numeric:tabular-nums}
.peta-daftar .pd-nama{font-weight:600;color:var(--ink)}
.peta-daftar .pd-pic{color:var(--ink-soft)}
.peta-daftar .pd-tikor{font-variant-numeric:tabular-nums;color:var(--ink-soft);white-space:nowrap}
.peta-daftar .pd-center{text-align:center}
.peta-daftar .pd-status i{font-size:14px}
.peta-daftar .pd-ok{color:var(--success)}
.peta-daftar .pd-no{color:var(--danger)}
/* Cabang tanpa koordinat ditandai redup — ia sebab 22 marker yang tidak ada. */
.peta-daftar .pd-kosong{color:var(--muted);font-weight:400}
.peta-daftar tr.pd-tanpa .pd-nama{color:var(--muted);font-weight:400}
.peta-gagal{display:flex;flex-direction:column;justify-content:center;height:100%;
            padding:18px;gap:5px;font-size:11.5px;line-height:1.55;color:var(--muted)}
.peta-gagal b{font-size:12.5px;color:var(--ink)}
/* Kartu angka: bisa diklik, jadi tampil seperti tombol. */
.stat{cursor:pointer;font:inherit;text-align:center;-webkit-appearance:none;appearance:none}
.stat:focus-visible{outline:2px solid var(--primary);outline-offset:2px}
/* Rincian di balik angka kartu. */
.rk-bar{display:flex;align-items:center;gap:9px;margin-bottom:10px;flex-wrap:wrap}
.rk-lb{font-size:10.5px;text-transform:uppercase;letter-spacing:.04em;color:var(--muted)}
.rk-bar .kl-input{margin-bottom:0;width:auto;min-width:180px;max-width:100%;font-size:12px;padding:6px 9px}
#rkKaryawan{min-width:230px}
.rk-info{margin-left:auto;font-size:11px;color:var(--muted);font-variant-numeric:tabular-nums}
#rkIsi{border:1px solid var(--line);border-radius:9px;overflow:auto}
/* Kolom per-tanggal "Tidak Absen 3 Hari": ikon ✓/✗ rata tengah. */
.rk-tabel th.rk-hari-h{text-align:center;white-space:nowrap;font-variant-numeric:tabular-nums}
.rk-tabel td.rk-hari-c{text-align:center}
.rk-tabel td.rk-hari-c i{font-size:15px}
.rk-tabel .rk-ya{color:var(--success)}
.rk-tabel .rk-tidak{color:var(--danger)}
.rk-tabel .rk-izin{color:#2563eb}
.rk-pager{display:flex;gap:4px;justify-content:flex-end;align-items:center;margin-top:10px;flex-wrap:wrap}
.rk-pager button{min-width:28px;height:28px;padding:0 7px;border:1px solid var(--line);
                 border-radius:7px;background:var(--surface);color:var(--ink-soft);
                 font:inherit;font-size:11.5px;cursor:pointer;font-variant-numeric:tabular-nums}
.rk-pager button:hover:not(:disabled){border-color:var(--primary);color:var(--primary)}
.rk-pager button.aktif{background:var(--primary);border-color:var(--primary);color:#fff;font-weight:700}
.rk-pager button:disabled{opacity:.4;cursor:default}
.rk-elips{color:var(--muted);padding:0 2px}
.rk-tabel{width:100%;border-collapse:collapse;font-size:11.5px}
.rk-tabel th{position:sticky;top:0;background:var(--surface-2);text-align:left;
             padding:7px 9px;font-size:10px;text-transform:uppercase;letter-spacing:.04em;
             color:var(--muted);border-bottom:1px solid var(--line);white-space:nowrap}
.rk-tabel th.rk-urut{cursor:pointer;user-select:none}
.rk-tabel th.rk-urut i{margin-left:5px;font-size:9px;opacity:.35}
.rk-tabel th.rk-urut:hover{color:var(--primary)}
.rk-tabel th.rk-urut:hover i{opacity:.7}
.rk-tabel th.rk-urut.aktif{color:var(--primary)}
.rk-tabel th.rk-urut.aktif i{opacity:1}
.rk-tabel th.rk-urut:focus-visible{outline:2px solid var(--primary);outline-offset:-2px}
.rk-tabel td{padding:6px 9px;border-bottom:1px solid var(--line);vertical-align:top}
.rk-tabel tr:last-child td{border-bottom:0}
.rk-no{color:var(--muted);font-variant-numeric:tabular-nums;width:1%}
.rk-nama{font-weight:600;color:var(--ink)}
.rk-kosong{margin:0;font-size:12px;color:var(--muted)}
/* Super-header sub-kolom (Sudah Absen: Jadwal/Absen → In/Out). */
.rk-tabel th.rk-grup{text-align:center;border-left:1px solid var(--line);border-right:1px solid var(--line)}
/* Badge keterangan (Belum Absen). */
.rk-ket{display:inline-flex;align-items:center;gap:5px;padding:2px 9px;border-radius:999px;font-size:10.5px;font-weight:700;white-space:nowrap}
.rk-ket i{font-size:9.5px;opacity:.9}
.rk-ket-cuti{background:rgba(37,99,235,.12);color:#1d4ed8}
.rk-ket-sakit{background:rgba(217,119,6,.14);color:#b45309}
.rk-ket-izin{background:rgba(22,163,74,.12);color:#15803d}
.rk-ket-alpa{background:rgba(220,38,38,.12);color:#b91c1c}
/* Shift / Informasi (Belum Absen): warna badge per kategori. */
.rk-info-pagi{background:rgba(234,88,12,.12);color:#c2410c}
.rk-info-malam{background:rgba(79,70,229,.12);color:#4338ca}
.rk-info-kosong{background:rgba(100,116,139,.12);color:#64748b}
/* Badge approval (Cuti/Sakit/Izin). */
.rk-ap{display:inline-flex;align-items:center;gap:5px;padding:2px 9px;border-radius:999px;font-size:11px;font-weight:700;white-space:nowrap}
.rk-ap i{font-size:10px}
.rk-ap-ya{background:rgba(22,163,74,.12);color:#15803d}
.rk-ap-no{background:rgba(220,38,38,.12);color:#b91c1c}
.rk-ap-tunggu{background:rgba(217,119,6,.14);color:#b45309}
/* Ikon surat dokter (Sakit). */
.rk-surat{display:inline-flex;align-items:center;justify-content:center;width:28px;height:24px;
  border-radius:6px;color:var(--primary);background:var(--primary-tint);font-size:13px;text-decoration:none}
.rk-surat:hover{filter:brightness(.95)}
/* Chip filter keterangan di atas tabel Belum Absen — rata KANAN. */
.rk-chips{display:flex;flex-wrap:wrap;justify-content:flex-end;gap:8px;margin:0 0 12px}
.rk-chip{display:inline-flex;align-items:center;gap:6px;padding:5px 12px;border-radius:999px;
         border:1px solid var(--line);background:var(--surface-2);font-size:12px;font-weight:600;
         color:var(--ink);cursor:pointer;transition:.12s}
.rk-chip b{font-variant-numeric:tabular-nums;color:var(--muted)}
.rk-chip:hover{border-color:var(--primary);color:var(--primary)}
.rk-chip.aktif{border-color:var(--primary);background:var(--primary-tint);color:var(--primary)}
.rk-chip.aktif b{color:var(--primary)}
.card{
  background:var(--surface);border-radius:var(--r-card);
  border:1px solid var(--line-3d);
  box-shadow:var(--shadow-3d);
  transition:box-shadow .18s;
}
/* Kartu diangkat sedikit saat disentuh — penegasan bahwa ia satu bidang utuh,
   bukan sekadar latar. TIDAK memakai transform seperti kartu statistik: kartu
   di sini memuat isian, tabel, dan panel mengambang, dan menggesernya saat
   kursor lewat membuat sasaran klik bergerak di bawah tangan. */
.card:hover{box-shadow:var(--shadow-3d-naik)}
.card-head{display:flex;align-items:center;justify-content:space-between;padding:18px 20px;border-bottom:1px solid var(--line)}
.card-head h4{font-size:15px;font-weight:800;letter-spacing:-.2px}
.card-head p{color:var(--muted);font-size:12px}
.card-body{padding:20px}
.chart-wrap{position:relative;height:270px}

/*
 * Sepuluh baris terlihat, sisanya digulir.
 *
 * Tingginya diikat ke --act-baris, yang HARUS sama dengan tinggi satu <li>:
 * ikon 36px + padding 12px atas-bawah + garis 1px = 61px. Kalau .activity li
 * di bawah diubah, angka itu ikut diubah — itulah sebabnya ia variabel dan
 * bukan angka yang ditulis lepas di tempat lain.
 *
 * Baris kesebelas sengaja terpotong separuh, bukan pas di tepi: potongan itu
 * satu-satunya tanda bahwa masih ada isi di bawahnya. Daftar yang berhenti
 * rapi di garis bawah terbaca sebagai daftar yang sudah habis.
 */
.activity{--act-baris:61px}
.activity.gulir{max-height:calc(var(--act-baris) * 6.5);overflow-y:auto;
                padding-right:6px;overscroll-behavior:contain}
.activity li{display:flex;gap:13px;padding:12px 0;border-bottom:1px dashed var(--line)}
.activity li:last-child{border-bottom:none;padding-bottom:0}
/* Yang digulir tetap memakai garis pemisah di baris terakhirnya: tanpa garis,
   baris terakhir yang kebetulan terlihat penuh tampak seperti akhir daftar. */
.activity.gulir li:last-child{border-bottom:1px dashed var(--line);padding-bottom:12px}
.na-nik{font-variant-numeric:tabular-nums}
.activity .a-ic{width:36px;height:36px;border-radius:10px;display:grid;place-items:center;font-size:14px;flex:none}
.activity b{font-weight:700;font-size:13px}
.activity small{color:var(--muted);font-size:11.5px}
.activity time{margin-left:auto;color:var(--muted-2);font-size:11px;white-space:nowrap;text-align:right;line-height:1.4}
.activity time .t-tgljam{font-variant-numeric:tabular-nums}
.activity time .t-cab{font-size:10.5px;color:var(--muted);font-weight:600;text-transform:uppercase;letter-spacing:.02em}
/* Baris pengajuan bisa diklik → modal detail. */
#activityList li.pgj-klik,#offList li.pgj-klik{cursor:pointer;border-radius:8px;transition:background .12s}
#activityList li.pgj-klik:hover,#offList li.pgj-klik:hover{background:var(--surface-2)}
/* Isi modal detail pengajuan: pasangan label–nilai. */
.pd-detail{display:grid;grid-template-columns:116px 1fr;gap:9px 14px;font-size:12.5px;margin:0}
.pd-detail dt{color:var(--muted);font-weight:600}
.pd-detail dd{color:var(--ink);margin:0;word-break:break-word}
.pd-detail dd.pd-ket{white-space:pre-wrap}
.pd-st{display:inline-flex;align-items:center;gap:6px;padding:2px 10px;border-radius:999px;font-size:11.5px;font-weight:700}
.pd-st.ok{background:var(--success-tint);color:var(--success)}
.pd-st.no{background:var(--danger-tint);color:var(--danger)}
.pd-st.wait{background:var(--warn-tint);color:var(--warn)}

/* ---- Toolbar above tables ---- */
/* .toolbar dibongkar oleh bindTable dan isinya dipindah ke .dt-top;
   aturan di bawah hanya berlaku sesaat sebelum pemindahan. */
.toolbar{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:12px}
.chip{
  padding:6px 12px;border:1px solid var(--line);background:var(--surface);
  border-radius:20px;font-size:12px;font-weight:600;color:var(--muted);transition:.15s;
}
.chip:hover{border-color:var(--primary);color:var(--primary)}
.chip.active{background:var(--primary);border-color:var(--primary);color:#fff;box-shadow:0 6px 14px -6px var(--primary)}

/* ---- Buttons ---- */
.btn{display:inline-flex;align-items:center;gap:7px;padding:8px 13px;border-radius:var(--r-btn);font-weight:700;font-size:12.5px;transition:.15s;white-space:nowrap}
.btn i{font-size:12px}
.btn-primary{background:var(--primary);color:#fff;box-shadow:0 8px 18px -8px var(--primary)}
.btn-primary:hover{background:var(--primary-600);transform:translateY(-1px)}
.btn-ghost{background:var(--surface);color:var(--ink-soft);border:1px solid var(--line)}
.btn-ghost:hover{background:var(--surface-2);border-color:var(--muted-2)}
.btn-sm{padding:5px 10px;font-size:11.5px}

/* ---- Action icon buttons in table ---- */
.act{display:inline-flex;gap:2px;align-items:center}
.act .rk-sel{margin-right:5px;cursor:pointer}
.act button{width:24px;height:24px;border-radius:6px;display:grid;place-items:center;font-size:12.5px;background:transparent;border:none;cursor:pointer;transition:.14s;color:var(--muted-2)}
.act .v{color:#3f7dc0}
.act .e{color:#d99236}
.act .d{color:#d15b60}
.act .ok{color:#3a9866}
.act .no{color:#d15b60}
.act button:hover{transform:translateY(-1px)}
.act .v:hover{background:rgba(63,125,192,.14)}
.act .e:hover{background:rgba(217,146,54,.16)}
.act .d:hover,.act .no:hover{background:rgba(209,91,96,.15)}
.act .ok:hover{background:rgba(58,152,102,.15)}

/* ---- Badges / status ---- */
.badge{display:inline-flex;align-items:center;justify-content:center;padding:2px 7px;border-radius:4px;font-size:10px;font-weight:700;white-space:nowrap;color:#fff;text-transform:uppercase;letter-spacing:.2px}
.b-green{background:#3a9866}
.b-amber{background:#d99236}
.b-red{background:#d15b60}
.b-blue{background:#3f7dc0}
/* Biru menyala — dipakai status FINAL APPROVED (rekrutmen/reposisi) agar menonjol. */
.b-blue-nyala{background:#2563eb;box-shadow:0 0 0 1px rgba(37,99,235,.25)}
.b-violet{background:#7360c2}
.b-gray{background:#8792a3}

/* ---- Employee cell ---- */
.emp{display:flex;align-items:center;gap:9px;min-width:150px}
.emp .av{width:32px;height:32px;border-radius:9px;display:grid;place-items:center;color:#fff;font-weight:700;font-size:12px;flex:none}
.emp .txt b{display:block;font-weight:700;font-size:12.5px;color:var(--ink)}
.emp .txt small{color:var(--muted);font-size:11px}
.mono{font-variant-numeric:tabular-nums;font-weight:600;color:var(--ink-soft)}

/* ---- DataTables overrides ---- */
.dt-card{background:transparent;border:none;border-radius:0;box-shadow:none;padding:0;overflow:visible}
table.dataTable{border-collapse:separate!important;border-spacing:0;width:100%!important}
.dt-card table thead th{
  height:var(--dt-head);padding:0 9px;
  /* Header abu-abu putih; baris putih lembut. Keduanya sengaja tidak putih
     murni agar tabel tidak menyilaukan di atas latar halaman. */
  background:#E9EAF0;color:#475569;
  /* Ukuran font header disamakan dengan baris (12px) sesuai permintaan. */
  font-weight:700;font-size:12px;letter-spacing:.2px;text-transform:uppercase;
  /* Tepi yang sama dengan selnya, hanya lebih tegas di sisi bawah supaya
     kepala tabel terbaca sebagai bidang tersendiri saat isinya digulir. */
  border-top:1px solid var(--tepi-terang);
  border-left:1px solid var(--tepi-terang);
  border-right:1px solid var(--tepi-gelap);
  border-bottom:1px solid var(--muted-2);
  position:sticky;top:0;z-index:2;text-align:left;white-space:nowrap;
}
/* Tinggi baris dikunci & teks tidak membungkus: itulah yang membuat batas
   "10 baris" bisa dihitung tepat. Kolom lebar cukup digulir mendatar. */
/*
 * Tepi sel dibuat dua warna: putih di sisi atas-kiri, abu di sisi bawah-kanan.
 * Itu arah cahaya yang sama untuk seluruh sel, sehingga tiap sel terbaca
 * sedikit timbul dan kisi tabelnya punya kedalaman — bukan satu garis rata
 * yang sama tebal di keempat sisinya.
 *
 * Warnanya lewat variabel, bukan ditulis di tiap aturan: tepi yang sama juga
 * dipakai header dan tabel .sg-tabel, dan tiga salinan angka heksa yang harus
 * diubah bersamaan adalah tiga kesempatan untuk lupa.
 */
.dt-card table tbody td{
  height:var(--dt-row);padding:0 9px;
  border-top:1px solid var(--tepi-terang);
  border-left:1px solid var(--tepi-terang);
  border-right:1px solid var(--tepi-gelap);
  border-bottom:1px solid var(--tepi-gelap);
  vertical-align:middle;font-size:12px;color:var(--ink-soft);white-space:nowrap;
}
/* Baris seragam putih lembut — tanpa selang-seling, sesuai permintaan
   "putih saja". */
.dt-card table tbody tr{background:#FBFBFC;transition:background .12s}
.dt-card table tbody tr:hover{background:var(--primary-tint)}
/* Kolom nomor urut: selebar isinya saja, angka sejajar. */
.dt-no{width:1%;text-align:center;color:var(--muted);font-variant-numeric:tabular-nums}
/* Kolom Status: header dan selnya rata tengah. !important diperlukan karena
   aturan dasar thead th menetapkan text-align:left. */
/* Sel label grup pada header bertingkat. Kolom non-grup memakai rowspan
   sehingga benar-benar menyatu di kedua baris — tanpa sel kosong. */
.dt-card table thead th.dt-grup{text-align:center;letter-spacing:.4px}
/* Grup Tarikan Gaji: Bonus biru muda, Potongan merah muda. Sub-kolomnya memakai
   WARNA LATAR yang SAMA dengan grupnya (bukan nada lebih muda), teks dibiarkan
   warna bawaan header (permintaan user: "warnanya samakan, fontnya biarkan"). */
.dt-card table thead th.tg-grup-bonus{background:var(--info-tint);color:var(--info)}
.dt-card table thead th.tg-grup-potongan{background:var(--danger-tint);color:var(--danger)}
.dt-card table thead th.tg-sub-bonus{background:var(--info-tint)}
.dt-card table thead th.tg-sub-potongan{background:var(--danger-tint)}
/* Grup "Absensi" (Hari·Gaji Harian·Telat·…·Justifikasi) — tint netral slate agar
   beda dari Tambahan (biru) & Potongan (merah). */
.dt-card table thead th.tg-grup-absensi{background:#e6ebf2;color:#475569}
.dt-card table thead th.tg-sub-absensi{background:#f2f5f9}
/* Grup "Tidak Masuk" (Cuti·Sakit·Izin) — tint netral sedikit beda dari Absensi. */
.dt-card table thead th.tg-grup-tidakmasuk{background:#eef0f4;color:#475569}
.dt-card table thead th.tg-sub-tidakmasuk{background:#f6f7fa}
/* Kolom "Non Verify" (bonus WO belum terverifikasi, TIDAK dibayar): header &
   sel seluruhnya abu-abu — penanda ia bukan angka yang masuk gaji. Ditaruh
   SESUDAH tg-sub-bonus agar menang atas tint birunya di header. */
.dt-card table thead th.dt-kol-abu{background:#e3e7ed;color:var(--muted)}
.dt-card table tbody td.dt-kol-abu{background:#eef1f5;color:var(--muted)}
.dt-card table tbody tr:hover td.dt-kol-abu{background:#e3e7ed}
/* Kolom Informasi Tarikan Gaji: daftar perpindahan efektif, satu item per baris. */
.tg-info{display:flex;flex-direction:column;gap:3px;min-width:200px;text-align:left}
.tg-info-item{font-size:12px;font-weight:600;color:var(--primary);white-space:nowrap}
.tg-info-item small{color:var(--muted);font-weight:500}
.tg-info-item small .tg-info-jalan{color:var(--success);font-weight:600}
/* Sel Cuti/Sakit/Izin/WO yang bisa diklik (nilai > 0) → modal rincian. */
.tg-rinci{background:none;border:0;padding:0;margin:0;font:inherit;color:inherit;cursor:pointer;
  text-decoration:underline;text-decoration-style:dotted;text-underline-offset:2px}
.tg-rinci:hover{color:var(--primary)}
/* Tabel di dalam modal rincian (Cuti/Sakit/Izin & WO). */
.tgr-wrap{max-height:52vh;overflow:auto;border:1px solid var(--line);border-radius:9px}
.tgr-tbl{width:100%;border-collapse:collapse;font-size:13px}
.tgr-tbl th{position:sticky;top:0;z-index:1;background:var(--surface-2,#f1f5f9);text-align:left;
  padding:8px 10px;font-weight:700;color:var(--muted);white-space:nowrap;border-bottom:1px solid var(--line)}
.tgr-tbl td{padding:7px 10px;border-bottom:1px solid var(--line);white-space:nowrap}
.tgr-tbl tbody tr:last-child td{border-bottom:0}
.tgr-tbl tbody tr:hover{background:rgba(37,99,235,.05)}
.tgr-no{color:var(--muted);text-align:center}
.tgr-pil{display:inline-block;padding:1px 8px;border-radius:999px;font-size:11.5px;font-weight:700}
.tgr-ok{background:var(--success-tint);color:var(--success)}
.tgr-warn{background:var(--warning-tint,#fef3c7);color:var(--warning,#b45309)}
.tgr-bad{background:var(--danger-tint);color:var(--danger)}
.tgr-paid{background:var(--info-tint);color:var(--info)}
.tgr-unpaid{background:rgba(0,0,0,.06);color:var(--muted)}
.tgr-txt-bad{color:var(--danger);font-weight:700}
.tgr-kaki{margin:8px 2px 0;font-size:12.5px;color:var(--muted)}
.tgr-kaki-n{font-weight:700;color:var(--ink)}
.tgr-kaki-flex{display:flex;justify-content:space-between;align-items:center;gap:16px;flex-wrap:wrap}
.tgr-total{color:var(--ink)}
.tgr-total b{color:#b45309;font-weight:800}
.tgr-uang{display:block;text-align:right;font-variant-numeric:tabular-nums}
.tgr-th-uang{text-align:right}
.tgr-uang-bersih{color:#b45309}
/* Dua kolom uang terakhir (Gaji Harian, Gaji Harian Bersih) rata kanan;
   kolom Justifikasi (ke-3 dari belakang) rata tengah. */
.tgr-tbl-gaji th:nth-last-child(-n+2),.tgr-tbl-gaji td:nth-last-child(-n+2){text-align:right}
.tgr-tbl-gaji th:nth-last-child(3),.tgr-tbl-gaji td:nth-last-child(3){text-align:center}
/* Label Justifikasi per hari di modal. */
.tgr-jf{display:inline-block;padding:1px 9px;border-radius:999px;font-size:11.5px;font-weight:700;white-space:nowrap}
.tgr-jf-ya{background:var(--success-tint);color:var(--success)}
.tgr-jf-reject{background:var(--danger-tint);color:var(--danger)}
.tgr-jf-tunggu{background:#FEF6E7;color:#7E5109}
.tgr-jf-tidak{background:rgba(0,0,0,.06);color:var(--muted)}
/* Hari yang dimaafkan (bersih 0) tampil redup supaya bedanya jelas. */
.tgr-row-maaf td{color:var(--muted);background:rgba(16,122,73,.045)}
.tgr-row-maaf .tgr-uang-bersih{color:var(--muted)}
.tgr-kosong{color:var(--muted);padding:6px 2px}
/* Ringkasan yang bisa diklik di kaki modal WO → menyaring tabelnya. */
.tgr-chips{display:flex;flex-wrap:wrap;gap:7px;margin:10px 2px 0}
.tgr-chip{display:inline-flex;align-items:center;gap:5px;padding:4px 11px;border:1px solid var(--line);
  border-radius:999px;background:var(--surface);color:var(--muted);font:inherit;font-size:12.5px;
  font-weight:600;cursor:pointer;transition:background .12s,border-color .12s,color .12s}
.tgr-chip b{font-weight:800;color:var(--ink)}
.tgr-chip:hover{border-color:var(--primary);color:var(--primary)}
.tgr-chip.aktif{background:var(--primary);border-color:var(--primary);color:#fff}
.tgr-chip.aktif b{color:#fff}
.tgr-chip.c-ok b{color:var(--success)}
.tgr-chip.c-warn b{color:var(--warning,#b45309)}
.tgr-chip.c-bad b{color:var(--danger)}
.tgr-chip.aktif.c-ok b,.tgr-chip.aktif.c-warn b,.tgr-chip.aktif.c-bad b,.tgr-chip.aktif.c-mut b{color:#fff}
/* Total bonus baris yang sedang tampil — dipisah Terverifikasi / Non Verifikasi,
   berdampingan dan didorong ke kanan baris chip. */
.tgr-totals{margin-left:auto;display:flex;gap:16px;align-items:center;flex-wrap:wrap}
.tgr-total{align-self:center;font-size:12.5px;font-weight:600;color:var(--muted);white-space:nowrap}
.tgr-total b{font-weight:800;font-size:13.5px;margin-left:4px}
.tgr-total-v{color:var(--success)}
.tgr-total-nv{color:var(--warning,#b45309)}
/* Header modal rincian bisa diklik untuk mengurutkan. */
.tgr-tbl th.tgr-sortable{cursor:pointer;user-select:none}
.tgr-tbl th.tgr-sortable:hover{color:var(--primary)}
.tgr-tbl th.tgr-asc::after{content:"▲";font-size:8px;margin-left:5px;color:var(--primary)}
.tgr-tbl th.tgr-desc::after{content:"▼";font-size:8px;margin-left:5px;color:var(--primary)}
/* Warna grup pada header bertingkat: Absen In hijau, Absen Out kuning — sub
   kolomnya memakai nada yang sama tapi lebih muda, sehingga satu blok terbaca
   sebagai satu kesatuan tanpa perlu garis pemisah tambahan.
   Warna teksnya ikut disesuaikan per grup; semua kombinasi di bawah ini diukur
   dan lolos jauh di atas ambang WCAG 4,5 (5,99 / 7,10 / 6,06 / 7,04). */
.dt-card table thead th.dt-hijau{background:#BCD9C4;color:#24513A}
.dt-card table thead th.dt-hijau-sub{background:#D6E8DA;color:#24513A}
.dt-card table thead th.dt-kuning{background:#E4D9A6;color:#5C4A0A}
.dt-card table thead th.dt-kuning-sub{background:#F0E9C6;color:#5C4A0A}
.dt-card table thead th[rowspan]{vertical-align:middle}

/* Header bertingkat & sticky: tiap baris harus menempel pada offset-nya
   sendiri. Kalau keduanya top:0 (bawaan aturan di atas), baris kedua menimpa
   baris grup begitu tabel digulir dan label "Absen In"/"Absen Out" hilang. */
.dt-card table thead tr:nth-child(2) th{top:var(--dt-head)}
/* Header TIGA baris (mis. Tarikan Gaji: Tambahan → Bonus WO → Verify/Non Verify):
   baris ketiga menempel pada tinggi DUA baris di atasnya. Tanpa ini ia balik
   top:0, menimpa baris grup, dan satu baris data menyembul di antara header. */
.dt-card table thead tr:nth-child(3) th{top:calc(var(--dt-head) * 2)}
/* Sel ber-rowspan tetap di paling atas dan menutupi semua baris header. */
.dt-card table thead th[rowspan]{z-index:3}
/* border-collapse membuat garis pada sel sticky ikut tergulir; bayangan tipis
   ini menggantikan garis bawah header agar batasnya tetap terlihat. */
.dt-card table thead th{box-shadow:inset 0 -1px 0 var(--line)}
.dt-card table thead th.dt-center,
.dt-card table tbody td.dt-center{text-align:center!important}
/* Angka rekap: lebar digit seragam agar kolomnya terbaca rapi berjajar.
   Diterapkan pada SEL, bukan pada span pembungkus di tiap nilai — dengan
   begitu angka 0 tidak perlu markup sama sekali. */
.dt-card table tbody td.dt-num{font-variant-numeric:tabular-nums;font-weight:600;color:var(--ink)}
/* Durasi kerja: lebar digit seragam supaya kolomnya sejajar, tapi TIDAK memakai
   kelas .dt-angka milik tabel rekap — kelas itu bermakna "angka rekap" dan
   memakainya di sini akan mengaburkan dua hal yang berbeda. */
.dt-durasi{font-variant-numeric:tabular-nums;color:var(--ink-soft)}
/* SPAN angka Hari (pengajuan cuti/izin/sakit) dipusatkan dalam selnya; ikon
   Surat Dokter (tabel Sakit) juga di tengah. Kelasnya SENDIRI, bukan .dt-center:
   .dt-center dipakai bindTable pada <td> kolom rata-tengah di SEMUA datatable,
   dan display:block pada sebuah <td> merusak tata letak tabel (sel jadi setinggi
   isinya lalu tak sejajar dengan sel lain yang meregang) — perataan <td> cukup
   lewat text-align di aturan th.dt-center/td.dt-center di atas. */
.dt-durasi.dt-hari-pusat{display:block;text-align:center}
.dt-surat-ic{display:block;margin:0 auto;background:none;border:none;cursor:pointer;color:var(--primary);font-size:15px;padding:2px;line-height:1}
.dt-surat-ic:hover{filter:brightness(.88)}
.dt-surat-kosong{display:block;text-align:center;color:var(--muted-2,#cbd5e1);font-size:15px}
/* Penanda pelanggaran. Warnanya dipilih agar kontrasnya tetap lolos WCAG di
   latar baris biasa (5,26) MAUPUN saat baris ter-hover (4,51) — merah yang
   lebih terang gagal pada kondisi hover. */
.dt-sorot{color:#C0392B;font-weight:800}
/* Ikon status aktif/nonaktif */
.st-ic{display:inline-flex;align-items:center;justify-content:center;font-size:15px;line-height:1}
.st-on{color:#3a9866}
.st-off{color:#d15b60}
.st-none{color:var(--muted-2);font-size:13px}
/* Teks khusus pembaca layar: tak terlihat, tapi tetap terbaca alat bantu
   dan tetap terbawa saat teks sel dipanen untuk opsi filter. */
.sr{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}
table.dataTable.no-footer{border-bottom:none}
.dataTables_wrapper .dataTables_length,.dataTables_wrapper .dataTables_filter{padding:9px 4px;font-size:12px;color:var(--muted)}
.dataTables_wrapper .dataTables_filter input,.dataTables_wrapper .dataTables_length select{
  border:1px solid var(--line);border-radius:8px;padding:6px 10px;margin-left:8px;font-family:inherit;font-size:12px;color:var(--ink);background:var(--surface-2);
}
.dataTables_wrapper .dataTables_filter input:focus,.dataTables_wrapper .dataTables_length select:focus{outline:none;border-color:var(--primary);box-shadow:0 0 0 3px var(--primary-tint)}
.dataTables_wrapper .dataTables_info{padding:10px 4px;color:var(--muted);font-size:11.5px}
.dataTables_wrapper .dataTables_paginate{padding:9px 4px}
.dataTables_wrapper .dataTables_paginate .paginate_button{
  border-radius:8px!important;border:1px solid var(--line)!important;padding:5px 11px!important;margin:0 2px!important;
  color:var(--ink-soft)!important;font-size:12px;font-weight:600;background:var(--surface)!important;
}
.dataTables_wrapper .dataTables_paginate .paginate_button.current{
  background:var(--primary)!important;border-color:var(--primary)!important;color:#fff!important;box-shadow:0 6px 14px -6px var(--primary);
}
.dataTables_wrapper .dataTables_paginate .paginate_button:hover{background:var(--surface-2)!important;border-color:var(--muted-2)!important;color:var(--primary)!important}
.dataTables_wrapper .dataTables_paginate .paginate_button.current:hover{background:var(--primary-600)!important;color:#fff!important}
.dataTables_wrapper .dataTables_paginate .paginate_button.disabled{opacity:.4}
table.dataTable>tbody>tr.child ul.dtr-details{width:100%}
table.dataTable>tbody>tr.child span.dtr-title{min-width:120px;color:var(--muted);font-weight:700}
table.dataTable.dtr-inline.collapsed>tbody>tr>td.dtr-control:before{
  background-color:var(--primary);border:none;box-shadow:0 3px 8px -2px var(--primary);top:60%;
}

/* ---- Modal (custom) ---- */
.modal-backdrop{position:fixed;inset:0;background:rgba(15,23,42,.55);backdrop-filter:blur(3px);z-index:80;display:none;align-items:center;justify-content:center;padding:20px 16px;overflow:hidden}
.modal-backdrop.show{display:flex}
/*
 * Ukuran modal mengikuti LAYARNYA, bukan angka tetap: lebarnya paling banyak
 * --modal-w (bawaan 1080px) tapi tidak pernah melebihi layar, dan tingginya
 * berhenti di tepi layar. Yang menggulir adalah ISINYA saja — kepala dan baris
 * tombol tetap terlihat, sehingga formulir sepanjang apa pun tetap bisa
 * dibaca sampai habis dan tombol Simpannya tidak pernah terdorong keluar.
 */
.modal{
  background:var(--surface);
  width:min(var(--modal-w,1080px),100%);
  /* vh lebih dulu sebagai cadangan: peramban yang belum mengenal dvh akan
     membuang baris berikutnya, dan modal tanpa batas tinggi akan terpotong
     diam-diam oleh backdrop-nya. */
  max-height:calc(100vh - 40px);
  max-height:calc(100dvh - 40px);
  border-radius:10px;box-shadow:var(--shadow-lg);
  display:flex;flex-direction:column;min-height:0;
  animation:pop .3s cubic-bezier(.34,1.56,.64,1) both;
}
.modal>.modal-body{flex:1;min-height:0;overflow-y:auto;overscroll-behavior:contain}
.modal>.modal-head,.modal>.modal-foot{flex:none}
/* Modal Divisi pendek & memakai picker Klien (panel mengambang) → jangan dipotong
   oleh overflow badan modal; panelnya membuka ke atas (lihat buka() picker). */
#divisiBackdrop>.modal>.modal-body{overflow:visible}
@keyframes pop{from{opacity:0;transform:scale(.94) translateY(14px)}to{opacity:1;transform:none}}
.modal-head{display:flex;align-items:center;gap:14px;padding:22px 24px;border-bottom:1px solid var(--line)}
.modal-head .mh-ic{width:46px;height:46px;border-radius:13px;display:grid;place-items:center;font-size:18px;background:var(--primary-tint);color:var(--primary);flex:none}
.modal-head h3{font-size:17px;font-weight:800}
.modal-head p{color:var(--muted);font-size:12.5px}
.modal-head .x{margin-left:auto;width:36px;height:36px;border-radius:10px;color:var(--muted);display:grid;place-items:center;font-size:16px}
.modal-head .x:hover{background:var(--surface-2);color:var(--danger)}
.modal-body{padding:22px 24px}
/* Di layar sempit modalnya memakai seluruh layar: sisa 16px di tepi hanya
   membuang ruang yang justru paling dibutuhkan di sana. */
@media (max-width:640px){
  .modal-backdrop{padding:0}
  .modal{max-height:100vh;max-height:100dvh;border-radius:0;width:100%}
  .modal-head{padding:16px}
  .modal-body{padding:16px}
  .modal-foot{padding:12px 16px;border-radius:0}
}
.modal-foot{padding:16px 24px;border-top:1px solid var(--line);display:flex;justify-content:flex-end;gap:10px;background:var(--surface-2);border-radius:0 0 10px 10px}
/* Tombol konfirmasi yang digerbang (mis. menunggu Permanent/Perbantuan dipilih). */
.modal-foot .btn:disabled{opacity:.5;cursor:not-allowed;box-shadow:none}

.form-grid{display:grid;grid-template-columns:1fr 1fr;gap:12px 14px}
.field{display:flex;flex-direction:column;gap:5px}
.field.full{grid-column:1/-1}
.field label{font-size:11.5px;font-weight:700;color:var(--ink-soft)}
.field label .req{color:var(--danger)}
.field input,.field select,.field textarea{
  padding:8px 11px;border:1px solid var(--line);border-radius:var(--r-input);
  font-family:inherit;font-size:12.5px;color:var(--ink);background:var(--surface-2);transition:.15s;width:100%;
}
.field textarea{resize:vertical;min-height:64px}
.field input:focus,.field select:focus,.field textarea:focus{outline:none;border-color:var(--primary);background:#fff;box-shadow:0 0 0 4px var(--primary-tint)}
.field .err{color:var(--danger);font-size:11.5px;font-weight:600;display:none}
.field.invalid input,.field.invalid select,.field.invalid textarea{border-color:var(--danger);background:var(--danger-tint)}
.field.invalid .err{display:block}

/* ---- SweetAlert theme ---- */
.swal2-popup{border-radius:8px!important;font-family:'Source Sans 3',sans-serif!important}
.swal2-title{font-size:19px!important;font-weight:800!important;color:var(--ink)!important}
.swal2-html-container{color:var(--muted)!important;font-size:14px!important}
.swal2-styled.swal2-confirm{background:var(--primary)!important;border-radius:10px!important;font-weight:700!important;box-shadow:0 8px 18px -8px var(--primary)!important}
.swal2-styled.swal2-cancel{background:#fff!important;color:var(--ink-soft)!important;border:1px solid var(--line)!important;border-radius:10px!important;font-weight:700!important}
.swal2-styled.swal2-deny{background:var(--danger)!important;border-radius:10px!important;font-weight:700!important}
.swal2-toast{border-radius:14px!important;box-shadow:var(--shadow-md)!important}
.swal-detail{text-align:left;display:grid;grid-template-columns:auto 1fr;gap:10px 16px;font-size:13.5px;margin-top:6px}
.swal-detail dt{color:var(--muted);font-weight:600}
.swal-detail dd{color:var(--ink);font-weight:700}

/* ---- Overlay for mobile sidebar ---- */
.overlay{position:fixed;inset:0;background:rgba(15,23,42,.5);z-index:55;display:none}
.overlay.show{display:block}

/* ---- Empty settings look ---- */
.settings-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:16px}
.setting-row{display:flex;align-items:center;justify-content:space-between;padding:15px 0;border-bottom:1px solid var(--line)}
.setting-row:last-child{border-bottom:none}
.setting-row .st-txt b{font-size:13.5px}
.setting-row .st-txt small{color:var(--muted);font-size:12px}
.switch{width:46px;height:26px;border-radius:20px;background:#cbd3e1;position:relative;transition:.2s;flex:none}
.switch::after{content:"";position:absolute;top:3px;left:3px;width:20px;height:20px;border-radius:50%;background:#fff;transition:.2s;box-shadow:var(--shadow-sm)}
.switch.on{background:var(--primary)}
.switch.on::after{left:23px}

/* ============ RESPONSIVE ============ */
@container isi (max-width:764px){
  .grid-2{grid-template-columns:1fr}
}
@media (max-width:860px){
  :root{--sidebar-w:264px}
  .sidebar{transform:translateX(-100%)}
  .sidebar.open{transform:none;box-shadow:var(--shadow-lg)}
  .main{margin-left:0}
  .hamburger{display:grid}
  .content{padding:18px}
  .topbar{padding:0 16px}
}
@media (max-width:560px){
  .form-grid{grid-template-columns:1fr}
  .page-head p{display:none}
  .user-meta{display:none}
  .user-btn{padding:5px}
}
/*
 * Layar sempit. Yang dikecilkan jarak dan bantalannya, BUKAN tabelnya: kolom
 * yang diciutkan sampai muat justru membuat isinya tidak terbaca, sementara
 * tabel yang tetap selebar isinya bisa digulir mendatar di dalam kotaknya
 * sendiri (.table-scroll / .sg-bungkus / .tg-gulir) tanpa menyeret seluruh
 * halaman. Halaman Home dikecualikan: kartunya sudah punya aturan @container
 * sendiri yang mengatur berapa kolom yang muat.
 */
@media (max-width:480px){
  .content{padding:12px}
  .page:not(#page-home) .dt-card{padding:10px}
  .page:not(#page-home) .card-body{padding:14px}
  .page:not(#page-home) .card-head{padding:14px}
  .dt-top,.dt-bottom{gap:7px}
  .dt-lead,.dt-trail,.filters{gap:6px}
  /* Kotak pencarian dan dropdown melebar penuh saat sudah terbungkus baris
     sendiri — setengah baris yang tersisa tidak cukup untuk keduanya. */
  .dt-trail{margin-left:0;width:100%}
  /* Kelompok ber-data-trail ikut melebar penuh: tanpa ini isinya yang memang
     flex:1 membagi lebar kelompoknya sendiri, bukan lebar barisnya. */
  .dt-trail>[data-trail]{width:100%}
  .dt-search{flex:1}
  .dt-search-in{flex:1}
  .dt-search input{width:100%;max-width:none}
  .dt-filter,.dt-top .cari-tombol{min-width:0;max-width:none;flex:1}
  .dt-bottom .dt-paginate{margin-left:0;width:100%;justify-content:center}
  /* Garis pemisahnya hilang saat barisnya sudah terbungkus: garis vertikal di
     awal baris tidak memisahkan apa pun. */
  .dt-top .dt-length{padding-left:0;border-left:0}
  /* Ringkasan mengambil barisnya sendiri di kaki tabel, di atas penomoran. */
  .dt-bottom .dt-rekap{width:100%}
}

/* ===== Kontrol tabel (vanilla, tanpa DataTables) ===== */
.dt-card table{width:100%;border-collapse:collapse}
/* Tinggi area gulir = header + sebanyak baris yang dipilih pengguna
   (--dt-rows diisi dari JS, bawaan 10). Jadi memilih 25/50/100 benar-benar
   memperbesar area tabel, bukan sekadar menambah isi di jendela 10 baris.
   min() menahannya pada tinggi layar perangkat: lebih dari itu barulah
   digulir. Dengan bawaan 10 baris, tidak ada gulir sama sekali. */
.table-scroll{
  overflow:auto;
  max-height:calc(var(--dt-head) + var(--dt-row) * var(--dt-rows,20) + 2px);
}
@supports (height:100dvh){
  /* max(...) sebagai lantai: pada layar pendek — ponsel mendatar, jendela
     yang dikecilkan — `100dvh - 240px` bisa jatuh ke angka kecil atau
     negatif, dan tabelnya menyusut sampai tidak ada satu baris pun yang
     terlihat. 180px menjamin sedikitnya kepala tabel dan dua baris. */
  .table-scroll{
    max-height:min(
      calc(var(--dt-head) + var(--dt-row) * var(--dt-rows,20) + 2px),
      max(180px, calc(100dvh - 240px))
    );
  }
}
.sidebar{overflow-y:auto}

/* Halaman bertabel: kartu mengisi sisa tinggi, area gulir mengambil sisanya,
   dan baris paging selalu menempel di bawah layar. Tinggi tabel jadi mengikuti
   layar perangkat apa pun tanpa angka ajaib. */
/* Tabel kini ringkas dan dibatasi 10 baris, jadi kartunya TIDAK lagi
   direntangkan memenuhi layar — paging menempel tepat di bawah tabel. */
.page.active:has(.dt-bottom){display:flex;flex-direction:column;min-height:0}
.page.active:has(.dt-bottom) .dt-card{display:flex;flex-direction:column;min-height:0}

/* Satu baris kontrol: [tombol aksi] [jumlah baris] ... [filter] [pencarian].
   Tombol halaman dipindahkan ke sini sehingga tidak lagi memakan baris sendiri. */
.dt-top{display:flex;align-items:center;gap:10px;padding:0 0 10px;flex-wrap:wrap}
.dt-lead{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.dt-lead:empty{display:none}
.dt-lead .btn{padding:6px 11px;font-size:12px}
/* Tombol ekspor bergaya Excel: ikonnya diberi warna hijau khas berkas XLS. */
/* Ikon saja: tombolnya dibuat persegi supaya tidak terlihat seperti tombol
   berlabel yang teksnya hilang. */
.btn-xls{padding:6px 9px;font-size:13px;line-height:1}
.btn-xls i{color:#1D6F42;margin:0}
/* Dua ikon status berdampingan dalam satu sel. */
.st-duo{display:inline-flex;align-items:center;gap:7px;justify-content:center}
.dt-trail{margin-left:auto;display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.filters{display:flex;align-items:center;gap:7px;flex-wrap:wrap}
.dt-length{display:inline-flex;align-items:center;font-size:12px;color:var(--muted)}
.dt-length select,.dt-filter{border:1px solid var(--line);border-radius:6px;padding:5px 8px;font-family:inherit;font-size:12px;background:var(--surface-2);color:var(--ink);cursor:pointer}
.dt-length select{margin:0 4px}
.dt-filter{min-width:130px;font-weight:600}
.dt-filter:focus{outline:none;border-color:var(--primary);box-shadow:0 0 0 3px var(--primary-tint)}
.dt-search{display:inline-flex;align-items:center;gap:6px}
/* Acuan posisi ikon kacanya pindah ke pembungkus input — kalau tetap di
   .dt-search, ikonnya mendarat di atas pemilih kolom di sebelah kirinya. */
.dt-search-in{position:relative;display:inline-flex;align-items:center}
.dt-search i{position:absolute;left:11px;color:var(--muted-2);font-size:12px;pointer-events:none}
/* Pemilih kolom pencarian. Sempit dengan sengaja: yang utama di baris ini
   kotak pencariannya, bukan pemilih kolomnya. */
.dt-search .dt-kolom,.dt-search .cari-tombol{
  font-family:inherit;font-size:11.5px;font-weight:600;color:var(--ink-soft);
  background:var(--surface-2);border:1px solid var(--line);border-radius:6px;
  padding:7px 8px;cursor:pointer;max-width:130px;min-width:0}
.dt-search .cari-sel{flex:none}
/* Teks yang cocok dengan pencarian. Kuning lembut dengan tulisan tetap gelap —
   sorotan yang membalik warna teks justru lebih sulit dibaca daripada
   sekitarnya. */
mark.dt-sorot{background:#FDE68A;color:inherit;border-radius:2px;padding:0 1px;font-weight:inherit}
.dt-search input{border:1px solid var(--line);border-radius:6px;padding:7px 12px 7px 30px;font-family:inherit;font-size:12px;background:var(--surface-2);color:var(--ink);width:200px;max-width:52vw}
.dt-search input:focus,.dt-length select:focus{outline:none;border-color:var(--primary);box-shadow:0 0 0 3px var(--primary-tint)}
/* Baris bawah: [Tampilkan N data] [1–50 dari 3221 data] … [paging] */
.dt-bottom{display:flex;align-items:center;gap:14px;padding:10px 2px 2px;flex-wrap:wrap}
.dt-bottom .dt-paginate{margin-left:auto}
.dt-info{font-size:11.5px;color:var(--muted)}
/* Rekap angka di kaki tabel. Titik warna, bukan tulisan berwarna: teks hijau
   dan merah berdampingan terbaca sebagai peringatan, padahal "tidak aktif"
   di sini cuma keadaan biasa. */
/* Ringkasan tinggal di KIRI kaki tabel; .dt-paginate memakai margin-left:auto
   sehingga penomoran terdorong ke kanan dan ringkasannya tinggal di kiri. */
.dt-rekap{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
/* Garis pemisah tipis dari kotak Cari, dipasang pada butir PERTAMA kelompok
   yang naik: tanpa itu "Tampilkan 20 data" terbaca sebagai bagian dari kotak
   pencarian di sebelahnya. Hilang begitu barisnya terbungkus, karena garis
   vertikal di awal baris tidak memisahkan apa pun. */
.dt-top .dt-length{padding-left:12px;border-left:1px solid var(--line);align-self:stretch}
.dt-top .dt-length,.dt-top .dt-info{white-space:nowrap}
.dt-rekap-item{display:inline-flex;align-items:center;gap:6px;
               font-size:11.5px;color:var(--muted);white-space:nowrap}
.dt-rekap-item::before{content:'';width:7px;height:7px;border-radius:50%;background:var(--muted-2)}
.dt-rekap-item.ok::before{background:var(--success)}
.dt-rekap-item.no::before{background:var(--danger)}
.dt-rekap-item b{color:var(--ink);font-size:12.5px;font-variant-numeric:tabular-nums}
/* Butir yang punya saringan menjadi TOMBOL. Rupanya sengaja tetap sama dengan
   yang tidak bisa diklik — yang membedakan hanya tanggapannya saat disentuh:
   angka ringkasan yang tiba-tiba berbentuk tombol akan terbaca sebagai aksi
   yang berbahaya, padahal ia cuma menyaring. */
button.dt-rekap-item{border:1px solid transparent;background:none;font-family:inherit;
                     padding:2px 8px 2px 6px;margin:-2px 0;border-radius:999px;cursor:pointer;
                     transition:.12s}
button.dt-rekap-item:hover{border-color:var(--line);background:var(--surface-2)}
button.dt-rekap-item:focus-visible{outline:none;border-color:var(--primary);
                     box-shadow:0 0 0 3px var(--primary-tint)}
/* Yang sedang dipakai menyaring. Angkanya sama dengan "1-20 dari N data" di
   sebelahnya, dan itulah yang mengikat keduanya: satu butir menyala, satu
   jumlah, satu himpunan. */
.dt-rekap-item.aktif{border-color:var(--primary);background:var(--primary-tint);color:var(--primary)}
.dt-rekap-item.aktif b{color:var(--primary)}
.dt-rekap-item.aktif i{font-size:9.5px;opacity:.75;margin-left:1px}
/* Butir LAIN diredupkan selagi ada yang aktif: tanpa itu, enam angka yang
   menghitung himpunan lebih luas berdiri sejajar dengan satu angka yang
   menghitung himpunan tersaring, dan tidak ada yang menandai mana yang mana. */
.dt-rekap-item.pudar{opacity:.5}
.dt-rekap-item.pudar:hover{opacity:1}
.dt-paginate{display:flex;gap:3px;flex-wrap:wrap}
.dt-paginate button{border:1px solid var(--line);background:var(--surface);color:var(--ink-soft);border-radius:6px;padding:5px 11px;font-size:12px;font-weight:600;cursor:pointer;transition:.12s;font-family:inherit}
.dt-paginate button:hover:not(:disabled):not(.current){background:var(--surface-2);border-color:var(--muted-2);color:var(--primary)}
.dt-paginate button.current{background:var(--primary);border-color:var(--primary);color:#fff;box-shadow:0 6px 14px -6px var(--primary)}
.dt-paginate button:disabled{opacity:.4;cursor:default}
.dt-paginate .pg-gap{padding:5px 5px;color:var(--muted-2);font-size:12px}
.dt-empty{text-align:center!important;color:var(--muted);height:auto!important;padding:22px 0!important;white-space:normal!important}
.dt-card table thead th.sortable{cursor:pointer;user-select:none}
.dt-card table thead th.sortable:hover{color:var(--primary)}
.dt-card table thead th.sort-asc::after{content:"▲";font-size:8px;margin-left:5px;color:var(--primary)}
.dt-card table thead th.sort-desc::after{content:"▼";font-size:8px;margin-left:5px;color:var(--primary)}
/* ===== Toast ===== */
.toast-wrap{position:fixed;top:16px;right:16px;z-index:200;display:flex;flex-direction:column;gap:10px}
.toast{background:var(--surface);border:1px solid var(--line);border-left:4px solid var(--primary);border-radius:8px;padding:11px 15px;box-shadow:var(--shadow-md);display:flex;align-items:center;gap:10px;font-size:13px;min-width:230px;transition:opacity .26s,transform .26s;animation:toastIn .26s ease}
.toast.success{border-left-color:#3a9866}.toast.success i{color:#3a9866}
.toast.error{border-left-color:#d15b60}.toast.error i{color:#d15b60}
.toast.info{border-left-color:#3f7dc0}.toast.info i{color:#3f7dc0}
.toast.warning{border-left-color:#d99236}.toast.warning i{color:#d99236}
.toast i{font-size:16px}
@keyframes toastIn{from{opacity:0;transform:translateX(24px)}to{opacity:1;transform:none}}
/* ===== Dialog tambahan ===== */
.mh-ic.danger{background:var(--danger-tint);color:var(--danger)}
.btn-danger{background:#d15b60;color:#fff}
.btn-danger:hover{background:#c34e53}
.dlg-input{width:100%;border:1px solid var(--line);border-radius:6px;padding:9px 11px;font-family:inherit;font-size:13px;background:var(--surface-2);color:var(--ink);min-height:72px;resize:vertical;margin-top:10px}
.dlg-input:focus{outline:none;border-color:var(--primary);box-shadow:0 0 0 3px var(--primary-tint)}
/* ===== Grafik SVG ===== */
.chart-wrap{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:12px}
.chart-legend{display:flex;gap:16px;flex-wrap:wrap;justify-content:center;font-size:12px;color:var(--muted)}
.chart-legend span{display:inline-flex;align-items:center;gap:7px;min-width:0;max-width:100%}
.chart-legend i{width:11px;height:11px;border-radius:3px;display:inline-block;flex:none}
.act-empty{padding:18px 0;text-align:center;color:var(--muted);font-size:12.5px;list-style:none}
/* Kondisi kosong: halaman yang belum berisi apa-apa sebaiknya menyatakannya,
   bukan tampil putih polos seperti gagal memuat. */
.page-kosong{display:flex;flex-direction:column;align-items:center;gap:8px;padding:56px 20px;text-align:center}
.page-kosong i{font-size:36px;color:var(--muted-2)}
.page-kosong b{font-size:14px;font-weight:700;color:var(--ink-soft)}
.page-kosong span{font-size:12.5px;color:var(--muted)}
/* Nama cabang bisa panjang: potong dengan elipsis, jangan dorong kartu melebar. */
.chart-legend span>span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.name-cell{color:var(--ink);font-weight:600;font-size:13px}
/* ============ LAYAR LOGIN ============ */
.login-screen{
  position:fixed;inset:0;z-index:100;
  display:grid;place-items:center;padding:24px;overflow-y:auto;
  background:
    radial-gradient(900px 420px at 12% -10%,rgba(79,70,229,.50),transparent),
    radial-gradient(700px 400px at 100% 110%,rgba(235,162,58,.20),transparent),
    linear-gradient(160deg,var(--sidebar-2),var(--sidebar-1));
}
/* Penyembunyian keduanya kini diurus aturan [hidden] global di atas. */

.login-card{
  width:100%;max-width:392px;
  background:var(--surface);border:1px solid var(--line);
  border-radius:var(--r-card);box-shadow:var(--shadow-lg);
  padding:30px 28px 28px;display:flex;flex-direction:column;gap:13px;
}
.login-brand{display:flex;flex-direction:column;align-items:center;text-align:center;gap:7px;margin-bottom:2px}
.login-brand img{width:56px;height:56px;border-radius:22.4%;box-shadow:0 10px 22px -8px rgba(0,0,0,.45)}
.login-brand h1{font-size:22px;font-weight:800;letter-spacing:-.4px;color:var(--ink)}
.login-brand p{font-size:12px;color:var(--muted)}

.login-alert{
  display:flex;align-items:flex-start;gap:9px;
  background:var(--danger-tint);color:#9f1d1d;
  border:1px solid rgba(239,68,68,.30);border-radius:var(--r-input);
  padding:9px 11px;font-size:12px;font-weight:600;
}

/* Input dengan ikon di kiri (memakai ulang gaya .field yang sudah ada) */
.in-icon{position:relative;display:flex;align-items:center}
.in-icon>i{position:absolute;left:11px;color:var(--muted-2);font-size:12.5px;pointer-events:none}
.in-icon input{padding-left:32px}
.in-icon.has-peek input{padding-right:36px}
.peek{
  position:absolute;right:6px;width:26px;height:26px;border-radius:5px;
  display:grid;place-items:center;color:var(--muted);font-size:12.5px;transition:.15s;
}
.peek:hover{background:var(--surface-2);color:var(--ink-soft)}

/* Captcha */
.cap-row{display:flex;align-items:center;gap:8px}
.cap-img{
  flex:1;height:52px;border:1px solid var(--line);border-radius:var(--r-input);
  background:#fff;overflow:hidden;display:grid;place-items:center;
  user-select:none;-webkit-user-select:none;
}
.cap-img svg{display:block;width:100%;height:100%}
.cap-refresh{
  width:42px;height:52px;flex:none;border-radius:var(--r-input);
  border:1px solid var(--line);background:var(--surface-2);color:var(--muted);
  display:grid;place-items:center;font-size:14px;transition:.15s;
}
.cap-refresh:hover{background:#fff;color:var(--primary);border-color:var(--primary)}
.cap-refresh i{transition:transform .35s}
.cap-refresh:hover i{transform:rotate(180deg)}

/* Input kode + tombol Login berbagi satu baris.
   align-items:stretch membuat tinggi tombol mengikuti input, jadi keduanya
   selalu sejajar tanpa perlu menyetel tinggi tetap di dua tempat. */
.cap-solve{display:flex;align-items:stretch;gap:8px}
.cap-solve .in-icon{flex:1;min-width:0}
/* Kodenya digambar sebagai huruf besar berjarak, sama seperti di gambarnya —
   supaya yang diketik dan yang dibaca terlihat sebagai hal yang sama. */
#loginCap{text-transform:uppercase;letter-spacing:.16em;font-weight:600}
#loginCap::placeholder{text-transform:none;letter-spacing:normal;font-weight:400}
.login-submit{flex:none;margin:0;padding:0 18px;font-size:13px}

/* ---- Bingkai menyala ----
   Cincin gradien diam di belakang kartu, ditambah salinannya yang diburamkan
   sebagai cahayanya; hanya cahayanya yang bernapas pelan. Keduanya z-index:-1
   dan kartunya sengaja TIDAK dibuat stacking context (tanpa isolation atau
   transform), supaya cincinnya tergambar di bawah latar kartu — bukan
   menutupi isinya.
   Gradiennya linear, bukan conic: cincin conic yang diam memperlihatkan
   sambungan di sudut awalnya, yang dulu tersamar karena berputar. */
@keyframes kilauNapas{50%{opacity:.30}}

.login-card{position:relative;border-color:transparent}
.login-card::before,.login-card::after{
  content:'';position:absolute;z-index:-1;pointer-events:none;
  background:linear-gradient(135deg,var(--primary),#7C6BE8 45%,#8FA6F0);
}
.login-card::before{inset:-1.5px;border-radius:calc(var(--r-card) + 1.5px);opacity:.8}
.login-card::after{
  inset:-7px;border-radius:calc(var(--r-card) + 7px);
  filter:blur(15px);opacity:.42;
  animation:kilauNapas 9s ease-in-out infinite;
}

/* Kolom isian ikut menyala saat disorot — fokusnya jadi terlihat dari jauh,
   bukan cuma garis tepi setebal 1px yang berubah warna. */
.login-card .field input{background:#fff;border-color:#C7CCDB}
.login-card .field input:focus{
  border-color:var(--primary);
  box-shadow:0 0 0 3px var(--primary-tint),0 0 16px -3px rgba(79,70,229,.8);
}
.login-card .in-icon:focus-within>i{color:var(--primary)}
.login-card .field.invalid input{
  border-color:var(--danger);background:var(--danger-tint);
  box-shadow:0 0 15px -4px rgba(239,68,68,.75);
}
.login-card .field.invalid input:focus{
  box-shadow:0 0 0 3px var(--danger-tint),0 0 16px -3px rgba(239,68,68,.85);
}
.login-alert{box-shadow:0 0 18px -6px rgba(239,68,68,.6)}

/* Kotak captcha dan tombol muat-ulangnya memakai tepi yang sama supaya
   satu baris itu terbaca sebagai satu kesatuan. */
.cap-img,.cap-refresh{border-color:#C7CCDB}
.cap-row:hover .cap-img{border-color:var(--primary);box-shadow:0 0 15px -5px rgba(79,70,229,.7)}
.cap-refresh:hover{box-shadow:0 0 15px -5px rgba(79,70,229,.7)}
.cap-refresh:focus-visible{outline:none;border-color:var(--primary);box-shadow:0 0 0 3px var(--primary-tint)}

@media (prefers-reduced-motion:reduce){
  .login-card::after{animation:none}
}

@media (max-width:420px){
  .login-card{padding:24px 20px 18px}
}

/* ===== Modal catatan (memakai ulang sistem .modal yang ada) ===== */
/* Hanya selisihnya yang didefinisikan: backdrop tanpa padding + item
   direntang, lalu modal jadi kolom setinggi layar. */
.modal-backdrop.full{padding:0;align-items:stretch}
.modal.modal-full{
  --modal-w:1080px;border-radius:0;
  height:100vh;height:100dvh;max-height:100vh;max-height:100dvh;
  animation:slideUp .26s cubic-bezier(.34,1.2,.64,1) both;
}
@keyframes slideUp{from{opacity:0;transform:translateY(18px)}to{opacity:1;transform:none}}

/* ---- Modal Catatan sebagai PANEL MENGAMBANG ----
   Halaman di belakang TETAP terbaca (tanpa blur/gelap) dan tetap bisa dipakai —
   latarnya meneruskan klik (pointer-events:none), hanya panelnya yang menangkap.
   Panel digeser ke mana saja lewat header-nya (lihat JS geser modal Catatan). */
#noteBackdrop{background:transparent;backdrop-filter:none;-webkit-backdrop-filter:none;
  pointer-events:none;align-items:flex-start;justify-content:center;padding:16px}
#noteBackdrop .modal{pointer-events:auto}
#noteBackdrop .modal.modal-full{
  width:min(1000px,94vw);height:calc(100dvh - 32px);max-height:calc(100dvh - 32px);
  border-radius:12px;border:1px solid var(--line);box-shadow:0 26px 70px rgba(15,23,42,.30);
  animation:pop .24s cubic-bezier(.34,1.4,.64,1) both;will-change:transform}
#noteBackdrop .modal-head{cursor:grab;user-select:none;touch-action:none}
#noteBackdrop .modal-head:active{cursor:grabbing}
#noteBackdrop .modal-head .x,#noteBackdrop .modal-head .x *{cursor:pointer}
#noteBackdrop.geser .modal.modal-full{animation:none}
/* Tombol Perkecil + Tutup dikelompokkan di kanan header. */
#noteBackdrop .note-head-x{margin-left:auto;display:flex;align-items:center;gap:6px}
#noteBackdrop .note-head-x .x{margin-left:0}
/* Ikon catatan mengambang (saat diperkecil). */
.note-fab{position:fixed;right:22px;bottom:22px;z-index:81;display:none;
  width:54px;height:54px;border-radius:50%;background:var(--primary);color:#fff;border:none;
  cursor:pointer;box-shadow:0 10px 28px rgba(79,70,229,.45);font-size:20px;
  align-items:center;justify-content:center;transition:transform .15s,box-shadow .15s}
.note-fab.show{display:inline-flex;animation:pop .22s cubic-bezier(.34,1.5,.64,1) both}
.note-fab:hover{transform:translateY(-2px);box-shadow:0 14px 34px rgba(79,70,229,.52)}
.note-fab:active{transform:translateY(0)}

/*
 * Modal SELAYAR PENUH: menempel ke keempat tepi perangkat, tanpa sisa latar di
 * sekelilingnya dan tanpa sudut membulat.
 *
 * Bedanya dengan .modal-full (modal catatan): yang itu setinggi layar tapi
 * lebarnya tetap dibatasi --modal-w. Yang ini lebarnya ikut penuh, karena
 * isinya memang perkakas — daftar tabel dan contoh isinya memakai setiap
 * piksel yang ada.
 *
 * Tingginya TIDAK mengikuti isi, dan itu disengaja: tab Koneksi pendek, tab
 * Telusuri panjang. Kotak yang tingginya mengikuti isi akan melompat setiap
 * kali tab berganti — di bawah kursor yang baru saja menekan tabnya —
 * dan tombol di kakinya ikut berpindah tempat.
 *
 * 100dvh, bukan 100vh: di peramban ponsel, 100vh memakai tinggi layar SEBELUM
 * bilah alamatnya menyusut, sehingga baris tombol di kaki modal terdorong ke
 * bawah lipatan dan tidak pernah terlihat. vh tetap ditulis lebih dulu sebagai
 * cadangan untuk peramban yang belum mengenal dvh.
 */
.modal.modal-layar{
  width:100%;
  height:100vh;
  height:100dvh;
  max-height:none;
  border-radius:0;
  /* Dari bawah, bukan mengembang dari tengah: kotak selayar penuh yang
     di-scale terasa seperti halaman yang melompat, bukan panel yang datang. */
  animation:slideUp .26s cubic-bezier(.34,1.2,.64,1) both;
}
.modal-layar .modal-foot{border-radius:0}
/* Badannya TIDAK menggulir sendiri: yang menggulir bagian di dalamnya, yang
   punya batasnya masing-masing. Dua penggulir bersarang membuat roda tetikus
   mengenai yang salah dan isi yang dicari justru tidak bergerak. */
.modal-layar>.modal-body{display:flex;flex-direction:column;min-height:0;overflow:hidden}
.modal-layar .tabpane.show{flex:1;min-height:0}
/* min-height:0 wajib: tanpa itu anak flex menolak menyusut dan textarea meluber. */
/* Modal penuh mengatur gulirannya SENDIRI di dalam (area catatan dan daftar
   cabang punya overflow masing-masing). Karena itu badannya tidak ikut
   menggulir — dua penggulir bersarang membuat roda tetikus mengenai yang salah
   dan isi yang dicari justru tidak bergerak. */
.modal-full>.modal-body{flex:1;min-height:0;display:flex;flex-direction:column;gap:9px;overflow:hidden}
.modal-full .modal-foot{border-radius:0;position:sticky;bottom:0}

.note-label{font-size:11.5px;font-weight:700;color:var(--ink-soft)}

/* ---- Bilah format catatan ---- */
.note-bar{
  display:flex;align-items:center;gap:3px;flex:none;flex-wrap:wrap;
  border:1px solid var(--line);border-radius:var(--r-input);
  background:var(--surface);padding:5px 7px;
}
.nb-btn{
  width:28px;height:28px;border:none;background:none;border-radius:6px;cursor:pointer;
  display:grid;place-items:center;font-size:12.5px;color:var(--ink-soft);transition:.12s;
}
.nb-btn:hover{background:var(--surface-2);color:var(--ink)}
.nb-btn:focus-visible{outline:2px solid var(--primary);outline-offset:-2px}
/* Tombol menyala saat kursor berada di dalam teks yang sudah berformat itu —
   jadi bilahnya melaporkan keadaan, bukan sekadar menjalankan perintah. */
.nb-btn.on{background:var(--primary-tint);color:var(--primary)}
.nb-sep{width:1px;height:18px;background:var(--line);margin:0 3px;flex:none}

/* Pilihan warna sebagai kelompok radio: hanya satu yang aktif, dan yang aktif
   terbaca dari lingkaran bertanda — bukan hanya dari warnanya sendiri, yang
   tidak terbaca oleh siapa pun yang sulit membedakan warna. */
.nb-warna{display:flex;align-items:center;gap:3px}
.nb-w{
  width:20px;height:20px;border-radius:50%;border:2px solid transparent;cursor:pointer;
  padding:0;display:grid;place-items:center;background:none;transition:.12s;
}
.nb-w::before{content:"";width:13px;height:13px;border-radius:50%;background:var(--w);border:1px solid rgba(0,0,0,.18)}
.nb-w:hover{border-color:var(--line)}
.nb-w:focus-visible{outline:2px solid var(--primary);outline-offset:1px}
.nb-w[aria-checked="true"]{border-color:var(--ink-soft)}
.nb-w[aria-checked="true"]::before{box-shadow:inset 0 0 0 2px #fff}

/* ---- Area catatan (contenteditable) ---- */
.note-area{
  /* relative: penopang untuk teks placeholder di bawah, yang harus MENUMPANG
     di atas baris pertama — bukan mendorongnya ke bawah. */
  position:relative;
  flex:1;min-height:200px;width:100%;overflow:auto;
  border:1px solid var(--line);border-radius:var(--r-input);
  background:var(--surface-2);color:var(--ink);
  font-family:inherit;font-size:13.5px;line-height:1.6;padding:12px 14px;transition:.15s;
  /* pre-wrap + anywhere: baris panjang DIBUNGKUS, tidak pernah menggulir
     mendatar. Tanpa anywhere, satu URL panjang tanpa spasi tetap melebarkan
     modal dan mendorong isinya keluar layar. */
  white-space:pre-wrap;overflow-wrap:anywhere;
}
.note-area:focus{outline:none;border-color:var(--primary);background:#fff;box-shadow:0 0 0 4px var(--primary-tint)}
/* Placeholder: contenteditable tidak punya atribut placeholder, jadi teksnya
   digambar dari data-kosong saat JS menandai areanya benar-benar kosong. */
.note-area.kosong::before{
  content:attr(data-kosong);color:var(--muted);pointer-events:none;
  position:absolute;left:14px;right:14px;top:12px;
}
.note-area .nl{min-height:1.6em}
.note-area b,.note-area strong{font-weight:800}
.note-area u{text-decoration:underline}

/* Baris tugas yang statusnya diketahui diberi warna DI TEMPATNYA DITULIS,
   supaya isi catatan dan daftar Task menceritakan hal yang sama. */
.note-area .nl-prog,
.note-area .nl-sel{
  border-radius:6px;padding:1px 8px;margin:1px 0;
  border-left:3px solid transparent;
}
.note-area .nl-sel{background:#E3F3E9;border-left-color:#3a9866;color:#24513A}
.note-area .nl-prog{background:#FBF1DC;border-left-color:#d99236;color:#5C4A0A}
/* Terkunci: kursor boleh berdiri di ujungnya (untuk menekan Enter), tapi
   hurufnya tidak bisa diubah — penjaganya ada di penangan keydown. */
.note-area .nl-sel{cursor:default}
.note-area .nl-kunci{user-select:text}
/* Penanda status di ujung baris: ikon + nama pengerjanya lewat tooltip. */
.nl-tag{
  display:inline-flex;align-items:center;gap:4px;margin-left:7px;
  font-size:10px;font-weight:800;letter-spacing:.2px;text-transform:uppercase;
  border-radius:4px;padding:1px 6px;vertical-align:1px;cursor:help;user-select:none;
}
.nl-sel .nl-tag{background:#3a9866;color:#fff}
.nl-prog .nl-tag{background:#d99236;color:#fff}
/* Siapa yang menyelesaikan dan kapan — di sebelah lencana Selesai. Bobotnya
   sengaja lebih ringan daripada lencananya: ia keterangan, bukan status.
   user-select:none supaya tidak ikut tersalin saat barisnya diblok. */
.nl-oleh{
  display:inline-flex;align-items:center;margin-left:6px;vertical-align:1px;
  font-size:10.5px;font-weight:600;color:#24513A;opacity:.85;
  white-space:nowrap;cursor:help;user-select:none;
}

/* Ikon lampiran di ujung baris catatan. */
.nl-lamp{display:inline-flex;align-items:center;gap:4px;margin-left:6px;vertical-align:1px;user-select:none}
.lamp-ic{
  display:inline-grid;place-items:center;width:20px;height:20px;border-radius:5px;
  background:var(--surface);border:1px solid var(--line);color:var(--primary);
  font:inherit;font-size:11px;padding:0;cursor:pointer;transition:.12s;
}
.lamp-ic:focus-visible{outline:2px solid var(--primary);outline-offset:1px}
.lamp-ic:hover{background:var(--primary-tint);border-color:var(--primary)}
.lamp-ic.berkas{color:var(--ink-soft)}
.note-hint{display:flex;align-items:flex-start;gap:8px;font-size:11.5px;color:var(--muted);line-height:1.5}
.note-hint i{color:var(--info);margin-top:2px;flex:none}
.note-count{margin-right:auto;align-self:center;font-size:11.5px;color:var(--muted);font-weight:600}

/* --- Tab Task: tugas ber-MODUL (form + daftar dikelompokkan) --- */
.tm-form{display:flex;flex-direction:column;gap:10px;margin-bottom:16px}
/* Ikon dokumen (tampil/sembunyi input tugas) — duduk di header modal Catatan,
   bersebelahan dgn pop-out/perkecil/tutup. Abu-abu default, biru saat aktif. */
#tmToggle{border:0;background:transparent;transition:.12s}
#tmToggle:hover{background:var(--surface-2);color:var(--ink)}
#tmToggle.on{background:var(--primary-tint);color:var(--primary)}
.tm-isi{display:flex;flex-direction:column;gap:12px}
/* Baris atas: Module (kiri) berdampingan dengan Tangkapan Layar (kanan). */
.tm-top{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:14px;align-items:start}
.tm-field{display:flex;flex-direction:column;gap:5px;min-width:0}
.tm-field-modul{position:relative}
.tm-field-foto .note-label{display:flex;align-items:center;gap:6px}
.tm-field-foto .note-label i{color:var(--primary)}
/* Tugas: lebar PENUH, editor kaya (contenteditable) + bilah format. */
.tm-field-teks{width:100%}
.tm-fmt{display:flex;align-items:center;gap:2px;flex-wrap:wrap;padding:4px 5px;
  border:1px solid var(--line);border-bottom:0;border-radius:8px 8px 0 0;background:var(--surface-2)}
.tm-fb{width:28px;height:26px;border:0;background:transparent;border-radius:6px;color:var(--muted);
  cursor:pointer;display:grid;place-items:center;font-size:12.5px;padding:0;position:relative;overflow:hidden}
.tm-fb:hover{background:var(--surface);color:var(--ink)}
.tm-fb.on{background:var(--primary-tint);color:var(--primary)}
.tm-fsep{width:1px;height:16px;background:var(--line);margin:0 3px}
.tm-fwarna input[type=color]{position:absolute;inset:0;width:100%;height:100%;opacity:0;cursor:pointer;border:0;padding:0}
.tm-ed{width:100%;min-height:120px;max-height:340px;overflow:auto;line-height:1.55;
  border-radius:0 0 8px 8px;cursor:text}
.tm-ed:empty::before{content:attr(data-ph);color:var(--muted);pointer-events:none}
.tm-ed ol,.tm-ed ul{margin:4px 0;padding-left:22px}
.tm-ed:focus{outline:none}
.tm-saran{position:absolute;top:100%;left:0;right:0;z-index:5;margin-top:4px;background:var(--surface);
  border:1px solid var(--line);border-radius:8px;box-shadow:0 10px 26px rgba(15,23,42,.14);
  max-height:220px;overflow:auto;padding:4px}
.tm-saran-item{display:flex;justify-content:space-between;align-items:center;gap:10px;width:100%;
  padding:7px 10px;border:0;background:transparent;border-radius:6px;cursor:pointer;font:inherit;font-size:12.5px;color:var(--ink);text-align:left}
.tm-saran-item:hover{background:var(--primary-tint);color:var(--primary)}
.tm-saran-item span{font-size:11px;color:var(--muted);font-variant-numeric:tabular-nums}
/* Area tangkapan layar: ringkas, setara tinggi dengan input Module (tumbuh saat ada thumbnail). */
.tm-paste{border:1.5px dashed var(--line);border-radius:10px;padding:10px 12px;cursor:pointer;
  background:var(--surface);transition:.12s;outline:none;min-height:40px;display:flex;flex-direction:column;justify-content:center}
.tm-paste:hover,.tm-paste:focus-visible{border-color:var(--primary);background:var(--primary-tint)}
.tm-paste.seret{border-color:var(--primary);background:var(--primary-tint)}
.tm-paste.ada{justify-content:flex-start}
.tm-paste-ket{font-size:18px;color:var(--muted);display:flex;align-items:center;justify-content:center}
.tm-paste.ada .tm-paste-ket{justify-content:flex-start}
.tm-thumbs{display:flex;flex-wrap:wrap;gap:8px}
.tm-thumbs:not(:empty){margin-top:9px}
.tm-stage{position:relative;width:56px;height:56px;border-radius:8px;overflow:hidden;border:1px solid var(--line)}
.tm-stage img{width:100%;height:100%;object-fit:cover;display:block}
.tm-stage-x{position:absolute;top:2px;right:2px;width:18px;height:18px;border-radius:50%;border:0;
  background:rgba(15,23,42,.72);color:#fff;font-size:13px;line-height:1;cursor:pointer;display:grid;place-items:center}
.tm-form-aksi{display:flex;align-items:center;gap:12px;justify-content:flex-end}
.tm-hint{margin-right:auto;font-size:11.5px;color:var(--muted)}
@media (max-width:720px){.tm-top{grid-template-columns:1fr}}
/* Daftar dikelompokkan per modul (expand/collapse) */
.tm-daftar{display:flex;flex-direction:column;gap:8px}
.tm-kosong{margin:0;font-size:12.5px;color:var(--muted);padding:14px;text-align:center;
  border:1px dashed var(--line);border-radius:10px}
.tm-grup{border:1px solid var(--line);border-radius:10px;overflow:hidden;background:var(--surface)}
.tm-grup-kepala{display:flex;align-items:center;gap:10px;width:100%;padding:11px 14px;border:0;
  background:var(--surface-2);cursor:pointer;font:inherit;text-align:left}
.tm-grup-kepala:hover{background:var(--primary-tint)}
.tm-grup-panah{font-size:11px;color:var(--muted);transition:transform .15s}
.tm-grup.buka .tm-grup-panah{transform:rotate(90deg);color:var(--primary)}
.tm-grup-nama{font-weight:700;font-size:13px;color:var(--ink);flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tm-grup-ket{font-size:11.5px;font-weight:700;color:var(--muted);font-variant-numeric:tabular-nums;
  background:var(--surface);border:1px solid var(--line);border-radius:999px;padding:2px 9px}
.tm-tabel{width:100%;border-collapse:collapse;font-size:12px}
.tm-tabel th{background:var(--surface);text-align:left;padding:7px 10px;font-size:10px;text-transform:uppercase;
  letter-spacing:.04em;color:var(--muted);border-bottom:1px solid var(--line)}
.tm-tabel td{padding:8px 10px;border-bottom:1px solid var(--line);vertical-align:top}
.tm-tabel tr:last-child td{border-bottom:0}
/* Lebar kolom: Tugas mengisi sisa (paling lega) + bergutter kiri; Gambar pas
   selebar thumbnail (tanpa celah kosong); Status/Aksi seringkas isinya. */
.tm-tabel th:first-child,.tm-tabel td.tm-teks{width:auto;padding-left:16px}
.tm-tabel .tm-kol-gbr,.tm-tabel td.tm-gbr{width:140px}
.tm-tabel .tm-kol-stat,.tm-tabel td.tm-kol-stat{width:1%;white-space:nowrap}
.tm-tabel th:last-child,.tm-tabel td:last-child{width:1%;white-space:nowrap}
.tm-teks{color:var(--ink);word-break:break-word;line-height:1.55}
.tm-teks ol,.tm-teks ul{margin:3px 0;padding-left:20px}
.tm-sel .tm-teks{text-decoration:line-through;color:var(--muted)}
.tm-gbr{display:flex;flex-wrap:wrap;gap:6px}
.tm-thumb{display:block;width:52px;height:52px;border-radius:7px;overflow:hidden;border:1px solid var(--line)}
.tm-thumb img{width:100%;height:100%;object-fit:cover;display:block}
.tm-hapus{border:0;background:transparent;color:var(--muted);cursor:pointer;font-size:13px;padding:4px 6px;border-radius:6px}
.tm-hapus:hover{background:rgba(220,38,38,.1);color:var(--danger)}
/* Kolom Status + Aksi (ikon status bergilir, edit, hapus) — rata tengah. */
.tm-tabel td.dt-center,.tm-tabel th.dt-center{text-align:center}
.tm-tabel .tm-kol-stat{width:1%;white-space:nowrap}
.tm-badge{display:inline-block;padding:2px 10px;border-radius:999px;font-size:11px;font-weight:700;line-height:1.7;letter-spacing:.02em}
.tm-badge.baru{background:var(--surface-2);color:var(--muted);border:1px solid var(--line)}
.tm-badge.todo{background:var(--primary-tint);color:var(--primary)}
.tm-badge.done{background:var(--success-tint);color:var(--success)}
/* Dropdown Aksi: pemicu menampilkan ikon status (default user), menu berisi aksinya. */
.tm-menu{position:relative;display:inline-block;text-align:left}
.tm-menu-btn{display:inline-flex;align-items:center;gap:6px;height:28px;padding:0 8px;cursor:pointer;
  border:1px solid var(--line);background:var(--surface);color:var(--muted);border-radius:8px;font-size:14px}
.tm-menu-btn:hover{border-color:var(--primary);color:var(--primary)}
.tm-menu.open .tm-menu-btn{border-color:var(--primary);color:var(--primary);background:var(--primary-tint)}
.tm-menu-btn .tm-stat-ic.aktif{color:var(--primary)}
.tm-menu-btn .tm-menu-caret{font-size:10px;opacity:.7}
.tm-menu-pop{position:absolute;top:calc(100% + 4px);right:0;z-index:40;min-width:200px;display:none;
  background:var(--surface);border:1px solid var(--line);border-radius:10px;box-shadow:0 14px 34px rgba(15,23,42,.18);padding:5px}
.tm-menu.open .tm-menu-pop{display:block}
.tm-mi{display:flex;align-items:center;gap:10px;width:100%;border:0;background:transparent;border-radius:7px;
  padding:8px 10px;font:inherit;font-size:12.5px;color:var(--ink);cursor:pointer;text-align:left}
.tm-mi i{width:16px;text-align:center;color:var(--muted);font-size:13px}
.tm-mi:hover{background:var(--primary-tint);color:var(--primary)}
.tm-mi:hover i{color:var(--primary)}
.tm-mi.danger:hover{background:rgba(220,38,38,.1);color:var(--danger)}
.tm-mi.danger:hover i{color:var(--danger)}
/* Popup tak boleh terpotong kartu grup → overflow dibuka; sudut header dibulatkan
   sendiri supaya kartu tetap rapi. */
.tm-grup{overflow:visible}
.tm-grup-kepala{border-radius:9px}
.tm-grup.buka .tm-grup-kepala{border-radius:9px 9px 0 0}

/* --- Tab (dipakai modal catatan & halaman Detail Absensi) --- */
/* .note-tabs/.note-tab adalah kelas RUPA yang dipakai tiga tempat: modal
   Catatan, modal Setting Menu, dan kartu Peta di Home. Dulu hanya modal
   Catatan yang tampil benar, karena ia KEBETULAN juga memakai .tabbar/.tabbtn;
   dua tempat lain tampil sebagai tombol polos tanpa garis aktif. Aturannya
   disatukan di sini supaya ketiganya sama, bukan ditambal satu per satu. */
.tabbar,.note-tabs{display:flex;gap:4px;border-bottom:1px solid var(--line);margin-bottom:2px;flex:none;flex-wrap:wrap}
.tabbtn,.note-tab{
  display:inline-flex;align-items:center;gap:7px;
  padding:8px 13px;border:none;background:none;cursor:pointer;
  font-family:inherit;font-size:12.5px;font-weight:700;color:var(--muted);
  border-bottom:2px solid transparent;margin-bottom:-1px;transition:color .15s,border-color .15s;
}
.tabbtn:hover,.note-tab:hover{color:var(--ink)}
.tabbtn.active,.note-tab.active{color:var(--primary);border-bottom-color:var(--primary)}
.tabbtn:focus-visible,.note-tab:focus-visible{outline:2px solid var(--primary);outline-offset:-2px}
.note-chip{
  min-width:18px;padding:1px 5px;border-radius:9px;text-align:center;
  background:var(--primary-tint);color:var(--primary);
  font-size:10.5px;font-weight:800;font-variant-numeric:tabular-nums;
}
/* Hanya panel aktif yang tampil; semuanya kolom setinggi sisa ruang. */
.tabpane{display:none;flex:1;min-height:0;flex-direction:column;gap:9px}
.tabpane.show{display:flex}
/* Di dalam modal, tinggi tabel mengikuti sisa ruang modal — bukan rumus tinggi
   layar yang dipakai tabel halaman, karena modalnya sudah setinggi layar. */
.modal .tabpane .dt-card{flex:1;min-height:0;display:flex;flex-direction:column}
.modal .tabpane .table-scroll{max-height:none;flex:1;min-height:0}
.dt-cek{width:1%;text-align:center}

/* --- Ikon catatan pada menu & tab --- */
/* Seluruh ikon catatan disembunyikan kecuali akun yang berwenang. Ini hanya
   lapisan tampilan; penjaga sebenarnya ada di server (setiap permintaan
   catatan dijawab 403 untuk akun lain). */
body:not(.bisa-catatan) .nav-note,
body:not(.bisa-catatan) .tab-note,
body:not(.bisa-catatan) #btnNote{display:none}
/* Note Plan berdampingan dengan catatan aplikasi di kepala sidebar. Warnanya
   dibedakan supaya dua ikon bersebelahan tidak tertukar sekilas. */
/* --- Ganti pengguna --- */
.gu-spanduk{display:flex;align-items:center;gap:10px;flex-wrap:wrap;
            padding:8px 18px;background:#FDF2E0;border-bottom:1px solid #E6C77A;
            color:#7D5A17;font-size:12px;line-height:1.5}
.gu-spanduk i{font-size:12px}
.gu-spanduk b{color:#5C4210}
.gu-spanduk .btn{margin-left:auto;font-size:11.5px;padding:5px 10px;color:#7D5A17}
.gu-peringatan{margin:0 0 12px;padding:9px 11px;border-radius:8px;
               background:#FDF2E0;border:1px solid #E6C77A;color:#7D5A17;
               font-size:11.5px;line-height:1.55}
.gu-cari{margin-bottom:10px}
.gu-daftar{max-height:320px;overflow:auto;display:grid;gap:5px}
.gu-baris{display:flex;align-items:center;gap:10px;width:100%;padding:7px 9px;
          border:1px solid var(--line);border-radius:8px;background:var(--surface);
          font:inherit;text-align:left;cursor:pointer}
.gu-baris:hover{border-color:var(--primary);background:var(--surface-2)}
.gu-av{flex:none;width:28px;height:28px;border-radius:50%;background:var(--primary-tint);
       color:var(--primary);font-size:10.5px;font-weight:700;
       display:flex;align-items:center;justify-content:center}
.gu-teks{min-width:0}
.gu-teks b{display:block;font-size:12.5px}
.gu-teks small{display:block;color:var(--muted);font-size:10.5px}
.gu-kosong{margin:8px 0;font-size:12px;color:var(--muted)}
.brand .nav-plan{margin-left:4px;color:#F4D03F}
.brand .nav-plan:hover,.brand .nav-plan:focus-visible{background:rgba(244,208,63,.18)}
/* Atribut hidden mudah dikalahkan aturan display mana pun; .dt-card punya
   display:flex saat halamannya aktif, jadi kartu yang disembunyikan harus
   ditegaskan. */

/* Lencana jumlah tugas yang belum selesai pada ikon catatan. */
.note-badge{
  position:absolute;top:-3px;right:-4px;
  min-width:15px;height:15px;padding:0 3px;border-radius:9px;
  background:#C0392B;color:#fff;
  font-size:9px;font-weight:800;line-height:15px;text-align:center;
  font-variant-numeric:tabular-nums;pointer-events:none;
}
.nav-note,.tab-note,#btnNote{position:relative}

.nav-note{
  margin-left:auto;flex:none;cursor:pointer;
  opacity:.45;font-size:11.5px;padding:2px 3px;border-radius:5px;transition:opacity .15s,background .15s;
}
/* Kalau sudah ada lencana atau tanda panah yang terdorong ke kanan, ikonnya
   cukup menempel di sebelahnya — dua margin auto akan saling berebut ruang
   dan justru melemparkan lencana ke tengah. */
.nav-item .badge-count ~ .nav-note,
.nav-item .caret ~ .nav-note{margin-left:6px}
.nav-item:hover .nav-note{opacity:.8}
.nav-note:hover,.nav-note:focus-visible{opacity:1;background:rgba(255,255,255,.16);outline:none}
.nav-item i.fa-note-sticky{width:auto}
/* Ikon catatan di kepala sidebar: sejajar dengan judul aplikasi, didorong ke
   ujung kanan blok brand. */
.brand .nav-note{margin-left:auto;font-size:13px;padding:4px 5px;color:#E4E5EC}
.brand .nav-note:hover,.brand .nav-note:focus-visible{opacity:1;background:rgba(255,255,255,.16)}
.brand .nav-note i{width:auto}

/* --- Mode tanggal: matriks kehadiran per tanggal --- */
.dt-card table.dt-tgl thead th,
.dt-card table.dt-tgl tbody td{text-align:center}
/* Nama karyawan tetap rata kiri: panjangnya berbeda-beda, dirata-tengahkan
   tepi kirinya bergerigi dan daftarnya jadi sulit dipindai. */
.dt-card table.dt-tgl thead th:nth-child(2),
.dt-card table.dt-tgl tbody td:nth-child(2){text-align:left}
/* Dengan lebar terkunci, nama yang panjang harus dipotong rapi — bukan
   meluber menimpa kolom tanggal di sebelahnya. */
.dt-card table.dt-tgl tbody td:nth-child(2) .name-cell{
  display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
/* Lebar kolom dikunci lewat table-layout:fixed. Dengan layout otomatis, kolom
   Karyawan menyerap SELURUH sisa lebar tabel (itulah ruang kosong lebar di
   sebelah namanya), dan lebar tiap kolom tanggal ikut berubah-ubah mengikuti
   jumlah digit judulnya — "1" lebih sempit daripada "30".
   Sisa lebar tetap dibagi proporsional, jadi ke-31 kolom tanggal selalu sama
   lebar satu sama lain. */
.dt-card table.dt-tgl{table-layout:fixed}
.dt-card table.dt-tgl th:nth-child(1),
.dt-card table.dt-tgl td:nth-child(1){width:44px}
.dt-card table.dt-tgl th:nth-child(2),
.dt-card table.dt-tgl td:nth-child(2){width:230px;overflow:hidden;text-overflow:ellipsis}
.dt-card table.dt-tgl th:nth-child(n+3),
.dt-card table.dt-tgl td:nth-child(n+3){width:34px;padding:0 4px}
/* Kolom Total sedikit lebih lebar: isinya angka dua digit plus garis pemisah. */
.dt-card table.dt-tgl th:last-child,
.dt-card table.dt-tgl td:last-child{width:62px}
/* Bulan pendek: kolom tanggal yang tidak ada disembunyikan, bukan dibuat ulang
   headernya. Kolom 1 = No, 2 = Karyawan, jadi tanggal ke-N ada di kolom N+2. */
/* :not(:last-child) melindungi kolom Total yang selalu berada di ujung —
   tanpa itu, bulan yang kurang dari 31 hari ikut menyembunyikan Total. */
.dt-tgl[data-hari="28"] th:nth-child(n+31):not(:last-child),.dt-tgl[data-hari="28"] td:nth-child(n+31):not(:last-child),
.dt-tgl[data-hari="29"] th:nth-child(n+32):not(:last-child),.dt-tgl[data-hari="29"] td:nth-child(n+32):not(:last-child),
.dt-tgl[data-hari="30"] th:nth-child(n+33):not(:last-child),.dt-tgl[data-hari="30"] td:nth-child(n+33):not(:last-child){display:none}
/* Kolom Total diberi jarak dan penekanan supaya terbaca sebagai ringkasan
   barisnya, bukan sebagai tanggal ke-32. */
.dt-card table.dt-tgl th:last-child,
.dt-card table.dt-tgl td:last-child{
  border-left:2px solid var(--line);font-variant-numeric:tabular-nums;
  font-weight:800;color:var(--ink);padding:0 10px;
}
/* Hijau ini dipilih setelah diukur: #2E7D46 lolos di baris biasa (4,91) tapi
   jatuh ke 4,21 saat baris ter-hover. #2A7340 lolos di keduanya (5,60 / 4,81),
   sepasang dengan merah #C0392B yang dipakai di seluruh aplikasi (5,26 / 4,51). */
.hd-ya{color:#2A7340}
.hd-no{color:#C0392B}

/* --- Dropdown filter yang bisa dicari --- */
/* Dibuat sendiri, bukan Select2: Select2 menuntut jQuery dan skrip dari CDN,
   sementara CSP aplikasi ini hanya mengizinkan script-src 'self'. Elemen
   <select> aslinya tetap dipakai sebagai sumber kebenaran, jadi kode mana pun
   (termasuk uji otomatis) yang menyetel .value lalu memicu "change" tetap
   bekerja seperti sebelumnya. */
.cari-sel{position:relative;display:inline-flex}
.cari-sel > select{position:absolute;width:1px;height:1px;opacity:0;pointer-events:none;margin:0;padding:0;border:0}
.cari-tombol{
  display:inline-flex;align-items:center;gap:7px;
  border:1px solid var(--line);border-radius:6px;padding:5px 9px;
  background:var(--surface-2);color:var(--ink);
  font-family:inherit;font-size:12px;cursor:pointer;max-width:210px;
}
.cari-tombol span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.cari-tombol i{font-size:9px;color:var(--muted-2);flex:none}
.cari-tombol:hover{border-color:var(--muted-2)}
/* Tombolnya menggantikan sebuah <select>, jadi tampilannya harus sama persis
   dengan <select> tetangganya — kalau tidak, satu kendali terlihat "beda
   sendiri" padahal fungsinya sejenis. Nilainya disalin dari aturan masing-
   masing tempat, bukan dikarang ulang. */
.dt-periode .cari-tombol{
  background:var(--surface);border-radius:var(--r-input);
  padding:6px 9px;font-weight:600;color:var(--ink);
}
.dt-periode .cari-sel.buka .cari-tombol,
.dt-periode .cari-tombol:focus-visible{border-color:var(--primary);box-shadow:0 0 0 3px var(--primary-tint);outline:none}
.dt-top .cari-tombol{padding:5px 8px}
/* Di dalam formulir modal, kendali ini berdiri sebagai ISIAN — bukan cip
   saringan di bilah alat. Jadi ukurannya disamakan dengan .kl-input di
   sebelahnya: selebar kolomnya, setinggi isian lain, dan chevron-nya di ujung
   kanan. Tanpa ini tombolnya menciut selebar isinya dan formulirnya terlihat
   seperti tiga kotak berbeda ukuran. */
.kl-form .cari-sel{display:block;width:100%}
.kl-form .cari-tombol{
  width:100%;max-width:none;justify-content:space-between;
  padding:9px 11px;font-size:13px;border-radius:var(--r-input);
  margin-bottom:6px;box-sizing:border-box;
}
.kl-form .cari-sel.buka .cari-tombol,
.kl-form .cari-tombol:focus-visible{border-color:var(--primary);box-shadow:0 0 0 3px var(--primary-tint);outline:none}
/* Placeholder ("— pilih karyawan —") ditulis redup supaya terbaca sebagai
   "belum dipilih", bukan sebagai nilai yang sudah terpilih. */
.kl-form .cari-tombol.kosong span{color:var(--muted)}
.cari-sel.buka .cari-tombol{border-color:var(--primary);box-shadow:0 0 0 3px var(--primary-tint)}
.cari-pop{
  display:none;position:absolute;top:calc(100% + 4px);left:0;z-index:60;
  width:max(220px,100%);background:var(--surface);
  border:1px solid var(--line);border-radius:8px;box-shadow:0 12px 28px -8px rgba(15,23,42,.28);
  padding:7px;
}
.cari-sel.buka .cari-pop{display:block}
/* Daftar pendek tidak diberi kotak cari — lihat AMBANG_CARI di jadikanCari. */
.cari-sel.tanpa-cari .cari-input{display:none}
.cari-sel.tanpa-cari .cari-pop{padding-top:4px}
/* .atas dipasang saat ruang di bawah tombol tidak cukup — lihat buka() di JS. */
.cari-sel.atas .cari-pop{top:auto;bottom:calc(100% + 4px)}
.cari-input{
  width:100%;box-sizing:border-box;font-family:inherit;font-size:12px;
  border:1px solid var(--line);border-radius:6px;padding:6px 9px;background:var(--surface-2);color:var(--ink);
}
.cari-input:focus{outline:none;border-color:var(--primary)}
.cari-daftar{max-height:260px;overflow:auto;margin-top:6px;display:flex;flex-direction:column;gap:1px}
/* WAJIB flex:none pada anak daftar bergulir berbasis flex.
   Bawaan flex-shrink adalah 1, jadi begitu isinya lebih tinggi daripada wadah,
   yang menyusut adalah BARISNYA — bukan wadahnya yang menggulir. Akibatnya tiap
   baris jadi gepeng dan teksnya terpotong/bertumpuk. Aturan ini ditulis untuk
   SEMUA daftar bergulir sekaligus supaya kesalahan yang sama tidak terulang di
   daftar berikutnya. */
.cari-daftar > *,
.tata-daftar > *{flex:none}
.cari-opsi{
  text-align:left;border:none;background:none;cursor:pointer;
  font-family:inherit;font-size:12px;color:var(--ink);
  padding:7px 8px;border-radius:5px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  /* Tinggi baris dikunci supaya sebuah pilihan tidak pernah lebih pendek
     daripada teksnya sendiri. Dipakai min-height + line-height, BUKAN kotak
     flex: pemotongan dengan elipsis hanya bekerja pada kotak blok. */
  min-height:30px;line-height:16px;box-sizing:border-box;
}
.cari-opsi:hover{background:var(--surface-2)}
.cari-opsi.aktif{background:var(--primary-tint);color:var(--primary);font-weight:700}
.cari-kosong{padding:10px 8px;font-size:11.5px;color:var(--muted)}
/* Keterangan ekor daftar yang tidak digambar — sengaja bukan tombol, supaya
   tidak terbaca sebagai pilihan yang bisa diklik. */
.cari-sisa{padding:7px 10px;font-size:11px;color:var(--muted);text-align:center;
           border-top:1px solid var(--line);background:var(--surface-2)}

/* --- Tombol & modal Setting Menu --- */
body:not(.bisa-tata-menu) .nav-tata{display:none}
/* Menu yang dinonaktifkan lewat Setting Menu. Disembunyikan, BUKAN dihapus:
   susunannya tetap menyimpannya, jadi ia bisa dihidupkan kembali dari sana. */
.nav-item.nav-mati{display:none!important}
.nav-sub.sub-mati{display:none!important}
/* Baris nonaktif di Setting Menu tetap terbaca — ia harus bisa dihidupkan lagi. */
.tata-baris.mati .nama{opacity:.5;text-decoration:line-through}
.tata-mati-cap{margin-left:7px;padding:1px 6px;border-radius:999px;
               background:#F3E0E0;color:#8E3B3B;font-size:9px;font-weight:700;
               letter-spacing:.03em;text-transform:uppercase;text-decoration:none;
               display:inline-block;vertical-align:1px}
.tata-mati{flex:none;width:26px;height:26px;border-radius:7px;border:1px solid var(--line);
           background:var(--surface);color:#C0392B;cursor:pointer;font-size:11px}
.tata-mati:hover{border-color:#C0392B;background:rgba(192,57,43,.08)}
.tata-mati.on{color:#1E8449}
.tata-mati.on:hover{border-color:#1E8449;background:rgba(30,132,73,.08)}
.tata-mati-kunci{flex:none;width:26px;height:26px;display:flex;align-items:center;
                 justify-content:center;color:var(--muted);opacity:.45;font-size:10px}
/* Tombol Setting Menu berbagi baris dengan ikon catatannya. */
.nav-tata-baris{display:flex;align-items:center;gap:2px}
.nav-tata-baris .nav-tata{flex:1;min-width:0}
body:not(.bisa-tata-menu) .nav-tata-baris{display:none}
.nav-tata-note{flex:none;margin-right:10px;color:#E4E5EC;font-size:12px;
               padding:4px 5px;border-radius:5px;cursor:pointer;opacity:.5}
.nav-tata-note:hover,.nav-tata-note:focus-visible{opacity:1;background:rgba(255,255,255,.16);outline:none}
/* --- Catatan sub-menu di dalam catatan menu --- */
.note-anak{margin-top:14px;padding-top:12px;border-top:1px dashed var(--line)}
.note-anak-judul{margin:0 0 9px;font-size:10.5px;text-transform:uppercase;
                 letter-spacing:.05em;color:var(--muted);display:flex;
                 align-items:center;gap:7px}
.note-anak-judul span{margin-left:auto;text-transform:none;letter-spacing:0;
                      font-size:10.5px;font-variant-numeric:tabular-nums}
.note-anak-daftar{list-style:none;margin:0;padding:0;display:grid;gap:6px}
.note-anak-daftar button{display:block;width:100%;text-align:left;padding:8px 10px;
                         border:1px solid var(--line);border-radius:8px;
                         background:var(--surface-2);font:inherit;cursor:pointer}
.note-anak-daftar button:hover{border-color:var(--primary);background:var(--surface)}
.note-anak-daftar b{font-size:12px;color:var(--ink)}
.note-anak-daftar small{float:right;font-size:10px;color:var(--muted)}
.note-anak-daftar span{display:block;margin-top:3px;font-size:11px;line-height:1.5;
                       color:var(--muted)}
.note-anak-kosong,.note-anak-tunggu{margin:0;font-size:11.5px;color:var(--muted)}
.note-anak-ket{margin:9px 0 0;font-size:10.5px;line-height:1.5;color:var(--muted);opacity:.85}
.nav-tata{
  margin:6px 12px 14px;padding:8px 12px;flex:none;
  display:flex;align-items:center;gap:9px;
  background:rgba(255,255,255,.08);border:1px solid rgba(255,255,255,.14);
  border-radius:8px;color:#E4E5EC;font-family:inherit;font-size:12.5px;font-weight:600;
  cursor:pointer;transition:background .15s;
}
.nav-tata:hover{background:rgba(255,255,255,.16);color:#fff}
.nav-tata i{font-size:12px}

.tata-daftar{display:flex;flex-direction:column;gap:5px;max-height:52vh;overflow:auto}
/* Tambah sub-menu (alias) */
.tata-tambah{margin-top:10px}
.tata-tambah-form{display:flex;flex-wrap:wrap;align-items:flex-end;gap:8px 10px;margin-top:8px;
  padding:10px 12px;border:1px dashed var(--line);border-radius:9px;background:var(--surface-2)}
.tata-tambah-form>label{display:flex;flex-direction:column;gap:3px;font-size:11px;font-weight:600;
  color:var(--muted);flex:1 1 160px}
.tata-tambah-form>label .kl-input{margin:0}
.tata-tambah-aksi{display:flex;gap:8px;flex:0 0 auto}
.tata-baris{
  display:flex;align-items:center;gap:8px;
  background:var(--surface-2);border:1px solid var(--line);border-radius:var(--r-input);
  padding:7px 9px;font-size:12.5px;
}
/* Baris kelompok dibedakan supaya batas antar kelompok terbaca sekali lihat. */
.tata-baris.grup{background:var(--primary-tint);border-color:var(--primary);font-weight:800}
.tata-baris.anak{margin-left:22px}
.tata-baris.tarik{opacity:.45}
.tata-baris .pegang{cursor:grab;color:var(--muted-2);font-size:12px}
.tata-baris .nama{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--ink)}
.tata-baris select{
  font-family:inherit;font-size:11.5px;color:var(--ink);background:var(--surface);
  border:1px solid var(--line);border-radius:6px;padding:4px 6px;cursor:pointer;max-width:42%;
}
.tata-baris .gerak{background:none;border:1px solid var(--line);border-radius:6px;cursor:pointer;
  color:var(--ink-soft);width:24px;height:24px;font-size:10px;padding:0;flex:none}
.tata-baris .gerak:hover:not(:disabled){background:var(--primary-tint);color:var(--primary)}
.tata-baris .gerak:disabled{opacity:.35;cursor:default}

/* Sub-menu yang dinaikkan ke tingkat atas tetap memakai ikon titik kecilnya;
   tanpa aturan ini titik itu membesar jadi bulatan 14px yang janggal. */
.nav-item i.fa-circle{font-size:5px;opacity:.5;width:auto;margin:0 3px}

/* --- Formulir klien --- */
.kl-form{display:grid;grid-template-columns:minmax(0,1fr);gap:4px}
/* Dua isian berdampingan di dalam .kl-form (mis. Durasi & Masa Percobaan). */
.kl-row2{display:grid;grid-template-columns:1fr 1fr;gap:10px;align-items:start}
.kl-row2>div{display:grid;grid-template-columns:minmax(0,1fr);gap:4px}
/* ===== Board Divisi: 4 kartu (Divisi | Role | Jabatan | User) =====
   Board MENGISI tinggi layar (tanpa scroll halaman); tiap kartu setinggi board
   dan daftar di dalamnya yang menggulir saat datanya banyak. */
.page.active:has(> .dv-board){display:flex;flex-direction:column;height:100%;min-height:0}
/* SEMUA kartu lebar SAMA RATA: board = flex baris; `.dv-rel` dibuat display:contents
   agar anak-anaknya (Jabatan/Karyawan/Belum) jadi flex-item langsung board — jadi
   semua kartu sejajar & flex:1 (3 kartu → 1/3 masing-masing, 4 kartu → 1/4). */
.dv-board{display:flex;gap:14px;align-items:stretch;flex:1 1 auto;min-height:0}
.dv-rel{display:contents}
.dv-board>.dv-card-divisi,.dv-rel>.dv-card{flex:1 1 0;min-width:0;min-height:0}
/* Kartu "Belum di Divisi" DEFAULT TERSEMBUNYI → tinggal 3 kartu rata (1/3).
   Ikon users di header Divisi → kelas .belum-on → kartu muncul → 4 kartu rata (1/4). */
.dv-rel>#dvCardBelum{display:none}
.dv-rel.belum-on>#dvCardBelum{display:flex}
.dv-h-aksi{display:flex;align-items:center;gap:8px;flex:0 0 auto}
/* Border kartu: HITAM BLUR 3D — garis gelap tipis + cincin putih (emboss) +
   bayang hitam lembut berlapis. */
.dv-card{border:1.5px solid rgba(0,0,0,.42);border-radius:14px;background:var(--surface,#fff);display:flex;flex-direction:column;min-width:0;min-height:0;
  box-shadow:inset 0 0 0 1.5px rgba(255,255,255,.75), 0 2px 6px rgba(0,0,0,.18), 0 10px 22px -6px rgba(0,0,0,.28), 0 22px 44px -16px rgba(0,0,0,.4)}
/* Header kartu: PUTIH, sudut atas membulat mengikuti kartu. */
.dv-card-h{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:10px 12px;border-bottom:1px solid var(--line);flex:0 0 auto;background:#fff;border-radius:13px 13px 0 0}
.dv-card-h h4{margin:0;font-size:13px;font-weight:700;color:var(--ink);display:flex;align-items:center;gap:7px}
.dv-card-h h4 i{color:var(--primary)}
.dv-card-hr{display:flex;align-items:center;gap:8px;min-width:0;flex:0 1 auto}
.dv-aktif-nama{font-size:11.5px;font-weight:600;color:var(--primary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:120px}
.dv-btn-sm{padding:5px 10px;font-size:12px}
/* Tombol show/hide sisi Tersedia (ikon khas tiap kartu). */
.dv-toggle{flex:0 0 auto;width:28px;height:28px;border-radius:8px;border:1px solid var(--line);background:var(--surface,#fff);color:var(--ink-soft,var(--muted));cursor:pointer;display:grid;place-items:center;font-size:12.5px;transition:.12s}
.dv-toggle:hover{background:var(--primary-tint);color:var(--primary);border-color:var(--primary)}
.dv-toggle.on{background:var(--primary);color:#fff;border-color:var(--primary);box-shadow:inset 0 0 0 1.5px rgba(255,255,255,.4)}
.dv-card .dv-cari{margin:8px 12px 0;flex:0 0 auto}
.dv-cari{font-family:inherit;font-size:12px;color:var(--ink);background:var(--bg);border:1px solid var(--line);border-radius:7px;padding:6px 9px;outline:none;width:auto}
.dv-cari:focus{border-color:var(--primary)}
.dv-jml{display:inline-block;min-width:18px;padding:0 6px;border-radius:9px;background:var(--surface-2,var(--bg));color:var(--muted);font-size:11px;text-align:center;font-weight:600}
.dv-jml-on{background:var(--primary-tint);color:var(--primary)}
.dv-list{overflow:auto;padding:6px;display:flex;flex-direction:column;gap:3px;min-height:0}
/* Datatable ringkas untuk daftar Divisi */
.dv-tbl-wrap{flex:1 1 auto;min-height:120px;margin-top:8px;overflow:auto;padding:0 2px 2px}
.dv-divisi-list{flex:1 1 auto;min-height:120px}
/* Footer kartu: total (Divisi: total karyawan; Role/Jabatan/User: total terpilih) */
.dv-divisi-foot,.dv-card-foot{flex:0 0 auto;margin-top:8px;padding:9px 12px;border-top:1.5px solid var(--line);
  background:var(--surface-2);border-radius:0 0 13px 13px;display:flex;align-items:center;justify-content:space-between;
  font-size:12px;font-weight:600;color:var(--muted)}
.dv-divisi-foot b,.dv-card-foot b{font-size:14px;color:var(--primary);font-weight:800}
.dv-tbl{width:100%;border-collapse:collapse;font-size:12.5px}
.dv-tbl thead th{position:sticky;top:0;z-index:3;background:var(--surface-2);color:var(--muted);font-weight:700;text-transform:uppercase;font-size:9.5px;letter-spacing:.03em;padding:6px 8px;text-align:left;border-bottom:1.5px solid var(--line);white-space:nowrap}
.dv-tbl thead th[data-dv-sort]{cursor:pointer;user-select:none}
.dv-tbl thead th[data-dv-sort]:hover{color:var(--primary)}
.dv-tbl thead th.num{text-align:center}
.dv-tbl tbody td{padding:6px 8px;border-bottom:1px solid var(--line);white-space:nowrap;vertical-align:middle}
.dv-tbl tbody tr{cursor:pointer}
.dv-tbl tbody tr:hover{background:var(--primary-tint)}
.dv-tbl tbody tr.on{background:var(--primary-tint);box-shadow:inset 3px 0 0 var(--primary)}
.dv-tbl .num{text-align:center;color:var(--muted);font-variant-numeric:tabular-nums}
.dv-tbl .num b{color:var(--primary)}
.dv-tbl td.nm{font-weight:700;color:var(--ink);max-width:132px;overflow:hidden;text-overflow:ellipsis}
/* Kolom checkbox pilih divisi + kolom Atasan (username). */
.dv-tbl .dv-chk{width:24px;text-align:center;padding:6px 2px 6px 6px}
.dv-tbl td.dv-chk input{cursor:pointer;margin:0;vertical-align:middle}
.dv-tbl thead th.dv-at{color:var(--muted)}
.dv-tbl .dv-at{max-width:104px;font-size:11px;color:var(--primary);vertical-align:middle}
.dv-tbl td.dv-at i{font-size:9px;margin-right:3px;color:var(--muted)}
.dv-tbl td.dv-at .dv-at-x{color:var(--muted)}
.dv-at-wrap{display:flex;flex-direction:column;line-height:1.18;min-width:0}
.dv-at-u{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.dv-at-j{color:var(--muted);font-size:9.5px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-transform:none}
.dv-tbl td.nm>span:last-child{overflow:hidden;text-overflow:ellipsis}
.dv-tbl .st-dot{display:inline-block;width:8px;height:8px;border-radius:50%;margin-right:6px;vertical-align:middle;flex:0 0 auto}
.dv-tbl .st-on{background:#16a34a}.dv-tbl .st-off{background:#9ca3af}
.dv-tbl td.aksi{text-align:right;padding-right:6px}
.dv-tbl td.aksi button{border:none;background:transparent;color:var(--muted);cursor:pointer;padding:3px 4px;border-radius:6px;font-size:11px;opacity:0;transition:.12s}
.dv-tbl tbody tr:hover td.aksi button,.dv-tbl tbody tr.on td.aksi button{opacity:1}
.dv-tbl td.aksi button:hover{background:var(--surface-2);color:var(--primary)}
.dv-tbl td.aksi button.del:hover{color:var(--danger,#dc2626)}
/* Seret-lepas untuk atur urutan */
.dv-tbl tbody tr[draggable="true"]{cursor:grab}
.dv-opsi.dv-seret{cursor:grab}
.dv-tarik{opacity:.4}
.dv-tbl tbody tr.dv-tarik td{background:var(--surface-2)}
/* Baris header grup Pusat / Cabang (collapsible). */
.dv-tbl tbody tr.dv-grup{cursor:pointer;user-select:none}
.dv-tbl tbody tr.dv-grup td{background:var(--surface-2);border-bottom:1.5px solid var(--line);
  padding:6px 10px 6px 8px;font-size:11px;text-transform:uppercase;letter-spacing:.03em;color:var(--ink)}
/* Header grup TOP-LEVEL (Pusat/Cabang) menempel di bawah thead (tinggi thead 29px)
   saat digulir — sub-grup cabang (.dv-grup-anak) tetap ikut gulir. */
.dv-tbl tbody tr.dv-grup:not(.dv-grup-anak) td{position:sticky;top:29px;z-index:2}
.dv-grup-in{display:flex;align-items:center;gap:6px;width:100%}
.dv-tbl tbody tr.dv-grup:hover td{background:var(--primary-tint)}
.dv-tbl tbody tr.dv-grup td b{font-weight:800}
.dv-grup-caret{font-size:10px;color:var(--muted);margin-right:4px;transition:transform .15s}
.dv-tbl tbody tr.dv-grup.tutup .dv-grup-caret{transform:rotate(-90deg)}
.dv-grup-n{display:inline-block;min-width:18px;text-align:center;margin-left:4px;padding:0 6px;
  border-radius:999px;background:var(--surface);border:1px solid var(--line);color:var(--muted);
  font-size:10px;font-weight:700;font-variant-numeric:tabular-nums;text-transform:none}
.dv-tbl tbody tr.dv-grup-kosong td{color:var(--muted);font-style:italic;white-space:normal}
/* Sub-grup cabang (level 2) di bawah induk "Cabang". */
.dv-tbl tbody tr.dv-grup.dv-grup-anak td{background:var(--surface);font-size:10.5px;padding-left:22px;text-transform:none;letter-spacing:0;border-bottom:1px solid var(--line)}
.dv-tbl tbody tr.dv-grup.dv-grup-anak:hover td{background:var(--primary-tint)}
.dv-tbl tbody tr.dv-grup.dv-grup-anak td b{font-weight:700}
.dv-tbl tbody tr.dv-lvl2 td.nm{padding-left:30px}
.dv-tbl tbody tr.dv-grup-kosong.dv-grup-anak td{padding-left:30px}
/* Ekor kanan header cabang: kolom klien (lebar tetap) + "+", right-aligned →
   chip & "+" sejajar satu kolom di semua baris cabang. */
.dv-grup-tail{margin-left:auto;display:flex;align-items:center;gap:8px;flex:0 0 auto}
.dv-grup-tail .dv-grup-add{margin-left:0}
.dv-klien{display:flex;align-items:center;gap:3px;flex:0 0 auto;width:130px;justify-content:flex-start;overflow:hidden}
/* Label grup boleh menyusut (ellipsis) supaya ekor klien+"+" tetap di kolom kanan. */
.dv-grup-in>b{flex:0 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.dv-klien-tag{flex:0 0 auto;font-size:9px;font-weight:700;padding:1px 6px;border-radius:999px;background:var(--primary-tint);color:var(--primary);
  text-transform:none;letter-spacing:0;white-space:nowrap;max-width:110px;overflow:hidden;text-overflow:ellipsis}
.dv-klien-more{background:var(--surface);color:var(--muted);border:1px solid var(--line)}
.dv-grup-add{border:none;background:transparent;color:var(--muted);cursor:pointer;padding:2px 7px;border-radius:6px;font-size:11px;margin-left:auto;flex:0 0 auto}
.dv-grup-add:hover{background:var(--surface);color:var(--primary)}
.dv-tbl tbody tr.dv-grup.dv-grup-anak .dv-grup-add:hover{background:var(--surface-2)}
/* Kotak filter nama cabang di header grup Cabang (dipaku kanan). */
.dv-cab-filter{margin-left:auto;flex:0 1 220px;min-width:90px;font:inherit;font-size:11px;text-transform:none;letter-spacing:0;
  padding:3px 9px;border:1px solid var(--line);border-radius:7px;background:var(--surface);color:var(--ink)}
.dv-cab-filter:focus{outline:none;border-color:var(--primary)}
/* Kartu "Belum di Divisi": header grup per cabang (collapsible). */
.dv-belum-grup{display:flex;align-items:center;gap:6px;cursor:pointer;user-select:none;
  padding:6px 9px;margin:8px 0 3px;font-size:10.5px;text-transform:uppercase;letter-spacing:.03em;
  color:var(--ink);background:var(--surface-2);border:1px solid var(--line);border-radius:7px}
.dv-belum-grup:first-child{margin-top:2px}
.dv-belum-grup:hover{border-color:var(--primary)}
.dv-belum-grup b{font-weight:800;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.dv-belum-grup .dv-grup-caret{font-size:10px;color:var(--muted);transition:transform .15s;flex:0 0 auto}
.dv-belum-grup.tutup .dv-grup-caret{transform:rotate(-90deg)}
.dv-belum-grup .dv-grup-n{margin-left:auto;flex:0 0 auto}
/* Filter berlabel 1 baris (label + input sejajar) di kartu Belum di Divisi. */
.dv-filter-row{display:flex;align-items:center;gap:8px;margin:6px 10px 0}
.dv-filter-row label{flex:0 0 52px;font-size:11px;font-weight:700;color:var(--muted);text-align:right}
/* Spesifisitas lebih tinggi dari `.dv-sisi .dv-cari` agar input MEMANJANG penuh ke tepi kartu. */
.dv-sisi .dv-filter-row .dv-cari{flex:1 1 auto;width:100%;margin:0;min-width:0}
/* Isi kartu transfer: SELALU satu kolom penuh. DEFAULT tampil "Terpilih"
   (selebar kartu), "Tersedia" tersembunyi. Tombol ikon di header → kelas .buka:
   "Tersedia" tampil penuh dan MENUTUPI "Terpilih" (Terpilih disembunyikan). */
.dv-dua{display:grid;grid-template-columns:1fr;gap:0;min-width:0;flex:1 1 auto;min-height:0}
.dv-sisi{display:flex;flex-direction:column;min-width:0;min-height:0}
.dv-sisi-tersedia{display:none}
.dv-card.buka .dv-sisi-tersedia{display:flex}
.dv-card.buka .dv-sisi-terpilih{display:none}
.dv-sisi-h{display:flex;align-items:center;justify-content:space-between;gap:6px;padding:8px 10px 4px;font-size:11px;font-weight:700;color:var(--muted);text-transform:uppercase;letter-spacing:.03em;flex:0 0 auto}
.dv-sisi .dv-cari{margin:0 10px;flex:0 0 auto}
.dv-sisi .dv-list{flex:1 1 auto;min-height:60px}
/* Layar sempit: board menumpuk & halaman yang menggulir; daftar dibatasi tinggi
   supaya tiap bagian tetap terbaca. */
@media(max-width:860px){
  .page.active:has(> .dv-board){display:block;height:auto}
  .dv-board{flex-wrap:wrap;flex:none;height:auto}
  .dv-board>.dv-card-divisi,.dv-rel>.dv-card{flex:1 1 100%;min-width:0}
  .dv-divisi-list{max-height:48vh}
  .dv-sisi .dv-list{max-height:44vh}
}
/* Bingkai 3D (sama rasa dgn kalender cuti): garis luar gelap + cincin putih di
   dalam (emboss) + bayang jatuh. Dipakai utk item TERPILIH & kartu divisi. */
.dv-3d{border:1.5px solid rgba(15,23,42,.5);
  box-shadow:inset 0 0 0 1.5px rgba(255,255,255,.92), 0 2px 4px rgba(15,23,42,.14), 0 10px 20px -11px rgba(15,23,42,.4)}
/* Baris item (role/jabatan/user) — klik memindahkan */
.dv-opsi{display:flex;align-items:center;gap:8px;padding:6px 8px;border-radius:8px;font-size:12.5px;color:var(--ink);cursor:pointer;user-select:none;border:1px solid transparent;background:var(--bg)}
.dv-opsi:hover{background:var(--primary-tint);border-color:var(--primary)}
.dv-opsi>span:first-child{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* No urut kartu Karyawan Terpilih (nomor di sisi kiri). Ditulis SESUDAH aturan
   span:first-child di atas: spesifisitas seri, jadi yang belakangan menang —
   nomor jadi lebar-tetap (tak ikut melar jadi kolom nama). tabular-nums biar
   lajur angka rata. */
.dv-opsi>span.dv-no{flex:0 0 auto;min-width:1.5em;overflow:visible;text-overflow:clip;
  white-space:nowrap;text-align:right;color:var(--muted-2);font-size:11px;font-weight:700;
  font-variant-numeric:tabular-nums;padding-top:1px}
.dv-act-ic{flex:0 0 auto;font-size:11px;color:var(--muted);opacity:.65;cursor:pointer;padding:2px;border-radius:5px;border:none;background:transparent;line-height:1;display:inline-flex;align-items:center}
button.dv-act-ic{font-family:inherit}
.dv-opsi:hover .dv-act-ic{color:var(--primary);opacity:1}
/* Ikon X (keluarkan) terpilih: kursor tangan + sorotan merah, seperti ikon Hapus. */
.dv-opsi[data-dv-aksi="lepas"] .dv-act-ic{cursor:pointer}
.dv-opsi[data-dv-aksi="lepas"] .dv-act-ic:hover{background:var(--danger-tint,#fde8e8);color:var(--danger,#dc2626);opacity:1}
/* TERPILIH → bingkai 3D hitam-putih terang. */
.dv-opsi[data-dv-aksi="lepas"]{background:var(--surface,#fff);border-color:rgba(15,23,42,.5);
  box-shadow:inset 0 0 0 1.5px rgba(255,255,255,.92), 0 2px 4px rgba(15,23,42,.14), 0 10px 20px -12px rgba(15,23,42,.38)}
.dv-opsi[data-dv-aksi="lepas"]:hover{background:var(--danger-tint,#fde8e8);border-color:var(--danger,#dc2626)}
.dv-opsi[data-dv-aksi="lepas"]:hover .dv-act-ic{color:var(--danger,#dc2626);opacity:1}
/* Ikon ATASAN (mahkota) di item Karyawan Terpilih: redup default, emas bila atasan. */
.dv-atasan-ic{flex:0 0 auto;font-size:12px;color:var(--muted);opacity:.3;cursor:pointer;padding:2px 4px;
  border-radius:5px;border:none;background:transparent;line-height:1;display:inline-flex;align-items:center;transition:.12s}
button.dv-atasan-ic{font-family:inherit}
.dv-opsi:hover .dv-atasan-ic{opacity:.6}
.dv-atasan-ic:hover{color:#d97706;opacity:1;background:#fef3c7}
.dv-atasan-ic.on,.dv-opsi:hover .dv-atasan-ic.on{color:#f59e0b;opacity:1}
.dv-atasan-ic.on:hover{color:#d97706;background:#fef3c7}
.dv-opsi-kar{align-items:flex-start}
/* Item User: nama + (role - jabatan) pada SATU baris, dipisah titik. Nama utuh;
   label sekunder yang menyusut/di-ellipsis bila ruang sempit. */
/* Item Jabatan di board Divisi: nama tumbuh (flex:1 1 auto via aturan
   .dv-opsi>span:first-child) → kotak klien lebar-tetap (.dv-klien) terdorong ke
   kolom kanan sejajar, sama dgn header cabang kartu Divisi. */
.dv-kar{display:flex;flex-direction:row;align-items:baseline;gap:6px;flex:1 1 auto;min-width:0}
.dv-kar b{font-weight:600;flex:0 1 auto;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.dv-kar small{color:var(--muted);font-size:11px;flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.dv-kar small::before{content:"· ";color:var(--muted)}
/* Kartu divisi (kiri) — default sudah bingkai 3D hitam-putih terang. */
.dv-divisi-item{padding:9px 11px;border:1.5px solid rgba(15,23,42,.5);border-radius:11px;cursor:pointer;background:var(--surface,#fff);
  box-shadow:inset 0 0 0 1.5px rgba(255,255,255,.92), 0 2px 4px rgba(15,23,42,.14), 0 10px 20px -11px rgba(15,23,42,.4);
  transition:transform .1s, box-shadow .12s}
.dv-divisi-item:hover{transform:translateY(-1px);box-shadow:inset 0 0 0 1.5px rgba(255,255,255,.95), 0 4px 8px rgba(15,23,42,.18), 0 16px 28px -12px rgba(15,23,42,.5)}
.dv-divisi-item.on{border-color:var(--primary);background:var(--primary-tint);
  box-shadow:inset 0 0 0 1.5px rgba(255,255,255,.85), inset 3px 0 0 var(--primary), 0 3px 6px rgba(15,23,42,.16), 0 16px 28px -12px rgba(15,23,42,.48)}
.dv-di-top{display:flex;align-items:center;justify-content:space-between;gap:6px}
.dv-di-top b{font-size:13px;font-weight:700;color:var(--ink);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.dv-di-act{display:flex;gap:2px;flex:0 0 auto;opacity:0;transition:opacity .12s}
.dv-divisi-item:hover .dv-di-act,.dv-divisi-item.on .dv-di-act{opacity:1}
/* Info satu baris: badge status + ringkasan role/jab/user/karyawan. */
.dv-di-meta{display:flex;align-items:center;gap:6px;margin-top:7px;font-size:11.5px;white-space:nowrap;overflow:hidden}
.dv-di-meta .badge{flex:0 0 auto;font-size:9.5px;padding:1px 6px;letter-spacing:0}
.dv-di-hit{color:var(--muted);overflow:hidden;text-overflow:ellipsis;min-width:0}
.dv-di-hit b{color:var(--primary);font-weight:700}
.dv-kosong{color:var(--muted);font-size:12px;text-align:center;padding:14px 8px;margin:0}
.kl-input{
  font-family:inherit;font-size:13px;color:var(--ink);
  background:var(--surface-2);border:1px solid var(--line);border-radius:var(--r-input);
  padding:9px 11px;margin-bottom:6px;width:100%;box-sizing:border-box;
}
.kl-input:focus{outline:none;border-color:var(--primary);background:#fff;box-shadow:0 0 0 3px var(--primary-tint)}
.kl-input.salah{border-color:#C0392B;box-shadow:0 0 0 3px rgba(192,57,43,.14)}
/* Tanda "wajib diisi HRD" saat Konfirmasi: border merah pada isian/dropdown yang
   masih kosong, hilang begitu terisi. Berlaku untuk input/textarea ber-.kl-input
   maupun tombol select2 (.cari-tombol) pada Jabatan. */
.kl-input.rf-perlu,.cari-tombol.rf-perlu{border-color:var(--danger);box-shadow:0 0 0 2px rgba(239,68,68,.14)}
.kl-wajib{color:#C0392B}
/* Catatan sistem (keterlambatan final) di datatable — informatif, warna amber,
   BUKAN galat. Dibedakan jelas dari catatan opsional manusia. */
.ket-sistem{display:inline-flex;align-items:center;gap:5px;font-size:11.5px;line-height:1.35;
  color:#92610A;background:#FEF3C7;border:1px solid #FCD9A0;border-radius:7px;padding:2px 7px;white-space:normal}
.ket-sistem i{font-size:10px;color:#B45309;flex:none}
:root:not([data-theme="light"]) .ket-sistem,:root[data-theme="dark"] .ket-sistem{
  color:#FBBF24;background:rgba(180,83,9,.18);border-color:rgba(251,191,36,.35)}
/* PKWT di kolom karyawan + drawer penetapan PKWT (slide-in kanan). */
/* Baris keterangan (merge) hari tanpa absen di detail absensi. */
.det-ket-cell{text-align:center;background:var(--surface-2)}
/* Action Detail Absensi: SATU ikon toggle (centang hijau / silang merah). */
/* Ikon Status yang bisa diklik (Kurang Bayar): toggle flag_active. */
.kby-togg{border:0;background:transparent;cursor:pointer;padding:2px;border-radius:7px;line-height:0}
.kby-togg:hover{background:var(--surface-2)}
.kby-togg:disabled{cursor:progress;opacity:.6}
.det-act{display:inline-flex;align-items:center;justify-content:center}
.det-ikon-btn{border:0;background:transparent;cursor:pointer;padding:3px;border-radius:7px;line-height:0}
.det-ikon-btn:hover{background:var(--surface-2)}
.det-ikon{font-size:17px}
.det-ikon.fa-circle-check{color:var(--success)}
.det-ikon.fa-circle-xmark{color:var(--danger)}
/* Tidak Absen / Belum Absen: ikon X abu-abu (disabled), bukan merah — tak bisa di-toggle. */
.det-mati{cursor:default;opacity:.55}
.det-mati .det-ikon{color:var(--muted)}
.det-ket-nonaktif{background:var(--danger-tint);color:var(--danger)}
.det-ket{display:inline-block;font-size:12.5px;font-weight:600;border-radius:999px;padding:2px 14px}
.det-ket-alpha{background:var(--danger-tint);color:var(--danger)}
.det-ket-ada{background:var(--primary-tint);color:var(--primary)}
.det-ket-belum{background:#DBEAFE;color:#1D4ED8}
:root:not([data-theme="light"]) .det-ket-belum,:root[data-theme="dark"] .det-ket-belum{background:rgba(37,99,235,.2);color:#60A5FA}
.km-pkwt{display:inline-flex;align-items:center;gap:5px;font-size:12px;background:var(--primary-tint);color:var(--primary);border-radius:6px;padding:2px 8px;border:0;cursor:pointer;font-family:inherit}
.km-pkwt i{font-size:10px;opacity:.8}
.km-pkwt:hover{filter:brightness(.96);text-decoration:underline}
.pkwt-hist-head{font-size:12.5px;color:var(--muted);margin-bottom:8px}
.pkwt-hist-wrap{max-height:50vh;overflow:auto;border:1px solid var(--line);border-radius:8px}
.pkwt-hist-tb{width:100%;border-collapse:collapse;font-size:12.5px}
.pkwt-hist-tb th,.pkwt-hist-tb td{padding:7px 10px;text-align:left;border-bottom:1px solid var(--line);white-space:nowrap}
.pkwt-hist-tb thead th{background:var(--surface-2);position:sticky;top:0;font-size:11px;text-transform:uppercase;letter-spacing:.03em;color:var(--muted)}
.pkwt-hist-tb tr:last-child td{border-bottom:0}
.pkwt-hist-now{background:var(--primary-tint)}
.pkwt-hist-fase{color:#92610A;font-weight:600}
.pkwt-hist-tb td small{color:var(--muted);font-weight:400}
:root:not([data-theme="light"]) .pkwt-hist-fase,:root[data-theme="dark"] .pkwt-hist-fase{color:#FBBF24}
.pkwt-hist-badge{display:inline-block;font-size:11px;background:var(--primary);color:#fff;border-radius:999px;padding:1px 8px}
.pkwt-hist-kosong{font-size:13px;color:var(--muted)}
.pkwt-prob{font-size:12.5px;background:#FEF3C7;color:#92610A;border:1px solid #FCD9A0;border-radius:8px;padding:8px 10px;margin-bottom:8px}
.pkwt-prob i{color:#B45309}
.pkwt-prob-hd{font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.03em;opacity:.85;margin-bottom:5px}
.pkwt-prob-line{display:flex;align-items:center;gap:7px;padding:2px 0}
.pkwt-prob-line>span:first-child{display:flex;align-items:center;gap:6px}
.pkwt-prob-stat{margin-left:auto;font-size:11px;border-radius:999px;padding:1px 8px;color:#fff;white-space:nowrap}
.pkwt-prob-now{background:#B45309}
.pkwt-prob-done{background:var(--muted-2)}
.pkwt-prob-soon{background:#9CA3AF}
:root:not([data-theme="light"]) .pkwt-prob,:root[data-theme="dark"] .pkwt-prob{
  color:#FBBF24;background:rgba(180,83,9,.18);border-color:rgba(251,191,36,.35)}
.dt-ikon-filter{border:1px solid var(--line);background:var(--surface);color:var(--ink-soft);border-radius:6px;width:30px;height:30px;cursor:pointer;flex:none;display:inline-grid;place-items:center;font-size:13px}
.dt-ikon-filter:hover{border-color:var(--primary);color:var(--primary)}
/* Ikon di dalam tombol ini TIDAK boleh ikut aturan ".dt-search i" (yang membuat
   ikon kaca pembesar jadi position:absolute) — selektor lebih spesifik agar
   ikon gear tetap di tengah tombol, bukan tersedot ke pojok kiri kotak Cari. */
.dt-search .dt-ikon-filter i,.dt-ikon-filter i{position:static;left:auto;color:inherit;font-size:13px;pointer-events:none}
.pkwt-backdrop{position:fixed;inset:0;background:rgba(15,23,42,.45);z-index:200;opacity:0;pointer-events:none;transition:opacity .2s}
.pkwt-backdrop.show{opacity:1;pointer-events:auto}
.pkwt-drawer{position:absolute;top:0;right:0;height:100%;width:min(420px,94vw);background:var(--surface);box-shadow:-8px 0 24px rgba(0,0,0,.18);display:flex;flex-direction:column;transform:translateX(100%);transition:transform .22s ease}
.pkwt-backdrop.show .pkwt-drawer{transform:none}
.pkwt-head{display:flex;align-items:flex-start;gap:10px;padding:15px 18px;border-bottom:1px solid var(--line)}
.pkwt-head h3{margin:0;font-size:15px}
.pkwt-head p{margin:2px 0 0;font-size:12px;color:var(--muted)}
.pkwt-head .x{margin-left:auto;background:none;border:0;cursor:pointer;color:var(--muted-2);font-size:16px}
.pkwt-body{flex:1;overflow:auto;padding:14px 18px;display:grid;gap:5px;align-content:start}
.pkwt-foot{display:flex;justify-content:flex-end;gap:8px;padding:12px 18px;border-top:1px solid var(--line)}
.pkwt-foot .btn:disabled{opacity:.5;cursor:not-allowed;box-shadow:none}
.pkwt-badge{font-size:11px;color:var(--primary);font-weight:600}
/* Drawer Klien Jabatan: tab Klien | Relasi Karyawan */
.jbk-tabs{display:flex;gap:4px;padding:8px 18px 0;border-bottom:1px solid var(--line)}
.jbk-tab{display:inline-flex;align-items:center;gap:6px;padding:8px 12px;font-size:13px;font-weight:600;color:var(--muted);border:1px solid transparent;border-bottom:none;border-radius:9px 9px 0 0;background:transparent;cursor:pointer;margin-bottom:-1px}
.jbk-tab:hover{color:var(--ink);background:var(--surface-2)}
.jbk-tab.on{color:var(--primary);background:var(--surface);border-color:var(--line);border-bottom-color:var(--surface)}
.jbk-pane{display:grid;gap:5px;align-content:start}
.jbk-kry-cari{margin-bottom:6px}
/* 2 kolom: satu baris = 2 karyawan. Tiap kartu menumpuk nama + cabang supaya
   tetap terbaca di lebar separuh drawer. */
.jbk-kry-list{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:6px}
.jbk-kry{display:flex;flex-direction:column;align-items:flex-start;gap:2px;min-width:0;padding:8px 10px;border:1px solid var(--line);border-radius:10px;background:var(--surface)}
.jbk-kry-nama{max-width:100%;font-weight:600;font-size:12.5px;color:var(--ink);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.jbk-kry-cab{max-width:100%;display:inline-flex;align-items:center;gap:5px;font-size:11px;color:var(--muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.jbk-kry-cab i{font-size:10px;opacity:.7;flex:0 0 auto}
/* Drawer sempit (ponsel) → kembali satu kolom biar nama tak terlalu terpotong. */
@media (max-width:430px){ .jbk-kry-list{grid-template-columns:1fr} }
/* Mode "hanya karyawan" (dibuka dari kolom Karyawan tabel Jabatan). */
.jbk-only .jbk-tabs{display:none}
/* Chip jumlah karyawan di kolom "Karyawan" tabel Jabatan — bisa diklik. */
.jb-kry-ct{display:inline-flex;align-items:center;justify-content:center;min-width:30px;padding:2px 9px;border-radius:999px;font-weight:700;font-size:12px;color:var(--primary);background:var(--primary-tint);border:1px solid transparent;cursor:pointer}
.jb-kry-ct:hover{border-color:var(--primary)}
.jb-kry-ct:focus-visible{outline:2px solid var(--primary);outline-offset:1px}
.pkwt-chips{display:flex;flex-wrap:wrap;gap:5px;margin:2px 0 4px;max-height:84px;overflow:auto}
.pkwt-chip{display:inline-flex;align-items:center;gap:4px;background:var(--primary-tint);color:var(--primary);border-radius:999px;padding:2px 5px 2px 9px;font-size:12px}
.pkwt-chip button{background:none;border:0;cursor:pointer;color:inherit;font-size:14px;line-height:1}
.pkwt-kosong{font-size:12px;color:var(--muted)}
/* Kartu peringatan kontrak di Home + baris dialog notifikasi. */
.kontrak-habis-kartu{display:flex;align-items:center;gap:12px;width:100%;text-align:left;cursor:pointer;
  background:#FEF3C7;border:1px solid #FCD9A0;color:#92610A;border-radius:12px;padding:12px 16px;margin-bottom:14px;font-family:inherit}
.kontrak-habis-kartu:hover{filter:brightness(.98)}
.khk-ic{display:grid;place-items:center;width:36px;height:36px;border-radius:10px;background:#F59E0B;color:#fff;font-size:15px;flex:none}
.khk-teks{display:flex;flex-direction:column;gap:1px;flex:1}
.khk-teks b{font-size:14px}.khk-teks small{font-size:12px;opacity:.85}
.khk-arrow{color:#B45309}
:root:not([data-theme="light"]) .kontrak-habis-kartu,:root[data-theme="dark"] .kontrak-habis-kartu{
  color:#FBBF24;background:rgba(180,83,9,.18);border-color:rgba(251,191,36,.35)}
/* Home "Perlu Tindakan": dua kartu-TOMBOL sejajar (diklik utuh → dialog
   daftar), gaya kartu dasbor (permukaan, garis, bayangan 3D) + garis aksen
   tipis di kiri. auto-fit: satu kartu saja → melebar penuh; layar sempit →
   bertumpuk. */
.tindakan-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(280px,100%),1fr));gap:12px;margin-bottom:18px}
.tindakan{display:flex;align-items:center;gap:12px;width:100%;min-width:0;text-align:left;cursor:pointer;font:inherit;
  background:var(--surface);color:var(--ink);border:1px solid var(--line-3d);border-left:4px solid var(--warn);
  border-radius:var(--r-card);box-shadow:var(--shadow-3d);padding:12px 16px;transition:transform .18s,box-shadow .18s}
.tindakan:hover{transform:translateY(-2px);box-shadow:var(--shadow-3d-naik)}
.tindakan-grid[hidden],.tindakan[hidden]{display:none}
.tindakan-merah{border-left-color:var(--danger)}
.tindakan .ic{width:36px;height:36px;border-radius:11px;display:grid;place-items:center;font-size:15px;flex:none}
.tdk-judul{display:flex;flex-direction:column;flex:1;min-width:0}
.tdk-judul b{font-size:14px;color:var(--ink);line-height:1.3}
.tdk-judul small{font-size:11.5px;color:var(--muted)}
/* Kartu tanpa subjudul (16 Okt, permintaan user); judul tetap SATU baris —
   kepanjangan dipotong "…" (teks lengkap di title kartu). */
.tdk-judul b,.tdk-judul small{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.tdk-n{font-size:22px;font-weight:800;letter-spacing:-.5px;line-height:1;color:var(--ink);
  display:inline-block;font-variant-numeric:tabular-nums}
/* Angka kartu berubah: naik = muncul dari bawah & membesar sesaat; turun = dari atas
   & mengecil sesaat (angkanya sendiri bergulir lewat angkaKartu di app.js). */
.tdk-n.naik{animation:tdkNaik .6s cubic-bezier(.2,.8,.3,1)}
.tdk-n.turun{animation:tdkTurun .6s cubic-bezier(.2,.8,.3,1)}
@keyframes tdkNaik{0%{transform:translateY(8px) scale(1.18);opacity:.35}55%{transform:translateY(-2px) scale(1.1);opacity:1}100%{transform:none}}
@keyframes tdkTurun{0%{transform:translateY(-8px) scale(.86);opacity:.35}55%{transform:translateY(2px) scale(.96);opacity:1}100%{transform:none}}
@media (prefers-reduced-motion:reduce){ .tdk-n.naik,.tdk-n.turun{animation:none} }
.tindakan-merah .tdk-n{color:var(--danger)}
.tindakan-kuning .tdk-n{color:#B45309}
.tindakan-ungu{border-left-color:var(--violet)}
.tindakan-ungu .tdk-n{color:var(--violet)}
.tindakan-biru{border-left-color:var(--info)}
.tindakan-biru .tdk-n{color:var(--info)}
/* Baris daftar kontrak cabang (read-only): tanggal habis + sisa hari. */
.pkwt-notif-tgl.info{color:var(--info)}
.pkwt-notif-tgl.pb{color:var(--violet)}
/* "Berjalan" = perbantuan tanpa Tanggal Selesai (daftar kartu & dialog Tetapkan Bonus). */
.pkwt-notif-tgl.pb .pb-jalan,.rp-kb-form .pb-jalan{color:var(--success);font-weight:600}
/* Tahap kedua perbantuan: tombol hijau "Tetapkan Bonus" (khusus HRD); pb-tunggu =
   tombol mati "Menunggu atasan" bagi yang bukan atasan karyawan itu. */
.pkwt-notif-btn.pb-bonus{background:var(--success);color:#fff;border:0}
.pkwt-notif-btn.pb-tunggu{background:var(--surface-2);color:var(--muted);border:1px dashed var(--line);cursor:default}
.tdk-panah{color:var(--muted-2);font-size:13px}
.pkwt-notif{display:grid;gap:4px}
/* Kotak cari dialog daftar — menempel di atas saat daftarnya digulir. */
/* top & margin = -padding atas .modal-body (22px; 16px di layar sempit) supaya
   menempel rapat di tepi atas isi dialog. */
.dd-cari{position:sticky;top:-22px;z-index:2;display:flex;align-items:center;gap:8px;margin:-22px -24px 8px;
  padding:16px 24px 12px;background:var(--surface);box-shadow:0 1px 0 var(--line)}
.dd-cari i{color:var(--muted);font-size:13px;position:absolute;left:36px;pointer-events:none}
.dd-cari input{flex:1;min-width:0;padding:8px 11px 8px 32px;border:1px solid var(--line);border-radius:var(--r-input);
  font:inherit;font-size:12.5px;color:var(--ink);background:var(--surface-2)}
.dd-cari input:focus{outline:none;border-color:var(--primary);background:#fff;box-shadow:0 0 0 4px var(--primary-tint)}
.dd-info{margin-right:auto;align-self:center;font-size:12px;font-weight:600;color:var(--muted)}
@media (max-width:640px){ .dd-cari{top:-16px;margin:-16px -16px 8px;padding:12px 16px 10px} .dd-cari i{left:28px} }
/* Tombol X: kotak kecil, ikon tepat di tengah. */
.pkwt-notif-btn.pkwt-x{width:28px;height:28px;padding:0;display:inline-flex;align-items:center;justify-content:center;
  font-size:11px;align-self:center}
/* Di HP tombol baris dibuat sama lebar (flex:1) — X tetap tombol ikon kecil. */
.pkwt-notif-aksi .pkwt-notif-btn.pkwt-x{flex:0 0 32px;width:32px;height:auto;min-height:28px}
.pkwt-notif-h{margin:10px 0 4px;font-size:11px;text-transform:uppercase;letter-spacing:.04em;color:var(--muted)}
.pkwt-notif-h:first-child{margin-top:0}
.pkwt-notif-row{display:flex;align-items:center;gap:10px;padding:8px 2px;border-bottom:1px solid var(--line)}
.pkwt-notif-nama{flex:1;display:flex;flex-direction:column;min-width:0}
.pkwt-notif-nama small{color:var(--muted);font-size:11px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.pkwt-notif-tgl{display:flex;flex-direction:column;align-items:flex-end;font-size:12.5px;white-space:nowrap}
.pkwt-notif-tgl small{font-size:11px}
.pkwt-notif-tgl.warn{color:#B45309}.pkwt-notif-tgl.bad{color:var(--danger)}
.pkwt-notif-btn{padding:5px 10px;font-size:12px}
/* Kolom Perpanjang: dua pilihan (1 Tahun / 6 Bulan) berdampingan. */
.pkwt-notif-aksi{display:flex;gap:6px;flex:none}
@media (max-width:480px){ .pkwt-notif-row{flex-wrap:wrap} .pkwt-notif-aksi{width:100%} .pkwt-notif-aksi .pkwt-notif-btn{flex:1} }
.pkwt-notif-kosong{font-size:13px;color:var(--muted)}
.pkwt-all{display:flex;align-items:center;gap:8px;font-size:12.5px;background:var(--surface-2);border:1px solid var(--line);border-radius:8px;padding:8px 10px;cursor:pointer;margin:2px 0}
.pkwt-all input{margin:0}
.pkwt-all b{margin-left:auto;color:var(--primary)}
/* Baris kepala drawer Cabang Klien: label kiri + "Pilih semua" kanan. */
.klc-head-row{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:2px}
.klc-all{margin:0;white-space:nowrap}
.pkwt-list{border:1px solid var(--line);border-radius:8px;max-height:44vh;overflow:auto;background:var(--surface-2);margin-bottom:4px}
.pkwt-item{display:flex;gap:8px;align-items:flex-start;padding:7px 10px;border-bottom:1px solid var(--line);cursor:pointer;font-size:12.5px}
.pkwt-item:last-child{border-bottom:0}
.pkwt-item input{margin-top:2px}
.pkwt-item-off{opacity:.55;cursor:not-allowed}
.pkwt-item-off input{cursor:not-allowed}
.pkwt-sudah{color:var(--primary);font-style:normal}
.pkwt-item span{display:flex;flex-direction:column;min-width:0}
.pkwt-item small{color:var(--muted);font-size:11px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.pkwt-more{padding:8px 10px;font-size:11.5px;color:var(--muted);text-align:center}
/* Longitude & latitude berpasangan: ditaruh sebaris supaya terbaca sebagai satu
   koordinat, bukan dua isian yang tak berhubungan. */
.kl-duo{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}
/* Satu sel disembunyikan (mis. Status saat Tambah) → sel tersisa penuh satu baris. */
.kl-duo.kl-duo-solo{grid-template-columns:minmax(0,1fr)}
@media (max-width:480px){ .kl-duo{grid-template-columns:minmax(0,1fr);gap:0} }
/* --- Halaman formulir Jadwal Absen --- */
/* Lebarnya ditentukan ISINYA, bukan layar. Yang paling lebar sekarang tabel per
   hari: 34 (centang) + 80 (nama hari) + 4 x 150 (isian jam) + 6 x 20 (padding
   sel) = 834px, jadi isi kartu dibuat pas menampungnya — 880 dikurangi padding
   20px kiri-kanan dan garis tepinya. Lebih sempit dari itu, kolom Penyesuaian
   terpotong; lebih lebar, mata melompat jauh dari label ke isian yang cuma
   butuh diisi "08:00". */
/* Halaman ini memakai pola yang sama dengan halaman datatable: mengisi tinggi
   .content, lalu yang menggulir bagian dalamnya — bukan seluruh halaman. Dengan
   begitu baris tombol tetap di layar berapa pun panjang isinya. */
#page-jadwal-form.active{display:flex;flex-direction:column;height:100%;min-height:0}

/* Dua lajur: formulir di kiri, pemilih Jabatan & User di kanan.
   Yang menggulir adalah BAGIAN DALAM tiap kartu, bukan lajurnya: kartu isian
   utama harus tetap terlihat sementara tabel tujuh hari digulir, dan tombol
   pemilih harus tetap di tempatnya sementara daftar terpilih digulir.
   overflow-y pada lajur hanya jaring pengaman untuk layar yang sangat pendek —
   dalam keadaan normal tidak ada yang meluber, jadi bilah gulirnya tidak muncul. */
/* Lajur kiri MENGISI ruang yang ada — tanpa batas piksel — sehingga menutup
   sidebar benar-benar melebarkan formulirnya, bukan menyisakan ruang kosong.
   Lajur kanan tumbuh seperlunya lalu berhenti: daftar cip tidak menjadi lebih
   terbaca hanya karena lebih lebar. */
.jf{display:grid;grid-template-columns:minmax(0,1fr) clamp(240px,23%,340px);
    grid-template-rows:minmax(0,1fr) auto;
    gap:0 18px;flex:1;min-height:0}
.jf-lajur{display:flex;flex-direction:column;gap:18px;
          min-height:0;overflow-y:auto;overscroll-behavior:contain;padding-right:2px}
.jf-kiri-lajur{grid-column:1;grid-row:1}
.jf-kanan-lajur{grid-column:2;grid-row:1}
.jf-bawah{grid-column:1/-1;grid-row:2;padding-top:12px}
/* Jarak antar-kartu diurus gap lajurnya. */
.jf-lajur .jf-kartu{margin-bottom:0}

/* Kiri — kartu isian utama TIDAK ikut menggulir dan tidak menyusut; sisa tinggi
   diberikan kepada kartu tabel hari, dan yang bergerak hanya isi tabelnya. */
.jf-kiri-lajur .jf-kartu-utama{flex:none}
.jf-kiri-lajur .jf-kartu-hari{flex:1 1 auto;min-height:170px;display:flex;flex-direction:column}
.jf-kiri-lajur .jf-kartu-hari>.card-body{flex:1;min-height:0;display:flex;flex-direction:column}
/* max-height bawaan .table-scroll dihitung untuk datatable (jumlah baris x tinggi
   baris); di sini tingginya datang dari kartunya, jadi batas itu dilepas. */
.jf-kiri-lajur .table-scroll{flex:1;min-height:0;max-height:none;overflow:auto;overscroll-behavior:contain}

/* Kanan — kini SATU kartu yang mengisi seluruh tinggi lajur (dulu dua kartu
   berbagi rata, dan masing-masing hanya kebagian setengah).
   Yang menggulir HANYA .pk-isi; tombol pemilih tetap di tempatnya, dan panel
   dropdown-nya tidak terpotong karena berada di LUAR wadah yang menggulir itu. */
.jf-kanan-lajur .jf-kartu{flex:1 1 auto;min-height:150px;display:flex;flex-direction:column}
.jf-kanan-lajur .card-body{flex:1;min-height:0;display:flex;flex-direction:column}
.jf-kanan-lajur .pk-isi{flex:1;min-height:0;overflow-y:auto;overscroll-behavior:contain;
                        margin-top:9px;padding-right:2px}
/* Tabbar menggantikan judul kartu, jadi padding tegaknya dilepas — garis bawah
   tabbar sendiri yang menjadi pemisah dengan isinya. */
.jf-tabhead{padding:0 12px;display:block}
.jf-tabhead .tabbar{border-bottom:0;margin-bottom:-1px}
.jf-tabhead .tabbtn{padding:9px 11px;font-size:12px}
.jt-pane{display:none;flex:1;min-height:0;flex-direction:column}
.jt-pane.show{display:flex}
/* Di dalam .pk-isi tidak boleh ada gulir kedua: bilah gulir bersarang membuat
   orang harus menebak yang mana yang sedang digerakkan. */
.jf-kanan-lajur .pk-terpilih{margin-top:0;max-height:none;overflow:visible}

/* --- Tabel kecil pemakai (tab Divisi / Jabatan / User) ---
   Bukan datatable penuh: tanpa pencarian, paging, dan pengurutan. Isinya
   laporan keadaan di lajur selebar ~340px, dan tiga baris kendali di atas tiap
   tabel akan memakan ruang yang justru dibutuhkan barisnya. */
.jf-tabel{margin-top:10px}
.jf-mini{width:100%;border-collapse:collapse;font-size:11.5px}
.jf-mini th{
  position:sticky;top:0;z-index:1;background:var(--surface);
  text-align:left;font-size:10px;font-weight:800;letter-spacing:.03em;text-transform:uppercase;
  color:var(--muted);padding:6px 7px;border-bottom:1px solid var(--line);white-space:nowrap;
}
.jf-mini td{padding:5px 7px;border-bottom:1px solid var(--line-2,rgba(15,23,42,.06));vertical-align:top}
.jf-mini tbody tr:hover{background:var(--surface-2)}
.jf-mini .dt-no{width:1%;color:var(--muted);text-align:right;padding-right:9px;white-space:nowrap}
.jf-mini .dt-num{text-align:right;font-variant-numeric:tabular-nums;white-space:nowrap}
.jf-mini .mono{font-size:11px;color:var(--muted)}
.jf-mini-kaki,.jf-mini-kosong{margin:8px 0 0;font-size:11px;color:var(--muted);line-height:1.5}
/* Pilihan yang tidak bisa diubah (tab Divisi): tetap terbaca, tapi tidak
   berpura-pura bisa ditekan. */
.pk-opsi.mati{cursor:default;opacity:.85}
.pk-opsi.mati input{cursor:default}

/* Ambangnya diukur dari RUANG ISI, bukan lebar layar — layar 1366px dengan
   sidebar terbuka hanya menyisakan ~1050px, dan itulah angka yang menentukan
   apakah dua lajur masih muat. */
@container isi (max-width:1000px){
  #page-jadwal-form.active{display:block;height:auto}
  .jf{display:block;max-width:none}
  .jf-lajur{display:block;overflow:visible}
  .jf-lajur .jf-kartu{margin-bottom:18px}
  .jf-kiri-lajur .jf-kartu-hari{min-height:0;display:block}
  .jf-kiri-lajur .jf-kartu-hari>.card-body{display:block}
  .jf-kiri-lajur .table-scroll{max-height:60vh}
  .jf-kanan-lajur .jf-kartu,.jf-kanan-lajur .card-body{display:block}
  /* Menumpuk: tidak ada lagi tinggi lajur yang bisa dibagi, jadi batasnya
     dikembalikan ke .pk-isi agar kartunya tidak memanjang tanpa ujung. */
  .jf-kanan-lajur .pk-isi{max-height:46vh;overflow-y:auto}
  .jf-kanan-lajur .pk-terpilih{display:grid}
  .jt-pane{display:none}
  .jt-pane.show{display:block}
}
.jf-kartu{margin-bottom:18px}
/* Judul kartu di formulir ini hanya satu baris teks — padding 18px bawaan
   .card-head menyisakan pita kosong setinggi dua kali tulisannya. */
.jf .card-head{padding:11px 20px}
.jf .card-body{padding:18px 20px}
/* Ukuran kecil khusus formulir ini — .kl-input global tetap seperti semula agar
   modal Klien, Divisi, dan Jabatan tidak ikut mengecil tanpa diminta. */
.jf .kl-input{font-size:12px;padding:6px 9px;margin-bottom:5px}
.jf select.kl-input{padding-right:6px}
/* Zone & Shift: <select> dibungkus jadikanCari (.cari-sel, default inline-flex &
   sempit) → tampil SEBARIS dgn label & beda sendiri. Samakan dgn .kl-input tetangga:
   label di atas, tombol selebar penuh. */
.jf-baris1 .note-label{display:block}
.jf-baris1 .cari-sel{display:flex;width:100%;margin-bottom:5px}
.jf-baris1 .cari-tombol{width:100%;max-width:none;box-sizing:border-box;
  background:var(--surface-2);border:1px solid var(--line);border-radius:var(--r-input);
  padding:6px 9px;font-size:12px;color:var(--ink)}
.jf-baris1 .cari-sel.buka .cari-tombol,.jf-baris1 .cari-tombol:focus-visible{border-color:var(--primary);box-shadow:0 0 0 3px var(--primary-tint);outline:none}
/* Kiri: Nama + Zone bertumpuk, selebar secukupnya untuk nama jadwal terpanjang
   di data (37 karakter). Kanan: Notes setinggi keduanya, mengisi sisa kartu. */
.jf-atas{display:grid;grid-template-columns:290px minmax(0,1fr);gap:14px;align-items:stretch}
@container isi (max-width:640px){ .jf-atas{grid-template-columns:minmax(0,1fr)} }
/* Baris atas tunggal: Jadwal Name + Zone + 4 isian waktu sejajar. Nama sedikit
   lebih lebar. Menyempit bertahap di kartu yang mengecil. */
.jf-baris1{display:grid;grid-template-columns:minmax(0,1.5fr) repeat(6,minmax(0,1fr));gap:12px;align-items:start}
@container isi (max-width:900px){ .jf-baris1{grid-template-columns:repeat(3,minmax(0,1fr))} }
@container isi (max-width:560px){ .jf-baris1{grid-template-columns:repeat(2,minmax(0,1fr))} }
.jf-notes-baris{margin-top:12px}
.jf-notes-baris .jf-notes{width:100%;min-height:60px}
/* Notes + kelompok radio "absen lewat 00:00" satu baris. */
/* Satu baris: Notes · izin absen lewat jam 00:00 · Status (kolom auto → menciut
   saat Status disembunyikan di mode Tambah). */
.jf-baris2{display:grid;grid-template-columns:minmax(0,1.6fr) minmax(0,1fr) auto;gap:16px;align-items:start;margin-top:12px}
@container isi (max-width:720px){ .jf-baris2{grid-template-columns:minmax(0,1fr)} }
.jf-baris2 .jf-notes-baris{margin-top:0}
.jf-status-baris{min-width:150px}
.jf-status-baris .kl-input{margin-bottom:0}
.jf-baris2 .jf-radio{flex-direction:column;align-items:flex-start;gap:9px;margin:0}
/* Kolom kanan dijadikan flex agar textarea-nya memanjang mengisi sisa tinggi
   yang ditinggalkan labelnya — bukan dipatok tinggi tetap yang akan meleset
   begitu tinggi isian di kiri berubah. */
.jf-kanan{display:flex;flex-direction:column}
.jf-notes{flex:1;min-height:92px;resize:vertical;line-height:1.5;font-family:inherit}
/* Isian terakhir di kolom kiri tidak perlu jarak bawah: jaraknya sudah diurus
   gap kisi di atasnya. */
.jf-kiri .kl-input:last-child{margin-bottom:0}

/* Lebar isian jam dipatok 150px — cukup untuk bentuk terpanjang yang digambar
   peramban ('01:50:22 PM' beserta ikon jamnya), dan tidak lebih. auto-fit
   membuatnya membungkus sendiri saat kartunya menyempit, jadi tidak perlu
   satu pun media query untuk baris ini.
   Keterangan di bawah Penyesuaian Waktu bisa memanjangkan satu sel, jadi
   align-items:start menjaga keempat isian tetap sejajar di atas. */
.jf-jam{display:grid;grid-template-columns:repeat(auto-fit,150px);gap:14px;
        margin-top:4px;align-items:start;justify-content:start}
.jf-bantu{display:block;margin:-2px 0 6px;color:var(--muted);font-size:11.5px}
/* Pertanyaan dan kedua pilihannya satu baris. Jarak antar-kolom (22px) dibuat
   jauh lebih lebar dari jarak antar-baris (8px) supaya saat membungkus di layar
   sempit, yang turun tetap terbaca sebagai satu kelompok. */
.jf-radio{display:flex;align-items:center;flex-wrap:wrap;gap:8px 22px;border:0;margin:14px 0 2px;padding:0}
.jf-radio .note-label{margin:0;white-space:nowrap}
.jf-radio label{display:inline-flex;align-items:center;gap:8px;font-size:13px;color:var(--ink);margin:0;cursor:pointer;white-space:nowrap}
.jf-radio input{accent-color:var(--primary);cursor:pointer;flex:none}
/* Tabelnya selebar isinya saja; sisa kartu dibiarkan kosong daripada
   merentangkan dua kolom jam sampai berjauhan dari nama harinya. */
.jf-hari{width:auto;border-collapse:collapse}
/* Padding sel 10px, bukan 12px: enam sel berarti setiap 2px tambahan menambah
   24px lebar tabel. */
.jf-hari th,.jf-hari td{padding:6px 10px;border-bottom:1px solid var(--line);text-align:left;vertical-align:middle}
.jf-hari th{
  font-size:11.5px;letter-spacing:.04em;text-transform:uppercase;color:var(--muted);
  background:var(--surface-2);
  /* Kepala tabel tetap terlihat saat tujuh barisnya digulir — perilaku yang
     sudah dimiliki seluruh datatable, dan satu-satunya tabel yang belum.
     Latar WAJIB legap: sel sticky yang tembus pandang akan menumpuk dengan
     baris yang lewat di belakangnya.
     Garis bawahnya dipasang lewat box-shadow, bukan border: dengan
     border-collapse, garis pada sel sticky ikut tergulir dan meninggalkan
     tepi yang bergerak sendiri. */
  position:sticky;top:0;z-index:2;
  border-bottom-color:transparent;
  box-shadow:inset 0 -1px 0 var(--line);
}
/* Kolom ditandai KELAS, bukan posisi. Aturan lama memakai td:first-child untuk
   kolom Hari — begitu kolom centang disisipkan di depannya, aturan itu menyasar
   sel yang salah dan kotak centang mendapat lebar 110px. */
.jf-hari .jf-hr{width:80px;white-space:nowrap;color:var(--muted)}
/* Isian jam per hari tidak perlu selebar kolomnya — ukurannya sama dengan
   saudaranya di baris jam di atas, supaya keduanya terbaca sebagai hal sejenis. */
.jf-hari .kl-input{margin-bottom:0;width:150px}
.jf-hari .jf-cek{width:34px;text-align:center;padding-right:0}
.jf-hari input[type="checkbox"]{width:15px;height:15px;accent-color:var(--primary);cursor:pointer;margin:0}
/* Baris yang belum dicentang diredupkan seluruhnya, bukan hanya isiannya:
   kotak centang tetap penuh warna supaya jelas di situlah satu-satunya yang
   bisa ditekan. */
.jf-hari tr[data-mati] td:not(.jf-cek){opacity:.45}
.jf-hari .kl-input:disabled{cursor:not-allowed}
.jf-aksi{display:flex;gap:10px;justify-content:flex-end;flex-wrap:wrap}

/* --- Halaman formulir Karyawan --- */
/* Berlaku untuk SETIAP halaman yang isinya formulir .kf — bukan dikunci ke satu
   id halaman. Aturan lama hanya menyebut #page-karyawan-form, sehingga halaman
   Rekrutmen yang memakai struktur sama tidak kebagian: seluruh halamannya ikut
   menggulir dan baris tombol terdorong keluar layar.
   Pola :has() sama dengan yang dipakai halaman datatable di berkas ini. */
.page.active:has(> .kf){display:flex;flex-direction:column;height:100%;min-height:0}
/* Tanpa batas lebar: kartunya mengisi ruang yang ada, dan menutup sidebar
   benar-benar melebarkannya. */
.kf{display:flex;flex-direction:column;flex:1;min-height:0}
/* Satu lajur yang menggulir, tombol di luarnya — dua puluh isian tidak akan
   muat di layar mana pun, jadi yang dijaga adalah tombolnya tetap terlihat. */
.kf-lajur{flex:1;min-height:0;overflow-y:auto;overscroll-behavior:contain;padding-right:2px}
.kf-kartu{margin-bottom:0}
.kf .card-body{padding:18px 20px}
.kf-bawah{padding-top:12px}
/* Judul bagian menggantikan lima kepala kartu. Garis di atasnya yang memisahkan
   kelompok, bukan jarak antar-kartu — satu bidang, lima bagian. */
.kf-judul{
  font-size:12px;font-weight:800;letter-spacing:.04em;text-transform:uppercase;
  color:var(--muted);margin:22px 0 12px;padding-top:16px;border-top:1px solid var(--line);
  display:flex;align-items:baseline;gap:10px;flex-wrap:wrap;
}
/* Header Perpindahan + checkbox Demosi (Jabatan/Gaji) sejajar, checkbox di kanan. */
.rpf-kepala{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap}
.rpf-kepala .kf-judul{margin-bottom:0;flex:0 1 auto}
.rpf-demosi-cek{display:inline-flex;gap:16px;align-items:center;border:1px solid var(--line);
  border-radius:9px;padding:7px 15px;background:var(--surface-2)}
.rpf-cek{display:inline-flex;align-items:center;gap:6px;font-size:13px;font-weight:600;
  color:var(--ink);cursor:pointer;user-select:none}
.rpf-cek input{width:16px;height:16px;cursor:pointer;accent-color:var(--primary)}
/* Bagian yang tak dicentang diredupkan (input juga di-disable di JS). */
.rpf-nonaktif,.rpf-gaji-mati{opacity:.5}
/* Yang pertama tidak perlu garis pemisah: tidak ada apa pun di atasnya. */
.kf-judul:first-child{margin-top:0;padding-top:0;border-top:0}
.kf-ket{font-size:11px;font-weight:600;letter-spacing:0;text-transform:none;color:var(--muted-2,var(--muted))}
.kf-ket:empty{display:none}
/* Isian dibatasi 200-280px, BUKAN 1fr: di kartu selebar layar, kolom yang ikut
   melar membuat isian "Nomor HP" jadi sepanjang setengah layar. Sisa ruangnya
   dibiarkan kosong di kanan — itu lebih mudah dibaca daripada isian selebar
   kalimat. */
.kf-kisi{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,280px));
         gap:12px 14px;justify-content:start;align-items:start}
.kf-kisi .kl-input{margin-bottom:0;font-size:12px;padding:6px 9px}
/* Tab Gaji: keenam isian dalam SATU baris (melebar mengisi lebar); menyempit per
   kolom sebelum akhirnya membungkus di layar sempit. */
.kf-kisi-gaji{grid-template-columns:repeat(6,minmax(0,1fr))}
@media (max-width:900px){.kf-kisi-gaji{grid-template-columns:repeat(3,minmax(0,1fr))}}
@media (max-width:560px){.kf-kisi-gaji{grid-template-columns:repeat(2,minmax(0,1fr))}}
/* Gaji di form Perpindahan: hanya 2 kolom (Gaji per Bulan + Gaji Harian). */
.kf-kisi-gaji2{grid-template-columns:repeat(2,minmax(0,1fr))}
@media (max-width:560px){.kf-kisi-gaji2{grid-template-columns:1fr}}
/* Gaji form Perpindahan dalam SATU baris: Saat ini (Bulan+Harian) + Baru (Bulan+Harian). */
.kf-kisi-gaji4{grid-template-columns:repeat(4,minmax(0,1fr))}
@media (max-width:900px){.kf-kisi-gaji4{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (max-width:560px){.kf-kisi-gaji4{grid-template-columns:1fr}}
.rpf-turunan{background:rgba(0,0,0,.04);color:var(--muted)}
/* Alamat & Catatan memakai TIGA kolom, bukan satu baris penuh: dengan begitu
   Alamat duduk di sisa baris Lokasi Kota alih-alih mendorong dirinya ke baris
   sendiri dan meninggalkan tiga kolom kosong di sebelahnya.
   'span 3' (bukan '2 / -1') dipilih supaya ia menempel pada isian sebelumnya di
   mana pun isian itu jatuh — kalau dipatok mulai kolom 2, ia akan meninggalkan
   lubang begitu jumlah kolomnya berubah. */
.kf-lebar{grid-column:span 3}
/* Di bawah ini kolomnya kurang dari tiga, dan 'span 3' akan MEMBUAT kolom
   tambahan yang merusak lebar seluruh kisi. Di sana ia kembali melintang
   penuh. */
@container isi (max-width:940px){ .kf-lebar{grid-column:1/-1} }
.kf-area{min-height:58px;resize:vertical;line-height:1.5;font-family:inherit}
/* Alamat di samping Lokasi Kota: lebar normal (sel grid), textarea ringkas. */
.kf-alamat .kf-area{min-height:38px}
/* Tab form Karyawan (Pengalaman & Kontak Darurat · Penempatan · Akun Pengguna). */
.kf-tabbar{display:flex;gap:4px;margin:18px 0 14px;border-bottom:2px solid var(--line);flex-wrap:wrap}
.kf-tab{appearance:none;border:none;background:transparent;font:inherit;font-size:13px;font-weight:700;
  color:var(--muted);cursor:pointer;padding:9px 14px;border-radius:9px 9px 0 0;position:relative;white-space:nowrap}
.kf-tab:hover{color:var(--ink);background:var(--surface-2,var(--bg))}
/* Tab dikunci saat EDIT (hanya tipe yang sedang disunting yang bisa diklik). */
.kf-tab:disabled{opacity:.4;cursor:not-allowed}
.kf-tab:disabled:hover{color:var(--muted);background:transparent}
.kf-tab.active{color:var(--primary)}
.kf-tab.active::after{content:'';position:absolute;left:0;right:0;bottom:-2px;height:2px;background:var(--primary);border-radius:2px}
.kf-pane[hidden]{display:none}
.kf-pane-note{margin:0 0 12px;font-size:12px;color:var(--muted);display:flex;align-items:center;gap:7px}
.kf-pane-note i{color:var(--primary)}
/* Rincian jadwal (baris penuh): chip hari di KIRI, informasi (ringkasan jam +
   keterangan hari libur) di KANAN. */
.kf-penuh{grid-column:1/-1}
.kf-span2{grid-column:span 2}
.kf-span3{grid-column:span 3}
/* Tab Penempatan: Divisi · Role · Jabatan · Cabang Utama · Tanggal Join · PKWT
   pada SATU baris (6 kolom); baris berikut Jadwal Absen + rincian jadwal (chip &
   jam) DI SAMPINGNYA. Turun bertahap pada layar sempit. */
/* Baris utama Penempatan SATU baris: field memuai mengisi lebar (flex), menyusut
   per-kolom lalu membungkus baru di layar sempit. Jumlah field berbeda (Status
   hanya saat Ubah) → flex lebih luwes dari grid kolom-tetap. */
.kf-penempatan{display:flex;flex-wrap:wrap}
.kf-penempatan>div{flex:1 1 150px;min-width:0}
@container isi (max-width:760px){ .kf-penempatan>div{flex:1 1 180px} }
@container isi (max-width:420px){ .kf-penempatan>div{flex:1 1 100%} }
/* Sub-tab DI DALAM tab Penempatan (Jadwal Absen · Klien · Cabang Akses). Lebih
   tipis dari tab utama agar hierarkinya jelas. */
.kf-subtabbar{display:flex;gap:4px;margin:2px 0 12px;border-bottom:1px solid var(--line);flex-wrap:wrap}
.kf-subtab{appearance:none;border:none;background:transparent;font:inherit;font-size:12px;font-weight:700;
  color:var(--muted);padding:7px 12px;cursor:pointer;position:relative;border-radius:8px 8px 0 0;
  display:inline-flex;align-items:center;gap:6px}
.kf-subtab:hover{color:var(--ink);background:var(--surface-2,var(--bg))}
.kf-subtab:disabled{opacity:.4;cursor:not-allowed}
.kf-subtab.active{color:var(--primary)}
.kf-subtab.active::after{content:'';position:absolute;left:0;right:0;bottom:-1px;height:2px;background:var(--primary);border-radius:2px}
.kf-subpane[hidden]{display:none}
/* Sub-pane Jadwal Absen: dropdown + rincian jadwal (chip & jam) di sampingnya. */
.kf-subpane[data-kfsubpane="jadwal"] .kf-kisi{grid-template-columns:repeat(6,minmax(0,1fr))}
.kf-subpane[data-kfsubpane="jadwal"] .kf-jd-samping{grid-column:span 5}
@container isi (max-width:780px){
  .kf-subpane[data-kfsubpane="jadwal"] .kf-kisi{grid-template-columns:repeat(2,minmax(0,1fr))}
  .kf-subpane[data-kfsubpane="jadwal"] .kf-jd-samping{grid-column:1/-1}
}
/* Klien: tombol tambah di atas + daftar klien terpilih (nama + Tipe WO per klien). */
.kf-klien-atas{max-width:360px;margin-bottom:12px}
.kf-klien-atas .pk-kf .pk-tombol{width:100%}
/* Daftar klien terpilih: kisi kartu (banyak klien tetap ringkas, tidak memanjang
   ke bawah). Tiap kartu = nama + dropdown Tipe WO sendiri + tombol lepas. */
.kf-klien-list{display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:8px 10px}
.kf-klien-kosong{grid-column:1/-1;color:var(--muted);font-size:12px;font-style:italic;margin:4px 0}
.kf-klien-row{display:grid;grid-template-columns:1fr auto;grid-template-areas:'nama x' 'tw tw';
  gap:6px 10px;align-items:center;padding:8px 10px;border:1px solid var(--line);
  border-radius:10px;background:var(--surface-2,var(--bg))}
.kf-klien-nama{grid-area:nama;font-size:12.5px;font-weight:600;color:var(--ink);min-width:0;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.kf-klien-tw{grid-area:tw;width:100%;margin-bottom:0;font-size:12px;padding:6px 9px}
.kf-klien-x{grid-area:x;appearance:none;border:none;background:transparent;color:var(--muted);cursor:pointer;
  padding:4px 7px;border-radius:6px;font-size:14px;line-height:1}
.kf-klien-x:hover{color:var(--danger,#dc2626);background:var(--surface-3,rgba(0,0,0,.05))}
.kf-lihat .kf-klien-x{display:none}
/* Form Perpindahan: baris utama dipaksa SATU baris sesuai jumlah isian per tipe
   (Demosi/Adjustment=4, Mutasi=5, Promosi=6); turun bertahap di layar sempit. */
.rpf-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}
.rpf-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}
.rpf-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}
.rpf-cols-6{grid-template-columns:repeat(6,minmax(0,1fr))}
@container isi (max-width:1180px){ .rpf-cols-3,.rpf-cols-4,.rpf-cols-5,.rpf-cols-6{grid-template-columns:repeat(3,minmax(0,1fr))} }
@container isi (max-width:720px){ .rpf-cols-3,.rpf-cols-4,.rpf-cols-5,.rpf-cols-6{grid-template-columns:repeat(2,minmax(0,1fr))} }
@container isi (max-width:480px){ .rpf-cols-3,.rpf-cols-4,.rpf-cols-5,.rpf-cols-6{grid-template-columns:minmax(0,1fr)} }
/* Keterangan (kiri, tak melebar penuh) + toggle Perbantuan Mutasi (kanan) sebaris.
   Saat toggle disembunyikan (tab non-Mutasi), Keterangan memuai mengisi barisnya. */
.rpf-ket-row{display:flex;gap:14px 18px;align-items:flex-start;flex-wrap:wrap;margin-top:4px}
.rpf-ket-kolom{flex:1 1 320px;min-width:240px;display:flex;flex-direction:column;gap:4px}
.rpf-ket-area{resize:vertical;min-height:58px;line-height:1.5;font-family:inherit;font-size:12px;padding:6px 9px}
.rpf-perb-kolom{flex:1 1 460px;min-width:280px}
.rpf-perb-isi{display:flex;flex-wrap:wrap;gap:12px 14px;align-items:flex-start}
.rpf-perb-isi>div{flex:1 1 150px;min-width:140px}
.rpf-perb-isi>div:first-child{flex:1 1 270px;min-width:270px}  /* sel Jenis: cukup utk 3 tombol */
.rpf-perb-isi .kf-gender-opt{white-space:nowrap}
.rpf-perb-isi .kl-input{font-size:12px;padding:6px 9px}
@container isi (max-width:720px){ .rpf-perb-kolom{flex-basis:100%} }
/* Cabang Akses: dropdown di KIRI, daftar cip terpilih DI SAMPING (bukan di bawah). */
.kf-ca-baris{display:flex;gap:12px;align-items:flex-start}
.kf-ca-baris>.pk{flex:0 0 300px;max-width:300px}
.kf-ca-baris>.pk-terpilih{flex:1 1 auto;margin-top:0;grid-template-columns:repeat(4,minmax(0,1fr));
  max-height:132px;align-content:start}
.kf-ca-baris>.pk-terpilih:empty{display:none}
@container isi (max-width:780px){
  .kf-ca-baris{flex-direction:column}
  .kf-ca-baris>.pk{flex:1 1 auto;max-width:none;width:100%}
  .kf-ca-baris>.pk-terpilih{width:100%;grid-template-columns:repeat(2,minmax(0,1fr))}
}
.kf-jd{padding:9px 12px;border:1px solid var(--line);border-radius:10px;background:var(--surface-2,var(--bg));
  display:flex;align-items:center;gap:14px;flex-wrap:wrap}
.kf-jd-hari{display:flex;gap:5px;flex-wrap:wrap}
/* Kelompok informasi di kanan (didorong oleh margin-left:auto). */
.kf-jd-info{margin-left:auto;display:flex;align-items:center;gap:8px 14px;flex-wrap:wrap;justify-content:flex-end}
.kf-jd-ringkas{display:inline-flex;align-items:center;gap:7px;font-size:12px;color:var(--ink);white-space:nowrap}
.kf-jd-ringkas i{color:var(--primary)}
.kf-jd-ringkas b{color:var(--primary);font-variant-numeric:tabular-nums}
.kf-jd-ringkas .rentang{font-weight:800;color:var(--ink)}
/* Keterangan hari libur (merah) di samping ringkasan. */
.kf-jd-libur{display:inline-flex;align-items:center;gap:6px;font-size:12px;font-weight:700;
  color:var(--danger,#dc2626);background:var(--danger-tint,#fde8e8);border:1px solid var(--danger,#dc2626);
  border-radius:8px;padding:4px 9px;white-space:nowrap}
/* Catatan hari yang jamnya beda dari dominan. */
.kf-jd-note{font-size:11.5px;color:var(--muted);display:inline-flex;gap:4px 12px;flex-wrap:wrap}
.kf-jd-note b{color:var(--ink);font-weight:600}
.kf-jd-chip{min-width:34px;text-align:center;padding:4px 7px;border-radius:7px;font-size:11px;font-weight:700;
  background:var(--surface,#fff);border:1px solid var(--line);color:var(--muted)}
.kf-jd-chip.on{background:var(--primary-tint);border-color:var(--primary);color:var(--primary)}
/* Hari kerja ditandai LIBUR khusus karyawan ini (override, merah). */
.kf-jd-chip.libur{background:var(--danger-tint,#fde8e8);border-color:var(--danger,#dc2626);color:var(--danger,#dc2626)}
.kf-jd-chip[data-d]{cursor:pointer;user-select:none}
.kf-jd-chip[data-d]:hover{filter:brightness(.97)}
.kf-jd-chip.mati{opacity:.5}  /* hari libur di master (di luar jadwal) */
.kf-lihat .kf-jd-chip[data-d]{cursor:default}
/* No KTP/KK + unggah pada SATU baris: input + ikon aksi. */
.kf-inline{display:flex;align-items:stretch;gap:6px}
.kf-inline .kl-input{flex:1 1 auto;min-width:0;margin-bottom:0}
/* Hint teks untuk unggah tanpa isian teks (mis. CV). */
.kf-berkas-hint{flex:1 1 auto;min-width:0;align-self:center;font-size:12px;color:var(--muted);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* RT / RW: dua isian kecil + pemisah "/". */
.kf-rtrw{align-items:center}
.kf-rtrw-sep{flex:none;color:var(--muted);font-weight:700}
/* Email Quantum: input NAMA + sufiks domain tetap. */
.kf-emailq{align-items:center}
.kf-suffix{flex:none;align-self:center;color:var(--muted);font-size:11px;white-space:nowrap}
/* Data Diri: 5 kolom supaya baris 1 (No KTP · No KK · Nama · Gender · Tgl Lahir)
   muat SATU baris; turun bertahap pada layar sempit. */
.kf-kisi-diri{grid-template-columns:repeat(5,minmax(0,1fr))}
@container isi (max-width:1180px){ .kf-kisi-diri{grid-template-columns:repeat(3,minmax(0,1fr))} }
@container isi (max-width:720px){ .kf-kisi-diri{grid-template-columns:repeat(2,minmax(0,1fr))} }
@container isi (max-width:480px){ .kf-kisi-diri{grid-template-columns:minmax(0,1fr)} }
/* Gender toggle (segmented dua-pilihan). */
.kf-gender{display:flex;border:1px solid var(--line);border-radius:var(--r-input);overflow:hidden;background:var(--surface-2)}
.kf-gender-opt{flex:1;appearance:none;border:none;background:transparent;font:inherit;font-size:12px;
  color:var(--muted);cursor:pointer;padding:6px 8px;display:flex;align-items:center;justify-content:center;gap:6px;white-space:nowrap}
.kf-gender-opt+.kf-gender-opt{border-left:1px solid var(--line)}
.kf-gender-opt i{font-size:12px;opacity:.85}
.kf-gender-opt.active{background:var(--primary);color:#fff}
.kf-gender-opt.active i{color:#fff;opacity:1}
.kf-gender-opt:disabled{cursor:default}
.kf-lihat .kf-gender-opt{cursor:default}
.kf-berkas-input{position:absolute;width:1px;height:1px;opacity:0;overflow:hidden;clip:rect(0 0 0 0)}
.kf-ic-btn{flex:0 0 auto;width:38px;display:inline-flex;align-items:center;justify-content:center;
  border-radius:var(--r-input,9px);border:1px solid var(--line);background:var(--surface,#fff);
  cursor:pointer;font-size:13px;color:var(--ink-soft,var(--muted));transition:.12s}
.kf-ic-up{color:var(--primary);border-color:var(--primary);background:var(--primary-tint)}
.kf-ic-up:hover{background:var(--primary);color:#fff}
.kf-ic-img{color:var(--primary);border-color:var(--primary)}
.kf-ic-img:hover{background:var(--primary-tint)}
.kf-ic-x{color:var(--danger,#dc2626);border-color:var(--danger,#dc2626)}
.kf-ic-x:hover{background:var(--danger-tint,#fde8e8)}
/* Mode LIHAT: sembunyikan unggah & hapus, sisakan ikon gambar (pratinjau). */
.kf-lihat .kf-ic-up,.kf-lihat .kf-ic-x{display:none}
.kf-berkas-input:disabled+.kf-ic-up{opacity:.5;cursor:not-allowed}
/* Status baca-NIK otomatis (OCR KTP di peramban) di bawah isian KTP. */
.kf-ocr{display:flex;align-items:center;gap:5px;margin-top:4px;font-size:11px;
  font-weight:600;line-height:1.3}
.kf-ocr i{font-size:11px}
.kf-ocr.is-proses{color:var(--muted)}
.kf-ocr.is-ok{color:var(--success,#16a34a)}
.kf-ocr.is-gagal{color:var(--warning,#d97706)}
.kf-ocr .fa-spin{animation:kf-spin .9s linear infinite}
@keyframes kf-spin{to{transform:rotate(360deg)}}
/* Tipe Rekrutmen di baris judul: didorong ke kanan supaya judul bagiannya tetap
   yang pertama terbaca, dan tingginya mengikuti judul agar barisnya tidak
   melar. */
.kf-tipe{display:inline-flex;gap:14px;align-items:center;align-self:center;
  margin-left:auto;flex-wrap:wrap}
.kf-tipe-opsi{display:inline-flex;gap:6px;align-items:center;cursor:pointer;
  font-size:12px;font-weight:600;color:var(--ink);text-transform:none;letter-spacing:0}
.kf-tipe-opsi input{accent-color:var(--primary);margin:0}
.kf-tipe-kosong{font-size:11px;font-weight:600;color:var(--muted);text-transform:none;letter-spacing:0}
/* Tombol kecil di samping label: mengatur daftar sebuah isian, bukan mengisinya. */
.kf-atur{
  margin-left:6px;width:20px;height:20px;padding:0;vertical-align:middle;
  display:inline-flex;align-items:center;justify-content:center;
  border:1px solid var(--line);border-radius:5px;background:var(--surface);
  color:var(--muted);cursor:pointer;font-size:9.5px;
}
.kf-atur:hover{color:var(--primary);border-color:var(--primary)}
.kf-atur:focus-visible{outline:2px solid var(--primary);outline-offset:1px}
/* Modal pengatur daftar Atasan. */
.at-bar{display:flex;gap:8px;align-items:center;margin-bottom:10px;flex-wrap:wrap}
.at-bar .kl-input{margin-bottom:0;flex:1 1 200px}
.at-daftar{max-height:46vh;overflow:auto;border:1px solid var(--line);border-radius:9px;padding:6px}
.at-opsi{display:flex;gap:8px;align-items:center;padding:5px 8px;border-radius:6px;
  font-size:12.5px;color:var(--ink);cursor:pointer}
.at-opsi:hover{background:var(--surface-2)}
.at-opsi input{accent-color:var(--primary);margin:0;flex:none}
.at-opsi span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.at-opsi b{margin-left:auto;font-size:10.5px;font-weight:700;color:var(--muted);flex:none}
.at-kosong{padding:14px;text-align:center;font-size:12px;color:var(--muted)}
/* Tabel Field Wajib: nama field + dua kolom centang (Request/Konfirmasi).
   Dibungkus .rw-scroll (satu-satunya area gulir) agar header lengket bekerja
   andal: border-collapse:separate wajib — dgn collapse, header lengket bocor
   di bawah baris pertama (bug lama tabel). */
.rw-scroll{max-height:52vh;overflow:auto;border:1px solid var(--line);border-radius:9px;
  -webkit-overflow-scrolling:touch}
.rw-tabel{width:100%;border-collapse:separate;border-spacing:0;font-size:12.5px}
.rw-tabel thead th{position:sticky;top:0;z-index:2;background:var(--surface-2);color:var(--muted);
  font-size:11px;font-weight:700;text-align:left;padding:8px;
  box-shadow:inset 0 -1px 0 var(--line)}
.rw-tabel th.rw-c{text-align:center;width:92px}
.rw-tabel tbody td{padding:7px 8px;border-bottom:1px solid var(--line);color:var(--ink)}
.rw-tabel tbody tr:last-child td{border-bottom:0}
.rw-tabel tbody td.rw-c{text-align:center}
.rw-tabel tbody tr:hover{background:var(--surface-2)}
.rw-tabel input[type="checkbox"]{accent-color:var(--primary);margin:0;cursor:pointer;width:16px;height:16px}
/* Baris kepala KELOMPOK (= tab form rekrutmen): latar tint, teks primary, ikon. */
.rw-tabel tbody tr.rw-grup td{background:var(--primary-tint);color:var(--primary);
  font-weight:800;font-size:11px;letter-spacing:.02em;text-transform:uppercase;padding:7px 8px}
.rw-tabel tbody tr.rw-grup:hover td.rw-grup-toggle{background:color-mix(in srgb,var(--primary) 16%,transparent)}
.rw-tabel tbody tr.rw-grup i{margin-right:7px;font-size:12px}
.rw-tabel tbody tr.rw-grup td.rw-c{text-transform:none}
/* Judul kelompok bisa diklik utk minimize/expand; chevron berputar saat ditutup. */
.rw-tabel tbody tr.rw-grup td.rw-grup-toggle{cursor:pointer;user-select:none}
.rw-tabel tbody tr.rw-grup td.rw-grup-toggle:focus-visible{outline:2px solid var(--primary);outline-offset:-2px}
.rw-tabel tbody tr.rw-grup .rw-chev{margin-right:6px;font-size:10px;transition:transform .15s;width:10px;display:inline-block;text-align:center}
.rw-tabel tbody tr.rw-grup.collapsed .rw-chev{transform:rotate(-90deg)}
.at-hitung{margin-right:auto;font-size:11.5px;color:var(--muted);font-variant-numeric:tabular-nums}
/* Formulir Rekrutmen: LIMA kolom, bukan lebar-otomatis.
 *
 * Tujuh kolom. "Data Calon" kini sebelas isian dan jatuh TEPAT dua baris:
 * tujuh di baris pertama (Cabang, Jabatan, Atasan, KTP, Nama, Kota, Tanggal
 * Lahir), lalu Pendidikan, HP, Email, dan Alamat selebar empat kolom di baris
 * kedua — 7 + 7 = 14 sel, tanpa sisa. "Pengalaman, Bank & Berkas" tujuh
 * isian, dan "Kontak Darurat & Catatan" dua isian + Remark selebar empat
 * kolom = enam sel; keduanya satu baris. Bagian "Berkas & Catatan" dibubarkan
 * karena kedua isinya pindah — judul tanpa isi hanya menambah garis pemisah
 * yang tidak menandai apa pun.
 *
 * Dibatasi ke #rekrutmenForm, bukan diubah pada .kf-kisi: kelas itu dipakai
 * juga oleh formulir Karyawan dan kartu Kalendar, yang jumlah isiannya lain
 * dan tidak diminta berubah. Seluruh bagian di formulir INI memakai lima kolom
 * yang sama supaya isiannya tetap segaris dari atas ke bawah.
 */
/* Form Rekrutmen kini MENGIKUTI tata letak form Karyawan persis: kartu Data Diri
   (.kf-kisi-diri, 5 kolom) + tab (.kf-tabbar) dengan pane Pengalaman/Penempatan
   (.kf-penempatan, 6 kolom)/Gaji/Akun. Jadi override 7-kolom lama DIHAPUS; kelas
   grid yang sama dengan Karyawan yang dipakai. */
/* Mode lihat: isian tetap terbaca jelas, hanya jelas-jelas tidak bisa disentuh.
   Diredupkan tipis saja — teks yang terlalu pudar justru menghalangi gunanya,
   yaitu dibaca. */
.kf-lihat .kl-input:disabled,
.kf-lihat .cari-tombol:disabled,
.kf-lihat .pk-tombol:disabled{opacity:.9;cursor:default;background:var(--surface-2)}
/* Tombol lepas pada cip tidak berlaku di sini; disembunyikan, bukan dibiarkan
   tampak bisa ditekan. */
.kf-lihat .pk-cip button{display:none}
.kf-lihat .pk-cip{padding-right:7px}
.rf-cv{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.rf-cv input[type="file"]{flex:1;min-width:0;font-size:11.5px;padding:5px 7px}
.rf-cv-ada{font-size:11.5px;color:var(--primary);font-weight:700;text-decoration:underline}
/* Ditandai warna peringatan: barisnya final tapi belum lengkap, dan itu perlu
   terlihat tanpa harus membaca satu per satu. */
.act .rk-lengkapi{color:var(--warning,#D97706)}
.rkf-sandi{display:flex;gap:8px;align-items:flex-start}
.rkf-sandi .kl-input{flex:1;min-width:0;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;
                     letter-spacing:.06em;font-size:14px}
.rkf-sandi .btn{flex:none}
/* Dialog Setujui Final: isian berpasangan dua kolom. Satu kolom di layar sempit. */
.rkf-kisi{display:grid;grid-template-columns:1fr 1fr;gap:12px;margin-bottom:12px}
.rkf-f{display:flex;flex-direction:column;gap:5px;min-width:0}
.rkf-f .kl-input,.rkf-f select.kl-input{width:100%}
@media (max-width:560px){.rkf-kisi{grid-template-columns:1fr}}
/* Kotak kredensial pada dialog hasil: sengaja berbeda dari teks biasa supaya
   yang harus disalin langsung terlihat. */
.rk-akun{display:grid;gap:6px;margin:8px 0 0;text-align:left}
.rk-akun div{display:flex;align-items:center;gap:8px;background:var(--surface-2);
             border:1px solid var(--line);border-radius:8px;padding:8px 10px}
.rk-akun b{font-size:11px;color:var(--muted);text-transform:uppercase;letter-spacing:.04em;min-width:78px}
.rk-akun .rk-sandi{flex:1}
.rk-mata{
  flex:none;width:26px;height:26px;display:grid;place-items:center;border:0;border-radius:6px;
  background:transparent;color:var(--muted);font-size:12px;cursor:pointer;
}
.rk-mata:hover{background:var(--primary-tint);color:var(--primary)}
.rk-akun span{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:14px;
              letter-spacing:.06em;color:var(--ink);word-break:break-all}
.rk-riwayat{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:7px;
            max-height:46vh;overflow:auto;text-align:left}
.rk-riwayat>li{flex:none;font-size:12px;line-height:1.5;padding:7px 9px;border-radius:7px;
               background:var(--surface-2);color:var(--ink)}
.rk-riwayat span{color:var(--muted);font-size:11px}
/* Ringkasan perubahan di atas daftar riwayat (Jabatan & Gaji per Bulan). */
.rk-rw-info{display:flex;flex-direction:column;gap:6px;margin:0 0 10px;padding:10px 12px;
            border-radius:9px;background:rgba(37,99,235,.07)}
.rk-rw-item{display:flex;flex-wrap:wrap;align-items:baseline;gap:4px 10px;font-size:12px;text-align:left}
.rk-rw-item>span{color:var(--muted);font-weight:600;min-width:96px}
.rk-rw-item>b{color:var(--ink);font-variant-numeric:tabular-nums}
/* "Jabatan/Gaji" (apa yang diubah) pada baris Jenis — diberi warna aksen. */
.rk-rw-ubah{color:var(--primary);font-weight:700}
.rk-rw-panah{font-size:10px;color:var(--muted);margin:0 2px}
.rk-rw-ikon{font-size:11px;color:var(--primary);margin-right:4px}
/* Modal persetujuan Cuti/Izin/Sakit — rincian rapi + daftar tanggal berhari. */
.aj-ap-nama{display:flex;align-items:center;gap:8px;padding:9px 12px;margin:0 0 10px;border-radius:9px;
  background:var(--primary-tint);font-size:13px}
.aj-ap-nama>i{color:var(--primary)}
.aj-ap-nama>span{color:var(--muted);font-weight:600}
.aj-ap-nama>b{color:var(--ink)}
.aj-ap-info{display:grid;grid-template-columns:1fr 1fr;gap:6px 14px;margin:0 0 10px}
.aj-ap-item{display:flex;flex-wrap:wrap;align-items:baseline;gap:3px 8px;font-size:12px}
.aj-ap-item>span{color:var(--muted);font-weight:600;min-width:118px}
.aj-ap-item>b{color:var(--ink)}
.aj-ap-hari{color:var(--primary)}
.aj-ap-jenis-sel{font:inherit;font-weight:600;padding:3px 7px;border:1px solid var(--line);border-radius:6px;
  background:var(--surface);color:var(--ink);max-width:180px;cursor:pointer}
.aj-ap-jenis-sel:focus{outline:none;border-color:var(--primary);box-shadow:0 0 0 3px var(--primary-tint)}
.aj-ap-tgl-lbl{font-size:12px;font-weight:600;color:var(--muted);margin:2px 0 5px}
/* Daftar tanggal DUA kolom (kiri-kanan). */
.aj-ap-tgl-list{list-style:none;margin:0 0 8px;padding:0;display:grid;grid-template-columns:1fr 1fr;gap:5px 8px;
  max-height:32vh;overflow:auto}
@media (max-width:480px){.aj-ap-tgl-list{grid-template-columns:1fr}}
.aj-ap-tgl-list>li{font-size:12.5px;padding:6px 10px;border-radius:7px;background:var(--surface-2);
  color:var(--ink);display:flex;align-items:baseline;gap:8px}
.aj-hr{min-width:58px;color:var(--primary);font-weight:600}
.aj-ap-akibat{font-size:12px;color:var(--muted);margin:0;line-height:1.5;flex:1 1 230px}
/* Baris bawah: teks akibat (kiri) + dropdown Ubah Jenis final (kanan). */
.aj-ap-foot{display:flex;flex-wrap:wrap;align-items:center;gap:10px 14px;justify-content:space-between;margin-top:4px}
.aj-ap-ubah{display:flex;flex-direction:column;gap:3px;flex:0 0 auto}
.aj-ap-ubah>span{font-size:11px;font-weight:600;color:var(--muted)}
@media (max-width:520px){.aj-ap-info{grid-template-columns:1fr}.aj-ap-ubah{flex-basis:100%}}
/* Kolom uang rata kanan dan bertabular: nominal yang tidak sejajar tidak bisa
   dibandingkan sekilas. */
.dt-rupiah{text-align:right;font-variant-numeric:tabular-nums;font-weight:600}
/* Kolom "tujuan" yang isinya sama dengan asalnya: ditandai, bukan diulang.
   Dua teks identik bersebelahan memaksa mata membandingkannya huruf per huruf
   hanya untuk menyimpulkan tidak ada yang berpindah. */
.dt-sama{color:var(--muted-2);font-weight:700}
/* Kotak sisa jatah cuti di formulir. Bukan hiasan: angkanya yang menentukan
   pengajuan diterima atau tidak, jadi ia harus terbaca sebelum Simpan ditekan
   — dan berubah warna begitu yang diajukan melampauinya. */
.ct-sisa{
  margin-top:12px;padding:9px 11px;border-radius:9px;
  background:var(--surface-2);border:1px solid var(--line);
  font-size:11.5px;line-height:1.6;color:var(--ink);
}
.ct-sisa b{font-size:13px;font-variant-numeric:tabular-nums}
.ct-sisa span{color:var(--muted)}
.ct-sisa.lebih{background:#FDECEA;border-color:rgba(192,57,43,.35);color:#7B241C}
/* Pemilih tanggal cuti multi-tanggal. */
.kl-bantu{margin-left:6px;font-weight:400;font-size:10.5px;color:var(--muted-2)}
/* Form cuti: baris atas 4 kolom (Karyawan, Cabang, Jenis, Tanggal). */
#cutiForm .kf-kisi{grid-template-columns:repeat(auto-fit,minmax(200px,1fr))}
#cutiForm .kf-lebar{grid-column:1/-1}
/* Surat Dokter (khusus SAKIT) di kolom kanan form pengajuan. */
.ctf-surat{margin-top:12px;display:flex;flex-direction:column;gap:4px}
/* Baris: KIRI kalender (8 kolom) · KANAN tanggal dipilih + keterangan (4 kolom). */
.ctf-dua{display:grid;grid-template-columns:8fr 4fr;gap:20px;margin-top:16px;align-items:start}
.ctf-dua-sel{min-width:0}
@container isi (max-width:820px){ .ctf-dua{grid-template-columns:minmax(0,1fr)} }
/* Kalender pemilih tanggal cuti — mengisi lebar kolomnya (8/12). */
/* Bingkai 3D: garis luar gelap + cincin putih di dalam (emboss) + bayang jatuh. */
.ctf-kal{border:1.5px solid rgba(15,23,42,.55);border-radius:12px;padding:11px 13px;background:var(--surface);margin-top:4px;
         box-shadow:inset 0 0 0 1.5px rgba(255,255,255,.9), 0 3px 6px rgba(15,23,42,.16), 0 16px 32px -12px rgba(15,23,42,.45)}
/* Terkunci sampai karyawan & jenis dipilih. */
.ctf-kal.nonaktif{opacity:.45;pointer-events:none;filter:grayscale(.25)}
/* Tombol aksi form (mis. Ajukan Cuti) saat terkunci. */
.jf-aksi .btn:disabled{opacity:.5;cursor:not-allowed;box-shadow:none}
#ctfKeterangan:disabled{background:var(--surface-2);cursor:not-allowed}
.ctf-kal-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:8px}
.ctf-kal-judul{font-weight:800;font-size:13px;color:var(--ink)}
.ctf-kal-nav{width:30px;height:30px;border-radius:8px;border:1px solid var(--line);background:var(--surface-2);
             color:var(--ink-soft);cursor:pointer;display:grid;place-items:center;font-size:12px}
.ctf-kal-nav:hover{background:var(--primary-tint);color:var(--primary)}
.ctf-kal-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:3px}
.ctf-kal-dow{text-align:center;font-size:10px;color:var(--muted);font-weight:700;padding:3px 0;text-transform:uppercase}
.ctf-kal-dow.mg{color:var(--danger)}
.ctf-kal-hari{height:42px;display:grid;place-items:center;border-radius:9px;font-size:13px;
              font-variant-numeric:tabular-nums;cursor:pointer;border:1px solid transparent;user-select:none}
.ctf-kal-hari:hover:not(.mati):not(.pilih){background:var(--surface-2)}
.ctf-kal-hari.ini{border-color:var(--primary)}            /* hari ini */
.ctf-kal-hari.pilih{background:#dc2626;color:#fff;font-weight:800;border-color:#dc2626}
.ctf-kal-hari.minggu{color:var(--danger)}
.ctf-kal-hari.mati{opacity:.32;cursor:not-allowed;pointer-events:none}
/* Tanggal yang sudah DISETUJUI: merah, terkunci, dengan label jenisnya. */
.ctf-kal-hari.terpakai{display:flex;flex-direction:column;align-items:center;justify-content:center;
  background:var(--danger-tint);border-color:var(--danger);color:var(--danger);
  cursor:not-allowed;gap:1px;padding:2px;overflow:hidden}
.ctf-kal-hari.terpakai:hover{background:var(--danger-tint)}
.ctf-kal-hari.terpakai .ctf-kal-num{font-weight:800;line-height:1;text-decoration:line-through}
.ctf-kal-hari.terpakai .ctf-kal-tag{font-size:8px;font-weight:700;line-height:1.05;text-align:center;
  max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-transform:uppercase;letter-spacing:.2px}
.ctf-kal-kosong{height:42px}
/* Judul "Tanggal dipilih" + total sebaris di atas chip (kolom kanan, paling atas). */
.ctf-tgl-kepala{display:flex;align-items:center;justify-content:space-between}
.ctf-tgl-chips{display:flex;flex-wrap:wrap;gap:6px;margin-top:6px;min-height:28px}
.ctf-tgl-chips:empty{display:block;color:var(--muted-2);font-size:11.5px}
.ctf-tgl-chips:empty::before{content:'Belum ada tanggal dipilih.'}
/* Keterangan di bawah daftar tanggal terpilih. */
.ctf-ket-label{display:block;margin-top:16px}
/* Toggle Paid/Unpaid: segmen dua tombol, default Unpaid terpilih. */
.ctf-bayar{margin-top:14px}
.ctf-bayar .note-label{display:block;margin-bottom:4px}
.ctf-seg{display:inline-flex;border:1px solid var(--line);border-radius:9px;overflow:hidden;background:var(--surface-2)}
.ctf-seg-opt{border:0;background:transparent;padding:7px 18px;font:inherit;font-weight:600;font-size:13px;
  color:var(--muted);cursor:pointer;line-height:1}
.ctf-seg-opt+.ctf-seg-opt{border-left:1px solid var(--line)}
.ctf-seg-opt.aktif{background:var(--primary);color:#fff}
.ctf-seg-opt[data-ctf-bayar="1"].aktif{background:var(--success)}
/* Info sisa jatah di bawah kalender. */
#ctfSisa{margin-top:12px}
/* Chip tanggal MERAH — konsisten dengan tanggal terpilih di kalender. */
.ctf-chip{display:inline-flex;align-items:center;gap:6px;padding:4px 6px 4px 10px;border-radius:999px;
          background:rgba(220,38,38,.1);color:#dc2626;border:1px solid rgba(220,38,38,.3);
          font-size:11.5px;font-weight:700;font-variant-numeric:tabular-nums}
.ctf-chip button{border:none;background:transparent;color:inherit;cursor:pointer;width:18px;height:18px;
                 border-radius:50%;display:grid;place-items:center;font-size:11px;line-height:1}
.ctf-chip button:hover{background:rgba(0,0,0,.08)}
.ctf-total{font-size:12px;color:var(--muted)}
.ctf-total b{font-size:14px;color:var(--ink);font-variant-numeric:tabular-nums}
/* Penanda lampiran di kolom Karyawan: pengajuan bersurat sering diputuskan
   berbeda, jadi keberadaannya perlu terlihat tanpa membuka rinciannya. */
.ct-lampir{margin-left:5px;font-size:10px;color:var(--muted-2)}
/* Tiga tab pada halaman Cuti-Izin-Sakit. Panenya disembunyikan, bukan dibongkar:
   tabel yang dibangun ulang tiap kali tab berpindah akan kehilangan pencarian,
   halaman, dan urutan yang sedang dipakai orang. */
.aju-pane{display:none}
.aju-pane.show{display:block}
#page-aju-cuti > .tabbar{margin-bottom:14px}

/* Halaman Pengajuan > Access Cabang: kartu permintaan di atas, antrean di
   bawah. Kartunya dibatasi lebarnya — isian yang melar selebar layar membuat
   mata melompat jauh dari label ke isian yang cuma butuh satu pilihan. */
.ac-kartu{margin-bottom:18px}
/* Kartu "Ajukan …" yang bisa dilipat: saat tertutup ia hanya sebaris judul,
   jadi bantalan kartunya dikecilkan supaya tak jadi kotak tinggi hampir kosong.
   Saat terbuka, .ac-isi (margin-top) tetap memberi jarak ke isinya. */
.ac-kartu>.card-body{padding:12px 18px}
/* Tiga isian sebaris, masing-masing berbagi lebar kartu sama rata: Catatan
   dulunya turun ke barisnya sendiri dan menyisakan satu baris hampir kosong
   di atasnya. */
.ac-kisi{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:12px 14px;align-items:start}
@container isi (max-width:820px){ .ac-kisi{grid-template-columns:minmax(0,1fr)} }
.ac-kartu .kl-input{margin-bottom:0;font-size:12px;padding:6px 9px}
.ac-kartu .pk-isi{margin-top:9px}
.ac-kartu .cari-sel{display:flex}
.ac-kartu .cari-tombol{width:100%;max-width:none;box-sizing:border-box;
                       border-radius:var(--r-input);padding:6px 9px}
/* Dua sisi berdampingan: yang dimiliki dan yang diajukan. Masing-masing kotak
   sendiri dengan kepala bernama, supaya jelas cip mana milik sisi mana —
   seorang karyawan bisa punya 48 akses, dan dua daftar panjang tanpa batas
   tegas akan terbaca menyambung. */
.ac-dua{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:14px;align-items:start;
        margin-top:14px}
@container isi (max-width:820px){ .ac-dua{grid-template-columns:minmax(0,1fr)} }
/* TANPA overflow:hidden. Panel dropdown di dalamnya mengambang (position:
   absolute), dan ancestor yang memotong isinya akan memotong panel itu juga —
   yang terlihat cuma kotak pencariannya, daftar cabangnya hilang. Sudut
   membulat kepalanya diurus kepala itu sendiri. */
.ac-sisi{min-width:0;border:1px solid var(--line);border-radius:10px;background:var(--surface)}
.ac-sisi-kepala{
  display:flex;align-items:center;gap:8px;padding:9px 12px;
  background:var(--surface-2);border-bottom:1px solid var(--line);
  border-radius:9px 9px 0 0;
  font-size:11px;font-weight:800;letter-spacing:.04em;text-transform:uppercase;color:var(--muted);
}
.ac-sisi>.ac-punya-daftar,.ac-sisi>.pk,.ac-sisi>.pk-isi{padding:0 12px}
.ac-sisi>.pk{padding-top:12px}
.ac-sisi>.pk-isi{padding-bottom:12px}
/* Tiga kolom cip, dan tingginya dibatasi LIMA baris — sisanya digulir.
   Tanpa batas ini, 48 akses mendorong tabel antrean di bawahnya keluar layar,
   dan yang sebenarnya dicari orang justru jadi tidak terlihat.
   Angkanya: 5 baris x tinggi cip + 4 jarak antarbaris. */
.ac-daftar-cip{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:5px;
               max-height:calc(5 * 27px + 4 * 5px);overflow-y:auto;overscroll-behavior:contain}
@container isi (max-width:1080px){ .ac-daftar-cip{grid-template-columns:repeat(2,minmax(0,1fr))} }
@container isi (max-width:520px){ .ac-daftar-cip{grid-template-columns:minmax(0,1fr)} }
.ac-punya-daftar{margin:12px 0}
.ac-punya-cip{
  display:flex;align-items:center;gap:5px;min-width:0;
  background:var(--surface-2);border:1px solid var(--line);border-radius:6px;padding:4px 8px;
  font-size:11.5px;color:var(--ink);
}
.ac-punya-cip>span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ac-punya-cip.utama{background:var(--primary-tint);border-color:var(--primary);color:var(--primary)}
.ac-punya-cip i{font-size:9px;flex:none}
/* Kepala kartu yang bisa dilipat: tombol selebar kartunya, panah berputar
   mengikuti keadaannya. */
.ac-kepala{
  display:flex;align-items:center;gap:9px;width:100%;background:none;border:0;
  padding:0;margin:0;cursor:pointer;text-align:left;color:var(--muted);
  font-size:12px;font-weight:800;letter-spacing:.04em;text-transform:uppercase;
}
.ac-kepala:hover{color:var(--primary)}
.ac-panah{font-size:10px;transition:transform .15s}
.ac-kepala.buka .ac-panah{transform:rotate(90deg)}
.ac-isi{margin-top:16px}
/* Tombol cabut pada cip akses yang dimiliki — sebentuk dengan tombol X pada
   cip pilihan di sebelahnya. */
.ac-cabut{
  flex:none;display:grid;place-items:center;width:16px;height:16px;margin-left:auto;
  background:none;border:0;border-radius:4px;color:var(--muted-2);font-size:9px;
  cursor:pointer;padding:0;
}
.ac-cabut:hover{background:rgba(192,57,43,.12);color:var(--danger)}
.ac-kosong{margin:0;font-size:11.5px;color:var(--muted);line-height:1.5}
/* Pratinjau jadwal cicilan sebelum kasbon diajukan: angka inilah yang nanti
   memotong gaji, jadi ia dibaca sebelum tombolnya ditekan — bukan sesudahnya. */
/* SATU baris: Karyawan · Cabang · Tanggal · Jumlah Kasbon · Bayar · Cicilan
   Perbulan · Keterangan. Lebarnya TIDAK sama rata — nama & keterangan butuh
   ruang, Bayar hanya dua huruf. */
.kb-kisi{display:grid;gap:12px 14px;align-items:start;
         grid-template-columns:1.5fr 1.2fr 1.1fr 1.1fr .7fr 1.1fr 1.5fr}
/* Sempit: pecah jadi 3 kolom, lalu 1 kolom. */
@container isi (max-width:1180px){
  .kb-kisi{grid-template-columns:repeat(3,minmax(0,1fr))}
  .kb-ket{grid-column:1/-1}
}
@container isi (max-width:640px){
  .kb-kisi{grid-template-columns:minmax(0,1fr)}
  .kb-ket{grid-column:1/-1}
}

.kb-pratinjau{margin-top:14px;padding:11px 13px;border-radius:9px;
              background:var(--surface-2);border:1px solid var(--line);
              font-size:12px;line-height:1.55}
.kb-prat-kepala{display:flex;flex-wrap:wrap;align-items:baseline;gap:4px 12px;
                padding-bottom:9px;margin-bottom:9px;border-bottom:1px dashed var(--line)}
.kb-prat-kepala b{font-size:13.5px}
.kb-prat-kepala span{color:var(--muted);font-size:11.5px}
.kb-prat-kepala i{margin-left:auto;font-style:normal;color:var(--muted);
                  font-size:11.5px;font-variant-numeric:tabular-nums}
/* Kotak-kotak sempit yang mengalir: 24 cicilan tetap terbaca tanpa membuat
   kartunya sepanjang halaman. */
.kb-prat-daftar{list-style:none;margin:0;padding:0;display:grid;gap:6px;
                grid-template-columns:repeat(auto-fill,minmax(168px,1fr));
                max-height:186px;overflow:auto}
.kb-prat-daftar li{display:flex;align-items:baseline;gap:7px;
                   padding:5px 9px;border-radius:7px;background:var(--surface);
                   border:1px solid var(--line);font-variant-numeric:tabular-nums}
.kb-prat-daftar li b{margin-left:auto;font-size:12px}
.kb-prat-ke{color:var(--muted);font-size:10.5px;min-width:22px}
.kb-prat-tgl{font-size:11px;color:var(--ink-soft)}
/* Di dalam dialog daftarnya boleh lebih tinggi: tidak ada apa pun di bawahnya
   yang terdorong. */
.kb-prat-dlg{margin-top:0;background:transparent;border:0;padding:0}
.kb-prat-dlg .kb-prat-daftar{max-height:262px;grid-template-columns:repeat(auto-fill,minmax(184px,1fr))}
.kb-prat-daftar li i{font-size:10px;color:var(--muted)}
/* Cicilan yang sudah LUNAS: latar hijau jelas + teks hijau tua supaya mudah
   dibedakan dari yang belum dibayar. Selektor diperketat (li.kelas) agar menang
   atas `.kb-prat-daftar li` yang menyetel background/border lebih spesifik. */
.kb-prat-daftar li.kb-prat-lunas{border-color:#86E0A5;background:#D6F5E0}
.kb-prat-lunas b{color:#14713A}
.kb-prat-lunas i{color:#1E8449}
.kb-prat-daftar li.kb-prat-sisa{border-color:#E6B0AA;background:#FDF2F0}
.kb-prat-sisa b{color:#7B241C}
/* Cicilan BELUM lunas (hanya di modal Jadwal cicilan): latar merah supaya
   kontras dengan yang sudah lunas (hijau). */
.kb-prat-daftar li.kb-prat-belum{border-color:#E6B0AA;background:#FCE8E6}
.kb-prat-belum b{color:#A93226}
.kb-prat-belum i{color:#C0392B}
.kb-pratinjau small{display:block;color:var(--muted);font-size:10.5px;margin-top:8px}
input.kb-uang{text-align:right;font-variant-numeric:tabular-nums}
.kb-lunas{font-size:10px;color:var(--muted);font-variant-numeric:tabular-nums}
/* Nilai yang belum diputuskan ditulis redup: ia bukan angka nol, dan bukan
   pula angka yang bisa dipercaya. */
.kb-belum{color:var(--muted);font-weight:400}
/* Kasbon yang cicilannya sudah habis terpotong. */
.kb-lunas-ok{display:inline-flex;align-items:center;padding:2px 8px;border-radius:999px;
  font-size:10.5px;font-weight:700;background:var(--success-tint);color:var(--success);
  text-transform:uppercase;letter-spacing:.3px}
/* Jenis Tipe WO (Backbone/IKR): chip read-only & dropdown inline di sel. Warna
   membedakan jenis — Backbone biru (jaringan inti), IKR ungu (instalasi rumah). */
.tw-jenis-chip{display:inline-flex;align-items:center;padding:2px 9px;border-radius:999px;
  font-size:10.5px;font-weight:700;text-transform:uppercase;letter-spacing:.3px}
.tw-jenis-backbone,.tw-jenis-sel.tw-jenis-backbone{background:var(--info-tint);color:var(--info);border-color:var(--info)}
.tw-jenis-ikr,.tw-jenis-sel.tw-jenis-ikr{background:var(--violet-tint);color:var(--violet);border-color:var(--violet)}
.tw-jenis-kosong{background:var(--surface-2);color:var(--muted-2)}
.tw-jenis-sel{border:1px solid var(--line);border-radius:999px;padding:3px 10px;
  font-family:inherit;font-size:11px;font-weight:700;cursor:pointer;
  background:var(--surface-2);color:var(--muted);text-align:center;min-width:104px}
.tw-jenis-sel.tw-jenis-kosong{color:var(--muted-2)}
.tw-jenis-sel:focus{outline:2px solid var(--primary);outline-offset:1px}
/* Kolom Jenis dipusatkan: No(1) disisipkan bindTable, lalu Initial(2), Tipe Wo(3),
   Jenis(4). */
#tblTipeWo thead th:nth-child(4),#tblTipeWo tbody td:nth-child(4){text-align:center}
/* Kolom "Under" daftar Karyawan: chip QN (ungu) / LTI (teal). */
.und-chip{display:inline-flex;align-items:center;justify-content:center;min-width:38px;padding:2px 9px;
  border-radius:999px;font-size:10.5px;font-weight:800;letter-spacing:.4px}
.und-qn{background:var(--primary-tint);color:var(--primary-600,var(--primary))}
.und-lti{background:var(--success-tint);color:var(--success)}
/* Under sebagai dropdown inline (QN/LTI) auto-save. */
.undsel{cursor:pointer;gap:5px;min-width:52px}
.undsel:hover{filter:brightness(.97);box-shadow:0 0 0 1px var(--line) inset}
.undsel-car{font-size:9px;opacity:.7;flex:none}
.und-pop{position:fixed;z-index:1000;width:230px;max-width:92vw;background:var(--surface);
  border:1px solid var(--line);border-radius:10px;box-shadow:var(--shadow-md,0 8px 24px rgba(0,0,0,.14));
  padding:5px;display:flex;flex-direction:column;gap:2px}
.und-pop-item{display:flex;align-items:baseline;gap:8px;width:100%;text-align:left;cursor:pointer;
  border:none;background:transparent;font:inherit;padding:8px 10px;border-radius:7px;color:var(--ink)}
.und-pop-item:hover{background:var(--surface-2,var(--bg))}
.und-pop-item.sel{background:var(--primary-tint,#eef2ff)}
.und-pop-item.sel::after{content:'✓';margin-left:auto;font-size:11px;font-weight:900;color:var(--primary)}
.und-pop-item b{flex:none;font-size:11px;font-weight:800;color:var(--primary);min-width:30px}
.und-pop-item span{font-size:12px;color:var(--muted)}
/* Kolom DISEMBUNYIKAN di daftar Karyawan (data & fitur tetap jalan). Posisi
   TERRENDER (termasuk kolom No sisipan bindTable): Under KINI tampil (nth-child 7,
   setelah Klien); Kode Karyawan = 8, Role = 9 (geser +1 karena Under disisipkan).
   Data tetap ada di DOM → filter "Semua Role" & indeks lain utuh. */
#tblKaryawan thead th:nth-child(8),#tblKaryawan tbody td:nth-child(8),
#tblKaryawan thead th:nth-child(9),#tblKaryawan tbody td:nth-child(9),
#tblKaryawanLti thead th:nth-child(8),#tblKaryawanLti tbody td:nth-child(8),
#tblKaryawanLti thead th:nth-child(9),#tblKaryawanLti tbody td:nth-child(9){display:none}
/* Kolom Role DISEMBUNYIKAN di Rekap Absensi (#tblAbsensi). Header 2 baris: Role ada
   di BARIS PERTAMA (rowspan2) posisi ke-4 (No·Karyawan·Divisi·Role…); body td ke-4.
   Data tetap di DOM; hapus baris ini untuk menampilkannya lagi. */
#tblAbsensi thead tr:first-child th:nth-child(4),
#tblAbsensi tbody td:nth-child(4){display:none}
/* Tombol import Excel (saring by nama) di samping kotak Cari. Ikon biru; saat
   filter aktif (.on) jadi solid ungu dgn ikon putih sebagai penanda + "klik lagi
   untuk hapus". */
.btn-imp{padding:6px 9px;font-size:13px;line-height:1}
.btn-imp i{color:var(--info)}
.btn-imp.on{background:var(--primary);border-color:var(--primary)}
.btn-imp.on i{color:#fff}
/* Sel Klien inline (multi-select auto-save) di daftar Karyawan + pop-up pilihannya. */
.klsel{display:inline-flex;align-items:center;gap:6px;cursor:pointer;max-width:100%;
  padding:2px 6px;border-radius:6px;border:1px solid transparent}
.klsel:hover{background:var(--surface-2);border-color:var(--line)}
.klsel-chips{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:600;color:var(--ink)}
.klsel-kosong{color:var(--muted-2)}
.klsel-car{font-size:10px;color:var(--muted-2);flex:none}
.kl-pop{position:fixed;z-index:1000;width:300px;max-width:92vw;background:var(--surface);
  border:1px solid var(--line-3d);border-radius:10px;box-shadow:var(--shadow-lg);padding:8px;
  display:flex;flex-direction:column;gap:6px}
.kl-pop-cari{border:1px solid var(--line);border-radius:6px;padding:7px 10px;font-family:inherit;
  font-size:12px;background:var(--surface-2);color:var(--ink)}
.kl-pop-cari:focus{outline:none;border-color:var(--primary);box-shadow:0 0 0 3px var(--primary-tint)}
.kl-pop-list{max-height:220px;overflow-y:auto;display:flex;flex-direction:column;gap:2px}
.kl-pop-item{display:flex;align-items:center;gap:8px;padding:6px 7px;border-radius:7px;cursor:pointer;font-size:12.5px}
.kl-pop-item:hover{background:var(--surface-2)}
.kl-pop-ini{flex:none;font-weight:800;font-size:10.5px;color:var(--primary-600,var(--primary));
  background:var(--primary-tint);border-radius:999px;padding:1px 7px;min-width:34px;text-align:center}
.kl-pop-nm{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--ink)}
.kl-pop-kosong{color:var(--muted);font-size:12px;text-align:center;padding:12px}
/* Kolom Cicilan (ke-9) dipusatkan & ditebalkan; Sisa Cicilan (ke-11) dipusatkan
   agar sebanding. Indeks terrender: No(1) disisipkan bindTable, lalu checkbox(2). */
#tblAjuKasbon thead th:nth-child(9),#tblAjuKasbon tbody td:nth-child(9){text-align:center}
#tblAjuKasbon tbody td:nth-child(9),#tblAjuKasbon tbody td:nth-child(9) .dt-durasi{font-weight:700;color:var(--ink)}
#tblAjuKasbon thead th:nth-child(11),#tblAjuKasbon tbody td:nth-child(11){text-align:center}
/* Dropdown di dalam sel: setinggi teks barisnya, tanpa membuat barisnya lebih
   tinggi daripada baris yang sudah diputuskan. */
.kb-sel-cicilan{width:100%;max-width:74px;padding:2px 4px;font:inherit;font-size:11.5px;
                border:1px solid var(--line);border-radius:6px;background:var(--surface);
                color:var(--ink);font-variant-numeric:tabular-nums}
.kb-sel-cicilan:focus{outline:2px solid var(--brand);outline-offset:-1px}

/* ---- Pintasan melayang (pojok kanan bawah) ---- */
/* Hanya untuk akun yang berwenang; penjaganya tetap di server — yang tidak
   berhak pun tidak mendapat apa-apa dari keempat tombol ini.
   Keempatnya tersusun pada seperempat lingkaran berjari-jari 96px: dari lurus
   ke atas (0 derajat) sampai lurus ke kiri (90 derajat), dengan jeda berurutan
   supaya terlihat mengembang, bukan muncul serentak. */
/* ---- Halaman Sinkron Data ---- */
/* Menunya hanya untuk akun berwenang. Penjaganya di server; ini menyembunyikan
   apa yang tidak bisa dipakai. */
body:not(.bisa-sinkron) .nav-item[data-page="sinkron"]{display:none}
/* ---- Halaman Face Verification ---- */
/* Sama seperti Sinkron: menunya hanya untuk akun berwenang (FACE_AKSES);
   penjaga sebenarnya di server. */
body:not(.bisa-face) .nav-item[data-page="face-verification"]{display:none}
.fv-engine{flex:none;font-size:11.5px;font-weight:700;padding:3px 10px;border-radius:999px;
  background:var(--surface-2);color:var(--muted)}
.fv-engine.ok{background:var(--success-tint);color:var(--success)}
.fv-engine.galat{background:var(--danger-tint);color:var(--danger)}
#page-face-verification .switch{cursor:pointer}
#page-face-verification .switch.fv-mati{opacity:.45;cursor:not-allowed}
.fv-sub{display:flex;align-items:center;gap:8px;font-size:10.5px;text-transform:uppercase;
  letter-spacing:.04em;color:var(--muted);font-weight:700;margin:18px 0 8px}
.fv-status{border:0;border-radius:999px;padding:3px 12px;font-size:11.5px;font-weight:700;cursor:pointer}
.fv-status.on{background:var(--success-tint);color:var(--success)}
.fv-status.off{background:var(--surface-2);color:var(--muted)}
.fv-ulang{display:inline-block;margin-left:6px;border-radius:999px;padding:3px 10px;font-size:11px;font-weight:700;background:var(--warning-tint,#fff4e0);color:var(--warning,#b26a00);white-space:nowrap}
.fv-status:disabled{opacity:.6;cursor:wait}
.fv-foto{border:0;background:none;color:var(--primary);cursor:pointer;font-size:15px;padding:2px 6px}
.sn-bar{display:flex;gap:9px;align-items:center;flex-wrap:wrap;margin-bottom:10px}
.sn-lb{display:inline-flex;align-items:center;gap:6px;font-size:11.5px;font-weight:700;color:var(--muted)}
.sn-aksi-kanan{margin-left:auto;display:flex;gap:8px}
.sn-catatan{display:flex;gap:9px;margin:0 0 14px;padding:10px 12px;border-radius:9px;
            background:var(--surface-2);border:1px solid var(--line);
            font-size:11.5px;line-height:1.55;color:var(--muted)}
.sn-catatan i{flex:none;margin-top:2px;color:var(--primary)}
.sn-catatan > span{min-width:0}
.sn-catatan b{color:var(--ink-soft)}
.sn-pilih{border:1px solid var(--line);border-radius:9px;padding:11px 12px;background:var(--surface)}
.sn-pilih-kepala{display:flex;align-items:center;gap:10px;margin-bottom:9px}
.sn-pilih-kepala b{font-size:11.5px;text-transform:uppercase;letter-spacing:.04em;color:var(--muted)}
.sn-aksi{margin-left:auto;display:flex;gap:6px}
.sn-aksi .btn{font-size:11px;padding:4px 9px}
/* Satu kotak per kelompok tabel, sama seperti papan centang Akses Menu —
   kisinya menempatkan KOTAK, bukan butirnya, supaya satu kelompok tidak
   terbelah antar-kolom. */
.sn-tabel{display:grid;grid-template-columns:repeat(auto-fill,minmax(210px,1fr));gap:9px;align-content:start}
.sn-grup{border:1px solid var(--line);border-radius:8px;background:var(--surface-2);padding:4px}
.sn-grup-nama{font-size:10px;text-transform:uppercase;letter-spacing:.04em;color:var(--muted);
              font-weight:700;padding:3px 6px}
.sn-item{display:flex;align-items:center;gap:7px;font-size:12px;padding:3px 6px;border-radius:6px;cursor:pointer}
.sn-item:hover{background:var(--surface)}
.sn-item span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-family:ui-monospace,monospace;font-size:11px}
.sn-lewat{margin-top:10px;font-size:11.5px;color:var(--muted)}
.sn-lewat summary{cursor:pointer;font-weight:600}
.sn-lewat ul{margin:7px 0 0;padding-left:18px;line-height:1.6}
.sn-lewat code{font-family:ui-monospace,monospace;font-size:11px;color:var(--ink-soft)}
/* Bilah kemajuan: tanpa persentase palsu. Lebarnya mengikuti tabel keberapa
   yang sedang dikerjakan — satu-satunya kemajuan yang benar-benar diketahui. */
.sn-jalan{margin-top:14px;padding:12px;border:1px solid var(--primary);border-radius:9px;
          background:var(--primary-tint)}
.sn-jalan-kepala{display:flex;align-items:center;gap:10px;margin-bottom:8px}
.sn-jalan-kepala b{font-size:12.5px;color:var(--ink)}
.sn-tahap{margin-left:auto;font-size:11px;color:var(--muted);font-variant-numeric:tabular-nums}
.sn-batang{height:6px;border-radius:999px;background:var(--surface);overflow:hidden}
.sn-batang span{display:block;height:100%;width:0;background:var(--primary);transition:width .4s ease}
.sn-pesan{margin-top:7px;font-size:11.5px;color:var(--ink-soft)}
.sn-sub{font-size:10.5px;text-transform:uppercase;letter-spacing:.04em;color:var(--muted);
        font-weight:700;margin-bottom:7px}
.sn-gulir{max-height:min(340px,max(160px,calc(100dvh - 420px)));overflow:auto;overscroll-behavior:contain}
#tblSinkron{font-size:11.5px}
.sn-hapus{width:24px;height:24px;border-radius:6px;border:1px solid var(--line);
          background:var(--surface);cursor:pointer;font-size:10px;color:var(--muted)}
.sn-hapus:hover:not(:disabled){border-color:#C0392B;color:#C0392B}
.sn-hapus:disabled{opacity:.35;cursor:default}

/* ---- Modal Koneksi Server & Basis Data ---- */
/* Tombolnya hanya ada untuk akun berwenang. Penjaganya di server; ini cuma
   menyembunyikan apa yang tidak bisa dipakai. */
body:not(.bisa-koneksi) [data-layang="koneksi"]{display:none}
/* Dua lajur SEREGANG tinggi modalnya (align-items:stretch, bukan start), dan
   masing-masing menggulir sendiri: daftar koneksi di kiri bisa panjang, dan
   formulir di kanan lebih panjang lagi di layar pendek. */
.kn-susun{display:grid;grid-template-columns:270px minmax(0,1fr);gap:16px;
          align-items:stretch;flex:1;min-height:0}
@media (max-width:760px){
  /* Satu lajur: keduanya tidak lagi berbagi tinggi, jadi tingginya dikembalikan
     ke isi masing-masing dan yang menggulir badan panenya. */
  .kn-susun{grid-template-columns:minmax(0,1fr);overflow:auto;align-items:start}
  .kn-daftar{max-height:220px}
  .kn-kiri,.kn-kanan{min-height:auto}
}
.kn-kiri{display:flex;flex-direction:column;min-height:0}
.kn-kanan{overflow:auto;min-height:0;padding-right:4px;overscroll-behavior:contain}
/* Isian TIDAK ikut melebar bersama modalnya. Lebar modal ada untuk daftar
   koneksi dan tabel di tab sebelah — bukan untuk merentangkan formulir:
   kotak teks selebar 700px lebih sulit dipindai daripada yang setengahnya, dan
   mata harus berjalan lebih jauh antara label dan isinya. */
.kn-kanan > *{max-width:820px}
.kn-kiri-kepala{display:flex;align-items:center;justify-content:space-between;margin-bottom:8px;flex:none}
.kn-kiri-kepala b{font-size:12px;text-transform:uppercase;letter-spacing:.04em;color:var(--muted)}
.kn-daftar{display:grid;gap:6px;align-content:start;flex:1;min-height:0;overflow:auto;overscroll-behavior:contain}
.kn-item{display:grid;gap:2px;padding:9px 11px;border:1px solid var(--line);border-radius:9px;
         background:var(--surface);cursor:pointer;text-align:left;font-family:inherit;width:100%}
.kn-item:hover{border-color:var(--muted-2)}
.kn-item.aktif{border-color:var(--primary);box-shadow:0 0 0 3px var(--primary-tint)}
.kn-item b{font-size:12.5px;color:var(--ink)}
.kn-item small{font-size:11px;color:var(--muted);font-variant-numeric:tabular-nums;
               overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.kn-kosong{margin:0;padding:14px 0;font-size:11.5px;color:var(--muted);text-align:center}
.kn-kanan{display:block}
/*
 * Nama / Host / Port satu baris, dengan lebar menurut KEBUTUHAN datanya dan
 * bukan tiga kolom sama lebar: port cuma perlu lima digit, dan kotak selebar
 * nama koneksi untuk lima digit membuat baris itu terbaca sebagai tiga isian
 * yang sama pentingnya.
 *
 * Dua belas jalur dipakai supaya perbandingannya (6 : 4 : 2) bisa ditulis apa
 * adanya, dan baris di bawahnya tetap setengah-setengah (6 : 6) tanpa aturan
 * tambahan.
 *
 * Keterangan penyimpanan sandi yang dulu ada di bawah formulir ini dilepas atas
 * permintaan pemilik aplikasi. Isinya tidak hilang: petunjuk "biarkan kosong
 * untuk mempertahankan sandi lama" tetap terbaca di placeholder isian sandinya
 * sendiri, dan cara penyimpanannya ada di README.
 */
.kn-kanan .form-grid{grid-template-columns:repeat(12,minmax(0,1fr))}
/*
 * Semua aturan di bawah memakai bentuk selektor yang SAMA
 * (.kn-kanan .form-grid > X), jadi kekhususannya seri dan urutannyalah yang
 * menentukan. Itu disengaja: bawaannya ditulis lebih dulu sebagai jaring
 * pengaman untuk isian yang kelak ditambahkan tanpa kelas kn-f- — tanpa
 * bawaan itu, isian baru akan muncul selebar satu dari dua belas jalur.
 */
.kn-kanan .form-grid > .field{grid-column:span 12}
/* Baris 1 — 6 : 4 : 2. Port cuma perlu lima digit. */
.kn-kanan .form-grid > .kn-f-nama{grid-column:span 6}
.kn-kanan .form-grid > .kn-f-host{grid-column:span 4}
.kn-kanan .form-grid > .kn-f-port{grid-column:span 2}
/* Baris 2 — 3 : 5 : 4. Nama pengguna basis data hampir selalu pendek
   ("root", "hris_app"); isian sandinya justru yang paling butuh lebar karena
   menampung tombol intip sekaligus keterangan "tersimpan — biarkan kosong
   untuk mempertahankannya"; nama basis data di antara keduanya. */
.kn-kanan .form-grid > .kn-f-user{grid-column:span 3}
.kn-kanan .form-grid > .kn-f-sandi{grid-column:span 5}
.kn-kanan .form-grid > .kn-f-basis{grid-column:span 4}
/* Baris 3 — catatan bebas, jadi selebar barisnya (ikut bawaan di atas). */
/* Di modal sempit tiap isian berdiri sendiri — kecuali host dan port, yang
   tetap berdampingan: port yang menempati satu baris penuh sendirian justru
   terbaca sebagai isian yang jauh lebih penting daripada yang sebenarnya. */
@media (max-width:620px){
  .kn-kanan .form-grid > .field{grid-column:span 12}
  .kn-kanan .form-grid > .kn-f-host{grid-column:span 8}
  .kn-kanan .form-grid > .kn-f-port{grid-column:span 4}
}

.kn-hasil{margin:10px 0 0;padding:9px 12px;border-radius:9px;font-size:11.5px;line-height:1.55;
          background:var(--success-tint);border:1px solid var(--success);color:#1B5E43}
.kn-hasil.gagal{background:var(--danger-tint);border-color:var(--danger);color:#8C2F26}
.kn-aksi{display:flex;align-items:center;gap:8px;margin-top:14px}
.kn-aksi-kanan{margin-left:auto;display:flex;gap:8px}
.kn-hapus:hover{border-color:#C0392B;color:#C0392B}
.kn-bar{display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin-bottom:10px}
.kn-bar .cari-tombol{min-width:170px}
.kn-bar-info{margin-left:auto;font-size:11px;color:var(--muted);font-variant-numeric:tabular-nums}
/* Sama seperti tab Koneksi: dua lajur seregang tinggi panenya, dan tabelnya
   yang menggulir — bukan seluruh modal. */
.kn-jelajah{display:grid;grid-template-columns:300px minmax(0,1fr);gap:14px;
            align-items:stretch;flex:1;min-height:0}
.kn-tabel-daftar,.kn-isi{display:flex;flex-direction:column;min-height:0}
@media (max-width:760px){
  .kn-jelajah{grid-template-columns:minmax(0,1fr);overflow:auto;align-items:start}
  .kn-tabel-daftar,.kn-isi{min-height:auto}
  .kn-gulir{flex:none;max-height:200px}
}
.kn-sub{font-size:10.5px;text-transform:uppercase;letter-spacing:.04em;color:var(--muted);
        font-weight:700;margin-bottom:6px;flex:none}
.kn-sub2{margin-top:12px}
/* Tingginya dibagi rata dari sisa ruang modal, bukan dipatok angka: modalnya
   sudah setinggi layar, jadi tabelnya tinggal mengisi apa yang tersisa.
   Daftar tabel bisa berisi ratusan nama dan contoh isinya lima puluh baris,
   jadi keduanya memang perlu menggulir sendiri. */
.kn-gulir{flex:1;min-height:110px;overflow:auto;
          border:1px solid var(--line);border-radius:9px;overscroll-behavior:contain}
.kn-gulir .sg-tabel{font-size:11.5px}
.kn-tabel-baris{cursor:pointer}
.kn-tabel-baris.aktif td{background:var(--primary-tint)!important}
.kn-sistem td:first-child{color:var(--muted);font-style:italic}
/* Sel contoh isi dibatasi lebarnya: satu kolom TEXT bisa berisi ribuan huruf
   dan akan meregangkan tabelnya sampai tidak ada kolom lain yang terlihat. */
#knTblIsi td{max-width:220px;overflow:hidden;text-overflow:ellipsis}
#knTblIsi td.kn-null{color:var(--muted-2);font-style:italic}

/* ---- Tab Akses Menu di dalam Setting Menu ---- */
/* Menu yang tidak boleh dibuka akun ini — disembunyikan, bukan dihapus dari
   susunannya: aturannya milik akun, bukan milik menunya. */
.nav-item.nav-terlarang{display:none!important}
.nav-sub.sub-terlarang{display:none!important}
.am-bar{display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin-bottom:8px}
.am-bar .kl-input{margin-bottom:0;width:auto;min-width:170px;font-size:12px;padding:6px 9px}
/* Kedua daftar dibungkus jadikanCari: 320 jabatan aktif terlalu banyak untuk
   <select> polos. Lebarnya disamakan supaya barisnya tidak bergoyang setiap
   kali namanya berganti panjang. */
.am-bar .cari-tombol{min-width:190px;max-width:230px}
.am-petunjuk{margin:0 0 12px;font-size:11px;line-height:1.5;color:var(--muted)}
.am-kepala{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:8px}
.am-kepala b{font-size:12.5px}
.am-aksi{margin-left:auto;display:flex;gap:6px}
.am-aksi .btn{font-size:11px;padding:4px 9px}
/* Yang ditempatkan kisinya adalah KOTAK KELOMPOK, bukan butir menunya satu per
   satu: kisi yang menempatkan butir akan memisahkan "Karyawan" dari "Master"
   yang menaunginya ke kolom yang berbeda. align-content:start menahan kotaknya
   tetap serapat isinya saat barisnya belum penuh. */
.am-menu{display:grid;grid-template-columns:repeat(auto-fill,minmax(196px,1fr));gap:9px;
         align-content:start;max-height:300px;overflow:auto;padding:10px;
         border:1px solid var(--line);border-radius:9px;background:var(--surface-2)}
.am-grup{border:1px solid var(--line);border-radius:8px;background:var(--surface);padding:3px}
.am-grup.am-aktif{border-color:var(--primary)}
.am-item{display:flex;align-items:center;gap:7px;font-size:12px;padding:4px 6px;
         border-radius:6px;cursor:pointer}
.am-item:hover{background:var(--surface-2)}
.am-item > span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.am-item.induk{font-weight:600}
.am-item.induk > i{flex:none;width:13px;text-align:center;font-size:10px;color:var(--muted-2)}
.am-grup.am-aktif .am-item.induk > i{color:var(--primary)}
/* Anaknya menjorok sejauh kotak centang + ikon induknya, supaya tepi kirinya
   sejajar dengan NAMA induknya dan hubungan keduanya terbaca sekali lihat. */
.am-anak{border-top:1px dashed var(--line);margin:2px 5px 0;padding:2px 0 1px}
.am-anak .am-item{padding-left:20px;color:var(--ink-soft);font-size:11.5px}
.am-hitung{flex:none;margin-left:auto;font-style:normal;font-size:9.5px;
           color:var(--muted);font-variant-numeric:tabular-nums}
.am-hitung-total{font-size:11px;color:var(--muted);font-variant-numeric:tabular-nums}
.am-simpan{display:flex;gap:8px;justify-content:flex-end;margin-top:10px}
.am-judul-daftar{margin:16px 0 8px;font-size:11px;text-transform:uppercase;
                 letter-spacing:.04em;color:var(--muted)}
.am-daftar{display:grid;gap:5px}
.am-baris{display:flex;align-items:center;gap:9px;padding:7px 10px;border:1px solid var(--line);
          border-radius:8px;background:var(--surface);font-size:12px}
.am-cip{flex:none;padding:1px 7px;border-radius:999px;background:var(--primary-tint);
        color:var(--primary);font-size:9.5px;font-weight:700;text-transform:uppercase;
        letter-spacing:.03em}
.am-jml{margin-left:auto;color:var(--muted);font-size:11px;font-variant-numeric:tabular-nums}
.am-ubah,.am-buang{flex:none;width:24px;height:24px;border-radius:6px;border:1px solid var(--line);
                   background:var(--surface);cursor:pointer;font-size:10px;color:var(--muted)}
.am-ubah:hover{border-color:var(--primary);color:var(--primary)}
.am-buang:hover{border-color:#C0392B;color:#C0392B}
.am-kosong{margin:0;font-size:11.5px;color:var(--muted)}

/* Pintasan melayang SEMBUNYI sampai dipanggil: ikon yang menetap di sudut
   kanan bawah menutupi isi halaman sepanjang hari — persis di tempat tabel
   menaruh baris terakhir dan tombol pagingnya. Ia muncul setelah klik ganda di
   sudut itu, dan hilang lagi dengan klik ganda berikutnya.
   Disembunyikan dengan opacity + pointer-events, BUKAN display:none: elemen
   ber-display none tidak bisa menerima fokus, dan itu akan memutus satu-satunya
   jalan menuju pintasan ini bagi pemakai papan ketik. */
.layang{position:fixed;right:22px;bottom:22px;z-index:75;width:0;height:0;
  opacity:0;pointer-events:none;transition:opacity .2s ease}
.layang.tampak,.layang:focus-within{opacity:1;pointer-events:auto}
body:not(.bisa-pintasan) .layang{display:none!important}
.layang-picu{
  position:absolute;right:0;bottom:0;width:44px;height:44px;border-radius:50%;
  border:none;background:var(--primary);color:#fff;font-size:15px;cursor:pointer;
  box-shadow:0 8px 20px -6px rgba(15,23,42,.45);
  display:grid;place-items:center;
  opacity:.34;transform:scale(.86);
  transition:opacity .22s ease,transform .22s cubic-bezier(.34,1.4,.64,1);
}
/* Begitu dipanggil ia tampil penuh — tidak ada gunanya setengah redup pada
   ikon yang memang baru saja diminta muncul. */
.layang.tampak .layang-picu,.layang:focus-within .layang-picu{opacity:1;transform:scale(1)}
.layang.buka .layang-picu{transform:scale(1) rotate(135deg)}
.layang-picu:focus-visible{outline:2px solid var(--primary);outline-offset:3px;opacity:1}
.layang-aksi{position:absolute;right:0;bottom:0;width:44px;height:44px}
.layang-btn{
  position:absolute;right:0;bottom:0;width:40px;height:40px;border-radius:50%;
  border:1px solid var(--line);background:var(--surface);color:var(--ink-soft);
  font-size:13px;cursor:pointer;display:grid;place-items:center;
  box-shadow:0 6px 16px -6px rgba(15,23,42,.38);
  transform:translate(0,0) scale(.3);opacity:0;pointer-events:none;
  transition:transform .3s cubic-bezier(.34,1.5,.64,1),opacity .22s ease;
}
.layang.buka .layang-btn{pointer-events:auto}
.layang-btn:hover{border-color:var(--primary);color:var(--primary);background:var(--surface-2)}
.layang-btn:focus-visible{outline:2px solid var(--primary);outline-offset:2px}
/* Busur 5 posisi (90°→180°, radius 96px, berjarak 22,5°). Tombol "koneksi"
   bisa tersembunyi; karena ia anak TERAKHIR, saat tak tampak hanya slot ke-5
   yang kosong dan busurnya tetap rapat tanpa lubang. */
.layang.buka .layang-btn:nth-child(1){transform:translate(-0.0px,-96.0px) scale(1);opacity:1;transition-delay:0ms}
.layang.buka .layang-btn:nth-child(2){transform:translate(-36.7px,-88.7px) scale(1);opacity:1;transition-delay:45ms}
.layang.buka .layang-btn:nth-child(3){transform:translate(-67.9px,-67.9px) scale(1);opacity:1;transition-delay:90ms}
.layang.buka .layang-btn:nth-child(4){transform:translate(-88.7px,-36.7px) scale(1);opacity:1;transition-delay:135ms}
.layang.buka .layang-btn:nth-child(5){transform:translate(-96.0px,-0.0px) scale(1);opacity:1;transition-delay:180ms}
@media (prefers-reduced-motion:reduce){
  .layang-picu,.layang-btn{transition:opacity .01s linear}
  .layang.buka .layang-btn{transition-delay:0ms}
}
/* Di layar sempit busurnya dirapatkan supaya tidak menabrak tepi kiri. */
@media (max-width:420px){
  .layang{right:14px;bottom:14px}
  .layang-btn{width:36px;height:36px}
}

.kb-saring{display:flex;gap:8px;flex-wrap:wrap;align-items:center}
.pc-saring,.ac-saring,.bn-saring,.ju-saring{display:flex;gap:8px;flex-wrap:wrap;align-items:center}

/* ---- Justifikasi absensi ----
   Awalannya ju-, BUKAN jf-. jf- sudah dipakai formulir Jadwal Absen, dan dua
   aturan .jf-hari dengan kekhususan sama membuat yang belakangan menang: tabel
   tujuh hari di formulir jadwal ikut menjadi flex. */
.ju-pilih{margin:14px 0;border:1px solid var(--line);border-radius:9px;background:var(--surface-2);padding:10px 12px}
.ju-pilih-kepala{display:flex;align-items:center;gap:9px;font-size:11.5px;font-weight:700;
                 color:var(--muted);text-transform:uppercase;letter-spacing:.04em;margin-bottom:8px}
.ju-pilih-kepala .ju-tambah{text-transform:none;letter-spacing:0}
/* Dropdown "tambah tanggal tanpa absen": didorong ke kanan bersama tombol Tambah. */
.ju-pilih-kepala .ju-tanpa-sel{margin-left:auto;width:auto;max-width:230px;height:32px;
  padding:3px 10px;font-size:12px;font-weight:600;text-transform:none;letter-spacing:0;margin-bottom:0}
.ju-pilih-kepala .ju-tanpa-sel[hidden]{display:none}
/* Masalah "Tidak Absen" (baris tanpa absen): statis, bukan dropdown. */
.ju-jenis-tetap{display:inline-flex;align-items:center;gap:6px;white-space:nowrap;
  font-size:12.5px;font-weight:600;color:var(--danger)}
.ju-jenis-tetap i{font-size:11px}
/* Daftarnya menggulir: satu bulan bisa berisi belasan hari bermasalah, dan
   kartu pengajuan yang memanjang tanpa ujung membuat tombol Ajukan terdorong
   keluar layar. Kepala tabelnya melekat supaya sembilan lajur itu tetap
   berjudul saat digulir. */
.ju-gulir{max-height:340px;overflow:auto;overscroll-behavior:contain;
          border:1px solid var(--line);border-radius:8px;background:var(--surface)}
.ju-baris{width:100%;border-collapse:collapse;font-size:11.5px}
.ju-baris th{position:sticky;top:0;z-index:1;background:var(--surface-2);
             padding:7px 8px;text-align:left;font-size:10.5px;font-weight:700;color:var(--muted);
             text-transform:uppercase;letter-spacing:.04em;white-space:nowrap;
             border-bottom:1px solid var(--line)}
.ju-baris td{padding:7px 8px;border-bottom:1px solid var(--line-2,rgba(15,23,42,.06));vertical-align:top}
.ju-baris tbody tr:last-child td{border-bottom:0}
.ju-baris .kl-input{margin-bottom:0;width:100%}
.ju-baris .ju-no,.ju-baris .ju-fakta,.ju-baris .ju-buang{padding-top:13px}
.ju-baris .ju-no{width:1%;color:var(--muted);text-align:right;padding-right:4px;
                 white-space:nowrap;font-variant-numeric:tabular-nums}
.ju-baris .ju-fakta{white-space:nowrap;font-variant-numeric:tabular-nums;color:var(--ink-soft);text-align:center}
/* Kolom fakta (Absen In · Jarak In · Absen Out · Jarak Out) dipusatkan — header
   & selnya — agar angka pendek terbaca rapi di tengah, bukan menggantung di kiri. */
.ju-baris th:nth-child(3),.ju-baris th:nth-child(4),
.ju-baris th:nth-child(5),.ju-baris th:nth-child(6){text-align:center}
/* Nilai yang MELEWATI ambangnya ditandai di tempatnya sendiri. Menyebut "jarak
   jauh" tanpa memperlihatkan angkanya bersebelahan dengan angka yang normal
   memaksa orang menebak mana yang sebenarnya dipersoalkan. */
.ju-baris .ju-lewat{color:var(--danger);font-weight:700}
.ju-baris .ju-tgl{min-width:118px;width:118px}
/* Masalah dipatok ~205px (cukup utk "Jarak Check-out (70 m)") supaya ia tak ikut
   menyerap sisa lebar; sisanya jatuh ke Keterangan. */
.ju-baris .ju-jenis-sel{min-width:205px;width:205px}
.ju-baris .ju-alasan-sel{min-width:210px;width:210px}
/* Keterangan = catatan bebas → kolom TERLEBAR; menyerap sisa lebar tabel. */
.ju-baris .ju-ket{min-width:360px}
.ju-baris textarea.kl-input{resize:vertical;min-height:40px;line-height:1.45;font-family:inherit}
.ju-baris .ju-buang{width:1%}
.ju-baris .ju-buang button{border:0;background:none;cursor:pointer;color:var(--muted-2);
                           padding:3px 5px;border-radius:6px;font-size:12px}
.ju-baris .ju-buang button:hover{color:var(--danger);background:var(--danger-tint,rgba(220,38,38,.1))}
/* Galat per baris, bukan satu pesan untuk seluruh formulir: sembilan baris yang
   dikirim satu per satu bisa gagal sebagian, dan "ada yang gagal" tanpa
   menunjuk barisnya tidak bisa ditindaklanjuti. */
.ju-baris .ju-galat-baris{display:block;margin:4px 0 0;color:var(--danger);font-size:10.5px;line-height:1.4}
.ju-baris tr.ju-gagal>td{background:var(--danger-tint,rgba(220,38,38,.06))}
/* Lampiran: input berkas bawaan selebar 250 px akan mengusir lajur lain keluar
   tabel, jadi yang terlihat hanya labelnya. */
.ju-lampir{display:inline-flex;align-items:center;gap:6px;max-width:150px;
           font-size:11px;font-weight:600;color:var(--primary);background:var(--primary-tint);
           border:0;border-radius:20px;padding:5px 11px;cursor:pointer;white-space:nowrap;
           font-family:inherit;margin:0}
.ju-lampir input{position:absolute;opacity:0;width:0;height:0}
.ju-lampir span{overflow:hidden;text-overflow:ellipsis}
.ju-lampir:focus-within{box-shadow:0 0 0 3px var(--primary-tint)}
.ju-kosong{margin:0;padding:10px 2px;font-size:11.5px;color:var(--muted)}
.ju-bantu{font-size:10.5px;color:var(--muted);line-height:1.45;display:block;margin-top:8px}
.ju-jenis{display:inline-flex;align-items:center;gap:5px;white-space:nowrap}
.ju-jenis i{font-size:10.5px;color:var(--muted-2)}
.ju-asli{font-weight:700;color:var(--danger);font-variant-numeric:tabular-nums}
.ju-alasan{display:inline-block;max-width:280px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;vertical-align:bottom}
/* Sub-baris keterangan di bawah kategori (kolom ALASAN datatable). */
.ju-alasan-sub{display:block;max-width:280px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  color:var(--muted);font-size:10.5px;margin-top:2px}
.ju-bukti{display:inline-flex;align-items:center;gap:5px;font-size:11px;font-weight:600;
          color:var(--primary);background:var(--primary-tint);border:none;border-radius:20px;
          padding:3px 10px;cursor:pointer;font-family:inherit}
.ju-nol{color:var(--muted-2)}
.ju-foto-besar{max-width:100%;max-height:70vh;border-radius:9px;display:block;margin:0 auto}
/* Akun tanpa wewenang memutuskan tetap melihat antreannya — server menolak
   juga, jadi ini kenyamanan, bukan penjagaan. */
.ju-baca-saja #tblJustifikasi .act{display:none}
@container isi (max-width:820px){
  /* Sembilan lajur tidak muat; tabelnya digulir mendatar alih-alih diremas. */
  .ju-gulir{overflow:auto}
  .ju-baris{min-width:820px}
}
/* Kisi 12 lajur: tiap isian menyatakan sendiri berapa lajur yang ia butuhkan,
   jadi lebarnya mengikuti isi yang diharapkan alih-alih dibagi rata dua-dua. */
.bn-form{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));gap:12px 14px}
.bn-form > *{grid-column:span 12}
.bn-form > .bn-3{grid-column:span 3}
.bn-form > .bn-4{grid-column:span 4}
.bn-form > .bn-5{grid-column:span 5}
.bn-form > .bn-6{grid-column:span 6}
.bn-form > .bn-12{grid-column:span 12}
/* Label dipaksa satu baris: "Min. WO" satu baris sementara "Extra Bonus Rp"
   membungkus jadi dua akan menurunkan kotaknya dan membuat barisnya bergerigi. */
.bn-form .field > label{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* jadikanCari MENGGANTI tiap <select> dengan tombol yang lebarnya mengikuti
   isinya. Di dalam kisi ini akibatnya terlihat: "BONUS OJT" jadi kotak sempit
   di sebelah kotak angka yang melebar penuh, dan barisnya terbaca
   lompat-lompat meski lajur kisinya sudah benar.
   Jadi tombolnya dibuat memenuhi lajurnya DAN disamakan persis dengan
   .field input — padding, ukuran huruf, sudut, dan latar yang sama — supaya
   satu baris berisi dropdown dan kotak angka tetap terbaca sebagai satu baris.
   Pola yang sama sudah dipakai .kl-form. */
.bn-form .cari-sel{display:block;width:100%}
.bn-form .cari-tombol{
  width:100%;max-width:none;box-sizing:border-box;justify-content:space-between;
  padding:8px 11px;font-size:12.5px;border-radius:var(--r-input);
  background:var(--surface-2);color:var(--ink);
}
.bn-form .cari-sel.buka .cari-tombol,
.bn-form .cari-tombol:focus-visible{
  border-color:var(--primary);box-shadow:0 0 0 3px var(--primary-tint);outline:none}
/* Placeholder "— pilih jabatan —" ditulis redup supaya terbaca sebagai "belum
   dipilih", bukan sebagai nilai yang sudah terpilih. */
.bn-form .cari-tombol.kosong span{color:var(--muted)}
/* Tinggi tiap isian dipaksa sama: kotak angka punya tombol naik-turun bawaan
   peramban yang menambah tingginya beberapa piksel di sebagian peramban. */
.bn-form .field > select,.bn-form .field > input,.bn-form .cari-tombol{min-height:34px}

/* Angka dirata-kanan: digitnya jadi sejajar, dan selisih satu nol lebih mudah
   terlihat pada kolom uang. */
.bn-angka-in{text-align:right;font-variant-numeric:tabular-nums}
/* Satuan ditempel pada labelnya, bukan di dalam kotaknya: kotak <input
   type=number> punya tombol naik-turun bawaan peramban di sisi kanan, dan
   awalan "Rp" di dalamnya akan berdesakan dengan tombol itu. */
.bn-sat{font-weight:600;color:var(--muted-2);font-size:10.5px}
.bn-bantu{font-size:10.5px;color:var(--muted);line-height:1.45;margin:-4px 0 0}

/* Kotak cari di kepala kartu dasbor. Menggantikan sub-judulnya, jadi ukurannya
   dijaga sekecil baris teks yang tadinya ada di sana — kepala kartu yang
   meninggi akan mendorong daftarnya turun di ketiga kartu sekaligus. */
.hc-cari{position:relative;display:flex;align-items:center;margin-top:5px;max-width:220px}
.hc-cari i{position:absolute;left:9px;font-size:10.5px;color:var(--muted-2);pointer-events:none}
.hc-cari input{
  width:100%;border:1px solid var(--line);border-radius:6px;
  padding:5px 9px 5px 26px;font-family:inherit;font-size:11.5px;
  background:var(--surface-2);color:var(--ink);
}
.hc-cari input::placeholder{color:var(--muted-2)}
.hc-cari input:focus{outline:none;border-color:var(--primary);box-shadow:0 0 0 3px var(--primary-tint)}
@media (max-width:820px){ .hc-cari{max-width:none} }
/* Di layar sempit kisinya runtuh jadi dua lajur; isian yang tadinya 3-5 lajur
   tetap punya lebar yang bisa dipakai. */
@media (max-width:520px){
  .bn-form > .bn-3,.bn-form > .bn-4,.bn-form > .bn-5{grid-column:span 6}
}
/* Kolom rujukan yang dijembatani, disebut kecil di sebelah nama tabelnya. */
.snb-fk{color:var(--muted);font-size:10px;font-weight:400}
.sn-tanpa{color:var(--muted);font-style:italic}
/* Kolom uang dan angka dirata-kanan supaya digitnya sejajar. */
#tblBonus td.bn-uang,#tblBonus td.bn-angka{text-align:right;font-variant-numeric:tabular-nums}
/* Akun tanpa wewenang tetap melihat tarifnya, hanya tidak bisa mengubahnya.
   Ikonnya disembunyikan lewat CSS supaya barisnya tetap satu bentuk untuk
   semua peran — server tetap menolak, jadi ini kenyamanan bukan penjagaan. */
.bn-baca-saja #tblBonus .act{display:none}
/* Gembok pada baris cabang utama: penanda, bukan tombol. */
.ac-kunci{display:inline-grid;place-items:center;width:26px;height:26px;color:var(--muted-2);font-size:11px}
/* Jatah yang sudah habis ditandai, bukan dibiarkan sebagai angka nol biasa:
   itulah baris yang perlu diperhatikan sebelum menyetujui cuti berikutnya. */
.pc-habis{color:#7B241C;font-weight:600}
/* Status perbantuan (Sedang Perbantuan): sedang berjalan vs akan datang. */
.pb-stat{display:inline-block;padding:2px 9px;border-radius:999px;font-size:11px;font-weight:600;line-height:1.7;white-space:nowrap}
.pb-stat i{font-size:10px;margin-right:3px}
.pb-stat.jalan{background:rgba(22,163,74,.12);color:#15803d}
.pb-stat.akan{background:rgba(37,99,235,.12);color:#1d4ed8}
.pb-stat.tunggu{background:rgba(217,119,6,.14);color:#b45309}
/* SP/Pinalti: pilihan bentuk pinalti dan penanda baris yang catatannya
   bertentangan dengan persennya. */
/* SP (kiri, sempit) + Pinalti (kanan, mengisi sisa) dalam satu baris. Di layar
   sempit keduanya kembali menumpuk. */
.sp-baris{display:grid;grid-template-columns:minmax(0,120px) minmax(0,1fr);gap:12px;align-items:start}
@media (max-width:480px){ .sp-baris{grid-template-columns:minmax(0,1fr);gap:0} }
.sp-pinalti{display:grid;grid-template-columns:auto minmax(0,1fr);gap:12px;align-items:center}
.sp-nilai .kl-input{margin-bottom:0}
@media (max-width:480px){ .sp-pinalti{grid-template-columns:minmax(0,1fr);gap:6px} }
.sp-pilih{display:flex;gap:16px;align-items:center;font-size:12px;white-space:nowrap}
.sp-pilih label{display:flex;gap:6px;align-items:center;cursor:pointer;color:var(--ink)}
.sp-pilih input{accent-color:var(--brand)}
.sp-pisah{opacity:.45}
.sp-selisih{color:#B7791F;margin-left:4px;cursor:help}
/* Nama karyawan MERAH = pinaltinya masih berlaku di periode bulan berjalan
   (masih akan memotong gaji di tarikan bulan ini). */
.name-cell.sp-aktif{color:var(--danger)}
/* Simulasi gaji: tabel berjudul dua tingkat. Dibuat sendiri, bukan lewat
   bindTable — lihat alasannya di skripnya. */
/* Kotaknya menggulir DUA arah: ke kanan karena 18 kolom, ke bawah karena
   sebulan bisa 31 baris. Tingginya dipatok SEBELAS BARIS, dihitung skripnya
   dari tinggi baris yang sebenarnya (lihat sgTinggi) — bukan angka piksel yang
   akan meleset begitu ukuran huruf atau jaraknya berubah. Nilai di sini hanya
   jaring pengaman sebelum pengukuran pertama selesai. */
/* Tinggi tetap 440px terlalu tinggi untuk layar pendek (ponsel mendatar,
   jendela yang dikecilkan): kotaknya akan lebih tinggi daripada layarnya dan
   baris kontrol di bawahnya terdorong keluar. min() menahannya pada tinggi
   layar perangkat, max() menjaga agar tidak menyusut jadi tidak terbaca. */
.sg-bungkus{overflow:auto;border:1px solid var(--line);border-radius:9px;
  max-height:min(440px,max(220px,calc(100dvh - 260px)));overscroll-behavior:contain}
/* Detail Gaji (tab Gaji Absensi di Tarikan Gaji): tabel sebulan penuh bisa 31 baris,
   jadi TINGGINYA mengikuti layar perangkat — bukan dipatok 440px. Gulir di DALAM
   tabel bila melebihi; di layar kecil tetap ≥220px. Hanya di sini (Simulasi Gaji
   tak terpengaruh). */
[data-tgdpane="absensi"] .sg-bungkus{
  /* Cadangan sebelum JS mengukur: ikut tinggi layar supaya halaman tak ikut
     bergulir. sgTinggi() lalu mematoknya tepat 10 baris (atau viewport, yang
     terkecil). Jangan pasang lantai 600px — di layar pendek itu melebihi
     viewport & memunculkan scroll halaman. */
  max-height:calc(100dvh - 150px);
}
/* Tab Bonus WO: tabel WO juga MENGIKUTI tinggi layar (gulir di dalam), bukan
   dipatok 440px. Offsetnya lebih besar daripada Gaji Absensi karena ada baris
   kartu ringkasan (Verify/Non Verify dll.) di atas tabel. Di layar kecil tetap
   ≥220px. */
[data-tgdpane="bonus"] .sg-bungkus{
  max-height:max(220px, calc(100dvh - 330px));
}
/* border-collapse:separate wajib untuk kolom beku: dengan collapse, garis
   antar sel dimiliki tabel, bukan selnya, sehingga sel yang menempel kehilangan
   garisnya dan isi di belakangnya menyembul. */
.sg-tabel{width:100%;border-collapse:separate;border-spacing:0;font-size:12px}
.sg-tabel th,.sg-tabel td{padding:7px 10px;border-top:1px solid var(--tepi-terang);
  border-left:1px solid var(--tepi-terang);border-bottom:1px solid var(--tepi-gelap);
  border-right:1px solid var(--tepi-gelap);white-space:nowrap;background:var(--surface)}
/* Kolom terakhir tanpa garis kanan — garis di tepi kotaknya sendiri sudah ada,
   dan dua garis berhimpit terbaca sebagai satu garis tebal yang salah. */
.sg-tabel th:last-child,.sg-tabel td:last-child{border-right:none}
/* Batas ANTAR KELOMPOK ditebalkan: garis seragam membuat "Telat" dan "Time"
   milik Absen Out terbaca sama dekatnya, padahal yang satu masih satu kelompok
   dan yang lain kelompok berikutnya. */
.sg-batas{border-left:2px solid var(--line)}
/* Kolom Jadwal (jam seharusnya) diredupkan sedikit supaya "Time" (jam absen
   sebenarnya) di sebelahnya yang lebih menonjol. */
.sg-jadwal{color:var(--muted)}
/* Kolom "Cabang" (tempat absen). Tag "luar" = absen di cabang lain (perbantuan). */
.sg-cabang{white-space:nowrap}
.sg-jabatan{white-space:nowrap}
.sg-cab-luar{display:inline-block;padding:0 6px;border-radius:999px;font-size:10px;font-weight:700;background:var(--warning-tint,#fef3c7);color:var(--warning,#b45309);margin-left:4px}
/* Kolom "Informasi" (dulu "Reposisi"): lencana perpindahan per tanggal. */
.sg-info{text-align:center;white-space:normal}
.sg-info-wrap{display:flex;flex-direction:column;gap:3px;align-items:center}
.sg-info-item{font-size:11px;white-space:nowrap}
.sg-info-item small{font-weight:600;opacity:.85}
.sg-info-jalan{font-style:italic}
/* Kolom "Justifikasi" (setelah Problem) di Detail/Simulasi Gaji. */
.sg-jf{display:inline-block;padding:1px 9px;border-radius:999px;font-size:11px;font-weight:700;white-space:nowrap}
.sg-jf-ya{background:var(--success-tint);color:var(--success)}
.sg-jf-sebagian{background:#FEF6E7;color:#7E5109}
.sg-jf-tunggu{background:#FEF6E7;color:#7E5109}
.sg-jf-reject{background:var(--danger-tint);color:var(--danger)}
/* Bilah tab-dalam Detail Gaji yang dipindah ke bilah tab halaman: mentok kanan,
   tanpa garis bawah sendiri (garis bilah induk yang dipakai). */
.tgd-subbar{margin-left:auto;border-bottom:0;margin-bottom:0;padding-left:12px}
/* Periode + tombol Tarik yang dipindah ke bilah tab halaman: mentok kanan,
   sejajar vertikal dengan tombol tab, tanpa garis bawah sendiri. Mutually
   exclusive dengan .tgd-subbar (keduanya margin-left:auto; hanya satu tampil). */
.tg-tabalat{margin-left:auto;display:inline-flex;align-items:center;gap:10px;
  align-self:center;padding-bottom:4px;flex-wrap:wrap;justify-content:flex-end}
.tg-tabalat[hidden]{display:none}
.tg-tabalat .dt-periode{flex-wrap:nowrap}
/* Kotak cari kini anggota TERAKHIR & paling kanan di bilah tab — margin-right:auto
   dari aturan umum .tg-cari-bar justru menariknya menjauh dari tepi kanan, jadi
   dinetralkan di sini. */
.tg-tabalat .tg-cari-bar{margin-right:0}
/* Bilah kemajuan di bilah tab: lebih ringkas supaya bersama tombol & kotak cari
   tetap muat sebaris; kalau sempit, tabbar membungkusnya ke bawah. */
.tg-tabalat .tg-kemajuan{width:clamp(140px,18vw,220px)}
/* Baris kendali tabel Hasil Tarikan (.dt-top dipindah ke sini) di bilah tab:
   mentok kanan, sejajar tab. .dt-top sudah flex; di sini padding bawahnya
   dibuang (ia tak lagi di atas tabel) dan isinya dirapatkan ke kanan. */
.tg-hasilalat{margin-left:auto;align-self:center}
.tg-hasilalat[hidden]{display:none}
.tg-hasilalat .dt-top{padding:0;justify-content:flex-end}
/* .dt-lead (tombol mata) tak perlu lagi mendorong .dt-trail jauh ke kanan di
   wadah seukuran-isi ini — jarak antar-anak cukup gap .dt-top. */
.tg-hasilalat .dt-trail{margin-left:0}
/* Baris total di tab Bonus Perbantuan: dipertegas dari baris rincian di atasnya. */
.pb-total td{border-top:2px solid var(--line);background:var(--surface-2)}
/* Lama hari di kolom Tanggal: keterangan, bukan angka utama. */
.pb-hari{color:var(--muted);font-weight:600;white-space:nowrap}
/* SELURUH kolomnya rata tengah — judul maupun isinya. Ditulis sekali di sini,
   bukan kelas per kolom: kolom yang ditambahkan nanti ikut dengan sendirinya,
   dan tidak ada satu kolom yang diam-diam tertinggal rata kiri. */
.sg-tabel th,.sg-tabel td{text-align:center}
.sg-tabel thead th{
  background:var(--surface-2);color:var(--muted);font-size:10.5px;font-weight:800;
  text-transform:uppercase;letter-spacing:.04em;position:sticky;z-index:2;
}
/* Judul tingkat pertama menempel di puncak; tingkat kedua tepat di bawahnya.
   Jaraknya diambil dari tinggi baris pertama, bukan ditebak. */
.sg-tabel thead tr:first-child th{top:0}
/* Jarak baris kedua dipasang skripnya dari tinggi baris pertama yang DIUKUR;
   nilai di sini hanya jaring pengaman sebelum pengukuran pertama selesai. */
.sg-tabel thead tr:nth-child(2) th{top:29px}
.sg-tabel thead th.sg-grup{border-right:1px solid var(--line)}
.sg-tabel tbody tr:hover td{background:var(--surface-2)}
/* Baris BERBONUS tapi BELUM terverifikasi (Non Verify) ditandai merah muda —
   bonusnya tidak masuk Total Bonus. Ditaruh SESUDAH aturan :hover agar menang. */
.sg-tabel tbody tr.bw-nonverif td{background:var(--danger-tint,#fde8e8)}
.sg-tabel tbody tr.bw-nonverif:hover td{background:#fbd0d0}
/* Riwayat Tarikan Gaji = datatable RINGKAS: barisnya pendek & rapat, bukan
   setinggi tabel Detail Gaji yang berbagi kelas .sg-tabel. Scoped ke tabelnya. */
#tblTgRiwayat th,#tblTgRiwayat td{padding:4px 9px;font-size:11.5px}
#tblTgRiwayat .tg-hapus{padding:2px 5px}
#tblTgRiwayat .tg-st{padding:1px 8px;font-size:10px}
/* Kolom beku: tetap di tempatnya saat digulir ke kanan. Latarnya wajib —
   tanpa itu isi kolom di belakangnya menyembul lewat. */
.sg-beku{position:sticky;z-index:1}
.sg-tabel thead .sg-beku{z-index:3}
/* Garis tegas di batas terakhirnya: tanpa penanda, kolom yang diam dan kolom
   yang bergerak terbaca sebagai satu kesatuan yang patah. */
.sg-beku-tepi{box-shadow:inset -1px 0 0 var(--line),6px 0 10px -8px rgba(15,23,42,.35)}
/* Angka tetap berlebar-tetap meski dirata-tengahkan: tanpa ini digit rupiah
   bergoyang dari baris ke baris dan kolomnya jadi sulit dipindai. */
.sg-uang,.sg-no,.sg-tengah{font-variant-numeric:tabular-nums}
.sg-telat{color:#B7791F}
/* "Ya" adalah tombol: ketentuannya muncul saat diklik. */
.sg-problem{border:none;cursor:pointer;font:inherit;font-size:10px;font-weight:800}
.sg-problem:focus-visible{outline:2px solid var(--primary);outline-offset:2px}
.sg-tip{
  position:fixed;z-index:120;
  min-width:230px;max-width:320px;padding:9px 11px;text-align:left;white-space:normal;
  background:var(--surface);border:1px solid var(--line);border-radius:9px;
  box-shadow:0 12px 28px -8px rgba(15,23,42,.28);
}
.sg-tip b{display:block;font-size:10px;font-weight:800;text-transform:uppercase;
  letter-spacing:.04em;color:var(--muted);margin-bottom:5px}
.sg-tip ul{margin:0;padding-left:16px}
.sg-tip li{font-size:11.5px;line-height:1.55;color:var(--ink)}
.sg-kosong{padding:22px;text-align:center;color:var(--muted)}
/* Tanda "tidak masuk": hanya yang terpakai yang bertanda. */
/* Periode didorong ke ujung kanan bilah saringan: ketiga dropdown di kiri
   memilih SIAPA, periode memilih KAPAN — dua pertanyaan berbeda, dan
   memisahkannya membuat bilahnya terbaca sekali lihat. */
#page-fin-simulasi .pr-saring{width:100%}
#page-fin-simulasi .dt-periode{margin-left:auto}
/* --- Tarikan Gaji --- */
/* Periode dan tombolnya duduk tepat di atas kiri daftar tiket, di dalam tab:
   di sinilah tarikan dimulai dan di sini pula hasilnya tercatat, jadi tidak
   ada gunanya memisahkan keduanya ke bilah tersendiri di luar kartu. */
.tg-isi{min-width:0}
/* Periode di ujung kanan bilah tab. Bukan tab, jadi tanpa rangka tombol dan
   tanpa garis bawah aktif — ia keterangan, bukan tempat yang bisa dituju. */
/* Identitas didorong ke kanan; penanda periode mengekor tepat di sebelahnya. */
/* Nama di ujung KIRI bilah tab dalam; bilah tabnya sendiri sudah didorong ke
   kanan oleh margin-left:auto miliknya, jadi keduanya duduk di dua ujung baris
   yang sama tanpa pengisi di tengah. */
#tgdOrangBar{align-self:center;min-width:0;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}
#tgdOrangBar b{font-size:13px}
/* Penanda periode selalu di ujung kanan bilah tab luar. */
.tg-periode-tab{margin-left:auto;align-self:center;padding:0 2px;
  font-size:12.5px;font-weight:800;color:var(--primary);white-space:nowrap}

.tg-cari-bar{display:flex;align-items:center;gap:12px}
.tg-cari-bar[hidden]{display:none}
.tg-cari-info{font-size:11px;color:var(--muted)}
.tg-hapus{background:none;border:none;padding:4px 6px;border-radius:7px;cursor:pointer;
  color:var(--muted);line-height:1}
.tg-hapus:hover{background:#FDEDEC;color:#C0392B}
.tg-hapus[disabled]{opacity:.35;cursor:default;background:none;color:var(--muted)}
/* Kirim Slip (baris tiket Tarikan Gaji): biru bila tiket itu sudah pernah mengirim slip. */
.tg-kirim{background:none;border:none;padding:4px 6px;border-radius:7px;cursor:pointer;
  color:var(--muted);line-height:1;white-space:nowrap}
.tg-kirim:hover{background:#EEF0FF;color:#4F46E5}
.tg-kirim.on{color:#4F46E5}
.tg-kirim.jalan{color:#4F46E5;font-size:10.5px;cursor:default}
.tg-kirim[disabled]:not(.jalan){opacity:.35;cursor:default;background:none;color:var(--muted)}
/* Sudah terkirim tuntas: bukan "tidak tersedia" (abu pudar) tapi "selesai". */
.tg-kirim.tuntas[disabled]{opacity:1;color:#16A34A}
.tg-penerima{background:none;border:none;padding:2px 5px;border-radius:7px;cursor:pointer;
  color:var(--muted);line-height:1}
.tg-penerima:hover{background:#EEF0FF;color:#4F46E5}
.tg-penerima[disabled]{cursor:progress;opacity:.5}
/* Modal Penerima Slip: chip di ATAS tabel, kotak cari di ujung kanannya. */
.tgr-chips.tgp-alat{margin:0 2px 10px;align-items:center}
.tgp-cari{margin-left:auto;min-width:220px;padding:6px 10px;border:1px solid var(--line);
  border-radius:8px;font:inherit;font-size:12.5px;background:var(--card,#fff);color:var(--ink)}
#tblTgRiwayat .tg-kirim{padding:2px 5px}
/* Kepala tab Detail Gaji: tombol kembali dan nama orangnya. Nama disebut di
   sini DAN di label tabnya — label tab terpotong di layar sempit, dan slip
   gaji yang tidak jelas milik siapa lebih berbahaya daripada berulang. */
button.tgd-buka{background:none;border:none;padding:0;font:inherit;cursor:pointer;
  color:var(--primary);text-align:left;text-decoration:underline;text-underline-offset:2px}
button.tgd-buka:hover{text-decoration-thickness:2px}
/* Nama, tombol kembali, dan bilah tab dalam berbagi SATU baris. Tabnya
   didorong mentok kanan; garis bawah bilah tab dilepas karena di sini garis
   pemisahnya sudah dipegang tepi bawah barisnya sendiri — dua garis bertumpuk
   hanya menebalkan satu batas. */
.tgd-kep{display:flex;align-items:center;gap:12px;flex-wrap:wrap;
  border-bottom:1px solid var(--line);margin:0 0 10px}
.tgd-orang{font-size:12px;color:var(--muted);min-width:0;padding:6px 0}
.tgd-orang b{font-size:13px;color:var(--ink);margin-right:8px}
.tgd-tabbar{margin-left:auto;border-bottom:none;margin-bottom:0}
/* Di layar sempit barisnya membungkus; tabnya kembali rata kiri supaya tidak
   menggantung sendirian di kanan tanpa apa pun di sebelahnya. */
@container isi (max-width:760px){
  .tgd-tabbar{margin-left:0;width:100%}
}
/* Diturunkan dari bilah tab dan DIRAPATKAN ke tabelnya: bilah yang menempel di
   tab terbaca seperti bagian dari tab, sementara jarak lebar ke tabel membuat
   keduanya tampak tidak berhubungan — padahal tombol di bilah inilah yang
   mengisi tabel itu. */
/* Kotak cari di kiri, periode dan tombolnya di kanan. Yang mendorong pemisahan
   itu margin-right:auto pada kotak cari, bukan justify-content:flex-end pada
   barisnya — dengan begitu sisi kirinya tetap terpakai saat kotak cari ada,
   dan tetap rata kanan kalau suatu saat ia tidak ada. */
/* .tg-cari-bar: aturan umum masih dipakai (kini di dalam #tgTabAlat). margin-right
   auto dinetralkan di konteks bilah tab (lihat .tg-tabalat .tg-cari-bar). */
.tg-cari-bar{margin-right:auto}
/* Periode pada label tab: sengaja lebih redup dan lebih kecil dari nama tabnya
   - ia keterangan, bukan judul. */
.tg-per{font-weight:600;color:var(--muted);font-size:11px;margin-left:5px}
.tabbtn.active .tg-per{color:var(--primary);opacity:.8}
/* Nomor tiket bisa diklik untuk membuka hasilnya kembali. Dibuat seperti
   tautan, bukan tombol berkotak: satu kolom penuh tombol membuat tabelnya
   terbaca seperti papan kendali, padahal ia daftar riwayat. */
.tg-tiket{background:none;border:none;padding:0;font:inherit;font-size:inherit;
  color:var(--primary);font-weight:700;cursor:pointer;text-decoration:underline;
  text-underline-offset:2px;font-variant-numeric:tabular-nums}
.tg-tiket:hover{text-decoration-thickness:2px}
.tg-tiket[disabled]{color:var(--muted);cursor:default;text-decoration:none}
/* Kemajuan menempel pada tombolnya, bukan memakan satu baris sendiri. Lebarnya
   dipatok supaya baris ini tidak melompat-lompat setiap pesan tahapnya
   berganti panjang. */
.tg-kemajuan{display:inline-flex;flex-direction:column;justify-content:center;gap:5px;
  width:clamp(150px,22vw,260px);min-width:0}
.tg-kep{display:flex;align-items:baseline;gap:7px;min-width:0}
.tg-kep b{font-size:10.5px;color:var(--primary);font-variant-numeric:tabular-nums;
  white-space:nowrap}
.tg-kep span{font-size:10.5px;color:var(--ink-soft);white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis}
/* Bilah kemajuan sengaja TIDAK berpura-pura tahu persen yang sebenarnya:
   agregat OSS tidak melaporkan kemajuan, jadi yang ditunjukkan adalah TAHAP
   keberapa dari lima. Bilah palsu yang merangkak mulus lebih menyesatkan
   daripada bilah yang melompat per tahap. */
/* Bilah dan angkanya sebaris; angkanya berlebar-tetap supaya bilahnya tidak
   memendek-memanjang tiap kali angkanya berganti dari 1 digit ke 3. */
.tg-garis{display:flex;align-items:center;gap:8px}
.tg-persen{flex:0 0 auto;min-width:34px;text-align:right;font-size:10.5px;
  font-weight:800;color:var(--primary);font-variant-numeric:tabular-nums}
.tg-bar.gagal+.tg-persen,.tg-garis .tg-bar.gagal~.tg-persen{color:var(--danger,#C0392B)}
.tg-bar{flex:1;display:block;height:5px;border-radius:99px;background:var(--line);overflow:hidden}
.tg-bar i{display:block;height:100%;width:0;border-radius:99px;
  background:var(--primary);transition:width .35s ease}
.tg-bar.gagal i{background:var(--danger,#C0392B)}
/* Dua riwayat berdampingan: membandingkan periode yang sama di dua sistem
   adalah satu-satunya cara memeriksa apakah perlakuannya benar-benar sudah
   sama, dan perbandingan yang memaksa berpindah layar tidak akan dilakukan. */
.tg-nota{margin:9px 0 0;font-size:10.5px;color:var(--muted);line-height:1.55}
/* Riwayat pun bisa lebih lebar dari kolomnya di layar sempit: yang digulir
   TABELNYA, bukan seluruh halaman. */
/* Dulu hanya mendatar. Daftar tiket bisa panjang, dan tanpa batas tegak
   kartunya memanjang melewati layar sehingga baris di bawahnya tidak terjangkau
   tanpa menggulir seluruh halaman. */
/* Tinggi daftar mengikuti LAYAR, bukan dipaku 420px: tabel tumbuh memakai ruang
   yang ada (sampai ~layar penuh) lalu baru menggulir bila barisnya lebih banyak,
   jadi tidak lagi menyisakan area kosong besar di bawahnya pada layar tinggi.
   Lantai 240px menjaga minimal beberapa baris di layar pendek. */
.tg-gulir{overflow:auto;border:1px solid var(--line);border-radius:9px;
  max-height:max(240px,calc(100dvh - 250px));overscroll-behavior:contain}
.tg-gulir .sg-tabel{min-width:430px}
/* Tabel hasil 20 kolom tidak akan pernah muat di layar ponsel, dan memang
   tidak perlu: bindTable sudah membungkusnya dengan .table-scroll yang
   menggulir dua arah. Yang ditambahkan di sini hanya penjaga agar pembungkus
   tabnya BOLEH menyempit — tanpa min-width:0 sebuah anak grid/flex menolak
   mengecil di bawah lebar isinya, dan yang melar jadi halamannya, bukan
   tabelnya. Menumpuk overflow kedua di sini justru melahirkan dua bilah gulir
   dan mematahkan judul tabel yang menempel. */
#page-fin-tarikan-gaji .tabpane,
#page-fin-tarikan-gaji .tg-dtcard{min-width:0;max-width:100%}
/* Header Hasil Tarikan Gaji kini 3 baris (Tambahan → Bonus WO → Verify/Non
   Verify). Area gulirnya menyediakan tinggi header 3× supaya jumlah baris data
   yang terlihat tak berkurang terdesak header yang lebih tinggi. Hanya tabel
   HASIL (.tg-dtcard), bukan tabel Detail Gaji di halaman yang sama. */
#page-fin-tarikan-gaji .tg-dtcard .table-scroll{
  max-height:calc(var(--dt-head) * 3 + var(--dt-row) * var(--dt-rows,20) + 2px);
}
@supports (height:100dvh){
  #page-fin-tarikan-gaji .tg-dtcard .table-scroll{
    max-height:min(
      calc(var(--dt-head) * 3 + var(--dt-row) * var(--dt-rows,20) + 2px),
      max(180px, calc(100dvh - 240px))
    );
  }
}
/* Di layar sempit tombol dan kemajuannya turun ke barisnya sendiri dan
   memanjang penuh: berdesakan di sisa lebar bersama pemilih periode membuat
   bilah kemajuannya menyempit sampai tidak terbaca. */
@container isi (max-width:760px){
  .tg-jalankan{width:100%}
  .tg-kemajuan{width:auto;flex:1}
}
/* Enam kolom pertama tabel hasil — No sampai Gaji Harian — tetap di tempatnya
   saat tabelnya digulir ke kanan. Angka di kanan (absen, bonus, kasbon) tidak
   ada artinya tanpa nama dan jabatan yang melahirkannya.
   Latar sel beku WAJIB legap: sel tembus pandang akan memperlihatkan kolom
   yang lewat di belakangnya. Warnanya mengikuti warna baris aslinya, termasuk
   saat baris itu disorot. */
/* Tingkat SP: satu-satunya kolom di baris tarikan yang menyatakan sanksi. */
.tg-sp{display:inline-flex;align-items:center;gap:4px;font-weight:700;color:var(--danger);
       background:var(--danger-tint);border-radius:20px;padding:1px 8px;font-size:11px;white-space:nowrap}
.tg-sp small{font-weight:600;opacity:.8}
.tg-nol{color:var(--muted-2)}
.tg-kosong{color:var(--muted-2);font-style:italic}
/* Kolom beku — dipakai tabel mana pun yang mendaftarkannya lewat pasangBeku().
   Warnanya SAMA PERSIS dengan latar baris dan kepala tabel biasa (#FBFBFC dan
   #E9EAF0): sel beku yang sedikit berbeda warna akan terbaca sebagai kolom
   yang disorot, padahal ia cuma tidak ikut bergulir. */
.dt-card table .dt-beku{position:sticky;z-index:1;background:#FBFBFC}
/*
 * ============ Judul kolom beku HARUS di atas judul yang bergulir ============
 *
 * Ditulis dua kali, yang kedua dengan [rowspan], dan itu bukan pengulangan
 * yang bisa dibuang: di atas ada .dt-card table thead th[rowspan]{z-index:3}
 * untuk kepala BERTINGKAT, dan kekhususannya (0,2,3) MENGALAHKAN pemilih
 * berkelas .dt-beku (0,2,2). Akibatnya judul yang beku ikut turun ke 3 —
 * sederajat dengan judul yang bergulir di sebelahnya, sehingga urutan DOM yang
 * menentukan siapa di atas, dan yang belakangan (Jabatan, Cabang) menimpa
 * judul beku di depannya.
 *
 * Gejalanya persis seperti yang dilaporkan: tabel digulir ke kanan, lalu
 * "MASA KERJA" lenyap dan "JABATAN" duduk menempel pada "NAMA KARYAWAN",
 * sementara SELNYA di bawah tetap pada tempatnya. Tidak ada galat yang
 * dilempar — hanya kepala tabel yang berbohong tentang isi di bawahnya.
 *
 * [rowspan] di pemilih kedua menaikkan kekhususannya ke (0,3,3), jadi ia
 * menang atas aturan itu tanpa !important dan tanpa bergantung pada urutan
 * penulisan di berkas.
 */
.dt-card table thead .dt-beku{background:#E9EAF0}
/*
 * ============ Celah sub-piksel di antara dua sel beku ============
 *
 * Jarak kiri tiap sel beku adalah lebar kolom yang dijumlahkan, dan lebar itu
 * PECAHAN (199,797px). Peramban membulatkan posisi cat tiap sel sticky
 * sendiri-sendiri, jadi di batas antara dua sel beku tersisa celah selebar
 * kurang dari satu piksel — dan yang tergambar di celah itu adalah kolom yang
 * sedang tergulir di bawahnya. Gejalanya: potongan huruf tegak (":", "l", "|")
 * berbaris rapi di tepi kiri lajur Masa Kerja, di SETIAP baris.
 *
 * Ditutup dengan pelebaran 1px ke kiri, BUKAN dengan menggeser posisi selnya:
 * menggeser akan memotong angka yang rata kanan di lajur sebelumnya.
 *
 * `background:inherit` membuat pelebarannya ikut warna selnya sendiri — putih
 * lembut di isi, abu-abu di kepala, dan warna sorot saat barisnya disorot —
 * tanpa perlu satu aturan untuk tiap keadaan yang cepat atau lambat akan
 * ketinggalan satu.
 */
.dt-card table .dt-beku::before{
  content:"";position:absolute;top:0;bottom:0;left:-1px;width:1px;
  background:inherit;pointer-events:none;
}
/* Sel pertama tidak perlu — di kirinya tidak ada apa-apa selain tepi kotaknya,
   dan pelebaran di sana justru menutupi garis tepi tabel. Ditandai dengan
   KELAS dari bekukanKolom(), bukan dengan mengintip atribut style: jarak kiri
   ditulis JS sebagai teks, dan pemilih yang mencocokkan potongan teks itu akan
   diam-diam berhenti bekerja begitu bentuk penulisannya berubah. */
.dt-card table .dt-beku-awal::before{display:none}
.dt-card table thead th.dt-beku,
.dt-card table thead th.dt-beku[rowspan]{z-index:5}
.dt-card table tbody tr:hover .dt-beku{background:var(--primary-tint)}
/* Garis tegas di batas terakhirnya: tanpa penanda, kolom yang diam dan kolom
   yang bergerak terbaca sebagai satu kesatuan yang patah. */
.dt-card table .dt-beku-tepi{box-shadow:inset -1px 0 0 var(--line),6px 0 10px -8px rgba(15,23,42,.35)}
/* Baris Hasil Tarikan Gaji yang DIPILIH (klik) → KUNING pada SELURUH sel,
   termasuk kolom beku & kolom "Non Verify" (abu). Di-scope ke #tblTarikan (ID
   mengalahkan aturan hover/kelas) agar tak terganggu. Klik lagi = batal. */
#tblTarikan tbody tr.tg-row-sel td,
#tblTarikan tbody tr.tg-row-sel .dt-beku,
#tblTarikan tbody tr.tg-row-sel td.dt-kol-abu{background:#fef3c7}
#tblTarikan tbody tr.tg-row-sel:hover td,
#tblTarikan tbody tr.tg-row-sel:hover .dt-beku,
#tblTarikan tbody tr.tg-row-sel:hover td.dt-kol-abu{background:#fde9a8}
/* Angka yang perlu diperiksa ditandai merah. Bukan seluruh selnya yang
   diwarnai melainkan angkanya saja: latar merah sepanjang enam kolom membuat
   tabelnya terbaca seperti peringatan besar, padahal yang dimaksud adalah
   "lihat angka ini". */
.tg-buruk{color:#C0392B;font-weight:800}
/*
 * Kolom Action disembunyikan SECARA BAWAAN dan dimunculkan tombol mata.
 *
 * Disembunyikan lewat sel penandanya sendiri (.tg-kol-aksi di judul,
 * .tg-sel-aksi di isi), BUKAN lewat nth-child: nomor lajur di tabel ini sudah
 * bergeser dua kali (kolom Perlakuan dilepas, kolom Action disisipkan), dan
 * angka yang ditulis di CSS tidak ikut bergeser bersamanya — yang tersembunyi
 * diam-diam menjadi lajur tetangganya.
 *
 * display:none, bukan visibility/lebar nol: lajurnya harus benar-benar hilang
 * dari aliran tabel, bukan menyisakan celah kosong selebar satu kolom.
 */
#tblTarikan:not(.tg-aksi-on) th.tg-kol-aksi,
#tblTarikan:not(.tg-aksi-on) td:has(.tg-sel-aksi){display:none}
/* Tombol mata di baris kendali. Abu-abu = kolomnya tersembunyi, biru = tampil.
   Ikonnya tetap sama; hanya warnanya yang berganti — pergantian bentuk membuat
   orang mengira ia menekan tombol yang berbeda. */
/* Gaji harian di daftar Reposisi: ikon mata sampai diklik.
   Lebarnya dijaga minimum supaya lajurnya tidak melompat-lompat saat satu
   baris dibuka dan yang lain masih tertutup. */
.rp-gaji{border:1px solid transparent;background:none;color:var(--muted-2);
         border-radius:6px;padding:2px 8px;min-width:86px;cursor:pointer;
         font-family:inherit;font-size:12px;line-height:1.5;transition:.12s}
.rp-gaji:hover{border-color:var(--line);background:var(--surface-2);color:var(--ink-soft)}
.rp-gaji.buka{color:var(--ink);font-variant-numeric:tabular-nums;font-weight:600}
.rp-gaji:focus-visible{outline:none;border-color:var(--primary);box-shadow:0 0 0 3px var(--primary-tint)}
.rp-gaji-tutup{color:var(--muted-2);cursor:help}

/* ---------- Dialog persetujuan reposisi ---------- */
/* Dua pilihan mode dibuat sebagai KARTU, bukan dua radio berdampingan:
   keduanya memindahkan orang ke tempat yang berbeda, dan bedanya perlu terbaca
   tanpa harus diingat. Tidak ada yang tercentang lebih dulu — pilihan bawaan
   pada keputusan berakibat adalah pilihan yang tidak dibaca. */
.rp-mode{display:grid;gap:8px;margin:12px 0 4px}
/* Permanent & Perbantuan satu baris (dua kolom), tanpa keterangan panjang. */
.rp-mode-row{grid-template-columns:1fr 1fr}
.rp-mode-row .rp-mode-p{align-items:center}
.rp-mode-p{display:flex;gap:10px;align-items:flex-start;padding:10px 12px;cursor:pointer;
           border:1px solid var(--line);border-radius:8px;background:var(--surface-2);transition:.12s}
.rp-mode-p:hover{border-color:var(--muted-2);background:var(--surface)}
.rp-mode-p input{margin:2px 0 0;accent-color:var(--primary);flex:none}
.rp-mode-p b{display:block;font-size:13px;color:var(--ink)}
.rp-mode-p small{display:block;margin-top:2px;font-size:11.5px;color:var(--muted);line-height:1.45}
.rp-mode-p:has(input:checked){border-color:var(--primary);background:var(--primary-tint)}
.rp-mode-p:has(input:focus-visible){box-shadow:0 0 0 3px var(--primary-tint)}
/* Jenis Mutasi (read-only) di dialog persetujuan: pil Jenis + chip Selesai/Bonus. */
.rp-jenis{display:flex;flex-wrap:wrap;align-items:center;gap:8px 10px;margin:10px 0 2px}
.rp-jenis-lbl{font-size:12px;font-weight:600;color:var(--muted)}
.rp-jenis-pil{display:inline-flex;align-items:center;gap:6px;padding:4px 11px;border-radius:999px;
              font-size:12.5px;font-weight:700}
.rp-jenis-pil i{font-size:11px}
.rp-jenis-permanen{background:rgba(22,163,74,.12);color:#15803d}
.rp-jenis-perbantuan{background:rgba(37,99,235,.12);color:#1d4ed8}
.rp-jenis-temporer{background:rgba(217,119,6,.14);color:#b45309}
.rp-jenis-x{display:inline-flex;align-items:center;gap:5px;font-size:12px;color:var(--muted)}
.rp-jenis-x i{font-size:11px;opacity:.8}
.rp-jenis-bonus{font-weight:700;color:var(--ink)}
/* Baris Bonus + Tanggal Efektif di bawah Catatan (modal persetujuan MUTASI). */
.rp-eff-bawah{display:flex;flex-wrap:wrap;align-items:center;gap:10px;margin:10px 0 2px}
.rp-eff-kanan{margin-left:auto}
@media (max-width:520px){.rp-eff-bawah .rp-eff-kanan{margin-left:0}}
/* Dialog "Kembalikan ke cabang utama" (perbantuan): info lama (1 baris) + isian bonus. */
.rp-kb-info{display:flex;flex-wrap:wrap;align-items:center;gap:4px 8px;margin:10px 0 4px;
  padding:10px 12px;border-radius:9px;background:rgba(37,99,235,.08)}
.rp-kb-lbl{font-size:13px;font-weight:600;color:var(--muted)}
.rp-kb-hari{font-size:14px;font-weight:700;color:#1d4ed8}
.rp-kb-rentang{font-size:12.5px;color:var(--muted)}
/* Form kembalikan perbantuan: Tgl Efektif + datepicker Tgl Selesai + Lama (live). */
.rp-kb-form{display:flex;flex-direction:column;gap:9px;margin:10px 0 4px;
  padding:11px 13px;border-radius:9px;background:rgba(37,99,235,.08)}
.rp-kb-row{display:flex;align-items:center;justify-content:space-between;gap:12px}
.rp-kb-row .rp-kb-lbl{font-size:13px}
.rp-kb-date{padding:6px 10px;border:1px solid var(--line);border-radius:7px;
  font:inherit;font-size:13px;color:var(--ink);background:var(--surface)}
.rp-kb-rate{max-width:180px}
.rp-kb-total{border-top:1px dashed var(--line);padding-top:8px;margin-top:1px}
/* Judul bagian di dialog kembalikan (dua bagian: Detail Perpindahan / Pengembalian). */
.rp-kb-sec{font-size:11.5px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;
  color:var(--muted);margin:12px 2px -3px}
.rp-kb-bonus{display:grid;gap:5px;margin:10px 0 2px}
.rp-kb-bonus>span{font-size:13px;font-weight:600;color:var(--muted)}
.rp-uang-grup{display:flex;align-items:stretch;border:1px solid var(--line);border-radius:8px;overflow:hidden}
.rp-uang-grup i{font-style:normal;display:flex;align-items:center;padding:0 11px;background:rgba(0,0,0,.04);
  color:var(--muted);font-weight:700;font-size:13px;border-right:1px solid var(--line)}
.rp-uang-grup input{border:0;flex:1;min-width:0;padding:9px 11px;font-size:14px;background:transparent;outline:none}

/* Gaji: nilai LAMA ditulis kecil di bawah labelnya, isiannya nilai BARU.
   Keduanya dalam satu baris supaya perbandingannya tidak menuntut mata
   berpindah jauh. */
/* Jabatan sebelumnya | baru — dua kotak berdampingan di atas dialog persetujuan
   reposisi Jabatan. Yang BARU ditonjolkan (border & teks primary). */
.rp-jab-row{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin:0 0 12px}
.rp-jab{display:grid;gap:3px;padding:9px 12px;border:1px solid var(--line);
        border-radius:9px;background:var(--surface);min-width:0}
.rp-jab>span{font-size:11px;font-weight:600;color:var(--muted);letter-spacing:.02em}
.rp-jab>b{font-size:13px;color:var(--ink);line-height:1.3;word-break:break-word}
.rp-jab-baru{border-color:var(--primary);background:var(--primary-tint);cursor:pointer}
.rp-jab-baru>b{color:var(--primary)}
/* Pane tiap tab Perpindahan. */
.rp-pane{margin-top:10px}
/* Sub-tab di dalam tab Mutasi (tab di dalam tab). Dibuat sebagai "pill" di atas
   kartu, bukan tab bergaris penuh, supaya terbaca sebagai tingkat kedua dan tak
   tertukar dengan tab utama tepat di atasnya. */
.rp-subtabs{
  display:inline-flex;gap:3px;flex-wrap:wrap;margin:0;
  padding:3px;border-radius:9px;background:var(--surface-2);border:1px solid var(--line);
}
/* Bar sub-tab tinggal di baris kontrol tabel (dipindah ke .dt-trail oleh JS,
   paling kanan sendirian). */
.dt-trail .rp-subtabs{margin:0}
.rp-subtabs .rp-subtab{
  padding:6px 14px;font-size:12px;border:0;border-radius:6px;margin:0;color:var(--muted);
}
.rp-subtabs .rp-subtab:hover{color:var(--ink)}
.rp-subtabs .rp-subtab.active{
  color:var(--primary);background:#fff;border-bottom-color:transparent;
  box-shadow:0 1px 2px rgba(30,41,59,.1);
}
.rp-subpane{margin-top:2px}
/* Sub-tab Temporer (dalam tab "Mutasi Cabang"): 4 kolom disembunyikan atas
   permintaan — Jabatan Awal, Jabatan Akhir, Bonus Perbantuan, Gaji Harian.
   HANYA tabel Temporer (#tblRepoTemporer); Permanent & Perbantuan tetap lengkap.
   Indeks kolom terrender (No disisipkan bindTable sbg kolom 1):
   9=Jabatan Awal, 10=Jabatan Akhir, 13=Bonus Perbantuan, 14=Gaji Harian. */
#tblRepoTemporer thead th:nth-child(9),
#tblRepoTemporer tbody td:nth-child(9),
#tblRepoTemporer thead th:nth-child(10),
#tblRepoTemporer tbody td:nth-child(10),
#tblRepoTemporer thead th:nth-child(13),
#tblRepoTemporer tbody td:nth-child(13),
#tblRepoTemporer thead th:nth-child(14),
#tblRepoTemporer tbody td:nth-child(14){display:none}
/* Kolom yang disembunyikan per tab jenis perpindahan (indeks terrender:
   9 = Jabatan Awal, 10 = Jabatan Akhir, 13 = Bonus Perbantuan, 14 = Gaji Harian).
   Permanent: 9+10+13+14 · Perbantuan: 9+10+14 · Demosi/Promosi/Adjustment: 13.
   Hanya tabel masing-masing yang terpengaruh. */
#tblRepoPermanent thead th:nth-child(9),#tblRepoPermanent tbody td:nth-child(9),
#tblRepoPermanent thead th:nth-child(10),#tblRepoPermanent tbody td:nth-child(10),
#tblRepoPermanent thead th:nth-child(13),#tblRepoPermanent tbody td:nth-child(13),
#tblRepoPermanent thead th:nth-child(14),#tblRepoPermanent tbody td:nth-child(14),
#tblRepoPerbantuan thead th:nth-child(9),#tblRepoPerbantuan tbody td:nth-child(9),
#tblRepoPerbantuan thead th:nth-child(10),#tblRepoPerbantuan tbody td:nth-child(10),
#tblRepoPerbantuan thead th:nth-child(14),#tblRepoPerbantuan tbody td:nth-child(14),
/* Demosi/Promosi/Adjustment punya kolom Jenis ekstra → Bonus Perbantuan geser
   13→14; sembunyikan kolom Bonus Perbantuan itu. */
#tblRepoDemosi thead th:nth-child(14),#tblRepoDemosi tbody td:nth-child(14),
#tblRepoPromosi thead th:nth-child(14),#tblRepoPromosi tbody td:nth-child(14),
#tblRepoAdjustment thead th:nth-child(14),#tblRepoAdjustment tbody td:nth-child(14),
/* Tab AJUAN (tblAjuReposisi): sembunyikan Bonus Perbantuan + Gaji Harian. Punya
   kolom Jenis ekstra → indeks +1 dari tabel lain: Bonus=14, Gaji Harian=15. */
#tblAjuReposisi thead th:nth-child(14),#tblAjuReposisi tbody td:nth-child(14),
#tblAjuReposisi thead th:nth-child(15),#tblAjuReposisi tbody td:nth-child(15),
/* +Keterangan Sistem (rendered 16 = statis 15 + kolom No). */
#tblAjuReposisi thead th:nth-child(16),#tblAjuReposisi tbody td:nth-child(16){display:none}
/* Cabang Pindah (Mutasi) — biru menyala, dibedakan dari Cabang Utama. */
.rp-jab-pindah{border-color:#2563eb;background:#eaf1ff;box-shadow:0 0 0 1px rgba(37,99,235,.35)}
.rp-jab-pindah>span{color:#2563eb}
.rp-jab-pindah>b{color:#1d4ed8}
/* Satu baris: Jenis di kiri, Tanggal Efektif didorong ke ujung kanan. */
.rp-jenis-eff{flex-wrap:nowrap}
.rp-eff-inline{margin-left:auto;display:flex;align-items:center;gap:7px;flex:0 0 auto}
.rp-eff-inline>span{font-size:11px;font-weight:600;color:var(--muted);letter-spacing:.02em}
.rp-eff-inp{padding:6px 9px;border:1px solid var(--line);border-radius:7px;
  font-family:inherit;font-size:13px;color:var(--ink);background:var(--surface)}
@media (max-width:520px){.rp-jenis-eff{flex-wrap:wrap}.rp-eff-inline{margin-left:0}}
/* Label & kotak catatan (pengajuan read-only vs persetujuan). */
.rp-cat-lbl{display:block;font-size:11px;font-weight:600;color:var(--muted);letter-spacing:.02em;margin:9px 0 3px}
.rp-catatan-ro{background:var(--surface-2);color:var(--muted);cursor:not-allowed;resize:none}
.rp-jab-sel{width:100%;border:1px solid var(--primary);border-radius:6px;padding:6px 8px;
            font-family:inherit;font-size:13px;color:var(--ink);background:var(--surface)}
.rp-jab-sel:focus{outline:none;box-shadow:0 0 0 3px var(--primary-tint)}
/* Setelah jadikanCari membungkusnya, kendali pencari mengisi selebar kotaknya. */
.rp-jab-baru .cari-sel{display:block;width:100%}
.rp-jab-baru .cari-tombol{width:100%;justify-content:space-between;border-color:var(--primary);background:var(--surface)}
/* Baris karyawan yang diajukan — menonjol di atas (judul memakai nama pengaju). */
.rp-karyawan{display:flex;align-items:center;gap:10px;margin:0 0 12px;padding:10px 13px;
             border:1px solid var(--primary);border-radius:9px;background:var(--primary-tint)}
.rp-karyawan>i{color:var(--primary);font-size:15px;flex:none}
.rp-karyawan>span{font-size:11px;font-weight:600;color:var(--primary);
                  text-transform:uppercase;letter-spacing:.03em;flex:none}
.rp-karyawan>b{font-size:15px;color:var(--ink);font-weight:700;min-width:0;word-break:break-word}
.rp-gaji-set{display:grid;gap:8px;margin:12px 0 4px}
.rp-gj-ket{font-size:11.5px;color:var(--muted);line-height:1.5;margin:0 0 2px}
.rp-gj{display:grid;grid-template-columns:1fr auto;align-items:center;gap:2px 10px}
.rp-gj>span{font-size:12px;color:var(--ink-soft);font-weight:600}
.rp-gj>small{grid-column:1;font-size:11px;color:var(--muted-2);font-variant-numeric:tabular-nums;cursor:help}
.rp-gj>input{grid-column:2;grid-row:1/3;width:150px;text-align:right;
             border:1px solid var(--line);border-radius:6px;padding:6px 9px;
             font-family:inherit;font-size:13px;font-variant-numeric:tabular-nums;
             background:var(--surface);color:var(--ink)}
.rp-gj>input:focus{outline:none;border-color:var(--primary);box-shadow:0 0 0 3px var(--primary-tint)}
/* Varian: hanya Gaji per Bulan + Harian (Saat ini read-only + Baru). Tanpa <small>,
   input tak perlu membentang 2 baris. */
.rp-gj2>input{grid-row:auto;width:160px}
.rp-gj-ro{background:rgba(0,0,0,.05);color:var(--muted)}
/* Tanggal Efektif pada dialog persetujuan — DI BAWAH catatan, berdampingan
   dengan keterangan jenis reposisinya. Baris dua lajur: tanggalnya melebar,
   keterangannya menyesuaikan isinya di kanan. */
.rp-catatan{margin-top:2px}
/* Tanggal Efektif & Tanggal Selesai SATU baris (dua kolom sama lebar). Saat
   bukan perbantuan, Selesai disembunyikan dan keterangan jenis reposisi tampil
   di tempatnya; saat perbantuan, Selesai muncul dan keterangan disembunyikan
   supaya dua tanggal muat rapi. Flex-wrap: di layar sempit keduanya menumpuk. */
.rp-tgl-row{display:flex;flex-wrap:wrap;gap:12px;align-items:end;margin:10px 0 2px}
.rp-tgl-row>.rp-eff{flex:1 1 180px}
.rp-selesai-x{display:none;flex:1 1 180px;min-width:0}
.modal-body:has(input[name="mode"][value="perbantuan"]:checked) .rp-selesai-x{display:block}
.rp-selesai-x>.rp-eff{margin:0}
.modal-body:has(input[name="mode"][value="perbantuan"]:checked) .rp-eff-ket{display:none}
.rp-eff{display:grid;gap:4px;margin:0;min-width:0}
.rp-eff>span{font-size:12px;color:var(--ink-soft);font-weight:600}
.rp-eff>small{font-size:11px;color:var(--muted);line-height:1.45}
.rp-eff>input{border:1px solid var(--line);border-radius:6px;padding:7px 10px;
              font-family:inherit;font-size:13px;background:var(--surface);color:var(--ink)}
.rp-eff>input:focus{outline:none;border-color:var(--primary);box-shadow:0 0 0 3px var(--primary-tint)}
.rp-eff-ket{align-self:end;display:inline-flex;align-items:center;gap:6px;white-space:nowrap;
            padding:7px 12px;margin-bottom:1px;border-radius:999px;font-size:12px;font-weight:600;
            background:var(--primary-tint);color:var(--primary)}
.rp-eff-ket i{font-size:11px}
/* Badge jenis pengajuan di HEADER KANAN dialog persetujuan (dipindah dari samping
   Tanggal Efektif). */
.mh-badge{margin-left:auto;align-self:center}
.rp-tipe-badge{display:inline-flex;align-items:center;gap:6px;white-space:nowrap;
               padding:6px 12px;border-radius:999px;font-size:12px;font-weight:700;
               background:var(--primary-tint);color:var(--primary)}
.rp-tipe-badge i{font-size:11px}
/* Tanggal Selesai read-only (Mutasi perbantuan/temporer): tampak seperti field
   Tanggal Efektif tapi diredupkan karena hanya dibaca. */
.rp-eff-ro>input[disabled]{background:var(--surface-2);color:var(--muted);cursor:default;opacity:1}
/* Kotak bonus perbantuan (checkbox + nominal), di bawah baris tanggal. Muncul
   HANYA saat Perbantuan terpilih — toggle lewat leluhur bersama .modal-body,
   sebab radionya ada di blok .rp-mode di atas. Nominal muncul hanya saat
   checkbox-nya dicentang. */
.rp-perbantuan-x{display:none;grid-template-columns:1fr;gap:10px;margin:8px 0 2px;
                 padding:11px 12px;border:1px dashed var(--line);border-radius:9px;
                 background:var(--surface)}
.modal-body:has(input[name="mode"][value="perbantuan"]:checked) .rp-perbantuan-x{display:grid}
.rp-bonus-chk{display:flex;align-items:center;gap:8px;font-size:13px;color:var(--ink);
              font-weight:600;cursor:pointer}
.rp-bonus-chk input{accent-color:var(--primary);width:16px;height:16px;flex:none}
.rp-bonus-nom{display:none;grid-template-columns:1fr;gap:4px}
.rp-perbantuan-x:has(input[name="bonusAktif"]:checked) .rp-bonus-nom{display:grid}
.rp-bonus-nom>span{font-size:12px;color:var(--ink-soft);font-weight:600}
.rp-bonus-nom>small{font-size:11px;color:var(--muted);line-height:1.45}
.rp-bonus-nom>input{border:1px solid var(--line);border-radius:6px;padding:7px 10px;
                    font-family:inherit;font-size:13px;text-align:right;
                    font-variant-numeric:tabular-nums;background:var(--surface);color:var(--ink)}
.rp-bonus-nom>input:focus{outline:none;border-color:var(--primary);box-shadow:0 0 0 3px var(--primary-tint)}

.tg-mata{border:1px solid var(--line);background:var(--surface);color:var(--muted-2);
         border-radius:6px;padding:5px 9px;font-size:13px;line-height:1;cursor:pointer;
         font-family:inherit;transition:.12s}
.tg-mata:hover{border-color:var(--muted-2);color:var(--ink-soft);background:var(--surface-2)}
.tg-mata[aria-pressed="true"]{color:var(--primary);border-color:var(--primary);
         background:var(--primary-tint)}
.tg-mata:focus-visible{outline:none;box-shadow:0 0 0 3px var(--primary-tint)}

/*
 * ============ Plafon Reimbursement: rincian tertutup secara bawaan ============
 *
 * Yang tertutup ada dua macam dan keduanya dikendalikan SATU kelas pada
 * tabelnya (.pr-rinci-on), bukan gaya yang dipasang ke sel satu per satu:
 * tbody digambar ulang tiap kali tabelnya disaring, diurutkan, atau berpindah
 * halaman, dan gaya yang menempel di sel akan ikut hilang pada penggambaran
 * berikutnya tanpa memberi tahu siapa pun.
 *
 * (1) Lajur Jabatan & Cabang — display:none, bukan lebar nol: lajurnya harus
 *     benar-benar keluar dari aliran tabel, bukan menyisakan celah kosong.
 *     Selnya dikenali dari penanda di dalamnya (.pr-sel-rinci) lewat :has(),
 *     dengan alasan yang sama seperti kelas di judulnya.
 *
 * (2) Nilai rupiah Jumlah Plafon & Sisa — diganti titik. Angkanya tetap ada di
 *     halaman, hanya tidak tergambar; ini SAKLAR TAMPILAN, bukan pembatasan
 *     hak. Yang membatasi hak sudah berdiri di server (AKSES_PLAFON_R): tanpa
 *     hak itu, tidak ada satu baris pun yang sampai ke sini untuk ditutupi.
 */
#tblPlafonR:not(.pr-rinci-on) th.pr-kol-rinci,
#tblPlafonR:not(.pr-rinci-on) td:has(.pr-sel-rinci){display:none}
#tblPlafonR:not(.pr-rinci-on) .pr-nilai{display:none}
#tblPlafonR.pr-rinci-on .pr-titik{display:none}
/* Titiknya selebar angka supaya lajurnya tidak melompat saat dibuka-tutup, dan
   diredupkan supaya terbaca sebagai "tertutup", bukan sebagai nilai nol. */
.pr-titik{color:var(--muted-2);letter-spacing:3px;font-weight:700;cursor:help}
/* Sisa yang tidak cocok dengan kolom `sisa` tersimpan di HRIS lama. Digarisbawahi
   putus-putus — sama seperti penanda "pemakaiannya belum tercatat" di lajur
   Izin — supaya bedanya ditanyakan, bukan dipercaya diam-diam. */
.pr-beda{text-decoration:underline dotted;text-underline-offset:3px;cursor:help}

/* Tombol slip di kolom Action. Abu-abu = belum terbit, biru = sudah.
   Bentuknya sama persis di kedua keadaan; hanya warnanya yang berbeda, supaya
   satu lajur centang bisa dipindai tanpa membaca apa pun. */
/* Kotak centang dan ikon centang berdampingan dalam satu sel. */
.tg-sel-aksi{display:inline-flex;align-items:center;gap:7px}
.tg-cek{width:15px;height:15px;accent-color:var(--primary);cursor:pointer;margin:0;flex:none}
/* Baris yang ikonnya sudah biru tidak lagi menawarkan kotak centangnya.
   visibility, BUKAN display:none: ruangnya dipertahankan supaya ikon di baris
   yang ditandai tetap sebaris dengan ikon di baris lain — lajur centang yang
   bergerigi jauh lebih sulit dipindai daripada satu kotak yang kosong.
   Disandarkan pada kelas .on milik tombolnya lewat :has(), bukan kelas kedua
   yang dipasang JS: dua penanda untuk satu keadaan cepat atau lambat
   berselisih. */
.tg-sel-aksi:has(.tg-slip.on) .tg-cek{visibility:hidden}
/* Cacah baris bertanda, di kiri penomoran halaman.
   margin-left:auto dipindahkan KE SINI selagi ia tampil; kalau tidak, dua
   elemen ber-margin auto akan membagi ruang kosong di antara keduanya dan
   cacahnya melayang di tengah-tengah. */
.tg-tanda-jml{display:inline-flex;align-items:center;gap:6px;white-space:nowrap;
              font-size:11.5px;font-weight:700;color:var(--primary);
              background:var(--primary-tint);border-radius:999px;padding:3px 11px}
.tg-tanda-jml i{font-size:10.5px}
.dt-bottom:has(.tg-tanda-jml:not([hidden])) .dt-paginate{margin-left:0}
.tg-tanda-jml{margin-left:auto}
/* Tanggal efektif rekrutmen: tanggalnya saja tidak cukup — yang membedakan
   "akan berlaku" dari "sudah berlaku" adalah ikon dan warnanya. */
/* Angka yang jatahnya diketahui tapi pemakaiannya TIDAK: ditandai bergaris
   bawah putus-putus, tanda yang sudah lazim berarti "ada keterangannya". */
.pr-taktahu{border-bottom:1px dotted var(--muted-2);cursor:help}

.rk-ef{display:inline-flex;align-items:center;gap:5px;white-space:nowrap;font-size:11.5px}
.rk-ef i{font-size:10.5px;color:var(--muted-2)}
.rk-ef.nanti{color:#7E5109;font-weight:700}
.rk-ef.nanti i{color:#7E5109}
.rk-ef.jalan{color:#1E8449;font-weight:700}
.rk-ef.jalan i{color:#1E8449}

.tg-slip{border:0;background:none;padding:2px 4px;cursor:pointer;line-height:1;
         color:var(--muted-2);font-size:15px;border-radius:6px;transition:.12s}
.tg-slip:hover{color:var(--ink-soft);background:var(--surface-2)}
.tg-slip.on{color:var(--primary)}
.tg-slip.on:hover{background:var(--primary-tint)}
.tg-slip:focus-visible{outline:none;box-shadow:0 0 0 3px var(--primary-tint)}
.tg-slip:disabled{opacity:.45;cursor:progress}
/* Selisih yang dimaafkan justifikasi, dibuat REDUP dan kecil di samping angka
   yang terhitung. Yang dibaca orang saat menutup gaji adalah angka yang
   terhitung; selisihnya penjelasan, bukan angka kedua yang harus ditimbang. */
.tg-mf{white-space:nowrap}
.tg-mf small{margin-left:3px;font-weight:700;font-size:10px;color:var(--ok,#1E8449)}
/* Sel justifikasi. Yang MENUNGGU diberi latar supaya terlihat saat menyapu
   ratusan baris — ia satu-satunya bagian sel ini yang berarti "jangan tutup
   dulu"; yang disetujui dan ditolak sudah selesai urusannya. */
.tg-jf{display:inline-flex;align-items:center;gap:6px;white-space:nowrap;font-size:11px;font-weight:700}
.tg-jf i{font-size:9.5px}
.tg-jf-ok{color:#1E8449}
.tg-jf-tolak{color:var(--muted-2)}
.tg-jf-tunggu{color:#7E5109;background:#FEF6E7;border-radius:20px;padding:1px 8px}
#tblTgRiwayat{font-size:11.5px}
.tg-st{display:inline-block;padding:2px 9px;border-radius:999px;font-size:10.5px;font-weight:800}
.tg-st-jalan{background:#FEF6E7;color:#7E5109}
.tg-st-selesai{background:var(--primary-tint);color:var(--primary)}
.tg-st-gagal{background:#FDEDEC;color:#C0392B}
/* --- Tab Slip Gaji ---
 *
 * Lebarnya dipatok 720px dan dipusatkan, bukan melebar penuh: slip gaji yang
 * merentang sepanjang layar 27 inci tidak lagi terbaca sebagai slip. */
/* Ikon cetak di kop slip, di kiri judulnya. Dibuat datar tanpa rangka tombol:
   ia berdiri di dalam dokumen yang sedang dibaca, bukan di bilah alat. */
.slip-cetak{background:none;border:1px solid var(--line);border-radius:8px;
  width:30px;height:30px;display:inline-flex;align-items:center;justify-content:center;
  cursor:pointer;color:var(--primary);flex:0 0 auto}
.slip-cetak:hover{background:var(--primary-tint);border-color:var(--primary)}
.slip-cetak i{font-size:13px}
/* Garis slip dipegang SATU tetapan: abu terang, sedikit lebih redup daripada
   --line supaya kisi-kisinya membingkai tanpa ikut berteriak. Satu tetapan,
   bukan nilai yang disebar — mengubah ketebalan atau warnanya cukup di sini. */
/* Garis slip dipegang SATU tetapan: abu terang, sedikit lebih redup daripada
   --line supaya kisi-kisinya membingkai tanpa ikut berteriak. Satu tetapan,
   bukan nilai yang disebar — mengubah ketebalan atau warnanya cukup di sini.

   Bingkai LUARNYA menyala: tepi setipis rambut berwarna primer, lalu dua
   lapis cahaya di luarnya. Dibuat dengan box-shadow, bukan border tebal —
   border akan menggeser tata letak isinya, sedangkan bayangan tidak memakan
   ruang sama sekali. Cincin pertama (3px, tint) memberi tebal yang terlihat,
   cincin kedua (kabur, 28px) memberi pendar lembutnya. */
.slip{--slip-line:#E3E6EC;position:relative;
  /* Slip MEMENUHI lebar panenya (permintaan: "fullkan") — tak lagi dipatok 720px
     di tengah. Jarak atas-bawah kecil supaya pendarnya tak terpotong tepi pane. */
  max-width:none;margin:6px 0;border:1px solid var(--primary);border-radius:12px;
  background:var(--surface);overflow:hidden;
  box-shadow:0 0 0 3px var(--primary-tint),
             0 8px 28px -10px rgba(79,70,229,.45),
             0 1px 2px rgba(15,23,42,.05)}
/* Garis tebal berwarna di kop dan di baris total DIPERTAHANKAN: keduanya
   penanda awal dan akhir slip, bukan kisi-kisi. Yang ditambahkan hanya garis
   abu terang di antaranya. */
.slip-kop{padding:16px 22px;border-bottom:2px solid var(--primary);
  display:flex;align-items:center;gap:14px;flex-wrap:wrap}
/* Logo perusahaan di kiri kop. object-fit:contain menjaga rasio apa pun bentuk
   berkasnya; flex:none supaya tak ikut mengecil saat baris penuh. */
.slip-logo{width:48px;height:48px;flex:none;object-fit:contain}
/* Identitas perusahaan di samping logo. Alamatnya panjang, jadi lebarnya dibatasi
   supaya membungkus rapi 1-2 baris (bukan menjulur menggeser judul di kanan). */
.slip-pt{min-width:0;flex:0 1 auto;max-width:min(560px,46%)}
.slip-pt-nama{font-size:16px;font-weight:800;color:var(--ink);line-height:1.15;
  letter-spacing:.01em}
.slip-pt-sub{font-size:11px;color:var(--muted);font-weight:600;margin-top:2px;
  line-height:1.35;overflow-wrap:anywhere}
/* Judul dokumen + periode, mentok kanan kop. */
.slip-kop-kanan{margin-left:auto;text-align:right;min-width:0}
.slip-judul{font-size:15px;font-weight:800;color:var(--primary);
  text-transform:uppercase;letter-spacing:.05em}
/* Periode pada satu baris: labelnya sebaris dengan bulannya; di dalam blok kanan
   ia rata kanan, bukan didorong margin-left:auto. */
.slip-kop-kanan .slip-periode{margin-left:0;justify-content:flex-end;margin-top:2px}
.slip-periode{display:flex;align-items:baseline;gap:6px;white-space:nowrap}
.slip-periode span{font-size:11.5px;color:var(--muted)}
.slip-periode b{font-size:13px;color:var(--primary)}
/* Ikon cetak sebagai anggota TERAKHIR kop (paling kanan), sejajar tengah dengan
   logo & judul; bukan absolute supaya tak menimpa judul di sebelahnya. */
.slip-cetak{flex:none}
.slip-jati{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:0 18px;
  padding:10px 20px 12px;border-bottom:1px solid var(--slip-line);background:var(--surface-2)}
/* Tiap keterangan identitas dipisah garis tipis, seperti baris pada formulir.
   Pasangan terakhir di tiap kolom tidak diberi garis supaya tidak bertumpuk
   dengan garis bawah bloknya. */
.slip-jati div{display:flex;gap:8px;font-size:12px;padding:6px 0;min-width:0;
  border-bottom:1px solid var(--slip-line)}
.slip-jati div:nth-last-child(-n+2){border-bottom:none;padding-bottom:0}
.slip-jati dt{flex:0 0 86px;color:var(--muted);font-weight:700}
.slip-jati dd{margin:0;color:var(--ink);font-weight:700;overflow-wrap:anywhere}
/* Penerimaan dan potongan berdampingan supaya keduanya terbaca sekaligus —
   slip yang menumpuk keduanya memaksa orang menggulir untuk membandingkan. */
.slip-dua{display:grid;grid-template-columns:repeat(2,minmax(0,1fr))}
.slip-kol{padding:14px 20px}
.slip-kol+.slip-kol{border-left:1px solid var(--slip-line)}
.slip-kol h4{margin:0 0 0;padding:0 0 7px;border-bottom:1px solid var(--slip-line);
  font-size:10.5px;font-weight:800;text-transform:uppercase;
  letter-spacing:.05em;color:var(--muted)}
/* Tiap butir penerimaan/potongan berdiri di barisnya sendiri. */
.slip-br{display:flex;gap:10px;font-size:12px;padding:7px 0;align-items:baseline;
  border-bottom:1px solid var(--slip-line)}
.slip-br span:first-child{flex:1;color:var(--ink-soft);min-width:0;overflow-wrap:anywhere}
.slip-br span:last-child{font-variant-numeric:tabular-nums;font-weight:700;white-space:nowrap}
.slip-br small{display:block;color:var(--muted);font-size:10.5px;font-weight:600}
/* Baris jumlah: garisnya di ATAS dan lebih tegas, dan ia baris terakhir
   sehingga garis bawahnya dilepas. */
.slip-sub{margin-top:2px;padding-top:8px;border-top:1px solid var(--slip-line);
  border-bottom:none;font-weight:800}
.slip-sub span:first-child{color:var(--ink)}
.slip-plus span:last-child{color:#1E8449}
.slip-minus span:last-child{color:var(--danger,#C0392B)}
.slip-nihil{color:var(--muted);font-size:11.5px;padding:7px 0;
  border-bottom:1px solid var(--slip-line)}
.slip-total{display:flex;align-items:baseline;gap:12px;padding:14px 20px;
  border-top:2px solid var(--primary);background:var(--primary-tint)}
.slip-total b:first-child{font-size:12px;color:var(--primary);text-transform:uppercase;
  letter-spacing:.04em}
.slip-total b:last-child{margin-left:auto;font-size:19px;color:var(--primary);
  font-variant-numeric:tabular-nums}
/* Pembanding HRIS lama: latar berbeda supaya tidak terbaca sebagai bagian dari
   perhitungan yang dibayar. */
.slip-kaki{padding:11px 20px;border-top:1px solid var(--line);font-size:10.5px;
  color:var(--muted);line-height:1.6}
.slip-kosong{padding:40px 20px;text-align:center;color:var(--muted)}
@container isi (max-width:700px){
  .slip-dua{grid-template-columns:1fr}
  .slip-kol+.slip-kol{border-left:none;border-top:1px solid var(--line)}
  .slip-jati{grid-template-columns:1fr}
}
/* Saat dicetak yang tersisa hanya slipnya: sidebar, tab, dan tombol cetak
   tidak punya arti di atas kertas. */
@media print{
  .sidebar,.topbar,.tabbar,.slip-cetak,.dt-filter,.toolbar,.nav,.fab{display:none!important}
  .content,.card,.card-body,.tabpane{padding:0!important;margin:0!important;
    border:none!important;box-shadow:none!important;background:#fff!important}
  /* Di atas kertas garisnya digelapkan: abu terang yang pas di layar hampir
     hilang saat dicetak. --slip-line dipakai seluruh kisi-kisinya, jadi cukup
     satu nilai yang diubah. */
  /* Pendar dan warna primer dilepas saat dicetak: cahaya tidak ada artinya di
     atas kertas, dan tinta berwarna hanya memboroskan toner. */
  .slip{--slip-line:#B9BEC7;max-width:none;border-color:#8A8F98;break-inside:avoid;
    box-shadow:none}
  body{background:#fff!important}
}
/* --- Tab Bonus WO --- */
/* Ringkasan diletakkan DI ATAS tabel, bukan hanya di kakinya: daftar WO bisa
   ratusan baris, dan angka yang hanya ada di baris terakhir mengharuskan
   pembacanya menggulir dulu untuk tahu hasilnya. */
.bw-ringkas{display:flex;flex-wrap:wrap;gap:10px;margin:0 0 12px}
/* Tiap kartu ringkasan dibingkai dan diberi pendar. Cincin PUTIH di lapis
   pertama memisahkannya dari latar halaman yang juga keabuan — tanpa itu
   bayangannya terbaca sebagai noda, bukan sebagai tepi. Lapis keduanya
   bayangan gelap tipis yang memberi angkatnya. */
.bw-kartu{flex:1 1 130px;min-width:120px;padding:9px 12px;
  border:1px solid #C7CDD8;border-radius:9px;background:var(--surface-2);
  box-shadow:0 0 0 2px #fff, 0 3px 12px -4px rgba(15,23,42,.30)}
.bw-lb{display:block;font-size:10px;font-weight:800;text-transform:uppercase;
  letter-spacing:.04em;color:var(--muted);margin-bottom:3px}
.bw-kartu b{font-size:14px;color:var(--ink);font-weight:800}
/* Kartu Total Bonus menyala dengan warna primer: ia angka yang dicari, dan
   pendar yang sama untuk delapan kartu membuat tak satu pun menonjol. */
.bw-kartu-uang{background:var(--primary-tint);border-color:var(--primary);
  box-shadow:0 0 0 2px #fff, 0 6px 18px -6px rgba(79,70,229,.45)}
.bw-kartu-uang b{color:var(--primary)}
/* Kartu "Non Verify": bonus WO belum terverifikasi (TIDAK dibayar) — dibedakan
   dgn warna peringatan agar tak tertukar dgn "Verify" yang dibayar. */
.bw-kartu-nv{background:var(--warning-tint,#fef3c7);border-color:var(--warning,#f59e0b);
  box-shadow:0 0 0 2px #fff, 0 6px 18px -6px rgba(245,158,11,.4)}
.bw-kartu-nv b{color:var(--warning,#b45309)}
/* Peringatan "belum ada aturan" memakai warna ingat, bukan galat: datanya
   terbaca dengan benar, yang kurang adalah tarifnya di OSS. */
.bw-ingat{background:#FEF6E7;border-color:#F5B041;color:#7E5109}
.bw-nihil{color:var(--muted)}
.bw-belum{color:#B9770E;font-weight:700}
@container isi (max-width:640px){.bw-kartu{flex:1 1 100%}}
/* Saklar Standart Sallary: on/off yang menyimpan seketika. */
.sal-sw{
  display:inline-flex;align-items:center;gap:7px;padding:3px 9px 3px 4px;
  border:1px solid var(--line);border-radius:999px;background:var(--surface-2);
  color:var(--muted);font:inherit;font-size:10.5px;font-weight:800;cursor:pointer;
  transition:background .15s,border-color .15s,color .15s;
}
.sal-knop{width:22px;height:12px;border-radius:999px;background:var(--muted-2);
  position:relative;flex:none;transition:background .15s}
.sal-knop::after{content:'';position:absolute;top:2px;left:2px;width:8px;height:8px;
  border-radius:50%;background:#fff;transition:transform .15s}
.sal-sw.on{background:#EAF7EF;border-color:#1E8449;color:#1E8449}
.sal-sw.on .sal-knop{background:#1E8449}
.sal-sw.on .sal-knop::after{transform:translateX(10px)}
.sal-sw:disabled{opacity:.6;cursor:progress}
.sal-sw:focus-visible{outline:2px solid var(--primary);outline-offset:2px}
.sg-centang{color:#1E8449;font-size:12px}
/* Hari tanpa absensi: keterangannya menggantikan keenam sel absen, dan
   barisnya diredupkan supaya hari yang benar-benar bekerja tetap menonjol. */
.sg-ket{color:var(--muted);font-style:italic}
/* "Tidak absen out": keterangan yang menggantikan Time/Pulang Cepat/Jarak pada
   hari yang sudah absen in tapi tidak absen out. Nada peringatan lembut. */
.sg-noout{color:var(--danger);font-style:italic;font-size:12px}
/* Cuti/sakit yang dibayar: hari bergaji, jadi tidak diredupkan seperti hari
   kosong lainnya. */
.sg-ket-bayar{color:#1E8449;font-style:normal;font-weight:700}
/* Cuti/sakit yang DIBAYAR tidak ikut merah: ia memang tidak masuk, tapi tetap
   bergaji — memerahkannya akan menyamakannya dengan hari yang hilang. */
.sg-bayar td{background:#EAF7EF}
.sg-bayar:hover td{background:#D8F0E1}
/* Hari tanpa absensi berlatar merah jambu — ia hari yang tidak menghasilkan
   gaji, dan itu harus terlihat sebelum angkanya dibaca. */
.sg-tanpa td{background:#FDECEA}
.sg-tanpa:hover td{background:#FADBD8}
/* Hari yang BELUM tiba (masa depan): biru muda, bukan merah — belum absen bukan
   alpha. Menimpa .sg-tanpa di atas (urutan lebih bawah, selektor sama kuat). */
.sg-belum td{background:#EFF6FF}
.sg-belum:hover td{background:#DBEAFE}
.sg-ket-belum{color:#1D4ED8;font-style:normal;font-weight:600}
/* Di kotak yang sempit, pembekuan dilepas oleh skripnya; tabelnya cukup
   dirapatkan supaya tetap terbaca. */
@container isi (max-width:760px){
  .sg-tabel{font-size:11.5px}
  .sg-tabel th,.sg-tabel td{padding:6px 7px}
}
/* Kaki tabel menempel di dasar kotaknya: dengan 31 baris, jumlah sebulan tidak
   boleh ikut terdorong ke luar pandangan. */
.sg-tabel tfoot td{padding:9px 10px;background:var(--surface-2);font-size:12px;
  border-top:1px solid var(--line);position:sticky;bottom:0;z-index:2}
/* Kaki tabel menempel di dasar kotak gulir: jumlah sebulan adalah angka yang
   dicari orang, dan menyuruhnya menggulir 31 baris sampai dasar hanya untuk
   melihatnya berarti kaki itu tidak berguna sampai detik terakhir. Latarnya
   WAJIB legap, kalau tidak baris yang lewat di belakangnya terlihat menembus. */
/* Judul yang bisa diurutkan. Panahnya memakai tanda yang sama dengan datatable
   lain (▲/▼) supaya satu kebiasaan berlaku di seluruh aplikasi, tapi kelasnya
   sendiri karena tabel ini tidak melewati bindTable. */
.sg-tabel thead th.sortable{cursor:pointer;user-select:none}
.sg-tabel thead th.sortable:hover{color:var(--primary)}
.sg-tabel thead th.sg-urut-naik::after{content:"\25B2";font-size:8px;margin-left:5px;color:var(--primary)}
.sg-tabel thead th.sg-urut-turun::after{content:"\25BC";font-size:8px;margin-left:5px;color:var(--primary)}
.sg-tabel tfoot td{position:sticky;bottom:0;z-index:4;background:var(--surface-2)}
.sg-tabel tfoot tr:last-child td{box-shadow:inset 0 -1px 0 var(--line)}
.sg-tabel tfoot .sg-kaki-terima{background:var(--primary-tint)}
.sg-tabel tfoot .sg-kaki-pot{background:var(--surface-2)}
.sg-tabel tfoot .sg-beku{z-index:5}
/* Keterangan di kaki dirapatkan ke kanan supaya menempel pada angkanya —
   dibiarkan di tengah sembilan kolom, ia berdiri jauh dari yang dijelaskannya. */
.sg-kaki-lb{color:var(--muted);text-align:right}
/* Keterangan ringkas di baris potongan kaki Detail Gaji (mis. "SP-1 10%"). */
.sg-kaki-ket{color:var(--muted);font-weight:400;font-size:11px}
/* Keterangan potongan (sisi KANAN kaki dua-kolom): rata kiri tepat sesudah
   bagian Tambahan, dengan garis pemisah vertikal supaya dua sisi jelas. */
.sg-kaki-pot-lb{color:var(--muted);text-align:left;border-left:2px solid var(--line);padding-left:14px}
/* Bagian DUA KOLOM di kaki Detail Gaji: Tambahan (kiri) & Potongan (kanan),
   masing-masing kisi "label : nilai" 2 kolom, dipisah garis vertikal. */
.sg-kaki-dua{padding:9px 14px}
/* Panel rincian Detail Gaji DI LUAR kotak gulir tabel: statis di bawah tabel,
   selebar wadah, TAK pernah memunculkan scrollbar mendatar sendiri (overflow
   disembunyikan; kisinya membungkus ke bawah di layar sempit). Dengan begini
   scrollbar tinggal satu — di tabel data. */
.sg-kaki-panel{margin-top:10px;border:1px solid var(--line);border-radius:10px;
  background:var(--surface-2);padding:12px 14px;overflow:hidden}
.sg-kaki-panel .sg-kaki-grid{gap:24px;flex-wrap:wrap}
.sg-kaki-panel .sg-kaki-sisi{flex:1 1 240px}
.sg-kaki-panel .sg-kaki-diterima{flex:0 0 auto;min-width:170px;display:flex;
  flex-direction:column;justify-content:center;border-radius:8px;padding:10px 16px}
.sg-kaki-grid{display:flex;gap:28px;align-items:flex-start}
.sg-kaki-sisi{flex:1;min-width:0}
.sg-kaki-sisi-kanan{border-left:2px solid var(--line);padding-left:28px}
.sg-kaki-sisi-jd{font-weight:700;color:var(--muted);font-size:10.5px;text-transform:uppercase;letter-spacing:.05em;margin-bottom:6px}
.sg-kaki-sisi-grid{display:grid;grid-template-columns:1fr 1fr;gap:5px 22px}
.sg-kaki-item{display:flex;justify-content:space-between;gap:12px;font-size:12.5px;min-width:0;align-items:baseline}
.sg-kaki-item-lb{color:var(--muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* Subtotal tiap bagian (Total Tambahan / Total Potongan). */
.sg-kaki-sisi-total{display:flex;justify-content:space-between;gap:12px;margin-top:7px;padding-top:6px;border-top:1px solid var(--line);font-weight:700;font-size:12.5px;color:var(--ink)}
/* Blok GAJI DITERIMA menonjol di kolom "Gaji Absen" (sel terakhir baris besar),
   membentang setinggi kisi Tambahan/Potongan di sebelahnya. */
.sg-kaki-diterima{vertical-align:middle;text-align:center;background:var(--primary-tint);border-left:2px solid var(--line);padding:10px 8px;white-space:nowrap}
.sg-kaki-diterima-lb{font-size:10px;font-weight:700;color:var(--muted);text-transform:uppercase;letter-spacing:.05em;margin-bottom:5px}
.sg-kaki-diterima-val{font-size:15px;font-weight:800;color:var(--primary)}
/* Baris gaji standar di kaki: warnanya sama dengan saklarnya di master supaya
   keduanya terbaca sebagai satu hal. */
.sg-kaki-std{background:#EAF7EF;color:#1E8449;font-weight:700}
/* Potongan bulanan di kaki: dipisahkan dari jumlah harian di atasnya supaya
   jelas ia lapisan berikutnya, bukan kolom yang sama. */
.sg-kaki-pot td{border-top:1px solid var(--line)}
.sg-kaki-terima{background:var(--primary-tint);color:var(--primary);font-size:13px}
/* Yang menambah ditulis hijau, yang memotong tetap kuning-merah — arah uangnya
   harus terbaca sebelum angkanya dibaca. */
.sg-tambah{color:#1E8449;font-weight:700}
/* Label TAMBAHAN di sisi kiri kaki Detail Gaji (Bonus/Perbantuan/dll) — rata
   kiri, beda dari keterangan potongan yang rata kanan. */
.sg-kaki-tam-lb{text-align:left;color:var(--ink);white-space:nowrap}
/* Isian yang nilainya DITURUNKAN: terlihat seperti isian lain supaya sebarisnya
   tetap rapi, tapi jelas tidak bisa diketik. */
.gj-turunan{background:var(--surface-2);color:var(--muted);cursor:default;font-weight:700}
.gj-turunan:focus{outline:none;border-color:var(--line);box-shadow:none}
/* Setting Menu: tombol ubah nama & penyuntingan di tempat. */
.tata-ubah{
  flex:none;width:26px;height:26px;display:inline-flex;align-items:center;justify-content:center;
  border:1px solid var(--line);border-radius:6px;background:var(--surface);
  color:var(--muted);cursor:pointer;font-size:11px;
}
.tata-ubah:hover{color:var(--primary);border-color:var(--primary)}
.tata-ubah:focus-visible{outline:2px solid var(--primary);outline-offset:1px}
.tata-nama-input{
  width:100%;box-sizing:border-box;font-family:inherit;font-size:12.5px;font-weight:600;
  color:var(--ink);background:var(--surface);border:1px solid var(--primary);
  border-radius:6px;padding:3px 7px;
}
.tata-nama-input:focus{outline:none;box-shadow:0 0 0 3px var(--primary-tint)}
/* Cap kecil yang menandai butir bernama pengganti — supaya jelas mana yang
   sudah tidak memakai nama bawaannya. */
.tata-nama-cap{
  margin-left:6px;padding:1px 6px;border-radius:9px;font-size:9.5px;font-weight:800;
  background:var(--primary-tint);color:var(--primary);text-transform:uppercase;letter-spacing:.3px;
}
/* Kotak uang: awalan "Rp" menempel di kiri supaya tidak ada keraguan satuan,
   dan angkanya rata kanan seperti di tabel. */
.uang-kotak{position:relative;display:block}
.uang-kotak .uang-awalan{position:absolute;left:10px;top:50%;transform:translateY(-50%);
  font-size:12px;color:var(--muted);pointer-events:none}
.uang-kotak input{padding-left:32px}
/* Kendali yang belum boleh dipakai: terlihat, tapi jelas belum waktunya. */
.kl-form .cari-sel.mati .cari-tombol{opacity:.55;cursor:not-allowed;background:var(--surface-2)}
/* Pilihan yang sudah terpakai: tetap terlihat supaya yang mencarinya tahu
   namanya memang ada, tapi jelas tidak bisa diklik. */
.cari-opsi.mati{opacity:.45;cursor:not-allowed;text-decoration:line-through}
.cari-opsi.mati:hover{background:transparent}
.pr-saring{display:flex;gap:8px;flex-wrap:wrap;align-items:center}
/* Penanda surel di sebelah nama karyawan.
   Ditempel ke sel nama, BUKAN diberi lajur sendiri: tabel ini sudah sebelas
   lajur dan harus digulir mendatar, sementara yang ditanyakan cuma satu hal
   berjawaban ya/tidak. Font Awesome 6 tidak punya amplop bersilang, jadi
   silangnya ditempel sebagai lencana kecil di sudutnya — satu bentuk yang
   terbaca sebagai satu ikon, bukan dua ikon bersebelahan. */
.km-mail{position:relative;display:inline-block;margin-left:7px;font-size:11px;
         line-height:1;vertical-align:baseline}
.km-mail-ok{color:#1E8449}
.km-mail-luar{color:#C0392B}
/* Redup, bukan merah: belum punya surel bukan surel yang salah. */
.km-mail-kosong{color:var(--muted-2);opacity:.65}
.km-mail-x{position:absolute;right:-5px;bottom:-4px;font-size:8px;font-weight:900;
           background:var(--surface);border-radius:50%;padding:1px;
           box-shadow:0 0 0 1.5px var(--surface)}
/* Baris yang sedang disorot berlatar lain — cincin lencananya ikut, kalau
   tidak silangnya duduk di atas cincin putih yang tidak lagi cocok. */
#tblKaryawan tbody tr:hover .km-mail-x{background:var(--primary-tint);
           box-shadow:0 0 0 1.5px var(--primary-tint)}

/* Kolom Asal: cip yang bisa diklik. Dua rupa yang jelas berbeda supaya satu
   kolom itu bisa dipindai tanpa membaca kata demi kata. */
.kr-asal{display:inline-flex;align-items:center;gap:5px;padding:3px 9px;border-radius:999px;
         border:1px solid var(--line);background:var(--surface-2);color:var(--muted);
         font:inherit;font-size:10.5px;font-weight:600;letter-spacing:.02em;cursor:pointer}
.kr-asal i{font-size:9px}
.kr-asal:hover{border-color:var(--primary);color:var(--primary)}
.kr-asal-rekrut{background:#EAF4EC;border-color:#A9DFBF;color:#1E8449}
.kr-asal-rekrut:hover{border-color:#1E8449;color:#14663A}
.kr-asal-kepala{margin:0 0 12px;font-size:13px}
.kr-asal-rinci{margin:0;display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px 14px}
.kr-asal-rinci div{min-width:0}
.kr-asal-rinci dt{font-size:10px;text-transform:uppercase;letter-spacing:.04em;color:var(--muted)}
.kr-asal-rinci dd{margin:2px 0 0;font-size:12px;line-height:1.45;word-break:break-word}
.kr-asal-rinci small{color:var(--muted);font-size:10.5px}
.kr-asal-judul{margin:16px 0 8px;font-size:11px;text-transform:uppercase;
               letter-spacing:.04em;color:var(--muted)}
.kr-asal-catatan{margin:14px 0 0;font-size:11px;line-height:1.55;color:var(--muted)}
@media (max-width:520px){ .kr-asal-rinci{grid-template-columns:minmax(0,1fr)} }
.kb-batas{margin:0 0 10px;padding:8px 12px;border-radius:8px;font-size:11.5px;
          line-height:1.55;color:var(--muted);background:var(--surface-2);
          border:1px solid var(--line)}
.kb-batas b{color:var(--ink)}
.dlg-angka{display:block;margin-top:12px;font-size:12px;color:var(--muted)}
.dlg-angka input{display:block;width:100%;margin-top:5px;padding:9px 11px;
                 border:1px solid var(--line);border-radius:8px;
                 background:var(--surface);color:var(--ink);font:inherit;
                 font-variant-numeric:tabular-nums}
/* Cip pada halaman ini memakai batas & kolom yang sama di kedua sisinya. */
.ac-sisi .pk-terpilih{grid-template-columns:repeat(3,minmax(0,1fr));margin-top:9px;
                      max-height:calc(5 * 27px + 4 * 5px);overflow-y:auto}
@container isi (max-width:1080px){ .ac-sisi .pk-terpilih{grid-template-columns:repeat(2,minmax(0,1fr))} }
@container isi (max-width:520px){ .ac-sisi .pk-terpilih{grid-template-columns:minmax(0,1fr)} }
.ac-aksi{display:flex;justify-content:flex-end;padding-top:12px}
/* Cabang yang aksesnya sudah ada, ditandai di antrean: menyetujuinya lagi tidak
   menambah apa pun, dan itu lebih baik diketahui sebelum diklik. */
.ac-punya{color:#3a9866;font-size:10px;margin-left:4px}

/* Sub-tugas di daftar Task: menjorok, dengan panah kecil sebagai penanda
   hubungannya. Nomornya sendiri sudah bercerita (1.1, 1.2), jadi indentasinya
   dibuat halus — bukan blok terpisah yang memutus keterbacaan kolomnya. */
.tg-anak .dt-no{color:var(--muted-2);font-size:10.5px}
.tg-anak .tg-teks{padding-left:22px;position:relative}
.tg-panah{position:absolute;left:8px;top:9px;font-size:8px;color:var(--muted-2);
          transform:rotate(90deg)}

/* ---------- Pengaturan > Kalendar ---------- */
/* Lebarnya kini ditentukan lajur kisinya, bukan max-width sendiri — dua tempat
   yang mengatur lebar yang sama akan berselisih pada perubahan berikutnya. */
.kal-saring{margin-bottom:0}
/* Tiga kolom sama rata selebar kartunya — bukan selebar isinya. Nama cabang di
   data ini panjang-panjang ("PANDEGLANG PANIMBANG"), dan dropdown yang menyusut
   ke lebar isinya memotong justru yang perlu dibaca. */
.kal-kisi{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:12px 14px;align-items:start}
@container isi (max-width:760px){ .kal-kisi{grid-template-columns:minmax(0,1fr)} }
.kal-saring .kl-input,.kal-kartu .kl-input{margin-bottom:0;font-size:12px;padding:6px 9px}
.kal-saring .cari-sel{display:flex}
.kal-saring .cari-tombol{width:100%;max-width:none;box-sizing:border-box;
                         border-radius:var(--r-input);padding:6px 9px}
.kal-bantu{margin:10px 0 0;font-size:11px;color:var(--muted);line-height:1.5}
/* Dua kartu berdampingan; menumpuk sendiri saat ruang isinya menyempit —
   ambangnya diukur dari RUANG ISI, bukan lebar layar. */
/* SATU kisi untuk seluruh halaman:
     baris 1 lajur 1  saringan
     baris 2 lajur 1  kalender
     lajur 2          kartu acara, membentang kedua baris
   Dengan begitu kartu acara mulai dari tepi atas saringan — tanpa ini ada
   ruang kosong selebar kartu di kanan atas — dan berakhir di garis bawah yang
   sama dengan kalender.
   Lebarnya PROPORSIONAL, bukan dipatok piksel: patokan tetap membuat kalender
   berhenti melebar di layar lebar sementara kartu acara menelan sisanya —
   halaman jadi terasa menyempit justru saat layarnya besar. Perbandingan 1,9:1
   memberi kalender ruang untuk tujuh kolom tanggal dan kartu acara cukup untuk
   isian dua kolomnya. Keduanya tetap mengisi penuh lebar layar. */
.kal-halaman{display:grid;grid-template-columns:minmax(0,1.9fr) minmax(300px,1fr);
             grid-template-rows:auto minmax(0,1fr);gap:18px;align-items:stretch}
.kal-saring{grid-column:1;grid-row:1}
.kal-kartu-kalender{grid-column:1;grid-row:2}
.kal-kartu-acara{grid-column:2;grid-row:1 / span 2}
/* Menumpuk: satu lajur, dan kartu acara kembali menjadi baris ketiga. */
@container isi (max-width:900px){
  .kal-halaman{grid-template-columns:minmax(0,1fr);grid-template-rows:none;align-items:start}
  .kal-saring,.kal-kartu-kalender,.kal-kartu-acara{grid-column:1;grid-row:auto}
}
/* Kartu mengisi tinggi lajurnya; isinya mengalir apa adanya dari atas. */
.kal-kartu{margin-bottom:0;display:flex;flex-direction:column}
.kal-kartu>.card-body{flex:1;min-height:0}
.kal-kartu .kf-kisi{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));
                    gap:12px 14px;align-items:start}
.kal-kartu .kf-lebar{grid-column:1/-1}
/* Kepala kedua kartu dibuat setinggi yang sama supaya tepi atasnya sejajar:
   yang kiri tabbar, yang kanan judul + periode. Keduanya memakai .card-head,
   jadi tingginya datang dari aturan yang sama, bukan dari angka yang dicocokkan
   dengan mata. */
.kal-kepala{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap}
.kal-kepala h4{margin:0;font-size:13px}
.kal-kartu>.card-head{min-height:46px;padding:0 14px;display:flex;align-items:center}
.kal-kartu>.card-head.jf-tabhead{padding:0 12px}
.kal-kartu .tabbar{border-bottom:0;margin-bottom:-1px}
.kal-kartu .tabbtn{padding:9px 11px;font-size:12px}
.kal-pane{display:none}
.kal-pane.show{display:block}

/* Kalender bulanan. Lebar kolomnya dibagi rata lewat grid, bukan tabel: jumlah
   hari per baris selalu tujuh, dan tabel hanya menambah aturan yang harus
   dilawan. */
/* Tinggi baris datang dari SELNYA, bukan dari pembagian sisa ruang kartu.
   Sempat dicoba `flex:1 1 0` supaya kartunya terisi penuh — dan itu justru
   merusak tampilannya: tinggi kartu ditentukan isinya, sementara isinya
   menunggu tinggi kartu, sehingga barisnya runtuh ke nol dan sel-selnya
   bertumpuk. Yang mengisi ruang cukup tinggi selnya sendiri. */
.kal-baris{display:grid;grid-template-columns:repeat(7,minmax(0,1fr));gap:4px;margin-bottom:4px}
.kal-sel-kepala{
  text-align:center;font-size:10px;font-weight:800;letter-spacing:.04em;text-transform:uppercase;
  color:var(--muted);padding:6px 0;
}
.kal-sel-kepala.akhir{color:var(--danger)}
/* Tinggi selnya sendiri yang membuat kalender terisi penuh — angka yang
   dinaikkan di sini terlihat langsung, tanpa bergantung tinggi kartunya. */
.kal-sel{
  min-height:66px;border:1px solid var(--line);border-radius:8px;padding:6px 7px;
  display:flex;flex-direction:column;gap:3px;background:var(--surface);
}
.kal-sel.kosong{border:0;background:transparent}
.kal-sel.akhir{background:var(--surface-2)}
.kal-sel.kini{border-color:var(--primary);box-shadow:0 0 0 2px var(--primary-tint)}
.kal-sel.ada{border-color:rgba(58,152,102,.55)}
/* Libur nasional: seluruh selnya bernada merah, bukan cuma titiknya —
   tanggal merah memang cara orang membaca kalender. */
.kal-sel.libur{background:#FDECEA;border-color:rgba(192,57,43,.35)}
.kal-sel.libur .kal-tgl{color:var(--danger)}
.kal-tgl{font-size:11.5px;font-weight:700;font-variant-numeric:tabular-nums}
.kal-sel.akhir .kal-tgl{color:var(--danger)}
.kal-titik{display:flex;gap:3px;margin-top:auto}
/* Nama libur di dalam selnya: kecil, dua baris paling banyak, dan dipotong
   dengan elipsis — sel kalender bukan tempat kalimat. */
.kal-libur-nama{
  font-size:9px;line-height:1.25;color:var(--danger);font-weight:700;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
}
.kal-dot{width:6px;height:6px;border-radius:50%;background:var(--primary)}
.kal-dot.j-libur{background:var(--danger)}
.kal-dot.j-pengingat{background:#d99236}

/* Daftar acara bulan berjalan. */
.kal-daftar{display:flex;flex-direction:column;gap:8px;
            max-height:420px;overflow-y:auto;overscroll-behavior:contain;padding-right:2px}
.kal-item{display:flex;gap:10px;align-items:flex-start;padding:8px 10px;border-radius:9px;
          background:var(--surface-2);border-left:3px solid var(--primary)}
.kal-item.j-libur{border-left-color:var(--danger)}
.kal-item.j-pengingat{border-left-color:#d99236}
/* Libur nasional bawaan: tidak bisa dihapus, jadi tidak diberi tombol buang —
   tombol yang selalu menolak lebih buruk daripada tombol yang tidak ada. */
.kal-item.bawaan{background:#FDECEA;border-left-color:var(--danger)}
.kal-item.bawaan .kal-item-isi small{color:#7B241C;opacity:.75}
.kal-item-tgl{flex:none;width:34px;text-align:center;font-size:15px;font-weight:800;
              font-variant-numeric:tabular-nums;line-height:1.1}
.kal-item-tgl small{display:block;font-size:9px;font-weight:700;color:var(--muted);
                    text-transform:uppercase;letter-spacing:.03em}
.kal-item-isi{flex:1;min-width:0;font-size:12px;line-height:1.5}
.kal-item-isi span{display:block;color:var(--ink-soft)}
.kal-item-isi small{display:block;color:var(--muted);font-size:10.5px;margin-top:2px}
.kal-ubah,.kal-buang{flex:none;background:none;border:0;color:var(--muted-2);cursor:pointer;padding:2px 4px}
.kal-ubah:hover{color:var(--primary)}
.kal-buang:hover{color:var(--danger)}
/* Judul acara di dalam sel tanggal: dua baris paling banyak, dipotong elipsis.
   Sel kalender bukan tempat kalimat — yang lengkap ada di daftar sebelah. */
.kal-acara{display:flex;flex-direction:column;gap:2px;margin-top:auto;min-width:0}
.kal-nama{
  font-style:normal;font-size:9.5px;line-height:1.25;font-weight:700;
  padding:1px 4px;border-radius:4px;background:var(--primary-tint);color:var(--primary);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.kal-nama.j-libur{background:#FDECEA;color:#7B241C}
.kal-nama.j-pengingat{background:#FBF1DC;color:#5C4A0A}
.kal-lagi{font-style:normal;font-size:9px;color:var(--muted)}

/* ---------- Halaman Gaji (Karyawan > Gaji) ----------
   Susunannya mengikuti formulir Jadwal: halaman mengisi tinggi .content, lalu
   yang menggulir adalah bagian dalam tiap lajur — bukan seluruh halaman —
   sehingga baris tombol kartu gaji tidak pernah terdorong keluar layar. */
#page-karyawan-gaji.active{display:flex;flex-direction:column;height:100%;min-height:0}
.gj{display:grid;grid-template-columns:minmax(0,1fr) clamp(280px,30%,400px);
    gap:0 18px;flex:1;min-height:0}
.gj-kiri{min-width:0;min-height:0;display:flex;flex-direction:column}
.gj-kanan{min-height:0;display:flex;flex-direction:column}
.gj-kiri .dt-card{flex:1;min-height:0;display:flex;flex-direction:column;margin-bottom:0}
/* max-height bawaan .table-scroll dihitung dari jumlah baris; di sini tingginya
   datang dari kartunya, jadi batas itu dilepas. */
.gj-kiri .table-scroll{flex:1;min-height:0;max-height:none}
.gj-kartu{flex:1;min-height:0;display:flex;flex-direction:column;margin-bottom:0}
.gj-kartu>.card-body{flex:1;min-height:0;display:flex;flex-direction:column;padding:16px 18px}
/* Yang menggulir hanya isian tengahnya: kepala (nama karyawan) dan baris tombol
   tetap terlihat berapa pun panjang isinya. */
.gj-form{flex:1;min-height:0;display:flex;flex-direction:column}
.gj-isi{flex:1;min-height:0;overflow-y:auto;overscroll-behavior:contain;padding-right:2px}
.gj-kepala{flex:none;padding-bottom:12px;border-bottom:1px solid var(--line);margin-bottom:14px}
.gj-kepala b{display:block;font-size:14px;line-height:1.35}
.gj-kepala span{display:block;font-size:11.5px;color:var(--muted);margin-top:2px}
/* Satu kolom: lajurnya sempit, dan memaksa dua kolom di sini membuat label
   terpotong justru pada isian yang angkanya paling panjang. */
.gj-kisi{display:grid;grid-template-columns:minmax(0,1fr);gap:10px 14px;align-items:start}
.gj-kisi .kl-input{margin-bottom:0;font-size:12px;padding:6px 9px}
.gj-uang{text-align:right;font-variant-numeric:tabular-nums}
.gj-total{display:flex;align-items:baseline;justify-content:space-between;gap:10px;
          margin-top:12px;padding:9px 11px;border-radius:9px;background:var(--surface-2)}
.gj-total span{font-size:11.5px;color:var(--muted)}
.gj-total b{font-size:14px;font-variant-numeric:tabular-nums}
.gj-berkas,.gj-audit{margin:10px 0 0;font-size:11px;color:var(--muted);line-height:1.5}
.gj-bawah{flex:none;display:flex;gap:9px;justify-content:flex-end;padding-top:12px}
.gj-kosong{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;
           gap:7px;text-align:center;color:var(--muted);padding:26px 12px}
.gj-kosong i{font-size:26px;opacity:.5}
.gj-kosong b{font-size:13px;color:var(--ink)}
.gj-kosong span{font-size:11.5px;max-width:230px}
/* Nama karyawan adalah tombol, tapi harus terbaca sebagai isi sel biasa — yang
   membedakannya cukup warnanya saat disorot. */
.gj-nama{background:none;border:0;padding:0;font:inherit;font-weight:700;color:var(--ink);
         text-align:left;cursor:pointer}
.gj-nama:hover,.gj-nama:focus-visible{color:var(--primary);text-decoration:underline}
.gj-nama.aktif{color:var(--primary)}
/* Dropdown Bank juga dibungkus jadi dropdown bercari; tombol penggantinya harus
   selebar .kl-input di atas dan di bawahnya, bukan selebar isinya. Ketiga
   dropdown filter di atas tabel tidak perlu aturan sendiri — bindTable sudah
   membungkusnya, dan gaya bawaan .cari-tombol memang meniru <select>. */
.gj-kisi .cari-sel{display:flex}
.gj-kisi .cari-tombol{
  width:100%;max-width:none;box-sizing:border-box;
  border-radius:var(--r-input);padding:6px 9px;
}
.gj-kisi .cari-sel.buka .cari-tombol,
.gj-kisi .cari-tombol:focus-visible{
  border-color:var(--primary);box-shadow:0 0 0 3px var(--primary-tint);outline:none}

/* Ambangnya diukur dari RUANG ISI, bukan lebar layar — sama seperti formulir
   Jadwal: layar 1366px dengan sidebar terbuka hanya menyisakan ~1050px. */
@container isi (max-width:1000px){
  #page-karyawan-gaji.active{display:block;height:auto}
  .gj{display:block}
  .gj-kiri .dt-card{display:block;margin-bottom:18px}
  .gj-kiri .table-scroll{max-height:60vh}
  .gj-kartu,.gj-kartu>.card-body,.gj-form{display:block;min-height:0}
  .gj-isi{overflow:visible}
  .gj-kisi{grid-template-columns:repeat(auto-fit,minmax(200px,280px));justify-content:start}
}
/* Semua <select> di formulir ini dibungkus jadi dropdown bercari lewat
   jadikanCari(). Tombol penggantinya harus terlihat persis seperti .kl-input di
   sebelahnya — kalau tidak, satu kendali tampak "beda sendiri" padahal
   fungsinya sejenis. Nilainya disalin dari .kf-kisi .kl-input, bukan dikarang. */
.kf .cari-sel{display:flex}
.kf .cari-tombol{
  width:100%;max-width:none;box-sizing:border-box;
  background:var(--surface-2);border:1px solid var(--line);border-radius:var(--r-input);
  padding:6px 9px;font-size:12px;color:var(--ink);
}
.kf .cari-sel.buka .cari-tombol,
.kf .cari-tombol:focus-visible{border-color:var(--primary);box-shadow:0 0 0 3px var(--primary-tint);outline:none}
/* Pemilih aplikasi memakai dua kolom: tombolnya sempit, tapi daftar cip di
   bawahnya butuh ruang supaya nama aplikasi tidak terpotong. */
.kf-aplikasi{grid-column:span 2}
@container isi (max-width:700px){ .kf-aplikasi{grid-column:1/-1} }
.kf-aplikasi .pk-terpilih{max-height:190px}

/* --- Pemilih banyak-pilihan (Jabatan & User) --- */
.pk{position:relative}
.pk-tombol{
  display:flex;align-items:center;gap:8px;width:100%;cursor:pointer;
  font-family:inherit;font-size:12px;color:var(--ink);text-align:left;
  background:var(--surface-2);border:1px solid var(--line);border-radius:var(--r-input);padding:6px 9px;
}
.pk-tombol:focus-visible{outline:none;border-color:var(--primary);box-shadow:0 0 0 3px var(--primary-tint)}
.pk-tombol i{margin-left:auto;font-size:10px;opacity:.6;flex:none}
.pk-ringkas{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* Panel mengambang di ATAS isi lain supaya tidak mendorong kartunya memanjang
   setiap kali dibuka — daftarnya bisa ratusan baris. */
/* .atas dipasang JS saat ruang di bawah tombol tidak cukup — di dalam lajur
   yang menggulir, panel yang selalu membuka ke bawah akan terpotong tepinya. */
.pk-panel.atas{top:auto;bottom:calc(100% + 4px)}
.pk-panel{
  position:absolute;z-index:40;top:calc(100% + 4px);left:0;right:0;
  background:var(--surface);border:1px solid var(--line);border-radius:var(--r-input);
  box-shadow:var(--shadow-md,0 8px 24px rgba(0,0,0,.14));padding:7px;
}
.pk-cari{
  font-family:inherit;font-size:12px;color:var(--ink);width:100%;box-sizing:border-box;
  background:var(--surface-2);border:1px solid var(--line);border-radius:var(--r-input);padding:5px 8px;
}
.pk-cari:focus{outline:none;border-color:var(--primary);box-shadow:0 0 0 3px var(--primary-tint)}
.pk-daftar{max-height:230px;overflow:auto;margin-top:6px}
.pk-opsi{
  display:flex;align-items:center;gap:8px;width:100%;cursor:pointer;
  padding:4px 6px;border-radius:6px;font-size:12px;color:var(--ink);line-height:1.35;
}
.pk-opsi:hover{background:var(--surface-2)}
.pk-opsi input{width:14px;height:14px;accent-color:var(--primary);cursor:pointer;flex:none}
.pk-opsi small{display:block;color:var(--muted);font-size:11px}
.pk-info{margin:6px 2px 0;color:var(--muted);font-size:11px;line-height:1.4}
.pk-info:empty{display:none}
/* Dua bagian: daftar terpilih berisi puluhan baris, dan satu lajur membuat
   kartunya jadi gulungan panjang.
   Tingginya ditentukan kartunya (lihat .jf-kanan-lajur di atas), jadi di sinilah
   perilaku gulirnya — bukan batas pikselnya. */
.pk-terpilih{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:5px;margin-top:9px;
             overflow:auto;overscroll-behavior:contain}
@container isi (max-width:380px){ .pk-terpilih{grid-template-columns:minmax(0,1fr)} }
.pk-cip{
  display:flex;align-items:center;gap:5px;min-width:0;
  background:var(--surface-2);border:1px solid var(--line);border-radius:6px;padding:3px 4px 3px 7px;
  font-size:11.5px;color:var(--ink);
}
.pk-cip span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1}
.pk-cip button{
  flex:none;width:17px;height:17px;display:grid;place-items:center;cursor:pointer;
  background:transparent;border:0;border-radius:5px;color:var(--muted);font-size:10px;
}
.pk-cip button:hover{background:rgba(192,57,43,.12);color:var(--danger,#C0392B)}
.pk-cip.otomatis{background:var(--primary-tint);border-color:transparent}
.pk-tanda{flex:none;font-size:8.5px;opacity:.65}
.pk-kosong{grid-column:1/-1;color:var(--muted);font-size:11.5px;padding:2px}
/* Keterangan pemakaian nyata — sengaja TIDAK berbentuk cip: cip di panel ini
   berarti "terpilih dan akan disimpan", dan yang di bawah ini bukan keduanya. */
.pk-pakai{margin-top:10px;border-top:1px solid var(--line);padding-top:9px}
.pk-pakai:empty{display:none}
.pk-pakai h6{font-size:10.5px;font-weight:800;letter-spacing:.05em;text-transform:uppercase;
             color:var(--muted);margin-bottom:5px}
.pk-pakai p{font-size:11.5px;color:var(--muted);line-height:1.5;margin-bottom:5px}
.pk-pakai b{color:var(--ink-soft)}
.pk-pakai ul{max-height:150px;overflow:auto;overscroll-behavior:contain;
             display:flex;flex-direction:column;gap:2px;margin:0;padding:0;list-style:none}
.pk-pakai ul>li{flex:none;font-size:11.5px;color:var(--ink-soft);line-height:1.4;
                white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.pk-pakai li span{color:var(--muted)}
/* Keterangan netral di dalam formulir — menjelaskan akibat sebuah isian
   SEBELUM disimpan, bukan mengabarkan kesalahan. Karena itu warnanya tenang,
   berbeda dari .kl-galat di bawahnya. */
.kl-petunjuk{
  margin:2px 0 0;padding:9px 11px;border-radius:var(--r-input);
  background:var(--surface-2);color:var(--muted);font-size:12px;line-height:1.5;
}
.kl-petunjuk:empty{display:none}
/* Pesan galat dari server ditampilkan apa adanya di dekat formulirnya — bukan
   sebagai toast yang keburu hilang sebelum sempat dibaca. */
.kl-galat{
  margin:2px 0 0;padding:9px 11px;border-radius:var(--r-input);
  background:rgba(192,57,43,.1);color:#8E2A20;font-size:12.5px;line-height:1.5;
}

/* --- Akses cabang per karyawan --- */
.cab-tambah{display:flex;gap:8px;align-items:center;flex-wrap:wrap}
.cab-tambah .cari-sel{flex:1;min-width:0}
.cab-tambah .cari-tombol{width:100%;max-width:none;padding:8px 10px;font-size:12.5px}
.cab-tambah select{
  flex:1;min-width:0;font-family:inherit;font-size:12.5px;color:var(--ink);
  background:var(--surface-2);border:1px solid var(--line);border-radius:var(--r-input);padding:8px 10px;cursor:pointer;
}
.cab-tambah select:focus{outline:none;border-color:var(--primary);box-shadow:0 0 0 3px var(--primary-tint)}
/* Dua kolom: daftar cabang bisa berisi puluhan baris, dan satu kolom membuat
   modalnya jadi gulungan panjang. align-content:start supaya barisnya menumpuk
   dari atas, bukan direntangkan memenuhi tinggi. */
.cab-daftar{
  display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:6px;
  align-content:start;overflow:auto;flex:1;min-height:0;padding-right:2px;
}
/* Di layar sempit dua kolom justru memotong nama cabang — kembali satu kolom. */
@media (max-width:620px){ .cab-daftar{grid-template-columns:minmax(0,1fr)} }
.cab-jumlah{font-weight:600;color:var(--muted)}
.cab-baris{
  display:flex;align-items:center;gap:9px;
  background:var(--surface-2);border:1px solid var(--line);border-radius:var(--r-input);padding:8px 10px;font-size:12.5px;
}
.cab-baris b{font-weight:700;color:var(--ink);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.cab-utama{font-size:9.5px;font-weight:800;text-transform:uppercase;letter-spacing:.3px;
  background:var(--primary-tint);color:var(--primary);padding:2px 7px;border-radius:20px}
.cab-baris .hapus{margin-left:auto;background:none;border:none;cursor:pointer;color:#C0392B;
  padding:4px 7px;border-radius:6px;font-size:12px}
.cab-baris .hapus:hover{background:rgba(192,57,43,.12)}
.cab-kosong{color:var(--muted);font-size:12px;padding:14px 2px;grid-column:1/-1}
.cab-list{color:var(--ink-soft)}
.cab-list.kosong{color:var(--muted);font-style:italic}

/* --- Foto absen --- */
.ft-ada{color:var(--primary);cursor:pointer;font-size:14px}
.ft-ada:hover,.ft-ada:focus-visible{color:#3730A3;outline:none}
/* Tidak ada foto: ikon gambar yang dicoret, warnanya redam supaya tidak
   berteriak seperti penanda pelanggaran — ini keterangan, bukan masalah. */
.ft-no{color:var(--muted);opacity:.7;font-size:14px}
.ft-no .fa-slash{color:#C0392B}
/* Pratinjau foto */
.foto-bd{position:fixed;inset:0;background:rgba(15,23,42,.78);z-index:120;
  display:none;align-items:center;justify-content:center;padding:24px}
.foto-bd.show{display:flex}
.foto-box{max-width:min(92vw,720px);max-height:88vh;display:flex;flex-direction:column;gap:10px}
.foto-box img{max-width:100%;max-height:78vh;object-fit:contain;border-radius:10px;background:#0F172A}
.foto-head{display:flex;align-items:center;gap:10px;color:#fff;font-size:12.5px;font-weight:700}
.foto-head .x{margin-left:auto;background:rgba(255,255,255,.14);border:none;color:#fff;
  width:30px;height:30px;border-radius:8px;cursor:pointer;font-size:13px}
.foto-head .x:hover{background:rgba(255,255,255,.26)}
.foto-pesan{color:#E4E5EC;font-size:12.5px;background:rgba(255,255,255,.08);
  padding:26px 20px;border-radius:10px;text-align:center;line-height:1.6}

.tab-wrap{display:inline-flex;align-items:center}
.tab-note{
  cursor:pointer;color:var(--muted);opacity:.6;font-size:11px;
  padding:3px 4px;border-radius:5px;margin-left:-4px;transition:opacity .15s,background .15s,color .15s;
}
.tab-note:hover,.tab-note:focus-visible{opacity:1;color:var(--primary);background:var(--primary-tint);outline:none}

/* --- Filter periode di baris kontrol tabel --- */
.dt-periode{display:flex;align-items:center;gap:6px;flex-wrap:wrap}
.dt-periode-lb{font-size:11.5px;font-weight:700;color:var(--muted);display:inline-flex;align-items:center;gap:5px}
.dt-periode select{font-family:inherit;font-size:12px;font-weight:600;color:var(--ink);
  background:var(--surface);border:1px solid var(--line);border-radius:var(--r-input);padding:6px 9px;cursor:pointer}
.dt-periode select:focus{outline:none;border-color:var(--primary);box-shadow:0 0 0 3px var(--primary-tint)}
/* Kendali Mode menempel di kotak pencarian, jadi jaraknya dirapatkan. */
.dt-mode{gap:5px;margin-right:2px}
/* Nama jabatan dan nama karyawan jauh lebih panjang dari "Rekap" atau nama
   cabang, jadi tombol pencarinya dibatasi: tanpa batas, satu nama panjang
   mendorong kotak pencarian keluar baris. Isinya tetap terbaca penuh di dalam
   panel pilihannya. */
/* Disasar lewat aria-label tombolnya: jadikanCari MEMBUNGKUS <select> ke dalam
   .cari-sel dan menyalin aria-label-nya ke tombol, jadi kelas di <select>-nya
   sendiri tidak lagi bisa dipakai menata yang terlihat. */
.dt-mode .cari-tombol[aria-label="Jabatan"],
.dt-mode .cari-tombol[aria-label="Karyawan"]{max-width:180px;min-width:0}
/* Keterangan tanggal di atas tabel mode Absensi. */
.dt-cap{font-size:12px;font-weight:700;color:var(--ink-soft);padding:0 0 8px}

/* --- Nama karyawan yang bisa diklik --- */
/* Warna primary: kontras 6,08 pada baris biasa dan 5,22 saat baris ter-hover
   — keduanya lolos ambang WCAG 4,5. */
.name-link{color:var(--primary);cursor:pointer;text-decoration:none;border-bottom:1px dotted currentColor}
.name-link:hover,.name-link:focus-visible{text-decoration:underline;border-bottom-color:transparent}

/* --- Kepala halaman Detail Absensi --- */
.det-head{display:flex;align-items:center;gap:12px;flex-wrap:wrap;margin-bottom:12px}
/* Satu baris: nama karyawan + role/jabatan/NIK di SAMPINGnya (dulu bertumpuk). */
.det-id{display:flex;flex-direction:row;align-items:baseline;gap:7px;flex-wrap:wrap;min-width:0}
.det-id b{font-size:14px;color:var(--ink);line-height:1.3}
.det-id span{font-size:11.5px;color:var(--muted)}
.det-id span::before{content:"\00b7";margin-right:7px;color:var(--muted-2);font-weight:700}
/* Baris kendali tabel (Semua kolom + Cari) yang dinaikkan ke bilah tab: mentok
   kanan, sejajar tab; hanya milik tab aktif yang tampil. Padding bawah .dt-top
   dinolkan karena di sini ia berada di dalam .tabbar, bukan di atas tabel. */
.det-tab-alat{display:flex;align-items:center;margin-left:auto}
.det-tab-alat .dt-top{display:none;padding:0;margin:0 0 2px}
.det-tab-alat .dt-top.show-alat{display:flex}
/* Wadah lead/trail kosong tak perlu memakan celah gap — biar Cari mentok kanan. */
.det-tab-alat .dt-lead:empty,.det-tab-alat .dt-trail:empty{display:none}
.det-periode{margin-left:auto;font-size:11.5px;font-weight:700;color:var(--primary);
  background:var(--primary-tint);border-radius:999px;padding:5px 12px;white-space:nowrap}
@container isi (max-width:520px){ .det-periode{margin-left:0;order:9} }

/* Footer jumlah: menempel di bawah area gulir agar tetap terlihat. */
.dt-card table tfoot td{
  position:sticky;bottom:0;z-index:2;
  background:var(--surface-2);border-top:1px solid var(--line);
  font-size:11.5px;font-weight:800;color:var(--ink);padding:9px 12px;
}
.tg-cek{width:16px;height:16px;accent-color:var(--primary);cursor:pointer;display:block;margin:0 auto}
/* Tugas yang sudah dikerjakan tetap terbaca, tapi jelas berbeda dari yang belum. */
.tg-sel{color:var(--muted);text-decoration:line-through}

/* ---- Daftar Task di dalam modal ----
   Aturan dasar tabel mengunci tinggi baris dan melarang teks membungkus; itu
   benar untuk tabel data yang dipindai berkolom, tapi salah di sini: tugas
   adalah kalimat. Tanpa pengecualian ini, tugas yang panjang memanjang ke
   samping dan mendorong kolom Status keluar layar — persis yang tidak boleh
   terjadi, karena Status justru yang dicari orang saat membuka tab ini. */
#taskBody td{height:auto;padding:8px 9px;white-space:normal;vertical-align:top}
.tg-teks{overflow-wrap:anywhere;line-height:1.55;min-width:180px}
/* Kolom Aksi & Status selebar isinya saja dan tidak pernah membungkus, jadi
   sisa lebar sepenuhnya jatuh ke kolom tugas. */
.tg-kol-aksi,.tg-kol-status{width:1%;white-space:nowrap}
#taskBody td.tg-aksi,#taskBody td.tg-status{white-space:nowrap;width:1%;vertical-align:middle}
#taskBody td.dt-no,#taskBody td.dt-cek{vertical-align:middle}
.tg-tombol{display:inline-flex;gap:4px;justify-content:center}
.tg-tombol button{
  width:26px;height:26px;border:1px solid var(--line);background:var(--surface);
  border-radius:6px;cursor:pointer;display:grid;place-items:center;
  font-size:11.5px;color:var(--ink-soft);transition:.12s;
}
.tg-tombol button:hover{background:var(--primary-tint);border-color:var(--primary);color:var(--primary)}
.tg-tombol button:focus-visible{outline:2px solid var(--primary);outline-offset:1px}
/* Tombol progres menyala saat tugasnya memang sedang dikerjakan. */
.tg-tombol button.on{background:#FBF1DC;border-color:#d99236;color:#8a5a12}
.tg-tombol button[disabled]{opacity:.4;cursor:not-allowed}
/* Lencana status membawa tooltip berisi nama pengubah — kursor tanya
   memberi tahu bahwa ada yang bisa dibaca di situ. */
#taskBody .badge{cursor:help}
/* Lampiran pada baris tugas: keping kecil berisi nama berkasnya. */
.tg-lampiran{display:flex;flex-wrap:wrap;gap:5px;margin-top:6px}
.tg-keping{
  display:inline-flex;align-items:center;max-width:240px;
  border:1px solid var(--line);background:var(--surface);border-radius:6px;
  padding:2px 6px 2px 7px;font-size:11px;color:var(--ink-soft);
}
.tg-keping:hover{border-color:var(--primary)}
.tg-keping .buka{
  display:inline-flex;align-items:center;gap:5px;min-width:0;
  border:none;background:none;padding:0;cursor:pointer;
  font:inherit;font-size:11px;color:inherit;
}
.tg-keping .buka:hover{color:var(--primary)}
.tg-keping i{flex:none}
.tg-keping .buka span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tg-keping .buang{
  border:none;background:none;padding:0;margin-left:5px;cursor:pointer;
  color:var(--muted);font-size:10px;width:14px;height:14px;display:grid;place-items:center;
}
.tg-keping .buang:hover{color:var(--danger)}
.tg-keping button:focus-visible{outline:2px solid var(--primary);outline-offset:1px}

/* ---- Pratinjau lampiran ---- */
.lamp-modal{max-width:min(920px,94vw)}
.lamp-modal .lamp-judul{min-width:0}
.lamp-modal .lamp-judul h3{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.lamp-body{display:grid;place-items:center;background:var(--surface-2);max-height:70vh;overflow:auto}
.lamp-body img{max-width:100%;max-height:66vh;display:block;border-radius:6px}

@media (max-width:560px){
  .modal-full .modal-foot{flex-wrap:wrap}
  .note-count{width:100%;margin:0 0 4px}
}

/* ===== Filter dasbor ===== */
.dash-filter{
  display:flex;align-items:flex-end;gap:10px;flex-wrap:wrap;
  background:var(--surface);border:1px solid var(--line);
  border-radius:var(--r-card);padding:14px 16px;margin-bottom:18px;
  box-shadow:var(--shadow-sm);
}
.dash-filter .f-item{display:flex;flex-direction:column;gap:5px;min-width:0}
.dash-filter label{font-size:11px;font-weight:700;color:var(--ink-soft)}
.dash-filter select,.dash-filter input{
  padding:8px 11px;border:1px solid var(--line);border-radius:var(--r-input);
  font-family:inherit;font-size:12.5px;color:var(--ink);background:var(--surface-2);transition:.15s;
}
.dash-filter select{min-width:190px;max-width:100%}
/* Saringan Cabang kini pemilih-bisa-dicari: tombolnya menggantikan <select>,
   jadi ukurannya disamakan dengan kotak tanggal di sebelahnya — kalau tidak,
   satu kendali terlihat "beda sendiri" padahal fungsinya sejenis. */
.dash-filter .cari-sel{display:block}
.dash-filter .cari-tombol{
  width:100%;min-width:190px;max-width:none;justify-content:space-between;
  padding:8px 11px;font-size:12.5px;border-radius:var(--r-input);
}
.rk-bar .cari-tombol{min-width:190px;max-width:none;justify-content:space-between;
  font-size:12px;padding:6px 9px;border-radius:var(--r-input)}
.dash-filter select:focus,.dash-filter input:focus{
  outline:none;border-color:var(--primary);background:#fff;box-shadow:0 0 0 4px var(--primary-tint);
}
.dash-filter .btn{height:34px}
.dash-filter .btn:disabled{opacity:.55;cursor:default;transform:none}
.f-note{margin-left:auto;align-self:center;font-size:11.5px;color:var(--muted);font-weight:600}
@container isi (max-width:600px){
  .dash-filter .f-item{flex:1 1 140px}
  .dash-filter select{min-width:0;width:100%}
  /* Kolom tanggal melebar di layar sempit; kotak teksnya ikut melebar supaya
     ikon kalender (diposisikan di ujung kanan kolom) tetap DI DALAM kotak. */
  .dash-filter .tgl-tampil{width:100%}
  .dash-filter .cari-tombol{min-width:0}
  .f-note{margin-left:0;width:100%;order:9}
}

/* ============ HISTORY KARYAWAN ============ */
/* FULL HEIGHT: halaman mengisi TINGGI .content persis seperti halaman datatable/board
   lain (karyawan-gaji, jadwal-form, divisi) → TIDAK ada gulir halaman; datatable &
   panel menggulir di DALAM. `height:100%` WAJIB: tanpanya, override table-scroll
   (max-height:none) di bawah membuat tabel setinggi 20 baris dan seluruh halaman
   meluber di layar tinggi. :has(.dt-bottom) sudah beri flex-column; ini melengkapinya. */
#page-history-karyawan.active{display:flex;flex-direction:column;height:100%;min-height:0}
/* Layout mengisi SISA tinggi; tiap panel menggulir di DALAM, bukan seluruh halaman.
   3 panel: datatable karyawan (kiri) · menu jenis (tengah) · detail (kanan). */
.hk-layout{flex:1 1 auto;min-height:0;display:grid;
  grid-template-columns:minmax(340px,38%) 1fr;gap:16px;align-items:stretch}
@container isi (max-width:1000px){ .hk-layout{grid-template-columns:1fr;overflow-y:auto} }
.hk-left{min-height:0}
/* Point 1: datatable MENGISI tinggi kolomnya (bukan dibatasi jumlah baris); baris
   di luar layar digulir di dalam area tabel. Menang atas .table-scroll bawaan. */
#page-history-karyawan .hk-left .table-scroll{max-height:none;flex:1 1 auto;min-height:0}
/* Nama di datatable = tautan; terpilih → pil utama + baris tersorot. */
.hk-k-link{cursor:pointer;border-radius:5px}
.hk-k-link:hover{color:var(--primary);text-decoration:underline}
.hk-k-link.on{background:var(--primary);color:#fff;padding:2px 8px;border-radius:999px;text-decoration:none}
#tblHkKaryawan tbody tr:has(.hk-k-link.on){background:var(--primary-tint)}
/* Kanan: header identitas (tetap) + master-detail yang mengisi sisa tinggi. */
.hk-right{min-width:0;min-height:0;display:flex;flex-direction:column;gap:14px}
.hk-main{flex:1 1 auto;min-height:0;display:grid;
  grid-template-columns:minmax(200px,30%) 1fr;gap:14px;align-items:stretch}
@container isi (max-width:1000px){ .hk-main{min-height:360px} }
/* Header identitas + statistik (Tanggal Join / Lama Kerja / End Date). */
.hk-header{background:var(--surface);border:1px solid var(--line-3d);border-radius:var(--r-card);
  box-shadow:var(--shadow-3d);padding:14px 16px;display:flex;flex-wrap:wrap;align-items:center;
  gap:10px 24px;justify-content:space-between;flex:none}
.hk-hd-id{display:flex;flex-direction:column;gap:2px;min-width:0}
.hk-hd-id b{font-size:15px;color:var(--ink);line-height:1.25}
.hk-hd-id span{font-size:11.5px;color:var(--muted)}
.hk-hd-stats{display:flex;flex-wrap:wrap;gap:8px 10px}
.hk-stat{display:flex;flex-direction:column;gap:1px;padding:6px 12px;background:var(--surface-2);
  border:1px solid var(--line);border-radius:8px;min-width:96px}
.hk-stat-l{font-size:10px;font-weight:700;letter-spacing:.3px;text-transform:uppercase;color:var(--muted-2)}
.hk-stat b{font-size:12.5px;color:var(--ink);white-space:nowrap}
.hk-kosong{color:var(--muted);font-size:13px;padding:30px 4px;text-align:center}
/* Point 2: MENU jenis sejarah — kartu berisi daftar item; SCROLL hanya di sini. */
.hk-menu{background:var(--surface);border:1px solid var(--line-3d);border-radius:var(--r-card);
  box-shadow:var(--shadow-3d);padding:8px;overflow-y:auto;min-height:0;display:flex;flex-direction:column;gap:4px}
.hk-mitem{display:flex;align-items:center;gap:10px;width:100%;text-align:left;padding:9px 10px;
  border:1px solid transparent;border-radius:10px;background:transparent;cursor:pointer;
  font-family:inherit;transition:background .12s,border-color .12s}
.hk-mitem:hover{background:var(--surface-2)}
.hk-mitem.on{background:var(--primary-tint);border-color:var(--primary)}
.hk-mitem:focus-visible{outline:2px solid var(--primary);outline-offset:-2px}
.hk-mitem b{flex:1;min-width:0;font-size:13px;color:var(--ink);line-height:1.25}
.hk-mitem.on b{color:var(--primary-600)}
.hk-mcaret{color:var(--muted-2);font-size:11px;flex:none}
.hk-mitem.on .hk-mcaret{color:var(--primary)}
/* Point 3: DETAIL jenis terpilih — judul tetap (sticky) + daftar record; SCROLL di dalam. */
.hk-detail{background:var(--surface);border:1px solid var(--line-3d);border-radius:var(--r-card);
  box-shadow:var(--shadow-3d);min-height:0;overflow-y:auto;display:flex;flex-direction:column}
.hk-dhead{display:flex;align-items:center;gap:10px;padding:12px 14px;border-bottom:1px solid var(--line);
  position:sticky;top:0;background:var(--surface);z-index:1}
.hk-dhead b{flex:1;min-width:0;font-size:14px;color:var(--ink)}
.hk-dbody{padding:10px 12px 14px;display:flex;flex-direction:column;gap:7px}
/* Ikon chip dipakai bersama menu & detail. */
.hk-mitem .ic,.hk-dhead .ic{width:32px;height:32px;border-radius:9px;display:grid;place-items:center;font-size:13px;flex:none}
.hk-n{font-size:12px;font-weight:800;min-width:26px;height:22px;padding:0 7px;border-radius:999px;
  display:inline-flex;align-items:center;justify-content:center;background:var(--surface-2);
  color:var(--muted);font-variant-numeric:tabular-nums}
.hk-row{padding:8px 10px;border-radius:8px;background:var(--surface-2);font-size:12px;line-height:1.5}
.hk-row-top{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.hk-row-top b{color:var(--ink);font-size:12.5px}
.hk-row-meta{color:var(--muted);font-size:11px;margin-top:2px}
.hk-row-detail{color:var(--ink);font-size:11.5px;margin-top:4px;white-space:normal;
  background:rgba(0,0,0,.025);border-radius:6px;padding:5px 8px}
.hk-sub{font-size:11px;font-weight:700;color:var(--muted);text-transform:uppercase;letter-spacing:.04em;margin:6px 2px 1px}
.hk-kosong-sec{color:var(--muted);font-size:12px;padding:12px 4px;text-align:center;font-style:italic}
.hk-src,.hk-tag{font-size:10px;font-weight:700;padding:1px 7px;border-radius:999px;
  background:var(--surface);border:1px solid var(--line);color:var(--muted);text-transform:capitalize}
.hk-amt{font-size:11.5px;font-weight:700;color:var(--danger);font-variant-numeric:tabular-nums}
@media (prefers-color-scheme:dark){ .hk-row-detail{background:rgba(255,255,255,.04)} }
:root[data-theme="dark"] .hk-row-detail{background:rgba(255,255,255,.04)}

.hk-mode{background:var(--primary-tint);border-color:transparent;color:var(--primary);text-transform:none}

/* Baris keputusan (tgl+jam approve/tolak) di tiap history row. */
.hk-row-putus{margin-top:5px;font-size:11px;font-weight:600;display:flex;align-items:center;gap:5px;flex-wrap:wrap}
.hk-row-putus i{font-size:10.5px}
.hk-row-putus.ok{color:var(--success)}
.hk-row-putus.no{color:var(--danger)}

/* Perpindahan: Efektif + keputusan dalam SATU baris (hk-row-meta). */
.hk-eff{color:var(--muted)}
.hk-dot{margin:0 6px;color:var(--muted)}
.hk-putus-in{font-weight:600;white-space:nowrap}
.hk-putus-in.ok{color:var(--success)}
.hk-putus-in.no{color:var(--danger)}
.hk-putus-in i{font-size:10px;margin-right:2px}
.hk-ditarik{display:inline-flex;align-items:center;gap:5px;font-weight:600;color:var(--warning,#b45309)}
.hk-ditarik i{font-size:11px}

/* ---- Struktur Organisasi (hirarki atasan → divisi) ---- */
body:not(.bisa-struktur) .nav-struktur{display:none}
/* Master READ-ONLY (body.master-ro = bukan ITAdmin/andriansyah): sembunyikan tombol
   Tambah + ikon Ubah/Hapus di kolom Action pada SEMUA halaman Master. */
.master-ro #btnAddKlien,.master-ro #btnAddCabang,.master-ro #btnAddJabatan,
.master-ro #btnAddKaryawan,.master-ro #btnAddJadwal,.master-ro #btnAddTipeWo,
.master-ro #btnAddKontrak{display:none!important}
.master-ro #page-klien .act,.master-ro #page-cabang .act,.master-ro #page-jabatan .act,
.master-ro #page-karyawan .act,.master-ro #page-jadwal-absen .act,
.master-ro #page-tipewo .act,.master-ro #page-kontrak .act{display:none!important}
/* Divisi = board: "+" grup/cabang (Tambah) & ikon Ubah/Hapus baris datatable. */
/* Divisi disembunyikan HANYA bila read-only DAN bukan pengelola divisi: akun
   ber-DIVISI_AKSES (mis. salsabil) tetap bisa tambah/ubah/hapus di board ini
   walau master lain read-only. body.divisi-kelola dipasang dari flag kelolaDivisi. */
.master-ro:not(.divisi-kelola) #page-divisi .dv-grup-add,
.master-ro:not(.divisi-kelola) #page-divisi td.aksi button{display:none!important}
.so-bar{display:flex;align-items:center;gap:12px;margin-bottom:14px;flex-wrap:wrap}
.so-bar .kl-input{flex:1 1 320px;max-width:460px;margin:0}
.so-ringkas{color:var(--muted);font-size:12.5px;font-weight:600}
#soIsi{display:grid;grid-template-columns:repeat(auto-fill,minmax(min(420px,100%),1fr));gap:14px;align-items:start}
.so-card{border:1px solid var(--line);border-radius:12px;background:var(--surface,#fff);overflow:hidden;
  box-shadow:0 1px 3px rgba(15,23,42,.06),0 8px 24px -16px rgba(15,23,42,.3)}
.so-head{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:12px 14px;background:var(--surface-2);border-bottom:1px solid var(--line);cursor:pointer;user-select:none}
.so-head:hover{background:var(--primary-tint)}
.so-at{display:flex;align-items:center;gap:10px;min-width:0}
.so-at-ic{width:34px;height:34px;flex:0 0 auto;border-radius:9px;display:grid;place-items:center;background:var(--primary-tint);color:var(--primary);font-size:14px}
.so-at-ic.so-no{background:var(--surface);color:var(--muted)}
/* Nama + (@username · jabatan) pada SATU baris. */
.so-at-nm{display:flex;flex-direction:row;align-items:baseline;gap:7px;min-width:0;flex-wrap:wrap}
.so-at-nm b{font-size:13.5px;color:var(--ink);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:0 1 auto}
.so-at-nm small{color:var(--muted);font-size:11px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:0 1 auto;min-width:0}
.so-caret{flex:0 0 auto;font-size:11px;color:var(--muted);transition:transform .15s}
.so-card.tutup .so-caret{transform:rotate(-90deg)}
.so-card.tutup .so-body{display:none}
.so-card.tutup .so-head{border-bottom:0}
.so-body{padding:8px 10px;display:flex;flex-direction:column;gap:6px}
.so-div{border:1px solid var(--line);border-radius:9px;padding:8px 10px;background:var(--bg)}
.so-div-nm{font-size:12.5px;color:var(--ink);display:flex;align-items:center;gap:6px;flex-wrap:wrap}
.so-div-nm i{color:var(--primary);font-size:11px}
.so-div-meta{margin-top:4px;display:flex;align-items:center;gap:10px;flex-wrap:wrap;font-size:11px}
.so-kep{color:var(--ink);font-weight:600}
.so-kep i{color:#d97706;font-size:10px;margin-right:2px}
.so-kep-no{color:var(--muted);font-style:italic;font-weight:400}
/* Jumlah karyawan = tombol: klik → daftar karyawan muncul di bawah divisi. */
.so-kry{color:var(--primary);font-variant-numeric:tabular-nums;border:1px solid var(--line);background:var(--surface,#fff);
  border-radius:999px;padding:2px 9px;font-size:11px;cursor:pointer;display:inline-flex;align-items:center;gap:5px;font-family:inherit;transition:.12s}
.so-kry i{font-size:9px;color:var(--muted);transition:transform .15s}
.so-kry:hover{border-color:var(--primary);background:var(--primary-tint)}
.so-kry.on{background:var(--primary-tint);border-color:var(--primary)}
.so-kry-wrap{margin-top:7px;border-top:1px dashed var(--line);padding-top:7px;display:flex;flex-direction:column;gap:3px;max-height:240px;overflow:auto}
.so-kry-item{display:flex;flex-direction:column;line-height:1.2;padding:4px 7px;border-radius:7px;background:var(--surface,#fff);border:1px solid var(--line)}
.so-kry-item b{font-size:11.5px;color:var(--ink);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.so-kry-item small{color:var(--muted);font-size:10px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.so-tag{font-size:9.5px;font-weight:700;padding:1px 7px;border-radius:999px;text-transform:uppercase;letter-spacing:.02em}
.so-pusat{background:var(--primary-tint);color:var(--primary)}
.so-cab{background:#fef3c7;color:#b45309;text-transform:none}
.so-card-no .so-head{background:var(--surface)}

/* ============================ Bonus Motor ============================ */
/* Ringkasan kartu di atas tabel. */
.bm-ringkas{display:flex;flex-wrap:wrap;gap:10px;margin:0 0 12px}
.bm-kartu{flex:1 1 150px;min-width:140px;display:flex;flex-direction:column;gap:2px;
  padding:10px 14px;border:1px solid var(--line);border-radius:12px;background:var(--surface)}
.bm-kartu-label{font-size:11px;font-weight:700;color:var(--muted);text-transform:uppercase;letter-spacing:.3px}
.bm-kartu-nilai{font-size:18px;font-weight:800;color:var(--ink)}
.bm-kartu-sub{font-size:10.5px;color:var(--muted)}
/* Panel tarif per status. */
.bm-tarif{margin-bottom:12px;padding:14px 16px}
.bm-tarif-kepala{margin-bottom:12px}
.bm-tarif-sub{display:block;font-size:11.5px;color:var(--muted);font-weight:400;margin-top:2px}
.bm-tarif-isi{display:grid;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));gap:8px 12px}
.bm-tarif-baris{display:flex;align-items:center;gap:8px;padding:6px 8px;border:1px solid var(--line);
  border-radius:9px;background:var(--surface-2,var(--bg))}
.bm-tarif-nama{flex:1 1 auto;font-size:12.5px;font-weight:600;color:var(--ink);min-width:0;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.bm-tarif-rp{font-size:11px;color:var(--muted);font-weight:700}
.bm-tarif-input{flex:0 0 96px;width:96px;margin-bottom:0;text-align:right;font-size:12px;padding:5px 8px}
.bm-tarif-kaki{display:flex;align-items:center;gap:12px;margin-top:12px}
.bm-tarif-pesan{font-size:12px;color:var(--muted)}
.bm-tarif-kosong{color:var(--muted);font-style:italic;font-size:12px}
/* Chip motor (plat · status) di sel tabel. */
.bm-motor{display:flex;flex-wrap:wrap;gap:4px;max-width:420px}
.bm-motor .badge{text-transform:none;font-weight:600;letter-spacing:0}
.bm-motor .badge .mono{font-weight:700}
/* Badge abu-abu utk status Non Aktif. */
.b-slate{background:#64748b}
/* Selektor bulan di toolbar. */
.bm-bulan{display:inline-flex;align-items:center;gap:6px;font-size:12px;font-weight:700;color:var(--muted)}
.bm-bulan select{min-width:140px}
/* Per-motor: badge Sewa Dari & Status tanpa kapital paksa. */
#tblBonusMotor .badge{text-transform:none;letter-spacing:0;font-weight:700}
.bm-flat{font-weight:800;color:var(--primary);text-decoration:none;cursor:pointer}
.bm-flat:hover{text-decoration:underline}
.bm-hari{display:inline-flex;align-items:center;justify-content:center;min-width:30px;padding:2px 8px;
  border-radius:6px;background:var(--primary);color:#fff;font-weight:800;font-size:12px}
.bm-hari.nol{background:var(--surface-3,#e5e7eb);color:var(--muted)}
/* Toggle BBM Ya/Tidak per motor. */
.bm-bbm{display:inline-flex;align-items:center;gap:7px;border:none;background:transparent;cursor:pointer;
  font:inherit;padding:2px 4px;color:var(--muted)}
.bm-bbm:disabled{cursor:not-allowed;opacity:.6}
.bm-bbm-track{position:relative;width:34px;height:18px;border-radius:999px;background:var(--surface-3,#cbd5e1);
  transition:background .15s;flex:none}
.bm-bbm-dot{position:absolute;top:2px;left:2px;width:14px;height:14px;border-radius:50%;background:#fff;
  box-shadow:0 1px 2px rgba(0,0,0,.25);transition:transform .15s}
.bm-bbm.on .bm-bbm-track{background:var(--primary)}
.bm-bbm.on .bm-bbm-dot{transform:translateX(16px)}
.bm-bbm-lbl{font-size:11.5px;font-weight:700;min-width:30px;text-align:left}
.bm-bbm.on .bm-bbm-lbl{color:var(--primary)}
/* Ikon dolar (atur nominal BBM) di ujung kanan baris kontrol. */
.bm-rate-btn{flex:none;width:34px;height:34px;display:inline-flex;align-items:center;justify-content:center;
  border:1px solid var(--line);border-radius:9px;background:var(--surface);color:#1D6F42;cursor:pointer;font-size:15px}
.bm-rate-btn:hover{background:var(--surface-2,var(--bg));border-color:var(--primary);color:var(--primary)}
/* Modal atur nominal BBM. */
.bm-rate-modal{max-width:440px;width:92vw}
/* Dua field BBM berdampingan dalam SATU baris (grid 2 kolom). */
.bm-rate-form{display:grid;grid-template-columns:1fr 1fr;gap:12px;align-items:start}
.bm-rate-field{display:flex;flex-direction:column;gap:6px;min-width:0}
.bm-rate-lbl{font-size:11.5px;font-weight:700;color:var(--ink);display:inline-flex;align-items:center;gap:6px}
.bm-rate-lbl i{color:var(--muted)}
.bm-rate-inp{display:flex;align-items:center;gap:6px;border:1px solid var(--line);border-radius:9px;
  padding:2px 9px;background:var(--surface-2,var(--bg))}
.bm-rate-inp:focus-within{border-color:var(--primary);box-shadow:0 0 0 3px var(--primary-tint)}
.bm-rate-rp{font-size:11px;font-weight:800;color:var(--muted)}
.bm-rate-inp .kl-input{border:none;background:transparent;margin:0;padding:5px 0;font-size:13.5px;font-weight:700;
  text-align:right;flex:1 1 auto;min-width:0;box-shadow:none}
@media (max-width:420px){ .bm-rate-form{grid-template-columns:1fr} }
.bm-rate-ket{font-size:11.5px;color:var(--muted);line-height:1.5;margin:14px 0 0}
.bm-rate-jejak{display:flex;align-items:center;gap:7px;margin-top:10px;padding:8px 11px;
  border-radius:9px;background:var(--surface-2,var(--bg));border:1px solid var(--line);
  font-size:11.5px;color:var(--muted)}
.bm-rate-jejak i{color:var(--muted)}
.bm-rate-jejak b{color:var(--ink);font-weight:700}
/* Modal rincian motor. */
/* Layout kiri (tabel) + kanan (panel rincian, bentuk form bukan modal).
   Default panel TERTUTUP → tabel memakai lebar penuh device; panel hanya muncul
   (dan tabel menyusut) saat No Flat diklik (.bm-buka). */
.bm-split{display:flex;gap:14px;align-items:flex-start}
.bm-split .bm-tabel{flex:1 1 auto;min-width:0;width:100%}
.bm-samping{display:none;flex:0 0 360px;max-width:360px;align-self:flex-start;position:sticky;top:12px}
.bm-split.bm-buka .bm-samping{display:block}
@media (max-width:1400px){ .bm-split.bm-buka .bm-samping{flex-basis:320px;max-width:320px} }
.bm-samping-kosong{border:1px dashed var(--line);border-radius:14px;background:var(--surface);
  padding:28px 20px;text-align:center;color:var(--muted)}
.bm-samping-kosong i{font-size:26px;opacity:.5;display:block;margin-bottom:10px}
.bm-samping-kosong p{font-size:12.5px;line-height:1.5;margin:0}
.bm-samping-isi{border:1px solid var(--line);border-radius:14px;background:var(--surface);
  padding:14px 16px;box-shadow:var(--shadow-sm,0 1px 3px rgba(0,0,0,.06))}
.bm-samping-head{display:flex;align-items:flex-start;gap:10px;margin-bottom:12px}
.bm-samping-judul{flex:1 1 auto;min-width:0}
.bm-samping-judul strong{display:block;font-size:14px;color:var(--ink);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.bm-samping-judul span{display:block;font-size:11.5px;color:var(--muted);margin-top:1px}
.bm-samping-head .x{flex:none;border:none;background:transparent;color:var(--muted);cursor:pointer;
  font-size:15px;padding:2px 6px;border-radius:6px;line-height:1}
.bm-samping-head .x:hover{background:var(--surface-2,var(--bg));color:var(--ink)}
#tblBonusMotor tbody tr.bm-aktif{background:var(--primary-tint,#eef2ff)}
/* Sembunyikan kolom ID Pemilik (data tetap di DOM; posisi terrender incl No = 4). */
#tblBonusMotor thead th:nth-child(4),#tblBonusMotor tbody td:nth-child(4){display:none}
/* Akun tanpa hak finansial: sembunyikan kolom BBM(8)·Nominal(9)·Bonus(10). */
#page-fin-bonus-motor.bm-no-bonus #tblBonusMotor thead th:nth-child(8),
#page-fin-bonus-motor.bm-no-bonus #tblBonusMotor tbody td:nth-child(8),
#page-fin-bonus-motor.bm-no-bonus #tblBonusMotor thead th:nth-child(9),
#page-fin-bonus-motor.bm-no-bonus #tblBonusMotor tbody td:nth-child(9),
#page-fin-bonus-motor.bm-no-bonus #tblBonusMotor thead th:nth-child(10),
#page-fin-bonus-motor.bm-no-bonus #tblBonusMotor tbody td:nth-child(10){display:none}
/* Toolbar satu baris: aksi di kiri, filter Sewa Dari didorong ke kanan. */
#page-fin-bonus-motor .toolbar .pr-saring{margin-left:auto}
/* Rincian: No WO Klien panjang (mono) — jaga agar terbaca. */
.bm-detail-tbl .bm-td-tgl{white-space:nowrap}
.bm-detail-tbl .bm-td-wo{font-size:11.5px;white-space:nowrap}
@media (max-width:1100px){
  .bm-split{flex-direction:column}
  .bm-samping{flex:1 1 auto;max-width:none;width:100%;position:static}
}
.bm-detail-ringkas{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:12px}
.bm-dchip{display:inline-flex;align-items:center;padding:4px 12px;border-radius:999px;background:var(--surface-2,var(--bg));
  border:1px solid var(--line);font-size:12px;font-weight:700;color:var(--ink)}
.bm-dchip-rp{background:var(--primary-tint,#eef2ff);color:var(--primary);border-color:transparent}
.bm-detail-scroll{max-height:58vh;overflow:auto;border:1px solid var(--line);border-radius:10px}
/* Accordion rincian: satu baris per TANGGAL; WO muncul saat tanggalnya diklik. */
.bm-grp{border-bottom:1px solid var(--line)}
.bm-grp:last-child{border-bottom:0}
.bm-grp-head{display:flex;align-items:center;gap:10px;width:100%;cursor:pointer;
  background:var(--surface);border:none;font:inherit;text-align:left;padding:9px 12px;color:var(--ink)}
.bm-grp-head:hover{background:var(--surface-2,var(--bg))}
.bm-grp-ikon{font-size:10px;color:var(--muted);transition:transform .15s}
.bm-grp-head.buka .bm-grp-ikon{transform:rotate(90deg)}
.bm-grp-tgl{flex:1 1 auto;font-size:12.5px;font-weight:700}
.bm-grp-cnt{flex:none;font-size:10.5px;font-weight:700;color:var(--primary);
  background:var(--primary-tint,#eef2ff);padding:2px 9px;border-radius:999px}
.bm-grp-isi{background:var(--surface-2,var(--bg));padding:4px 0}
.bm-grp-kepala,.bm-grp-wo{display:grid;grid-template-columns:24px minmax(118px,1fr) auto auto;
  gap:8px;align-items:center;padding:5px 12px 5px 28px}
.bm-grp-kepala{font-size:10px;text-transform:uppercase;letter-spacing:.3px;color:var(--muted);font-weight:700}
.bm-grp-wo{font-size:12px;border-top:1px dashed var(--line)}
.bm-grp-wo .mono{font-weight:700}
.bm-wo-no{text-align:center;color:var(--muted)}
.bm-wo-kl{text-align:right;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:90px}
.bm-grp-tipe{text-align:right;color:var(--muted);white-space:nowrap}
.bm-detail-muat{text-align:center;color:var(--muted);font-style:italic;padding:16px}
.bm-detail-pesan{color:var(--danger,#dc2626);font-size:12px;margin-top:8px}

/* ---- Bonus SLA (pakai kerangka bm-*; tambahan khusus di bawah) ---- */
/* Tanpa hak uang: sembunyikan kolom Bonus (kolom ke-9: No+Cabang+Klien+TipeWO+TotalWO+Memenuhi+Ach+Tier+Bonus). */
#page-fin-bonus-sla.sla-no-bonus #tblBonusSla thead th:nth-child(9),
#page-fin-bonus-sla.sla-no-bonus #tblBonusSla tbody td:nth-child(9){display:none}
.sla-ach{display:inline-flex;align-items:center;padding:2px 10px;border-radius:999px;font-size:11.5px;font-weight:800}
.sla-ach-top{background:#dff3e8;color:#1d7a4d}
.sla-ach-good{background:#e2edfb;color:#2563a8}
.sla-ach-ok{background:#fdf0da;color:#9a6a16}
.sla-ach-low{background:#fbe3e4;color:#b23b40}
.sla-ach-nol{background:var(--surface-2,var(--bg));color:var(--muted)}
.sla-met{font-weight:700;color:var(--ink)}
.sla-met.nol{color:var(--muted);font-weight:600}
.sla-dchip-ok{background:#dff3e8;color:#1d7a4d;border-color:transparent}
.sla-dchip-no{background:#fbe3e4;color:#b23b40;border-color:transparent}
/* Daftar WO di panel samping: baris datar (bukan accordion). */
.sla-wo-kepala,.sla-wo{display:grid;grid-template-columns:62px minmax(78px,1fr) minmax(70px,1fr) 52px;
  gap:7px;align-items:center;padding:6px 10px}
.sla-wo-kepala{font-size:10px;text-transform:uppercase;letter-spacing:.3px;color:var(--muted);font-weight:700;
  position:sticky;top:0;background:var(--surface);z-index:1;border-bottom:1px solid var(--line)}
.sla-wo{font-size:12px;border-top:1px dashed var(--line)}
.sla-wo:first-of-type{border-top:0}
.sla-wo-lewat{background:#fdeef0}
.sla-wo-no{text-align:center;color:var(--muted)}
.sla-wo-tgl{color:var(--muted);white-space:nowrap}
.sla-wo-flat{font-weight:700;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.sla-wo-sla{color:var(--muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.sla-wo-st{text-align:right}

/* ============================ News Info (Pengumuman) ===================== */
.ni-judul{cursor:pointer}
.ni-judul:hover{color:var(--primary)}
.ni-tgt{font-size:12px;color:var(--ink)}
.ni-oleh{color:var(--muted)}
/* Drawer kanan */
.ni-drawer-bd{position:fixed;inset:0;background:rgba(15,23,42,.38);z-index:1200;display:flex;justify-content:flex-end}
.ni-drawer{width:min(460px,96vw);max-width:96vw;height:100%;background:var(--surface);display:flex;flex-direction:column;
  box-shadow:-8px 0 30px rgba(0,0,0,.18);transform:translateX(100%);transition:transform .18s ease}
.ni-drawer.buka{transform:translateX(0)}
.ni-drawer-head{display:flex;align-items:center;justify-content:space-between;padding:16px 18px;border-bottom:1px solid var(--line)}
.ni-drawer-head strong{font-size:15px}
.ni-drawer-body{flex:1 1 auto;overflow:auto;padding:16px 18px;display:flex;flex-direction:column;gap:14px}
.ni-drawer-foot{display:flex;justify-content:flex-end;gap:10px;padding:14px 18px;border-top:1px solid var(--line)}
.ni-field{display:flex;flex-direction:column;gap:6px}
.ni-field .note-label{display:block}
/* Semua teks keterangan di drawer pengumuman memakai warna teks normal (hitam),
   termasuk label beserta "(opsional)"-nya — bukan abu-abu. Diruang-lingkup ke
   #niDrawer agar tak menyentuh halaman lain. Placeholder input tetap seperti biasa. */
#niDrawer .note-label,#niDrawer .note-label small,#niDrawer .ni-target-ket,#niDrawer .ni-periode-ket{color:var(--text)}
.ni-field textarea.kl-input{resize:vertical;min-height:110px;line-height:1.5}
.ni-periode{display:grid;grid-template-columns:1fr 1fr;gap:12px}
/* Teks keterangan: HITAM (warna teks normal) agar mudah dibaca — bukan abu-abu. */
.ni-periode-ket,.ni-target-ket{font-size:11px;color:var(--text);margin:-4px 0 0;line-height:1.5}
/* Pratinjau audiens (berapa user yang akan menerima). Teksnya SELALU hitam
   (warna teks normal); sinyal ok/luas hanya lewat ikon + latar tipis. */
.ni-audiens{font-size:12.5px;line-height:1.5;margin:0;padding:8px 10px;border-radius:8px;display:flex;align-items:flex-start;gap:7px;color:var(--text)}
.ni-audiens:empty{display:none}
.ni-audiens i{margin-top:1px}
.ni-aud-muat{background:var(--surface-2,var(--bg))}
.ni-aud-muat i{color:var(--muted)}
.ni-aud-ok{background:rgba(16,185,129,.12)}
.ni-aud-ok i{color:#059669}
.ni-aud-warn{background:rgba(245,158,11,.14)}
.ni-aud-warn i{color:#d97706}
:root:not([data-theme="light"]) .ni-aud-ok,:root[data-theme="dark"] .ni-aud-ok{background:rgba(16,185,129,.16)}
:root:not([data-theme="light"]) .ni-aud-warn,:root[data-theme="dark"] .ni-aud-warn{background:rgba(245,158,11,.18)}
:root:not([data-theme="light"]) .ni-aud-ok i,:root[data-theme="dark"] .ni-aud-ok i{color:#6ee7b7}
:root:not([data-theme="light"]) .ni-aud-warn i,:root[data-theme="dark"] .ni-aud-warn i{color:#fcd34d}
/* Satu baris: toggle "Wajib dibaca" di kiri, pemilih lampiran di kanan. Membungkus
   ke bawah di layar sempit. */
.ni-wajiblamp{flex-direction:row;align-items:center;justify-content:space-between;gap:14px;flex-wrap:wrap}
.ni-lamp-wrap{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.ni-lamp-label{font-size:11.5px;font-weight:700;color:var(--text)}
.ni-lamp-label small{font-weight:400}
/* Lampiran + tautan di drawer */
.ni-lamp{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.ni-lamp-info{font-size:12.5px;color:var(--text);word-break:break-all}
.ni-lamp-info a{color:var(--primary);text-decoration:none}
.ni-lamp-info a:hover{text-decoration:underline}
.ni-lamp-baru{color:var(--text);font-size:11px;font-weight:600}
.ni-lamp-ada{color:var(--text);font-size:11px}
.ni-lamp-hapus{color:var(--danger,#dc2626)}
/* Tautan + lampiran saat ditampilkan (lonceng/modal/lihat isi) */
.ni-extra{display:flex;align-items:center;gap:7px;font-size:12.5px;margin-top:7px;word-break:break-all}
.ni-extra i{color:var(--muted);flex:none}
.ni-extra a{color:var(--primary);text-decoration:none}
.ni-extra a:hover{text-decoration:underline}
.ni-ic-extra{color:var(--muted);font-size:11px;margin-left:3px}
/* Toggle wajib */
.ni-switch{display:flex;align-items:center;gap:10px;cursor:pointer;font-size:13px;font-weight:600}
.ni-switch input{display:none}
.ni-switch-track{width:40px;height:22px;border-radius:999px;background:var(--line);position:relative;transition:background .15s;flex:none}
.ni-switch-dot{position:absolute;top:2px;left:2px;width:18px;height:18px;border-radius:50%;background:#fff;transition:left .15s;box-shadow:0 1px 3px rgba(0,0,0,.25)}
.ni-switch input:checked+.ni-switch-track{background:var(--primary)}
.ni-switch input:checked+.ni-switch-track .ni-switch-dot{left:20px}
.ni-switch small{color:var(--text);font-weight:400}
.ni-mode{display:flex;gap:16px}
.ni-radio{display:flex;align-items:center;gap:6px;font-size:13px;cursor:pointer}
/* Target picker */
.ni-target{display:flex;flex-direction:column;gap:14px;border:1px solid var(--line);border-radius:10px;padding:12px;background:var(--surface-2,var(--bg))}
.ni-pick{display:flex;flex-direction:column;gap:6px}
.ni-pick-chips{display:flex;flex-wrap:wrap;gap:6px;min-height:22px}
.ni-chip{display:inline-flex;align-items:center;gap:6px;background:var(--primary-tint,#eef2ff);color:var(--primary);
  border-radius:999px;padding:3px 6px 3px 10px;font-size:12px;font-weight:600}
.ni-chip button{border:none;background:none;color:inherit;cursor:pointer;font-size:14px;line-height:1;padding:0 2px}
.ni-chip-kosong{font-size:11.5px;color:var(--muted)}
.ni-pick-cari{position:relative}
.ni-pick-drop{position:absolute;top:100%;left:0;right:0;z-index:5;background:var(--surface);border:1px solid var(--line);
  border-radius:9px;margin-top:3px;max-height:200px;overflow:auto;box-shadow:0 8px 24px rgba(0,0,0,.14)}
.ni-drop-item{display:block;width:100%;text-align:left;border:none;background:none;padding:8px 11px;font:inherit;cursor:pointer;color:var(--ink)}
.ni-drop-item:hover{background:var(--surface-2,var(--bg))}
.ni-drop-kosong{padding:9px 11px;font-size:12px;color:var(--muted)}
/* Dialog baca isi */
.ni-baca-isi{font-size:13.5px;line-height:1.6;color:var(--ink);white-space:normal;word-break:break-word;max-height:55vh;overflow:auto}
.ni-baca-meta{margin-top:10px;color:var(--muted)}
/* Lonceng: baris pengumuman */
.ni-notif-row{border:1px solid var(--line);border-radius:10px;padding:10px 12px;margin-bottom:8px;background:var(--surface)}
.ni-notif-row.baru{border-color:var(--primary);background:var(--primary-tint,#eef2ff)}
.ni-notif-top{display:flex;align-items:center;gap:8px;font-size:13px}
.ni-notif-top b{flex:1 1 auto}
.ni-notif-dot{width:8px;height:8px;border-radius:50%;background:var(--danger,#dc2626);flex:none}
.ni-notif-isi{font-size:12.5px;color:var(--ink);line-height:1.5;margin:6px 0;max-height:120px;overflow:auto;white-space:normal}
.ni-notif-kaki{display:flex;align-items:center;justify-content:space-between;gap:8px}
.ni-notif-kaki small{color:var(--muted);font-size:11px}
.ni-notif-sudah{color:#1d7a4d!important}
.ni-notif-baca{padding:3px 10px;font-size:11.5px}
/* Laporan pembaca */
.ni-pb-ring{display:flex;gap:8px;flex-wrap:wrap;margin-bottom:10px}
.ni-pb-list{max-height:52vh;overflow:auto;border:1px solid var(--line);border-radius:9px}
.ni-pb-row{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:8px 11px;border-bottom:1px dashed var(--line)}
.ni-pb-row:last-child{border-bottom:0}
.ni-pb-row b{font-size:13px}.ni-pb-row small{display:block;color:var(--muted);font-size:11px}
.ni-pb-st .badge{font-size:10.5px}
.ni-pb-luar{display:inline-block;margin-left:7px;padding:1px 7px;border-radius:999px;font-size:10px;font-weight:600;color:#92400e;background:rgba(245,158,11,.16);vertical-align:middle}
:root:not([data-theme="light"]) .ni-pb-luar,:root[data-theme="dark"] .ni-pb-luar{color:#fcd34d;background:rgba(245,158,11,.2)}

/* Penanda "berjalan" pada Bonus Perbantuan di tabel Tarikan Gaji (nilai provisional). */
.tg-berjalan{color:#d99236;font-size:11px;margin-left:3px;cursor:help}

/* Master → Dokumen Kemitraan. Baris 1: SATU kartu template selebar halaman —
   ikon + nama/info di kiri, tombol Lihat & Unggah di ujung kanan kartu.
   Baris 2 (dt-top): filter & cari mulai dari kiri sejajar tabel, "Tampilkan"
   + info jumlah didorong ke kanan (bawaan .dt-trail menyisakan celah kiri). */
/* bindTable memindah isi .toolbar ke baris kendali: kartu → .dt-lead, filter →
   .dt-trail. .dt-lead dibuat SELEBAR PENUH supaya filter selalu turun ke baris 2. */
#page-dokumen-kemitraan .dt-lead{flex:1 1 100%;display:block}
.km-template{display:flex;align-items:center;gap:12px;padding:10px 14px;border:1px solid var(--line);
  border-radius:10px;background:var(--surface-2,#f8fafc);min-width:0;width:100%}
.km-template>i{color:#DC2626;font-size:20px;flex:none}
.km-info{display:flex;flex-direction:column;min-width:0;flex:1;font-size:12.5px}
.km-info b{font-size:12.5px;color:var(--ink)}
.km-info span{color:var(--muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.km-aksi{display:flex;gap:8px;flex:none;margin-left:auto}
.km-template.kosong{border-color:var(--danger);background:var(--danger-tint)}
.km-template.kosong .km-info span{color:var(--danger)}
#page-dokumen-kemitraan .dt-trail{margin-left:0}
#page-dokumen-kemitraan .dt-top .dt-length{margin-left:auto}
@media (max-width:640px){
  .km-template{flex-wrap:wrap}
  .km-aksi{width:100%;margin-left:0}
  .km-aksi .btn{flex:1;justify-content:center}
}
/* Dokumen Kemitraan — ikon Action berwarna bila berkasnya ada */
#tblKemitraan .act .km-pdf{color:#DC2626}
#tblKemitraan .act .km-pdf:hover{background:rgba(220,38,38,.12)}
#tblKemitraan .act .km-ttd{color:#2563EB}
#tblKemitraan .act .km-ttd:hover{background:rgba(37,99,235,.12)}
#tblKemitraan .act .km-kosong{color:var(--muted-2);opacity:.4}
#tblKemitraan .act .km-kosong:hover{transform:none;opacity:.7}
