:root {
  --diex-primary: #0d6b52;
  --diex-primary-dark: #0a5542;
  --diex-primary-light: #e8f5f0;
  --diex-accent: #2563eb;
  --diex-surface: #ffffff;
  --diex-bg: #f4f6f8;
  --diex-muted: #64748b;
  --diex-text: #0f172a;
  --diex-border: #e2e8f0;
  --diex-radius: 0.875rem;
  --diex-radius-lg: 1.125rem;
  --diex-shadow: 0 1px 2px rgb(15 23 42 / 5%), 0 1px 3px rgb(15 23 42 / 4%);
  --diex-shadow-md: 0 4px 12px rgb(15 23 42 / 6%);
  /* PWA iOS (laporan user 2026-07-20: tombol menu tertutup status bar iPhone).
     index.html memakai viewport-fit=cover + apple-mobile-web-app-status-bar-style
     "black-translucent", jadi di PWA terinstall konten memang MENJOROK ke bawah
     jam/notch — tanpa cadangan ini baris teratas (tombol buka sidebar) tertimpa
     dan tak bisa disentuh. Di browser biasa/Android env() = 0px, jadi tampilan
     lama tak berubah sama sekali.
     Tinggi header SENGAJA ikut menghitung cadangan itu supaya semua yang
     mengurangi --diex-header-h (tinggi konten, posisi dropdown, tinggi sidebar)
     ikut benar tanpa disentuh satu per satu. */
  --diex-safe-top: env(safe-area-inset-top, 0px);
  --diex-header-h: calc(3.75rem + var(--diex-safe-top));
  --diex-sidebar-w: 15.5rem;
}

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

body {
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
  background: var(--diex-bg);
  color: var(--diex-text);
  -webkit-font-smoothing: antialiased;
}

/* ── Shell layout (full width on laptop+) ── */

.diex-header {
  position: sticky;
  top: 0;
  z-index: 30;
  height: var(--diex-header-h);
  /* Isi header didorong ke bawah status bar; latar putihnya tetap memenuhi
     area notch supaya tidak ada pita transparan di atas. */
  padding-top: var(--diex-safe-top);
  background: rgb(255 255 255 / 92%);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--diex-border);
}

.diex-shell {
  display: flex;
  width: 100%;
  min-height: calc(100dvh - var(--diex-header-h));
  gap: 0;
}

.diex-sidebar {
  width: var(--diex-sidebar-w);
  flex-shrink: 0;
}

.diex-main {
  flex: 1;
  min-width: 0;
  padding: 1.25rem 1rem 2rem;
}

@media (min-width: 768px) {
  .diex-main {
    padding: 1.5rem 1.5rem 2.5rem;
  }
}

@media (min-width: 1024px) {
  .diex-main {
    padding: 1.75rem 2rem 3rem;
  }
}

@media (min-width: 1280px) {
  .diex-main {
    padding: 1.75rem 2.5rem 3rem;
  }
}

/* ── Cards & surfaces ── */

.diex-card {
  background: var(--diex-surface);
  border: 1px solid var(--diex-border);
  border-radius: var(--diex-radius-lg);
  box-shadow: var(--diex-shadow);
}

.diex-panel {
  background: var(--diex-surface);
  border: 1px solid var(--diex-border);
  border-radius: var(--diex-radius-lg);
  box-shadow: var(--diex-shadow);
}

/* ── Buttons ── */

.diex-btn-primary {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.375rem;
  background: var(--diex-primary);
  color: #fff;
  border: none;
  border-radius: 0.5rem;
  padding: 0.4375rem 1rem;
  font-size: 0.8125rem;
  font-weight: 500;
  cursor: pointer;
  transition: background 0.15s, box-shadow 0.15s;
}
.diex-btn-primary:hover {
  background: var(--diex-primary-dark);
}
.diex-btn-primary:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}

.diex-icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  border: 1px solid var(--diex-border);
  border-radius: 0.5rem;
  background: #fff;
  color: #475569;
  cursor: pointer;
  transition: background 0.12s, border-color 0.12s;
}
.diex-icon-btn:hover {
  background: var(--diex-primary-light);
  border-color: var(--diex-primary);
  color: var(--diex-primary);
}

.diex-btn-secondary {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.375rem;
  background: #fff;
  color: #334155;
  border: 1px solid var(--diex-border);
  border-radius: 0.5rem;
  padding: 0.4375rem 1rem;
  font-size: 0.8125rem;
  font-weight: 500;
  cursor: pointer;
  transition: background 0.12s, border-color 0.12s;
}
.diex-btn-secondary:hover {
  background: #f8fafc;
  border-color: #cbd5e1;
}

/* ── Link-button: aksi inline (Edit/Hapus/Lihat/Buka dsb) tampil sebagai
   tombol pill kecil, bukan teks link polos. Setara .small-btn legacy. ── */
.diex-linkbtn {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  font-size: 0.75rem;
  font-weight: 500;
  line-height: 1;
  color: #334155;
  background: #fff;
  border: 1px solid #cbd5e1;
  border-radius: 0.5rem;
  padding: 0.3rem 0.55rem;
  cursor: pointer;
  white-space: nowrap;
  text-decoration: none;
  vertical-align: middle;
  transition: background 0.12s, border-color 0.12s, color 0.12s;
}
.diex-linkbtn:hover {
  background: #f8fafc;
  border-color: #94a3b8;
}
.diex-linkbtn:disabled,
.diex-linkbtn[disabled] {
  opacity: 0.5;
  cursor: not-allowed;
}
.diex-linkbtn-primary {
  color: var(--diex-primary);
  border-color: #b6ddce;
}
.diex-linkbtn-primary:hover {
  background: var(--diex-primary-light);
  border-color: var(--diex-primary);
}
.diex-linkbtn-warn {
  color: #b45309;
  border-color: #fcd34d;
}
.diex-linkbtn-warn:hover {
  background: #fffbeb;
  border-color: #f59e0b;
}
.diex-linkbtn-danger {
  color: #b91c1c;
  border-color: #fca5a5;
}
.diex-linkbtn-danger:hover {
  background: #fef2f2;
  border-color: #ef4444;
}

/* ── Page header ── */

.diex-page-header {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 0.75rem 1.5rem;
  margin-bottom: 1.25rem;
}

.diex-page-title {
  font-size: 1.375rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--diex-text);
  line-height: 1.2;
}

.diex-page-subtitle {
  font-size: 0.8125rem;
  color: var(--diex-muted);
  margin-top: 0.25rem;
}

/* ── Stat cards ── */

.diex-stat-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 0.875rem;
}

@media (min-width: 640px) {
  .diex-stat-grid {
    grid-template-columns: repeat(3, 1fr);
  }
}

@media (min-width: 1024px) {
  .diex-stat-grid {
    grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
    gap: 1rem;
  }
}

.diex-stat-card {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  padding: 1rem 1.125rem;
  background: var(--diex-surface);
  border: 1px solid var(--diex-border);
  border-radius: var(--diex-radius-lg);
  box-shadow: var(--diex-shadow);
  text-decoration: none;
  color: inherit;
  transition: border-color 0.15s, box-shadow 0.15s, transform 0.15s;
  cursor: pointer;
}

.diex-stat-card:hover {
  border-color: #b8d4c8;
  box-shadow: var(--diex-shadow-md);
  transform: translateY(-1px);
}

.diex-stat-card:focus-visible {
  outline: 2px solid var(--diex-primary);
  outline-offset: 2px;
}

.diex-stat-card-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
}

.diex-stat-icon {
  width: 2.25rem;
  height: 2.25rem;
  border-radius: 0.625rem;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.875rem;
  flex-shrink: 0;
}

.diex-stat-icon--green { background: var(--diex-primary-light); color: var(--diex-primary); }
.diex-stat-icon--blue { background: #eff6ff; color: #2563eb; }
.diex-stat-icon--amber { background: #fffbeb; color: #d97706; }
.diex-stat-icon--violet { background: #f5f3ff; color: #7c3aed; }
.diex-stat-icon--slate { background: #f1f5f9; color: #475569; }

.diex-stat-label {
  font-size: 0.6875rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--diex-muted);
}

.diex-stat-value {
  font-size: 1.75rem;
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 1;
  color: var(--diex-text);
}

.diex-stat-value--amber { color: #d97706; }
.diex-stat-value--blue { color: #2563eb; }

.diex-stat-hint {
  font-size: 0.6875rem;
  color: #94a3b8;
}

/* ── Navigation ── */

.nav-group-label {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 0.625rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: #94a3b8;
  padding: 0.625rem 0.75rem 0.25rem;
  margin-top: 0.125rem;
  user-select: none;
}

.nav-group-label button {
  background: none;
  border: none;
  color: #cbd5e1;
  cursor: pointer;
  padding: 0.125rem 0.25rem;
  font-size: 0.625rem;
  line-height: 1;
  border-radius: 0.25rem;
  transition: color 0.12s;
}
.nav-group-label button:hover {
  color: #94a3b8;
}

.nav-group-items.collapsed {
  display: none;
}

/* Cari menu (cari-menu.js). Kelas nav-cari-luput milik pencarian saja —
   `hidden` tetap milik aturan peran/Hak Akses. Selektor ber-#sidebar-nav
   supaya menang atas gaya isian global `.diex-card input[type="search"]`. */
#sidebar-nav .nav-cari {
  position: sticky;
  /* Chrome mengukur sticky dari tepi DALAM padding nav (p-2) — tanpa -0.5rem
     menu yang digulir mengintip di celah atas kotak. */
  top: -0.5rem;
  z-index: 2;
  margin: -0.5rem -0.5rem 0.25rem;
  padding: 0.625rem 0.625rem 0.5rem;
  background: var(--diex-surface);
  border-radius: var(--diex-radius-lg) var(--diex-radius-lg) 0 0;
}
#sidebar-nav .nav-cari.hidden {
  display: none;
}
#sidebar-nav .nav-cari-kotak {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  height: 2.375rem;
  padding: 0 0.5rem 0 0.75rem;
  background: #f1f5f9;
  border: 1px solid transparent;
  border-radius: 0.625rem;
  cursor: text;
  transition: background 0.12s, border-color 0.12s, box-shadow 0.12s;
}
#sidebar-nav .nav-cari-kotak:hover {
  background: #e9eef4;
}
#sidebar-nav .nav-cari-kotak:focus-within {
  background: #fff;
  border-color: var(--diex-primary);
  box-shadow: 0 0 0 3px rgb(13 107 82 / 12%);
}
#sidebar-nav .nav-cari-ikon {
  font-size: 0.8125rem;
  color: #94a3b8;
  transition: color 0.12s;
}
#sidebar-nav .nav-cari-kotak:focus-within .nav-cari-ikon {
  color: var(--diex-primary);
}
#sidebar-nav .nav-cari input {
  flex: 1;
  min-width: 0;
  height: 100%;
  padding: 0;
  border: none;
  border-radius: 0;
  outline: none;
  box-shadow: none;
  background: transparent;
  font-size: 0.8125rem;
  color: var(--diex-text);
}
#sidebar-nav .nav-cari input::placeholder {
  color: #94a3b8;
}
#sidebar-nav .nav-cari input::-webkit-search-cancel-button {
  -webkit-appearance: none;
  appearance: none;
}
#sidebar-nav .nav-cari-hapus {
  display: none;
  align-items: center;
  justify-content: center;
  width: 1.375rem;
  height: 1.375rem;
  border: none;
  border-radius: 9999px;
  background: #cbd5e1;
  color: #fff;
  font-size: 0.6875rem;
  cursor: pointer;
}
#sidebar-nav .nav-cari-hapus:hover {
  background: #94a3b8;
}
#sidebar-nav .nav-cari-isi .nav-cari-hapus {
  display: inline-flex;
}
#sidebar-nav .nav-cari-kbd {
  font-family: inherit;
  font-size: 0.625rem;
  font-weight: 600;
  line-height: 1;
  padding: 0.25rem 0.375rem;
  background: #fff;
  border: 1px solid var(--diex-border);
  border-bottom-width: 2px;
  border-radius: 0.3125rem;
  color: #94a3b8;
  white-space: nowrap;
}
#sidebar-nav .nav-cari-kotak:focus-within .nav-cari-kbd,
#sidebar-nav .nav-cari-isi .nav-cari-kbd {
  display: none;
}
#sidebar-nav .nav-cari-info {
  margin: 0.4375rem 0.25rem 0;
  font-size: 0.6875rem;
  color: #94a3b8;
}
#sidebar-nav .nav-cari-info kbd {
  font-family: inherit;
  font-size: 0.625rem;
  font-weight: 600;
  padding: 0 0.25rem;
  border: 1px solid var(--diex-border);
  border-radius: 0.25rem;
  background: #fff;
  color: #64748b;
}
#sidebar-nav .nav-cari-kosong {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.25rem;
  padding: 1.5rem 0.75rem 1.25rem;
  text-align: center;
  color: #94a3b8;
  font-size: 0.6875rem;
}
#sidebar-nav .nav-cari-kosong.hidden {
  display: none;
}
#sidebar-nav .nav-cari-kosong i {
  font-size: 1.25rem;
  color: #cbd5e1;
  margin-bottom: 0.25rem;
}
#sidebar-nav .nav-cari-kosong p {
  font-size: 0.8125rem;
  font-weight: 600;
  color: #475569;
}
#sidebar-nav.nav-mencari .nav-group-items.collapsed {
  display: block;
}
#sidebar-nav.nav-mencari [data-nav-collapse] {
  visibility: hidden;
}
/* Hasil yang dibuka Enter. Menu aktif (hijau) tetap memakai gayanya sendiri. */
#sidebar-nav .nav-btn.nav-cari-pertama:not(.active) {
  background: var(--diex-primary-light);
  color: var(--diex-primary-dark);
}
::highlight(nav-cari) {
  background-color: rgb(250 204 21 / 45%);
  color: inherit;
}
#sidebar-nav .nav-cari-luput {
  display: none !important;
}
@media (max-width: 767px) {
  /* Cegah zoom otomatis iOS saat fokus (di bawah 16px). */
  #sidebar-nav .nav-cari input {
    font-size: 16px;
  }
  #sidebar-nav .nav-cari-kbd {
    display: none;
  }
}

.nav-btn {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  width: 100%;
  text-align: left;
  padding: 0.5rem 0.75rem;
  border-radius: 0.5rem;
  font-size: 0.8125rem;
  color: #475569;
  text-decoration: none;
  border: none;
  background: transparent;
  cursor: pointer;
  transition: background 0.12s, color 0.12s;
}
.nav-btn:hover {
  background: #f1f5f9;
  color: #1e293b;
}
.nav-btn.active {
  background: var(--diex-primary);
  color: #fff;
  font-weight: 500;
  box-shadow: 0 1px 3px rgb(13 107 82 / 25%);
}
.nav-btn .nav-icon {
  width: 1.125rem;
  text-align: center;
  opacity: 0.85;
  flex-shrink: 0;
}
.nav-btn.active .nav-icon {
  opacity: 1;
}
/* Penanda menu approval (badge angka jumlah pending di kanan item nav) */
.nav-approval-mark {
  margin-left: auto;
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.15rem;
  height: 1.15rem;
  padding: 0 0.3rem;
  border-radius: 9999px;
  background: #f59e0b;
  color: #fff;
  font-size: 0.65rem;
  font-weight: 700;
  line-height: 1;
}
.nav-approval-mark[hidden] {
  display: none;
}
.nav-btn.active .nav-approval-mark {
  background: rgb(255 255 255 / 90%);
  color: var(--diex-primary);
}

#mobile-nav-overlay {
  transition: opacity 0.2s;
}
#mobile-nav-panel {
  transition: transform 0.25s ease;
}

/* ── User chip ── */

.diex-user-chip {
  display: flex;
  align-items: center;
  gap: 0.625rem;
}

.diex-avatar {
  width: 2.25rem;
  height: 2.25rem;
  border-radius: 0.625rem;
  background: var(--diex-primary-light);
  color: var(--diex-primary);
  font-size: 0.8125rem;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.diex-avatar--photo {
  object-fit: cover;
  display: block;
  padding: 0;
}

.diex-tenant-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  font-size: 0.6875rem;
  font-weight: 500;
  color: var(--diex-primary);
  background: var(--diex-primary-light);
  padding: 0.125rem 0.5rem;
  border-radius: 9999px;
  max-width: 12rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Sorot picker company (mode Holding) saat aksi manajemen ditolak krn belum
   pilih company - lihat flashHoldingPicker() di shared.js. */
@keyframes diexFlashAttn {
  0%, 100% { box-shadow: 0 0 0 0 rgba(245, 158, 11, 0); }
  30% { box-shadow: 0 0 0 3px rgba(245, 158, 11, 0.55); }
}
.diex-flash-attn {
  animation: diexFlashAttn 0.8s ease-in-out 2;
  border-color: #f59e0b !important;
}

/* ── Progress legend ── */

.diex-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1rem;
  font-size: 0.75rem;
  color: var(--diex-muted);
}

.diex-legend-item {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
}

.diex-legend-dot {
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 9999px;
  flex-shrink: 0;
}

/* ── Kanban ── */

.kanban-col {
  min-width: 17rem;
  background: #f1f5f9;
  border-radius: var(--diex-radius);
  padding: 0.75rem;
}
.kanban-card {
  background: #fff;
  border: 1px solid var(--diex-border);
  border-radius: 0.625rem;
  padding: 0.625rem 0.75rem;
  font-size: 0.875rem;
  box-shadow: var(--diex-shadow);
  cursor: pointer;
  transition: border-color 0.15s, box-shadow 0.15s;
}
.kanban-card:hover {
  border-color: #93c5fd;
  box-shadow: 0 2px 8px rgb(37 99 235 / 10%);
}

/* ── Tables ── */

.data-table th {
  font-size: 0.6875rem;
  font-weight: 600;
  color: var(--diex-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.data-table tbody tr:hover {
  background: #f8fafc;
}

/* ── Modals ── */

.modal-backdrop {
  background: rgb(15 23 42 / 45%);
  backdrop-filter: blur(2px);
}

/* ── Candidate steps ── */

.cand-step-dot {
  width: 1.75rem;
  height: 1.75rem;
  border-radius: 9999px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-weight: 600;
  background: #e2e8f0;
  color: #64748b;
}
.cand-step-dot.active {
  background: var(--diex-primary);
  color: #fff;
}
.cand-step-dot.done {
  background: #86efac;
  color: #14532d;
}

/* ── Toast ── */

.toast-item {
  animation: toast-in 0.25s ease;
  pointer-events: auto;
}
.toast-item.toast-out {
  opacity: 0;
  transform: translateY(8px);
  transition: opacity 0.3s, transform 0.3s;
}
@keyframes toast-in {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: translateY(0); }
}

/* ── Skeleton ── */

.skeleton {
  background: linear-gradient(90deg, #e2e8f0 25%, #f1f5f9 50%, #e2e8f0 75%);
  background-size: 200% 100%;
  animation: skeleton-shimmer 1.2s ease-in-out infinite;
  border-radius: 0.375rem;
}
.skeleton-text {
  height: 0.875rem;
  width: 100%;
  max-width: 8rem;
}
.skeleton-stat-value {
  height: 1.75rem;
  width: 3rem;
  margin-top: 0.25rem;
}

@keyframes skeleton-shimmer {
  0% { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

/* ── Mobile sidebar ── */

@media (max-width: 767px) {
  .diex-sidebar {
    position: fixed;
    top: 0;
    left: 0;
    z-index: 50;
    height: 100dvh;
    transform: translateX(-100%);
    transition: transform 0.2s ease;
    /* Menu geser menutupi seluruh tinggi layar termasuk area notch — isinya
       diberi cadangan yang sama supaya item teratas tak tertimpa status bar. */
    padding: calc(1rem + var(--diex-safe-top)) 1rem 1rem;
    background: var(--diex-bg);
  }
  .diex-sidebar.open {
    transform: translateX(0);
  }
  .diex-page-title {
    font-size: 1.125rem;
  }

  /* Poles PWA karyawan: cegah auto-zoom iOS Safari saat fokus input (di
     bawah 16px iOS langsung zoom-in, terasa "berantakan") + perbesar area
     tap tombol aksi di 4 alur inti (absen/tugas/jadwal/cuti) ke standar
     ~40px minimal - pola sama yang sudah terbukti di Proyek /chat. */
  .diex-input,
  .diex-select,
  .diex-card input,
  .diex-card select,
  .diex-card textarea,
  .diex-panel-stack input,
  .diex-panel-stack select,
  .diex-panel-stack textarea {
    font-size: 16px;
  }
  #att-today-list button,
  #my-task-list button,
  #leave-rows button,
  #pay-me-wrap button,
  .diex-icon-btn {
    min-height: 2.5rem;
    min-width: 2.5rem;
  }
  #att-today-list .flex.gap-2 {
    flex-wrap: wrap;
  }
}

/* Safety-net anti-scroll-horizontal (tidak mengganggu overflow-x sengaja
   spt tabel/board yang memang scroll ke samping - cuma di elemen umum). */
body {
  overflow-x: hidden;
}
.diex-card,
.diex-panel-stack {
  max-width: 100%;
}

@media (min-width: 768px) {
  .diex-sidebar {
    position: sticky;
    top: calc(var(--diex-header-h) + 0.5rem);
    align-self: flex-start;
    max-height: calc(100dvh - var(--diex-header-h) - 1rem);
    padding: 0 0 0 1rem;
  }
}

/* ── Panel layout ── */

.diex-panel-stack {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.diex-panel {
  /* single-card panels inherit diex-card on mount or inner content */
}

/* ── Forms (scoped + utility) ── */

.diex-input,
.diex-select,
.diex-card input[type="text"],
.diex-card input[type="search"],
.diex-card input[type="email"],
.diex-card input[type="number"],
.diex-card input[type="date"],
.diex-card input[type="time"],
.diex-card input[type="month"],
.diex-card input[type="datetime-local"],
.diex-card select,
.diex-card textarea,
.diex-panel-stack input[type="text"],
.diex-panel-stack input[type="search"],
.diex-panel-stack input[type="email"],
.diex-panel-stack input[type="number"],
.diex-panel-stack input[type="date"],
.diex-panel-stack input[type="time"],
.diex-panel-stack input[type="month"],
.diex-panel-stack select,
.diex-panel-stack textarea {
  border: 1px solid var(--diex-border);
  border-radius: 0.5rem;
  padding: 0.4375rem 0.75rem;
  font-size: 0.8125rem;
  background: #fff;
  color: var(--diex-text);
  transition: border-color 0.12s, box-shadow 0.12s;
}

.diex-input:focus,
.diex-select:focus,
.diex-card input:focus,
.diex-card select:focus,
.diex-card textarea:focus,
.diex-panel-stack input:focus,
.diex-panel-stack select:focus,
.diex-panel-stack textarea:focus {
  outline: none;
  border-color: var(--diex-primary);
  box-shadow: 0 0 0 3px rgb(13 107 82 / 12%);
}

.diex-field-label {
  display: block;
  font-size: 0.75rem;
  font-weight: 500;
  color: var(--diex-muted);
}

/* ── Alerts ── */

.diex-alert {
  border-radius: var(--diex-radius);
  padding: 0.75rem 1rem;
  font-size: 0.8125rem;
}
.diex-alert--amber {
  background: #fffbeb;
  border: 1px solid #fde68a;
  color: #92400e;
}
/* Sebelum ini HANYA --amber yang ada, sementara panel Kontrak sudah memakai
   --red dan --green. Akibatnya kotak galat tampil tanpa warna sama sekali —
   cuma teks di dalam kotak, tak terbedakan dari keterangan biasa. Warnanya
   mengikuti pasangan Tailwind yang sudah dipakai panel lain (bg-red-50 /
   text-red-700, bg-emerald-50 / text-emerald-700) supaya seragam. */
.diex-alert--red {
  background: #fef2f2;
  border: 1px solid #fecaca;
  color: #b91c1c;
}
.diex-alert--green {
  background: #ecfdf5;
  border: 1px solid #a7f3d0;
  color: #065f46;
}

/* ── Tables ── */

.diex-table-wrap {
  overflow-x: auto;
}

.diex-card table,
.diex-panel-stack table {
  width: 100%;
  font-size: 0.8125rem;
}

.diex-card table thead,
.diex-panel-stack table thead {
  background: #f8fafc;
  color: var(--diex-muted);
  text-align: left;
}

.diex-card table th,
.diex-panel-stack table th {
  padding: 0.75rem 1.25rem;
  font-weight: 600;
  font-size: 0.6875rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.diex-card table td,
.diex-panel-stack table td {
  padding: 0.625rem 1.25rem;
}

.diex-card table tbody tr,
.diex-panel-stack table tbody tr {
  border-top: 1px solid #f1f5f9;
}

.diex-card table tbody tr:hover,
.diex-panel-stack table tbody tr:hover {
  background: #f8fafc;
}

.diex-table-toolbar {
  padding: 1rem 1.25rem;
  border-bottom: 1px solid var(--diex-border);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
}

.diex-section-title {
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--diex-text);
}

/* ── Wide modal (employee form) ── */

.diex-modal-shell--wide {
  width: 100%;
  max-width: 56rem;
}

@media (min-width: 1280px) {
  .diex-modal-shell--wide {
    max-width: 72rem;
  }
}

.diex-modal-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
  padding: 1.25rem 1.5rem;
  border-bottom: 1px solid var(--diex-border, #f3f4f6);
  flex-shrink: 0;
}

.diex-modal-body {
  padding: 1.25rem 1.5rem;
  overflow-y: auto;
  flex: 1;
  min-height: 0;
}

.diex-modal-footer {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 1rem 1.5rem;
  border-top: 1px solid var(--diex-border, #f3f4f6);
  background: #fafafa;
  border-radius: 0 0 1rem 1rem;
  flex-shrink: 0;
}

.diex-form-section-title {
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--diex-muted, #6b7280);
  margin-bottom: 0.875rem;
  padding-bottom: 0.5rem;
  border-bottom: 1px solid #f3f4f6;
}

.diex-emp-form-grid {
  display: grid;
  gap: 1.25rem 1.5rem;
}

@media (min-width: 768px) {
  .diex-emp-form-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 1024px) {
  .diex-emp-form-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

.diex-emp-photo-panel {
  margin-top: 0.25rem;
  padding-top: 0.75rem;
  border-top: 1px dashed #e5e7eb;
}

.diex-emp-photo-slot {
  text-align: center;
}

.diex-emp-photo-preview {
  width: 5.5rem;
  height: 5.5rem;
  object-fit: cover;
  border-radius: 0.75rem;
  border: 1px solid #e5e7eb;
  margin: 0 auto;
  display: block;
}

.diex-emp-photo-preview.hidden + .diex-emp-photo-placeholder,
.diex-emp-photo-slot:has(.diex-emp-photo-preview:not(.hidden)) .diex-emp-photo-placeholder {
  display: none;
}

.diex-emp-photo-placeholder {
  width: 5.5rem;
  height: 5.5rem;
  margin: 0 auto;
  border-radius: 0.75rem;
  border: 1px dashed #d1d5db;
  background: #f9fafb;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.25rem;
}

.diex-emp-upload-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.35rem;
  font-size: 0.6875rem;
  font-weight: 500;
  color: var(--diex-primary, #0d6b52);
  background: var(--diex-primary-light, #ecfdf5);
  border-radius: 0.5rem;
  padding: 0.35rem 0.65rem;
  cursor: pointer;
}

.diex-emp-upload-btn:hover {
  filter: brightness(0.97);
}

.diex-lock-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.5rem;
  height: 1.5rem;
  border-radius: 0.375rem;
  border: 1px solid #cbd5e1;
  background: #fff;
  color: #64748b;
  cursor: pointer;
  vertical-align: middle;
}
.diex-lock-btn:hover {
  background: #f8fafc;
  color: #334155;
}
.diex-lock-btn.locked {
  background: #334155;
  border-color: #334155;
  color: #fff;
  cursor: not-allowed;
}
.diex-disabled {
  opacity: 0.45;
  pointer-events: none;
}

/* Kolom khusus management (Bank, Aksi) - disembunyikan serempak di header &
   body lewat satu kelas di <table>, jadi kolom tak pernah geser. */
.emp-hide-mgmt .col-mgmt {
  display: none !important;
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* Legacy blue buttons inside panels → brand primary */
.diex-card .bg-blue-600,
.diex-panel-stack .bg-blue-600,
.diex-card .bg-indigo-600,
.diex-panel-stack .bg-indigo-600,
.diex-card .bg-emerald-700,
.diex-panel-stack .bg-emerald-700 {
  background: var(--diex-primary) !important;
}
.diex-card .bg-blue-600:hover,
.diex-panel-stack .bg-blue-600:hover,
.diex-card .bg-indigo-600:hover,
.diex-panel-stack .bg-indigo-600:hover,
.diex-card .bg-emerald-700:hover,
.diex-panel-stack .bg-emerald-700:hover {
  background: var(--diex-primary-dark) !important;
}

/* ── Kinerja & transfer helpers ── */

.diex-sort-pills {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.375rem;
}

.diex-sort-pill {
  font-size: 0.6875rem;
  padding: 0.25rem 0.625rem;
  border-radius: 9999px;
  border: 1px solid #e2e8f0;
  background: #fff;
  color: #64748b;
  cursor: pointer;
  transition: background 0.12s, color 0.12s, border-color 0.12s;
}
.diex-sort-pill:hover {
  border-color: #cbd5e1;
  color: #334155;
}
.diex-sort-pill.active {
  background: var(--diex-primary-light);
  border-color: var(--diex-primary);
  color: var(--diex-primary);
  font-weight: 600;
}

.diex-perf-bar {
  height: 0.25rem;
  background: #f1f5f9;
  border-radius: 9999px;
  overflow: hidden;
}
.diex-perf-bar span {
  display: block;
  height: 100%;
  background: var(--diex-primary);
  border-radius: 9999px;
  transition: width 0.2s;
}

.diex-chip {
  display: inline-block;
  font-size: 0.6875rem;
  font-weight: 600;
  padding: 0.125rem 0.5rem;
  border-radius: 9999px;
  text-transform: uppercase;
  letter-spacing: 0.02em;
}
.diex-chip--ok { background: #ecfdf5; color: #047857; }
.diex-chip--pending { background: #fffbeb; color: #b45309; }
.diex-chip--muted { background: #f1f5f9; color: #64748b; }
.diex-chip--holding { background: #f5f3ff; color: #6d28d9; }
.diex-chip--info { background: #eff6ff; color: #1d4ed8; }
.diex-theme-dark .diex-chip--holding { background: #2e1065; color: #ddd6fe; }
.diex-theme-dark .diex-chip--info { background: #172554; color: #bfdbfe; }
.diex-theme-dark .diex-chip--muted { background: #1e293b; color: #94a3b8; }

/* Segmented filter (chip pilihan tunggal) — Tugas/Backlog & sejenis */
.diex-seg {
  font-size: 0.75rem;
  font-weight: 500;
  padding: 0.3rem 0.8rem;
  border-radius: 9999px;
  background: #f1f5f9;
  color: #475569;
  border: 1px solid transparent;
  transition: background .12s, color .12s;
  white-space: nowrap;
  cursor: pointer;
}
.diex-seg:hover { background: #e2e8f0; }
.diex-seg--active { background: var(--diex-primary); color: #fff; }
.diex-seg--active:hover { background: var(--diex-primary-dark); }
.diex-seg-count { opacity: .75; font-variant-numeric: tabular-nums; margin-left: .2rem; }
.diex-theme-dark .diex-seg { background: #1e293b; color: #94a3b8; }
.diex-theme-dark .diex-seg:hover { background: #334155; }

/* ── Tema gelap (profil) ── */
.diex-theme-dark .diex-card,
.diex-theme-dark .diex-stat-card {
  background: #1e293b;
  border-color: #334155;
  color: #e2e8f0;
}
.diex-theme-dark .diex-input {
  background: #0f172a;
  border-color: #334155;
  color: #e2e8f0;
}
.diex-theme-dark .bg-gray-50 {
  background: #0f172a !important;
}

/* ===== Tab bar bawah — akun KARYAWAN, mobile (refactor user 2026-07-19) =====
   Tampil hanya bila body.has-emp-tabbar (di-set applyNavVisibility utk akun
   yang PUNYA DATA KARYAWAN — termasuk management sejak 2026-09-30) DAN layar
   < 768px. Desktop tetap sidebar. */
.emp-tabbar { display: none; }
@media (max-width: 767px) {
  body.has-emp-tabbar .emp-tabbar {
    position: fixed; bottom: 0; left: 0; right: 0; z-index: 40;
    display: grid; grid-template-columns: repeat(5, 1fr);
    background: #fff; border-top: 1px solid #e5e7eb;
    padding-bottom: env(safe-area-inset-bottom);
    box-shadow: 0 -2px 10px rgba(0, 0, 0, .04);
  }
  /* Ruang bawah supaya konten tak tertutup tab bar. */
  body.has-emp-tabbar #app { padding-bottom: calc(3.9rem + env(safe-area-inset-bottom)); }
  .emp-tabbar .nav-btn {
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 2px; padding: 7px 2px 6px; margin: 0; border-radius: 0;
    font-size: 10px; font-weight: 600; color: #6b7280; background: none;
  }
  .emp-tabbar .nav-btn .nav-icon {
    width: auto; height: auto; background: none; color: inherit; font-size: 17px;
    display: inline-flex;
  }
  .emp-tabbar .nav-btn.active { color: var(--diex-primary); background: none; }
  .emp-tabbar .nav-btn.active .nav-icon { color: var(--diex-primary); }
}

/* Tombol khusus management -> app.feremart.com (user 2026-07-20): tampil beda
   dari item nav biasa — berbingkai putus-putus warna aksen. */
#nav-feremart-app {
  border: 1.5px dashed var(--diex-primary, #0d6b52);
  color: var(--diex-primary, #0d6b52);
  font-weight: 600;
  margin-bottom: 0.4rem;
}
#nav-feremart-app:hover { background: var(--diex-primary-light, rgba(13, 107, 82, 0.12)); }

/* ── Pil status pelacak lokasi (live-location.js). Ditaruh di header, bukan
   melayang di sudut layar: pelacakan lokasi harus terlihat setiap saat, dan
   elemen melayang gampang ditutup toast/modal lalu terlupakan. Teksnya
   disembunyikan di layar sempit — ikon + warna sudah cukup, dan header ponsel
   tidak boleh terdorong sampai nama pengguna terpotong. ── */
.lloc-pill {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  border-radius: 9999px;
  padding: 0.3125rem 0.625rem;
  font-size: 0.6875rem;
  font-weight: 600;
  line-height: 1;
  border: 1px solid transparent;
  cursor: pointer;
  white-space: nowrap;
  transition: background-color 0.15s, border-color 0.15s;
}

.lloc-pill span {
  display: none;
}

@media (min-width: 640px) {
  .lloc-pill span {
    display: inline;
  }
}

.lloc-pill-on {
  background: #ecfdf5;
  color: #047857;
  border-color: #a7f3d0;
}

.lloc-pill-on:hover {
  background: #d1fae5;
}

.lloc-pill-warn {
  background: #fffbeb;
  color: #b45309;
  border-color: #fde68a;
}

.lloc-pill-warn:hover {
  background: #fef3c7;
}

.lloc-pill-off {
  background: #f1f5f9;
  color: #475569;
  border-color: #e2e8f0;
}

.lloc-pill-off:hover {
  background: #e2e8f0;
}

/* ── Dokumen kontrak di panel HR ─────────────────────────────────────────
   Dirender perender yang sama dengan halaman pelamar (web/kontrak-md.js),
   jadi gayanya harus sepadan: yang dilihat HR sebelum menekan Kirim harus
   sama dengan yang akan dibaca kandidat. Tingkat judulnya h2/h3/h4 — perender
   sengaja tidak memancarkan h1 (lihat catatan di kontrak-md.js). */
.kontrak-dokumen {
  font-size: 0.875rem;
  line-height: 1.6;
  color: var(--diex-text);
  max-height: 70vh;
  overflow-y: auto;
  padding-right: 0.5rem;
}
.kontrak-dokumen h2 {
  font-size: 1rem; font-weight: 700; text-align: center; margin: 0.25rem 0 0.25rem;
}
.kontrak-dokumen h3 {
  font-size: 0.875rem; font-weight: 600; color: var(--diex-primary);
  margin: 1.25rem 0 0.5rem; padding-top: 0.25rem;
  border-top: 2px solid var(--diex-border);
}
.kontrak-dokumen > h2 + h3 { border-top: 0; margin-top: 0.25rem; }
.kontrak-dokumen h4 {
  font-size: 0.8125rem; font-weight: 600; color: var(--diex-muted);
  margin: 0.875rem 0 0.375rem;
}
.kontrak-dokumen p { margin: 0 0 0.5rem; }
.kontrak-dokumen ol, .kontrak-dokumen ul { margin: 0 0 0.5rem; padding-left: 1.25rem; }
.kontrak-dokumen ol { list-style: decimal; }
.kontrak-dokumen ul { list-style: disc; }
.kontrak-dokumen li { margin-bottom: 0.25rem; }
.kontrak-dokumen hr { border: 0; border-top: 1px solid var(--diex-border); margin: 1rem 0; }
.kontrak-dokumen blockquote {
  margin: 0.75rem 0; padding: 0.5rem 0.75rem; font-size: 0.8125rem;
  background: #fffbeb; border-left: 3px solid #fcd34d; border-radius: 0 0.5rem 0.5rem 0;
}
/* Tabel lebar menggulir di dalam pembungkusnya — panel tak boleh menggulir
   mendatar seluruhnya. */
.kontrak-dokumen .tabel-bungkus { overflow-x: auto; margin: 0 0 0.75rem; }
.kontrak-dokumen table { border-collapse: collapse; width: 100%; font-size: 0.8125rem; }
.kontrak-dokumen th, .kontrak-dokumen td {
  border: 1px solid var(--diex-border); padding: 0.375rem 0.5rem;
  text-align: left; vertical-align: top;
}
.kontrak-dokumen th { background: var(--diex-bg); font-weight: 600; }

/* Perubahan angka uang di layar "terapkan usulan AI". Sengaja mencolok:
   satu klik yang terburu-buru mengirim angka yang tak dimaksud ke kandidat,
   dan yang terkirim sudah jadi janji. */
.kontrak-uang-berubah {
  border: 1px solid #fecaca; background: #fef2f2; border-radius: 0.5rem;
  padding: 0.5rem 0.75rem; margin-bottom: 0.5rem; font-size: 0.8125rem;
}
.kontrak-uang-berubah .lama { text-decoration: line-through; color: var(--diex-muted); }
.kontrak-uang-berubah .baru { font-weight: 700; color: #b91c1c; }

/* ── Penanda langkah kontrak ─────────────────────────────────────────────
   Panel ini dipakai staf HR, bukan orang yang membangunnya. Tanpa penanda
   langkah, layar detail penawaran adalah 27 isian dan tujuh tombol tanpa
   petunjuk mana yang harus ditekan lebih dulu — dan status seperti
   "disetujui_pelamar" tak memberi tahu siapa pun bahwa GILIRAN KITA yang
   menandatangani. */
.kontrak-langkah {
  display: flex; flex-wrap: wrap; gap: 0.375rem; margin-bottom: 0.75rem;
}
.kontrak-langkah > div {
  display: flex; align-items: center; gap: 0.375rem;
  font-size: 0.75rem; line-height: 1.2;
  padding: 0.3rem 0.6rem; border-radius: 999px;
  background: var(--diex-bg); color: var(--diex-muted);
  border: 1px solid var(--diex-border);
}
.kontrak-langkah .no {
  display: inline-flex; align-items: center; justify-content: center;
  width: 1.15rem; height: 1.15rem; border-radius: 999px;
  background: var(--diex-border); color: var(--diex-text);
  font-size: 0.65rem; font-weight: 700; flex: 0 0 auto;
}
.kontrak-langkah .selesai {
  background: var(--diex-primary-light); border-color: #a7f3d0; color: #065f46;
}
.kontrak-langkah .selesai .no { background: var(--diex-primary); color: #fff; }
.kontrak-langkah .kini {
  background: #fff; border-color: var(--diex-primary); color: var(--diex-text);
  font-weight: 600; box-shadow: var(--diex-shadow);
}
.kontrak-langkah .kini .no { background: var(--diex-primary); color: #fff; }

/* Setelan kontrak draft: dua pemilih sejajar, satu kolom di layar sempit. */
.kontrak-setelan {
  display: grid; gap: 0.75rem; grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
  background: var(--diex-bg); border: 1px solid var(--diex-border);
  border-radius: var(--diex-radius); padding: 0.75rem; margin-bottom: 0.75rem;
}
.kontrak-pratinjau-ket {
  border: 1px dashed var(--diex-border); background: var(--diex-bg);
  border-radius: var(--diex-radius); padding: 0.5rem 0.75rem; margin-bottom: 0.75rem;
  font-size: 0.75rem; color: var(--diex-muted);
}
.kontrak-setelan-ket {
  grid-column: 1 / -1; margin: 0; font-size: 0.75rem; color: var(--diex-muted);
}

/* Kalimat "sekarang harus apa". Satu kalimat, bukan daftar — orang yang
   bingung tidak membaca daftar. */
.kontrak-sekarang {
  border: 1px solid var(--diex-primary); background: var(--diex-primary-light);
  border-radius: var(--diex-radius); padding: 0.6rem 0.8rem;
  font-size: 0.8125rem; color: var(--diex-text);
}
.kontrak-sekarang b { color: var(--diex-primary-dark); }
.kontrak-sekarang.tunggu { border-color: #fcd34d; background: #fffbeb; }
.kontrak-sekarang.tutup { border-color: var(--diex-border); background: var(--diex-bg);
  color: var(--diex-muted); }

/* Kelompok isian. Yang terisi otomatis dilipat — ia bukan pekerjaan pengisi
   formulir, cuma bukti bahwa nilainya sudah benar. */
.kontrak-grup { border-top: 1px solid var(--diex-border); padding-top: 0.75rem; }
.kontrak-grup:first-child { border-top: 0; padding-top: 0; }
.kontrak-grup > summary {
  cursor: pointer; font-size: 0.75rem; font-weight: 600;
  color: var(--diex-muted); text-transform: uppercase; letter-spacing: .03em;
  margin-bottom: 0.5rem;
}
.kontrak-grup > summary::marker { color: var(--diex-border); }
.kontrak-grup .isi { display: grid; gap: 0.75rem; }
.kontrak-grup .hitung { font-weight: 400; text-transform: none; letter-spacing: 0; }

/* Jepitan `dvh` untuk `max-h-[Xvh]` sempat berdiri di sini (PR #178) dan TAK
   PERNAH BERLAKU: app.css dimuat SEBELUM tailwind.css, yang sudah memuat kelas
   yang sama sebagai `vh` polos — kekhususan sama, urutan yang menentukan.
   Pindah ke web/arbitrary.css yang dimuat sesudahnya. */

/* ── Pemilih rentang tanggal /schedules (satu kalender, klik dari→sampai) ──
   Ditulis sebagai CSS sendiri, bukan utilitas Tailwind: tailwind.css di Diex
   adalah berkas PRA-BUILD tanpa tailwind.config.js di repo, jadi kelas baru
   yang belum ikut ter-generate akan diam-diam tidak berefek. */
.rp-grid { display: grid; grid-template-columns: repeat(7, 2rem); gap: 2px; }
.rp-hari {
  width: 2rem; height: 2rem; border-radius: 0.5rem; font-size: 0.75rem;
  color: var(--diex-text, #1f2937); background: transparent; border: 0;
  cursor: pointer; line-height: 2rem; padding: 0;
}
.rp-hari:hover { background: var(--diex-bg, #f3f4f6); }
.rp-hari--dalam { background: #eef2ff; color: #4338ca; border-radius: 0; }
.rp-hari--ujung { background: var(--diex-primary, #4f46e5); color: #fff; font-weight: 700; }
.rp-hari--ujung:hover { background: var(--diex-primary, #4f46e5); }
.rp-hari--kini { box-shadow: inset 0 0 0 1px var(--diex-primary, #4f46e5); }
#sched-range-pop { max-width: calc(100vw - 1rem); }
/* Dua bulan berdampingan di layar lebar. Dipasang di sini karena `sm:flex-row`
   (dan `flex-row` polos) TIDAK ADA di tailwind.css pra-build — memakainya akan
   diam-diam tak berefek dan kedua bulan menumpuk di semua ukuran layar. */
.rp-bulan-wrap { display: flex; flex-direction: column; gap: 1rem; }
@media (min-width: 640px) { .rp-bulan-wrap { flex-direction: row; } }

/* ── Header tabel Karyawan yang bisa diklik untuk mengurutkan ────────────── */
.emp-th-sort { cursor: pointer; user-select: none; white-space: nowrap; }
.emp-th-sort:hover { background: var(--diex-bg, #f3f4f6); color: var(--diex-text, #374151); }
.emp-th-sort:focus-visible { outline: 2px solid var(--diex-primary, #4f46e5); outline-offset: -2px; }
.emp-th-sort--aktif { color: var(--diex-primary, #4f46e5); }
.emp-th-caret { font-size: 0.6em; }

/* ── Tambalan kelas Tailwind yang TAK ADA di berkas pra-build ──────────────
   Ditemukan 9 Sep dengan menyapu kelas yang dipakai /schedules terhadap
   tailwind.css. Semuanya no-op senyap sebelum ini: pratinjau Generator
   kehilangan indentasi + garis aksen kirinya, judulnya kehilangan warna,
   kotaknya kehilangan warna garis, dan tombol tutup modal tak merespons
   hover. Penjaga repo (cek-tailwind-arbitrary.py) hanya memeriksa kelas
   bernilai arbitrary `[...]`, jadi yang biasa seperti ini lolos. */
.pl-2 { padding-left: 0.5rem; }
.border-l-2 { border-left-width: 2px; }
.border-indigo-100 { border-color: #e0e7ff; }
.text-indigo-800 { color: #3730a3; }
.hover\:text-gray-600:hover { color: #4b5563; }
.hover\:bg-gray-50:hover { background-color: #f9fafb; }

/* Formulir Grade Gaji (index.html) — ditemukan pada sapuan yang sama, ditambal
   atas permintaan owner 10 Sep. `opacity-70` dan `opacity-90` ADA di berkas
   pra-build, hanya `opacity-80` yang tidak: ciri build Tailwind sebagian.
   Akibatnya dua teks bantuan tak pernah diredupkan, dan blok persentase
   kehilangan indentasinya sehingga tak terbaca sebagai anak dari ceklis di
   atasnya. Nilai mengikuti Tailwind apa adanya. */
.opacity-80 { opacity: 0.8; }
.pl-6 { padding-left: 1.5rem; }

/* `border-white/30` — tambalan ketiga di formulir yang sama (owner 11 Sep).
   `border-white/20` ADA di berkas pra-build, `/30` tidak: ciri build sebagian
   yang sama. Nilainya ditulis persis seformat saudaranya. */
.border-white\/30 { border-color: hsla(0, 0%, 100%, .3); }

/* TAPI menambahkan kelasnya saja TIDAK membuat garisnya terlihat. Putih 30%
   lahir untuk kartu gaji berlatar gradien emerald GELAP (home, payroll,
   my-salary) — di sana ia benar. Di formulir Grade Gaji ia dipakai pada kotak
   .diex-alert--green yang latarnya #ecfdf5, nyaris putih: kontrasnya ~0, jadi
   pemisahnya tetap tak tampak dan pemeriksa kelas justru berubah HIJAU sambil
   tampilannya tetap salah.
   Di dalam kotak alert, garisnya memakai warna garis kotak itu sendiri —
   nilai yang sudah dipakai .diex-alert--* di atas, jadi tak ada warna baru. */
.diex-alert--green .border-white\/30 { border-color: #a7f3d0; }
.diex-alert--amber .border-white\/30 { border-color: #fde68a; }
.diex-alert--red   .border-white\/30 { border-color: #fecaca; }

/* ── Poles HP halaman Jadwal (user 2026-09-09) ────────────────────────────── */

/* Kalender rentang: tak boleh lebih tinggi dari layar. Sebelum ini isinya
   cuma terpotong di HP pendek, tanpa cara menggulungnya. */
#sched-range-pop {
  max-width: calc(100vw - 1rem);
  max-height: calc(100dvh - 1rem);
  overflow-y: auto;
  overscroll-behavior: contain;
}
@media (max-width: 767px) {
  /* Area sentuh baris jadwal. Blok "4 alur inti" di atas tak mencakup tabel
     manajemen ini, jadi Edit/Hapus dan ceklis hapus-massal sebelumnya jauh di
     bawah ~40px dan mudah salah tekan — apalagi ketiganya berdempetan. */
  #schedule-rows .diex-linkbtn {
    display: inline-flex;
    align-items: center;
    min-height: 2.25rem;
    padding: 0 0.5rem;
  }
  #schedule-rows .sched-check,
  #sched-check-all {
    width: 1.25rem;
    height: 1.25rem;
  }
  #schedule-rows td:last-child,
  #schedule-rows th:last-child { padding-left: 0.5rem; padding-right: 0.5rem; }

  /* Tabel jadwal sesak di HP: padding px-6 tiap sel memakan ~3rem per kolom
     sekadar untuk ruang kosong. Dirapatkan supaya kolom yang penting muat
     tanpa harus menggulung ke samping. */
  #sched-mgmt-wrap table th,
  #sched-mgmt-wrap table td { padding-left: 0.625rem; padding-right: 0.625rem; }

  /* Bilah atas berisi ~10 kontrol dan di HP menumpuk jadi blok tinggi yang
     mendorong tabel jauh ke bawah. Dirapatkan, dan tiga tombol aksi utama
     dijadikan satu baris penuh selebar layar supaya mudah ditekan.
     SENGAJA TIDAK dijadikan strip gulung-samping: #sched-actions ada DI DALAM
     kelompok yang sama, jadi menggulungnya akan menyembunyikan tombol
     Tambah/Massal/Generator di luar layar — kontrol yang tak terlihat lebih
     buruk daripada bilah yang sedikit tinggi. */
  #sched-mgmt-wrap .diex-table-toolbar { padding: 0.75rem 0.875rem; gap: 0.5rem; }
  #sched-mgmt-wrap .diex-table-toolbar > div:last-child { width: 100%; gap: 0.5rem; }
  #sched-actions { width: 100%; margin-right: 0; }
  #sched-actions button { flex: 1 1 0; justify-content: center; min-height: 2.25rem; }
  /* Pencarian nama melar mengisi sisa baris, tak lagi terjepit 9rem. */
  #sched-search { flex: 1 1 8rem; min-width: 8rem; }
  /* Tombol rentang tanggal jangan memaksa 13rem di layar 360px. */
  #sched-range-btn { min-width: 0 !important; flex: 1 1 11rem; }
}

/* ── Modal: hentikan scroll berantai + beri ruang layar ────────────────────
   User 2026-09-10: "isi modal jadwal massal bisa goyang-goyang padahal niatnya
   mau scroll" + "modal jadwal massal dan modal lain dibuat full layar".

   Goyangnya: modal Jadwal Massal punya TIGA area scroll bersarang (badan form,
   daftar outlet, daftar karyawan) dan tak satu pun menahan rantai scroll —
   begitu area dalam mentok, gerakannya menular ke badan modal lalu ke halaman
   di belakangnya. Modal Generator & Hak Akses sudah lama punya penahan ini;
   yang lain terlewat. Dipasang sekali di sini untuk SEMUA modal.

   Pemilih atribut dipakai karena kelas Tailwind-nya literal di markup dan CSS
   tak bisa memilih elemen berdasarkan overflow terhitung. */
.modal-backdrop { overscroll-behavior: contain; }
.modal-backdrop [class*="overflow-y-auto"],
.modal-backdrop [class*="overflow-auto"] {
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
}

/* Penahan rantai DIMATIKAN selama area itu tak punya apa pun untuk digulung.
   Kelasnya dipasang JS (segarkanGulungMati di panels/schedules.js) + dijaga
   ResizeObserver, karena CSS tak bisa memilih elemen berdasarkan ada-tidaknya
   isi yang melebihi kotak.

   Kenapa perlu: container yang TAK BISA digulung tapi ber-`contain` MENELAN
   gerakan jari — ia tak menggulung apa pun dan menolak meneruskannya ke badan
   modal. Itu bug Android 13 Sep 2026 (daftar karyawan), dan hal yang sama
   mengenai daftar outlet mode Holding saat outletnya sedikit + daftar karyawan
   di layar lebar saat pencarian menyisakan 1-2 nama.

   Sengaja OPT-OUT, bukan mengubah aturan dasarnya: kalau JS-nya tak jalan,
   perilakunya sama seperti sebelum ini. */
.modal-backdrop [class*="overflow-y-auto"].gulung-mati,
.modal-backdrop [class*="overflow-auto"].gulung-mati {
  overscroll-behavior: auto !important;
}

/* Daftar karyawan Jadwal Massal: max-h-56 (14rem) memaksa scroll bersarang
   hampir selalu. Diberi ruang jauh lebih besar supaya biasanya TIDAK perlu
   scroll sendiri — menghapus rantainya, bukan sekadar menahannya. */
#bulk-employees-list { max-height: min(52vh, 30rem) !important; }
#bulk-multi-outlet-list,
#sched-multi-outlet-list { max-height: min(32vh, 18rem) !important; }

/* Modal selebar layar. Di HP benar-benar penuh (tanpa sudut membulat dan
   tanpa jarak tepi); di layar lebar hampir penuh supaya tetap terbaca sebagai
   dialog, bukan halaman. */
@media (max-width: 767px) {
  .modal-backdrop { padding: 0 !important; }
  /* Dialog KECIL (konfirmasi/prompt, max-w-sm/xs) sengaja dikecualikan —
     memenuhkan layar untuk satu pertanyaan pendek justru terasa berlebihan. */
  .modal-backdrop > div:not([class*="max-w-sm"]):not([class*="max-w-xs"]),
  .modal-backdrop > form:not([class*="max-w-sm"]):not([class*="max-w-xs"]) {
    width: 100% !important;
    max-width: none !important;
    height: 100dvh !important;
    max-height: 100dvh !important;
    border-radius: 0 !important;
    /* Tujuh dialog (employee-modal, payroll-*, bonus, transfer, tov,
       photo-preview) tak punya area scroll DI DALAMNYA. Tanpa baris ini,
       memaksa tingginya akan MEMOTONG isinya tanpa cara menggulung — lebih
       buruk daripada masalah awalnya. Dialog yang sudah punya scroller sendiri
       tak terpengaruh: isinya memang tak pernah melebihi kotaknya. */
    overflow-y: auto;
    overscroll-behavior: contain;
  }
  /* Isi modal ikut memanjang; kepala & kaki tetap terlihat. */
  .modal-backdrop > div > form { flex: 1 1 auto; min-height: 0; }
  /* INSIDEN 13 Sep 2026 — "di beberapa perangkat Android tidak bisa scroll
     bagian karyawan pada pembuatan jadwal".

     Di HP daftar ini sengaja dilepas batas tingginya supaya TIDAK perlu
     digulung sendiri (rantainya dihapus, bukan ditahan). Tapi kelas
     `overflow-y-auto` di markup tetap menjadikannya SCROLL CONTAINER, dan
     aturan blanket di atas memberinya `overscroll-behavior: contain`.
     Jadilah kotak yang TAK PUNYA apa pun untuk digulung, tapi menolak
     meneruskan gerakan jari ke badan modal — sentuhan yang mendarat di area
     nama (bagian terbesar layar) tidak menggulung apa pun.

     "Beberapa perangkat" karena perilakunya beda-beda: Chrome berubah sikap
     antar versi soal memblokir rantai dari container yang tak bisa digulung,
     dan iOS lama belum mendukung `overscroll-behavior` sama sekali sehingga
     gerakannya tetap menular dan bug-nya tak terlihat di sana.

     Perbaikannya: di HP jangan jadikan ia scroll container sama sekali.
     (`flex: 1 1 auto` yang dulu di sini TIDAK pernah berlaku — induknya
     `div.block.col-span-2`, bukan flex container. Dibuang, bukan diperbaiki:
     tingginya memang harus mengikuti isi.) */
  #bulk-employees-list {
    max-height: none !important;
    overflow-y: visible !important;
    overscroll-behavior: auto !important;
  }
}
@media (min-width: 768px) {
  .modal-backdrop > div:not([class*="max-w-sm"]):not([class*="max-w-xs"]),
  .modal-backdrop > form:not([class*="max-w-sm"]):not([class*="max-w-xs"]) {
    max-width: min(95vw, 64rem) !important;
    max-height: 92vh !important;
    overflow-y: auto;
    overscroll-behavior: contain;
  }
}

/* ── Sapuan kelas Tailwind yang tak ikut ter-build (10 Sep 2026) ───────────
   Ditemukan scripts/cek-tailwind-kelas-hilang.py di seluruh halaman Diex.
   Semuanya no-op senyap sebelum ini: warna, jarak, dan tata letak yang ditulis
   di markup tapi tak pernah berlaku. Nilai mengikuti Tailwind apa adanya.
   tailwind.css di Diex PRA-BUILD tanpa tailwind.config.js, jadi kelas baru
   tak bisa dibangkitkan ulang — ditambal di sini. */

/* Warna */
.text-amber-100 { color: #fef3c7; }
.text-amber-950 { color: #451a03; }
.text-emerald-900 { color: #064e3b; }
.text-indigo-200 { color: #c7d2fe; }
.text-sky-600 { color: #0284c7; }
.bg-amber-600 { background-color: #d97706; }
.bg-amber-50\/60 { background-color: rgb(255 251 235 / 0.6); }
.bg-gray-50\/50 { background-color: rgb(249 250 251 / 0.5); }
.border-emerald-100 { border-color: #d1fae5; }
.border-emerald-300 { border-color: #6ee7b7; }
.border-red-100 { border-color: #fee2e2; }
.hover\:bg-amber-700:hover { background-color: #b45309; }
.hover\:bg-gray-50\/60:hover { background-color: rgb(249 250 251 / 0.6); }
.active\:bg-slate-100:active { background-color: #f1f5f9; }
/* divide-* mewarnai garis ANTAR anak, bukan tepi wadahnya. */
.divide-gray-50 > :not([hidden]) ~ :not([hidden]) { border-color: #f9fafb; }

/* Jarak & tata letak */
.my-1 { margin-top: 0.25rem; margin-bottom: 0.25rem; }
.my-3 { margin-top: 0.75rem; margin-bottom: 0.75rem; }
.mb-8 { margin-bottom: 2rem; }
.pb-1 { padding-bottom: 0.25rem; }
.pr-4 { padding-right: 1rem; }
.py-14 { padding-top: 3.5rem; padding-bottom: 3.5rem; }
.float-right { float: right; }
.items-baseline { align-items: baseline; }
/* Angka selebar sama supaya kolom nominal tidak bergoyang saat nilainya berubah. */
.tabular-nums { font-variant-numeric: tabular-nums; }
.line-clamp-2 {
  overflow: hidden;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
}

@media (min-width: 640px) {
  .sm\:hidden { display: none; }
}
@media (min-width: 768px) {
  .md\:grid-cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .md\:grid-cols-5 { grid-template-columns: repeat(5, minmax(0, 1fr)); }
}

/* Sembunyikan nominal gaji di kartu Beranda (owner 2026-10-15: "seperti akun
   bank ... tanpa berubah tampilannya"). Teks asli TETAP di DOM tapi tak
   terlihat (ruangnya tetap, jadi tata letak tak bergeser); masker dari
   data-tutup digambar di atasnya dengan huruf yang sama. Lewat CSS, bukan
   menimpa teks: sebagian angka diisi belakangan secara async (infak), dan
   masker yang ditulis ke teks akan tertimpa balik angka aslinya. */
.nominal-tertutup .js-nominal { position: relative; visibility: hidden; }
.nominal-tertutup .js-nominal::after {
  content: attr(data-tutup);
  visibility: visible;
  position: absolute;
  left: 0;
  top: 0;
  white-space: nowrap;
}

/* ==========================================================================
   Insentif Produksi (owner 2026-10-21: "user friendly agar mudah dipahami").
   Kelas sendiri berawalan pi- karena tailwind.css pra-build tak memuat semua
   warna yang dibutuhkan (mis. bg-violet-50 tak ada).
   ========================================================================== */
.pi-tanggal { display: inline-flex; align-items: center; gap: 0.25rem; }
.pi-panah { padding: 0.3rem 0.55rem; }
.pi-ringkas { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.75rem; }
.pi-ringkas:empty { display: none; }
@media (min-width: 768px) { .pi-ringkas { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.pi-ringkas .pi-kartu { padding: 0.75rem 0.875rem; gap: 0.375rem; }
.pi-ringkas .diex-stat-value { font-size: 1.125rem; }

.pi-tabel tbody tr:hover { background: #f8fafc; }
.pi-grade { color: #6d28d9; font-weight: 600; }

.pi-bar-baris { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; }
.pi-bar { flex: 1 1 5rem; min-width: 4rem; height: 0.5rem; background: #e2e8f0; border-radius: 9999px; overflow: hidden; }
.pi-bar-isi { display: block; height: 100%; border-radius: 9999px; }
.pi-bar--ok { background: #10b981; }
.pi-bar--sedang { background: #f59e0b; }
.pi-bar--kurang { background: #ef4444; }
.pi-bar-angka { font-variant-numeric: tabular-nums; font-weight: 600; font-size: 0.75rem; }
.pi-bar-teks--ok { color: #047857; }
.pi-bar-teks--sedang { color: #b45309; }
.pi-bar-teks--kurang { color: #dc2626; }
.pi-lebih-chip { font-size: 0.6875rem; font-weight: 700; color: #1d4ed8; background: #eff6ff; border-radius: 9999px; padding: 0.05rem 0.45rem; }
.pi-lebih { color: #1d4ed8; font-weight: 600; }
.pi-bayar-batas { color: #b45309; font-weight: 600; }

.pi-langkah { border: 1px solid var(--diex-border); border-radius: var(--diex-radius); padding: 0.875rem 1rem; margin-bottom: 0.875rem; }
.pi-langkah-judul { display: flex; align-items: center; gap: 0.5rem; font-size: 0.8125rem; font-weight: 600; color: var(--diex-text); margin-bottom: 0.625rem; flex-wrap: wrap; }
.pi-langkah-sub { font-weight: 400; color: var(--diex-muted); font-size: 0.75rem; }
.pi-nomor { display: inline-flex; align-items: center; justify-content: center; width: 1.375rem; height: 1.375rem; border-radius: 9999px; background: var(--diex-primary); color: #fff; font-size: 0.75rem; font-weight: 700; flex: none; }

.pi-capaian { display: flex; align-items: center; gap: 1rem; flex-wrap: wrap; }
.pi-capaian-angka { font-size: 1.5rem; font-weight: 700; color: var(--diex-text); line-height: 1.1; font-variant-numeric: tabular-nums; }
.pi-capaian-angka span { font-size: 0.75rem; font-weight: 500; color: var(--diex-muted); }
.pi-info { font-size: 0.75rem; color: #5b21b6; background: #f5f3ff; border-radius: 0.5rem; padding: 0.5rem 0.75rem; }

.pi-jobs tbody tr { border-top: 1px solid #f1f5f9; }
.pi-job-tolak td { color: #94a3b8; text-decoration: line-through; }
.pi-job-tolak td:first-child, .pi-job-tolak td:last-child { text-decoration: none; }
.pi-foto { width: 2.25rem; height: 2.25rem; border-radius: 0.375rem; object-fit: cover; border: 1px solid var(--diex-border); }

.pi-grup { margin-bottom: 0.75rem; }
.pi-grup-judul { display: flex; justify-content: space-between; font-size: 0.6875rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; color: var(--diex-muted); border-bottom: 1px solid var(--diex-border); padding-bottom: 0.25rem; margin-bottom: 0.25rem; }
.pi-group-total { font-variant-numeric: tabular-nums; color: var(--diex-text); }

.pi-total { background: var(--diex-primary-light); border-radius: var(--diex-radius); padding: 0.625rem 0.875rem; font-size: 0.8125rem; }
.pi-total-baris { display: flex; justify-content: space-between; gap: 1rem; padding: 0.125rem 0; }
.pi-total-lebih { color: #1d4ed8; font-weight: 600; }
.pi-total-nyata { border-top: 1px dashed #a7d7c5; margin-top: 0.25rem; padding-top: 0.375rem; font-weight: 600; }
.pi-total-bayar { font-weight: 700; color: var(--diex-primary-dark); font-size: 0.9375rem; }
.pi-total-catatan { font-size: 0.6875rem; color: #b45309; margin-top: 0.375rem; }

.pi-set-grup { border: 1px solid var(--diex-border); border-radius: 0.75rem; padding: 0.75rem; margin-bottom: 0.75rem; background: #f8fafc; }
.pi-contoh { font-size: 0.75rem; color: var(--diex-text); background: #f8fafc; border-radius: 0.5rem; padding: 0.5rem 0.75rem; }
.pi-contoh:empty { display: none; }
.pi-contoh ul { margin: 0.25rem 0 0 1rem; list-style: disc; }
.pi-redup { opacity: 0.5; }

.pi-sakelar { position: relative; display: inline-flex; align-items: center; gap: 0.625rem; cursor: pointer; user-select: none; }
.pi-sakelar input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.pi-sakelar-tuas { position: relative; width: 2.5rem; height: 1.375rem; border-radius: 9999px; background: #cbd5e1; transition: background 0.15s; flex: none; }
.pi-sakelar-tuas::after { content: ""; position: absolute; top: 0.1875rem; left: 0.1875rem; width: 1rem; height: 1rem; border-radius: 9999px; background: #fff; box-shadow: 0 1px 2px rgb(0 0 0 / 20%); transition: transform 0.15s; }
.pi-sakelar input:checked + .pi-sakelar-tuas { background: var(--diex-primary); }
.pi-sakelar input:checked + .pi-sakelar-tuas::after { transform: translateX(1.125rem); }
.pi-sakelar input:focus-visible + .pi-sakelar-tuas { outline: 2px solid var(--diex-accent); outline-offset: 2px; }

.diex-theme-dark .pi-langkah, .diex-theme-dark .pi-grup-judul { border-color: #334155; }
.diex-theme-dark .pi-langkah-judul, .diex-theme-dark .pi-capaian-angka, .diex-theme-dark .pi-group-total { color: #e2e8f0; }
.diex-theme-dark .pi-tabel tbody tr:hover { background: #1e293b; }
.diex-theme-dark .pi-bar { background: #334155; }
.diex-theme-dark .pi-total { background: #064e3b; color: #d1fae5; }
.diex-theme-dark .pi-total-bayar { color: #6ee7b7; }
.diex-theme-dark .pi-set-grup, .diex-theme-dark .pi-contoh { background: #0f172a; border-color: #334155; color: #e2e8f0; }
.diex-theme-dark .pi-info { background: #2e1065; color: #ddd6fe; }
.diex-theme-dark .pi-lebih, .diex-theme-dark .pi-total-lebih { color: #93c5fd; }
.diex-theme-dark .pi-lebih-chip { background: #172554; color: #bfdbfe; }
.diex-theme-dark .pi-grade { color: #c4b5fd; }
