/* ==========================================================================
   IT ASSET MANAGEMENT — DESIGN SYSTEM
   File ini sengaja dipisah dari layout PHP supaya:
   1) Bisa di-cache browser (lebih cepat setelah load pertama)
   2) Lebih gampang di-maintain tanpa ubah-ubah file .php
   File dibagi jadi 2 bagian besar:
     A. BASE / DESKTOP  — token warna, tipografi, layout, komponen
     B. MOBILE          — semua override responsive, terkumpul di satu
                           tempat paling bawah (lihat "MOBILE CSS")
   ========================================================================== */

@import url('https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@500;600;700;800&family=Inter:wght@400;500;600;700&display=swap');

/* --------------------------------------------------------------------------
   A.1 — DESIGN TOKENS
   Palet "control tower": sidebar biru-malam gelap + aksen teal, konten
   terang & lapang. Dipilih supaya beda dari template ungu/indigo generik,
   sekaligus tetap netral & nyaman dipakai lama untuk kerja operasional.
   -------------------------------------------------------------------------- */
:root {
  /* Neutral / surface */
  --bg: #f4f6fb;
  --surface: #ffffff;
  --surface-alt: #f8fafc;
  --border: #e6e9f2;
  --border-strong: #d7dbe7;

  /* Ink */
  --ink-900: #0f1729;
  --ink-700: #333d55;
  --ink-500: #6b7385;
  --ink-400: #9399ab;

  /* Sidebar */
  --side-bg: #0b1220;
  --side-bg-raised: #131c30;
  --side-border: #1d2740;
  --side-text: #9aa4bf;
  --side-text-active: #ffffff;

  /* Accent */
  --accent: #17b3a3;
  --accent-dark: #0e9384;
  --accent-soft: rgba(23, 179, 163, 0.16);
  --accent-soft-strong: rgba(23, 179, 163, 0.28);

  /* Status */
  --danger: #e14848;
  --danger-soft: #fdeaea;
  --success: #1a9f5c;
  --success-soft: #e4f8ee;
  --warning: #b8720c;
  --warning-soft: #fdf1de;
  --info: #1570b8;
  --info-soft: #e5f2fc;
  --violet: #6d4fd1;
  --violet-soft: #eee9fc;

  /* Shape / motion */
  --radius-lg: 16px;
  --radius-md: 12px;
  --radius-sm: 8px;
  --shadow-sm: 0 1px 2px rgba(15, 23, 41, 0.05);
  --shadow-md: 0 10px 30px -12px rgba(15, 23, 41, 0.18);
  --shadow-side: 4px 0 24px rgba(15, 23, 41, 0.06);
  --ease: cubic-bezier(0.4, 0, 0.2, 1);

  --sidebar-w: 272px;
  --topbar-h: 68px;
}

/* --------------------------------------------------------------------------
   A.2 — RESET & BASE
   -------------------------------------------------------------------------- */
* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  font-family: 'Inter', 'Segoe UI', Arial, sans-serif;
  background: var(--bg);
  color: var(--ink-900);
  -webkit-font-smoothing: antialiased;
}
a { color: inherit; }
h1, h2, h3, h4 { font-family: 'Plus Jakarta Sans', 'Inter', sans-serif; }
button { font-family: inherit; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* --------------------------------------------------------------------------
   A.3 — APP SHELL
   -------------------------------------------------------------------------- */
.admin-shell { display: flex; min-height: 100vh; }

/* --------------------------------------------------------------------------
   A.4 — SIDEBAR
   -------------------------------------------------------------------------- */
.sidebar {
  width: var(--sidebar-w);
  flex-shrink: 0;
  background: var(--side-bg);
  color: var(--side-text);
  padding: 0 0 20px;
  display: flex;
  flex-direction: column;
  position: sticky;
  top: 0;
  height: 100vh;
  overflow-y: auto;
}
.sidebar::-webkit-scrollbar { width: 6px; }
.sidebar::-webkit-scrollbar-thumb { background: var(--side-border); border-radius: 6px; }

.sidebar-logo {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 22px 22px 18px;
}
.sidebar-logo-mark {
  width: 34px; height: 34px; border-radius: 10px;
  background: linear-gradient(135deg, var(--accent), var(--accent-dark));
  display: flex; align-items: center; justify-content: center;
  color: #fff; font-weight: 800; font-size: 14px; flex-shrink: 0;
  font-family: 'Plus Jakarta Sans', sans-serif;
}
.sidebar-logo-text {
  font-family: 'Plus Jakarta Sans', sans-serif;
  font-size: 15px; font-weight: 700; color: #fff; letter-spacing: 0.2px; line-height: 1.2;
}
.sidebar-logo-text small { display: block; font-size: 10.5px; font-weight: 500; color: var(--side-text); letter-spacing: 0.4px; margin-top: 1px; }

.sidebar-scroll { flex: 1; padding: 4px 12px 12px; }

.menu-section {
  padding: 16px 10px 8px;
  font-size: 10.5px;
  font-weight: 700;
  color: #566079;
  letter-spacing: 0.7px;
  text-transform: uppercase;
}

/* Item tunggal (tanpa grup), mis. Dashboard */
.menu-item {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 10px 12px;
  font-size: 13.5px;
  font-weight: 500;
  color: var(--side-text);
  text-decoration: none;
  border-radius: var(--radius-sm);
  margin-bottom: 2px;
  transition: background 0.15s var(--ease), color 0.15s var(--ease);
}
.menu-item .icon,
.menu-group-toggle .icon {
  width: 18px; height: 18px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  color: currentColor;
}
.menu-item .icon svg, .menu-group-toggle .icon svg { width: 18px; height: 18px; }
.menu-item:hover { background: var(--side-bg-raised); color: #fff; }
.menu-item.active {
  background: var(--accent-soft);
  color: #fff;
}
.menu-item.active .icon { color: var(--accent); }
.menu-item.disabled { color: #4a5169; pointer-events: none; }
.menu-badge {
  margin-left: auto;
  background: var(--danger);
  color: #fff;
  font-size: 10px;
  font-weight: 700;
  padding: 2px 7px;
  border-radius: 999px;
}

/* Grup menu (accordion) */
.menu-group { margin-bottom: 2px; }
.menu-group-toggle {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 10px 12px;
  background: none;
  border: none;
  color: var(--side-text);
  font-size: 13.5px;
  font-weight: 600;
  font-family: inherit;
  border-radius: var(--radius-sm);
  cursor: pointer;
  text-align: left;
  transition: background 0.15s var(--ease), color 0.15s var(--ease);
}
.menu-group-toggle:hover { background: var(--side-bg-raised); color: #fff; }
.menu-group-toggle .chevron {
  margin-left: auto;
  width: 14px; height: 14px;
  transition: transform 0.2s var(--ease);
  flex-shrink: 0;
  opacity: 0.7;
}
.menu-group.open .menu-group-toggle .chevron { transform: rotate(180deg); }
.menu-group.open .menu-group-toggle { color: #fff; }
.menu-group.has-active .menu-group-toggle { color: #fff; }
.menu-group.has-active .menu-group-toggle .icon { color: var(--accent); }

.menu-group-body {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 0.22s var(--ease);
}
.menu-group.open .menu-group-body { grid-template-rows: 1fr; }
.menu-group-body-inner { overflow: hidden; }
.menu-group .menu-item {
  padding-left: 41px;
  font-size: 13px;
}
.menu-group .menu-item::before {
  content: '';
  position: relative;
}

/* Kartu identitas role di bawah sidebar */
.sidebar-footer {
  padding: 12px 22px 4px;
  border-top: 1px solid var(--side-border);
  margin-top: 6px;
}
.sidebar-footer-note { font-size: 11px; color: #566079; line-height: 1.5; }

/* --------------------------------------------------------------------------
   A.5 — TOPBAR
   -------------------------------------------------------------------------- */
.main-area { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.topbar {
  background: rgba(255, 255, 255, 0.85);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--border);
  padding: 0 28px;
  height: var(--topbar-h);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  position: sticky;
  top: 0;
  z-index: 40;
}
.topbar-left { display: flex; align-items: center; gap: 14px; min-width: 0; }
.topbar-title { font-size: 15px; font-weight: 700; color: var(--ink-900); font-family: 'Plus Jakarta Sans', sans-serif; }

/* Skip-link: tersembunyi di luar layar sampai menerima fokus keyboard,
   lalu muncul di kiri-atas. Tidak mengubah tampilan untuk pengguna mouse. */
.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 1000;
  background: var(--surface); color: var(--ink-900);
  padding: 10px 16px; border-radius: 0 0 var(--radius-sm) 0;
  border: 2px solid var(--accent, #0f766e); font-size: 13px; font-weight: 700;
  text-decoration: none;
}
.skip-link:focus { left: 0; }
/* Target skip-link diberi tabindex="-1" supaya bisa difokus; jangan
   tampilkan outline-nya, fokus sudah jelas dari lompatan halaman. */
.content:focus { outline: none; }

/* 44x44: ini satu-satunya kontrol navigasi di mobile, sebelumnya 38px. */
.hamburger-btn {
  display: none;
  align-items: center; justify-content: center;
  width: 44px; height: 44px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border-strong);
  background: var(--surface);
  color: var(--ink-700);
  cursor: pointer;
  flex-shrink: 0;
}
.hamburger-btn svg { width: 19px; height: 19px; }

.topbar-right { display: flex; align-items: center; gap: 14px; flex-shrink: 0; }
.user-chip { display: flex; align-items: center; gap: 10px; }
.user-avatar {
  width: 34px; height: 34px; border-radius: 999px;
  background: linear-gradient(135deg, var(--accent), var(--accent-dark));
  color: #fff; display: flex; align-items: center; justify-content: center;
  font-weight: 700; font-size: 13px; font-family: 'Plus Jakarta Sans', sans-serif;
  flex-shrink: 0;
}
.user-meta { line-height: 1.3; display: flex; flex-direction: column; }
.user-meta .u-name { font-size: 13px; font-weight: 600; color: var(--ink-900); }
.user-meta .u-role { font-size: 11px; color: var(--ink-500); }

.logout-btn {
  display: inline-flex; align-items: center; gap: 6px;
  background: var(--danger-soft);
  color: var(--danger);
  border: none;
  padding: 8px 14px;
  border-radius: var(--radius-sm);
  font-size: 12.5px;
  font-weight: 700;
  cursor: pointer;
}
.logout-btn:hover { background: #fbdada; }
.logout-btn svg { width: 15px; height: 15px; }

/* --------------------------------------------------------------------------
   A.6 — CONTENT
   -------------------------------------------------------------------------- */
.content { padding: 26px 28px 48px; flex: 1; }
.content h1 { margin: 0 0 20px; font-size: 22px; font-weight: 800; color: var(--ink-900); }

.alert {
  padding: 12px 16px;
  border-radius: var(--radius-sm);
  font-size: 13px;
  font-weight: 500;
  margin-bottom: 18px;
  border: 1px solid transparent;
}
.alert.success { background: var(--success-soft); color: var(--success); border-color: #c3ecd8; }
.alert.error { background: var(--danger-soft); color: var(--danger); border-color: #f6cccc; }
.alert.warning { background: var(--warning-soft); color: var(--warning); border-color: #f3e0bb; }

/* --------------------------------------------------------------------------
   A.7 — STAT CARDS (dashboard)
   -------------------------------------------------------------------------- */
.stat-cards {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 16px;
  margin-bottom: 24px;
}
/* Kartu KPI (Okt 2026): kartu putih + garis aksen warna di atas, angka
   besar berwarna nada kartu. Sebelumnya gradien jenuh penuh + emoji
   dekoratif (.icon-bg) - tidak senada dengan kartu/panel lain dan emoji
   melanggar konvensi ikon app (ikon selalu ui_icon()). Kelas warna
   (green/cyan/blue/orange) tetap sama, jadi markup view tidak berubah. */
.stat-card {
  --tone: var(--accent-dark);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 18px 18px 16px;
  color: var(--ink-900);
  position: relative;
  overflow: hidden;
  min-height: 96px;
  box-shadow: var(--shadow-sm);
}
.stat-card::before { content: ""; position: absolute; inset: 0 0 auto 0; height: 3px; background: var(--tone); }
.stat-card.green  { --tone: var(--success); }
.stat-card.cyan   { --tone: var(--info); }
.stat-card.blue   { --tone: var(--accent-dark); }
.stat-card.orange { --tone: var(--warning); }
.stat-card h4 {
  margin: 0 0 8px;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--ink-500);
}
.stat-card .stat-value { font-size: 24px; font-weight: 800; margin-bottom: 4px; color: var(--tone); font-family: 'Plus Jakarta Sans', sans-serif; }
.stat-card .stat-sub { font-size: 12px; color: var(--ink-500); }
.stat-card .stat-sub a, .stat-card a { color: var(--accent-dark); }
.stat-card .icon-bg { display: none; }

/* Jumlah kolom per baris lewat modifier (dulu style inline
   "grid-template-columns: repeat(N, 1fr)" di view, yang MENGALAHKAN
   media query sehingga 6 kartu tetap 6 kolom di ponsel). */
.stat-cards--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.stat-cards--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.stat-cards--6 { grid-template-columns: repeat(6, minmax(0, 1fr)); }
@media (max-width: 1100px) {
  .stat-cards--4, .stat-cards--6 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (max-width: 780px) {
  .stat-cards.stat-cards--3, .stat-cards.stat-cards--4, .stat-cards.stat-cards--6 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* --------------------------------------------------------------------------
   A.8 — PANEL
   -------------------------------------------------------------------------- */
.panel {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 22px;
  margin-bottom: 20px;
  box-shadow: var(--shadow-sm);
}
.panel h3 { margin: 0 0 14px; color: var(--ink-900); font-size: 15.5px; font-weight: 700; }

.panel-header-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 16px;
  flex-wrap: wrap;
  gap: 10px;
}

/* --------------------------------------------------------------------------
   A.9 — BUTTONS
   -------------------------------------------------------------------------- */
.primary-btn {
  background: var(--accent); color: #fff; border: none;
  padding: 10px 16px; border-radius: var(--radius-sm); font-size: 13px;
  font-weight: 700; cursor: pointer; transition: background 0.15s var(--ease);
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  text-decoration: none; line-height: 1.2;
}
.primary-btn:hover { background: var(--accent-dark); }
.secondary-btn {
  background: #fff; color: var(--ink-700); border: 1px solid var(--border-strong);
  padding: 9px 16px; border-radius: var(--radius-sm); font-size: 13px;
  font-weight: 700; cursor: pointer; text-decoration: none;
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  transition: background 0.15s var(--ease), border-color 0.15s var(--ease);
  line-height: 1.2;
}
.secondary-btn:hover { background: var(--surface-alt); border-color: var(--ink-400); }
/* Ikon di dalam tombol: ukurannya tetap walau tombolnya di-resize flex,
   dan warnanya ikut warna teks tombol kecuali diberi warna aksen sendiri
   (mis. ikon hijau Excel di tombol outline, lihat .btn-icon-accent). */
.primary-btn .ui-icon, .secondary-btn .ui-icon { flex: none; }
.btn-icon-accent { color: #16a34a; }

/* --------------------------------------------------------------------------
   A.10 — FORMS
   -------------------------------------------------------------------------- */
.form-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
  margin-bottom: 20px;
}
.form-grid input, .form-grid select, .form-grid textarea {
  min-height: 42px; padding: 10px 12px; border: 1px solid var(--border-strong); border-radius: 10px;
  font-size: 14px; font-family: inherit; width: 100%; background: var(--surface);
}
.form-grid input:focus, .form-grid select:focus, .form-grid textarea:focus {
  outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft);
}
.form-grid button {
  grid-column: span 3;
  padding: 10px 16px; background: var(--accent); color: #fff; border: none;
  border-radius: var(--radius-sm); font-weight: 700; cursor: pointer;
}
.form-grid button:hover { background: var(--accent-dark); }

/* Form standar (Okt 2026): satu definisi kontrol untuk SEMUA pola form
   yang ada di app - .form-stack .field (mayoritas), .form-group (beberapa
   form lama yang sebelumnya tampil sebagai input mentah tanpa style), dan
   .form-grid di atas. Ukuran 42px, radius 10px, ring fokus teal, label di
   atas input - sama dengan form Karyawan (admin/employees/form.php).

   .form-stack sekarang GRID responsif: 2-3 kolom kalau wadahnya lebar (form
   halaman penuh), otomatis 1 kolom di wadah sempit (modal, ponsel). Elemen
   yang bukan .field (paragraf info, tombol, blok kondisional) dan field
   berisi textarea selalu selebar penuh. Field lain bisa dipaksa selebar
   penuh dengan .field--full. */
.form-stack {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr));
  gap: 18px 22px; max-width: 1240px; align-items: start;
  /* Tanpa ini, lebar intrinsik grid (2 kolom = 880px) ikut "mendorong"
     wadah induk yang berupa track grid 1fr (mis. Ajukan Lembur Admin) -
     halaman meluber ke samping di ponsel. Lebar form tetap mengisi wadah. */
  contain: inline-size;
}
.form-stack > :not(.field),
.form-stack > .field:has(textarea),
.form-stack > .field--full { grid-column: 1 / -1; }

.form-stack .field label,
.form-group > label {
  display: block; font-size: 13px; font-weight: 600; color: var(--ink-700); margin-bottom: 7px;
}
.form-stack .field input:not([type="checkbox"]):not([type="radio"]):not([type="file"]),
.form-stack .field select,
.form-stack .field textarea,
.form-group input:not([type="checkbox"]):not([type="radio"]):not([type="file"]),
.form-group select,
.form-group textarea {
  width: 100%; min-height: 42px; padding: 10px 12px; border: 1px solid var(--border-strong); border-radius: 10px;
  font-size: 14px; font-family: inherit; color: var(--ink-900); background: var(--surface);
  transition: border-color 0.15s var(--ease), box-shadow 0.15s var(--ease);
}
.form-stack .field textarea, .form-group textarea { min-height: 96px; line-height: 1.5; resize: vertical; }
.form-stack .field input:hover:not(:focus):not([type="checkbox"]):not([type="radio"]),
.form-stack .field select:hover:not(:focus),
.form-group input:hover:not(:focus):not([type="checkbox"]):not([type="radio"]),
.form-group select:hover:not(:focus) { border-color: var(--ink-400); }
.form-stack .field input:focus,
.form-stack .field select:focus,
.form-stack .field textarea:focus,
.form-group input:focus,
.form-group select:focus,
.form-group textarea:focus {
  outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft);
}
.form-stack .field input::placeholder, .form-group input::placeholder,
.form-stack .field textarea::placeholder, .form-group textarea::placeholder { color: var(--ink-400); }
.form-stack .field input[type="checkbox"], .form-stack .field input[type="radio"],
.form-group input[type="checkbox"], .form-group input[type="radio"] {
  width: 16px; height: 16px; accent-color: var(--accent); vertical-align: -3px; margin-right: 6px;
}
.form-stack .field input[type="file"], .form-group input[type="file"] { font-size: 13px; max-width: 100%; }
.form-stack .hint, .form-group .hint { font-size: 12px; color: var(--ink-500); margin-top: 6px; line-height: 1.45; }
.form-group { margin-bottom: 18px; }
/* Penanda field wajib & judul kelompok field di dalam form panjang. */
.req { color: var(--danger); font-weight: 700; }
.form-section-title {
  margin: 6px 0 -6px; padding-top: 16px; border-top: 1px solid var(--border);
  font-size: 11.5px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; color: var(--ink-500);
}
.form-stack > .form-section-title:first-of-type { padding-top: 0; border-top: 0; margin-top: 0; }
/* Label pembungkus checkbox ("[x] Aktif") jangan tampil seperti judul field. */
.form-group > label:has(> input[type="checkbox"]) { display: flex; align-items: center; font-weight: 500; }

/* Input dengan prefix/suffix menyatu (mis. "Rp" di depan tarif, "menit" di
   belakang durasi) - dipakai pertama kali di Pengaturan Lembur, ditaruh di
   sini (bukan CSS lokal halaman) supaya form angka/satuan lain bisa pakai
   pola yang sama tanpa menulis ulang. */
.input-affix {
  display: flex; align-items: stretch; border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm); background: var(--surface); overflow: hidden;
  transition: border-color 0.12s var(--ease), box-shadow 0.12s var(--ease);
}
.input-affix:focus-within { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.input-affix input {
  flex: 1; min-width: 0; border: 0 !important; box-shadow: none !important;
  background: transparent; padding: 10px 12px; font-size: 13px; font-family: inherit;
}
.input-affix input:focus { outline: none; }
.input-affix-prefix, .input-affix-suffix {
  display: flex; align-items: center; flex: none; padding: 0 12px;
  font-size: 12.5px; font-weight: 700; color: var(--ink-500); background: var(--surface-alt);
}
.input-affix-prefix { border-right: 1px solid var(--border-strong); }
.input-affix-suffix { border-left: 1px solid var(--border-strong); }
/* Tombol submit form: rata kiri & selebar isinya (dulu bar penuh selebar
   form), sama seperti tombol utama di halaman lain. */
.form-stack button[type="submit"] {
  justify-self: start; min-width: 160px; min-height: 42px;
  padding: 11px 20px; background: var(--accent); color: #fff; border: none;
  border-radius: var(--radius-sm); font-weight: 700; cursor: pointer; font-size: 14px;
}
.form-stack button[type="submit"]:hover { background: var(--accent-dark); }

/* --------------------------------------------------------------------------
   A.11 — TABLE
   Style tabel dibuat sekali di sini (class .data-table) dan otomatis
   dipakai oleh hampir semua modul (aset, karyawan, cuti, payroll, dst),
   jadi cukup rapi & modern tanpa harus sentuh tiap file view.
   -------------------------------------------------------------------------- */
.table-wrap {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  /* bayangan tipis di kiri/kanan sebagai penanda "masih bisa di-scroll"
     saat tabel lebih lebar dari layar (kepakai terutama di mobile) */
  background:
    linear-gradient(var(--surface), var(--surface)) left,
    linear-gradient(var(--surface), var(--surface)) right,
    radial-gradient(farthest-side at left, rgba(15,23,41,0.10), transparent) left,
    radial-gradient(farthest-side at right, rgba(15,23,41,0.10), transparent) right;
  background-repeat: no-repeat;
  background-size: 20px 100%, 20px 100%, 12px 100%, 12px 100%;
  background-attachment: local, local, scroll, scroll;
}

/* border-collapse: separate (bukan collapse) - WAJIB untuk thead sticky di
   bawah. position:sticky pada <th> di dalam tabel border-collapse:collapse
   rusak di banyak browser (th lepas dari alur baris, tumpang tindih baris
   data pertama) - ini gotcha CSS yang dikonfirmasi lewat pengujian
   Playwright, bukan cuma teori. border-spacing:0 membuat hasil visualnya
   tetap identik dengan collapse (tabel ini toh cuma pakai border-bottom
   per sel, bukan grid penuh). */
.data-table { width: 100%; border-collapse: separate; border-spacing: 0; font-size: 13px; background: var(--surface); }
.data-table thead th {
  text-align: left;
  padding: 12px 14px;
  background: var(--surface-alt);
  color: var(--ink-500);
  font-weight: 700;
  font-size: 11.5px;
  text-transform: uppercase;
  letter-spacing: 0.4px;
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}
.data-table thead th:first-child { border-top-left-radius: var(--radius-md); }
.data-table thead th:last-child { border-top-right-radius: var(--radius-md); }

/* --------------------------------------------------------------------------
   A.11b — TABLE-WRAP DENGAN STICKY HEADER (opt-in via --sticky)
   Header sticky RELATIF KE HALAMAN (top: var(--topbar-h), tanpa membatasi
   tinggi table-wrap) SUDAH DICOBA dan RUSAK: overflow-x:auto pada
   .table-wrap membuat browser meresolusi overflow-y-nya jadi "auto" juga
   (aturan CSS Overflow spec - satu sumbu non-visible memaksa sumbu lain
   yang visible ikut jadi auto), sehingga .table-wrap sendiri (bukan
   halaman) jadi acuan sticky, dan karena tingginya tidak dibatasi, thead
   malah lepas dari alur baris dan tumpang tindih baris pertama.
   Dikonfirmasi lewat reproduksi minimal (bukan cuma teori), sebelum
   diperbaiki dengan pola di bawah.

   Perbaikannya: TERIMA .table-wrap sebagai area scroll sendiri (bukan
   dilawan) - beri tinggi maksimum + overflow:auto di KEDUA sumbu, sticky-
   nya relatif ke table-wrap itu sendiri (top:0), bukan ke halaman. Ini pola
   "data grid dengan scroll internal" yang lazim dipakai dashboard modern
   (Notion/Airtable/Linear) - filter & paginasi tetap selalu terlihat tanpa
   ikut ke-scroll, cuma badan tabelnya yang scroll.

   SENGAJA opt-in (bukan default semua .table-wrap) - kalau ini jadi
   default, ~58 halaman lain yang sudah pakai .table-wrap kepotong tinggi
   & dapat scrollbar internal yang tidak diminta. Halaman yang mau sticky
   header tinggal tambah kelas ini di div.table-wrap-nya. */
.table-wrap.table-wrap--sticky {
  overflow: auto;
  max-height: 62vh;
}
.table-wrap--sticky .data-table thead th {
  position: sticky;
  top: 0;
  z-index: 2;
}

/* --------------------------------------------------------------------------
   A.11c — HEADER KOLOM YANG BISA DIURUTKAN (sortable)
   Dibungkus <a>, bukan <button>+JS: klik header = navigasi biasa ke
   ?sort=x&dir=y&q=... (server yang re-query & re-sort, keyword pencarian
   ikut dibawa). Tanpa JS pun tetap berfungsi penuh.

   Sengaja BUKAN link di dalam .filter-target yang di-fetch instan oleh
   initInstantFilter() - link header ada di thead yang statis (di LUAR
   filter-target), jadi klik sort = navigasi halaman penuh seperti biasa.
   Ini pilihan sadar: mencampur ganti-urutan dengan pencarian-sambil-
   mengetik lewat fetch partial yang sama gampang bikin state kacau (query
   mana yang menang kalau keduanya nyaris bersamaan). */
.sort-link {
  display: inline-flex; align-items: center; gap: 4px;
  color: inherit; text-decoration: none; cursor: pointer;
}
.sort-link:hover { color: var(--ink-900); }
.sort-link .ui-icon { flex: none; opacity: .5; }
.sort-link:hover .ui-icon { opacity: 1; }
.sort-link.is-active .ui-icon { opacity: 1; color: var(--accent); }

/* --------------------------------------------------------------------------
   A.11d — CHECKBOX KOLOM TABEL + BILAH AKSI MASSAL (bulk action)
   -------------------------------------------------------------------------- */
/* Kotak centang bawaan browser kecil & tidak konsisten antar OS - diganti
   tampilan kustom minimal, TANPA menyembunyikan input aslinya dari
   keyboard/pembaca layar (opacity, bukan display:none/visibility:hidden). */
.row-check {
  position: relative; display: inline-flex; width: 18px; height: 18px;
  flex: none; cursor: pointer;
}
.row-check input {
  position: absolute; inset: 0; margin: 0; opacity: 0; cursor: pointer;
  width: 100%; height: 100%;
}
.row-check .box {
  position: absolute; inset: 0; border: 1.5px solid var(--border-strong);
  border-radius: 5px; background: var(--surface); pointer-events: none;
  display: flex; align-items: center; justify-content: center;
  transition: background 0.12s var(--ease), border-color 0.12s var(--ease);
}
.row-check .box svg { width: 12px; height: 12px; color: #fff; opacity: 0; transform: scale(.5); transition: opacity .1s, transform .1s; }
.row-check input:checked ~ .box { background: var(--accent); border-color: var(--accent); }
.row-check input:checked ~ .box svg { opacity: 1; transform: scale(1); }
.row-check input:indeterminate ~ .box { background: var(--accent); border-color: var(--accent); }
.row-check input:focus-visible ~ .box { outline: 2px solid var(--accent); outline-offset: 2px; }
.row-check input:disabled ~ .box { background: var(--surface-alt); border-color: var(--border); cursor: not-allowed; }
.row-check input:disabled { cursor: not-allowed; }

/* Bilah aksi massal - tersembunyi sampai ada baris tercentang (dikontrol
   lewat kelas .is-visible dari JS, bukan JS yang menyisipkan/membongkar
   elemen, supaya animasinya mulus & DOM-nya tetap statis/predictable). */
.bulk-bar {
  display: none; align-items: center; gap: 12px; flex-wrap: wrap;
  background: var(--accent-soft); border: 1px solid var(--accent);
  border-radius: var(--radius-sm); padding: 10px 14px; margin-bottom: 14px;
}
.bulk-bar.is-visible { display: flex; }
.bulk-bar-count { font-size: 13px; font-weight: 700; color: var(--accent-dark); }
.bulk-bar-clear {
  background: none; border: none; color: var(--accent-dark); font-size: 12.5px;
  font-weight: 600; text-decoration: underline; cursor: pointer; padding: 0;
}
.bulk-bar .action-btn.delete {
  min-height: 36px; padding: 0 14px; margin-left: auto;
}

.data-table tbody td {
  padding: 14px;
  border-bottom: 1px solid var(--border);
  color: var(--ink-900);
  vertical-align: middle;
}
.data-table tbody tr:last-child td { border-bottom: none; }
.data-table tbody tr { transition: background 0.12s var(--ease); }
.data-table tbody tr:hover td { background: var(--surface-alt); }
/* Perataan kolom. Aturannya: teks panjang yang dibaca menyamping (nama,
   departemen, jabatan) rata kiri supaya tepi kirinya lurus dan mata punya
   titik awal yang tetap; data pendek & seragam (no, kode, status, aksi)
   rata tengah supaya kolomnya terbaca simetris.
   Kelas dipasang di <th> DAN <td> kolom yang sama - kalau cuma di salah
   satu, header dan isinya jadi tidak sejajar. */
.data-table .ta-center { text-align: center; }
.data-table .ta-right  { text-align: right; }
.data-table .ta-left   { text-align: left; }

/* Angka uang/nominal - monospace + tabular-nums supaya digit sejajar rapi
   antar baris (bukan proporsional yang lebarnya beda-beda per digit),
   dipakai kolom Estimasi Rp dkk. */
.num-mono {
  font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
  font-variant-numeric: tabular-nums; font-weight: 700; color: var(--ink-900);
}

/* Anotasi sekunder di dalam sel (kode karyawan/toko, catatan admin, dsb) -
   SATU ukuran & warna konsisten (bukan 10.5/11/11.5px bercampur seperti
   sebelumnya) supaya iramanya gampang dipindai mata, tetap kebaca jelas
   (12px = lantai minimum yang nyaman dibaca untuk teks sekunder), dan
   jelas beda tingkat dari teks utama di baris yang sama. */
.row-sub {
  display: block; margin-top: 3px; font-size: 12px; font-weight: 400;
  color: var(--ink-500); line-height: 1.5;
}
.row-sub-accent { color: var(--info); font-weight: 600; }


/* text-align tidak berlaku pada anak flex, jadi isi sel yang berupa
   komponen (kebab menu, grup badge) diratakan lewat justify-content. */
.data-table td.ta-center > .row-actions { justify-content: center; }
.data-table td.ta-right  > .row-actions { justify-content: flex-end; }

/* Placeholder sel kosong - lihat ui_val() di ui_helper.php. Diredupkan
   supaya tidak ikut terbaca sebagai data saat memindai kolom. */
.cell-empty { color: var(--ink-400); }

.empty-row {
  text-align: center; color: var(--ink-400); padding: 36px 20px !important;
  font-size: 13px;
}
.empty-row::before {
  content: '—';
  display: block;
  font-size: 20px;
  margin-bottom: 4px;
  color: var(--border-strong);
}

/* Varian empty state yang lebih lengkap (ikon + judul + saran) - dipakai
   lewat <td class="empty-row empty-row--rich"><div class="empty-state">...
   Kelas dasar .empty-row TETAP dipakai apa adanya di puluhan halaman lain
   yang isinya cuma teks polos, jadi glyph "—" di atas TIDAK disentuh;
   --rich cuma mematikannya supaya tidak dobel dengan ikon SVG di bawah. */
.empty-row.empty-row--rich::before { content: none; }
.empty-row .empty-state {
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  padding: 12px 0;
}
.empty-row .empty-state .ui-icon { color: var(--border-strong); }
.empty-row .empty-state-title { font-size: 14px; font-weight: 700; color: var(--ink-700); margin: 0; }
.empty-row .empty-state-sub { font-size: 12.5px; color: var(--ink-400); margin: 0; max-width: 320px; }
.empty-row .empty-state .primary-btn { margin-top: 4px; padding: 8px 16px; font-size: 12.5px; }

/* --------------------------------------------------------------------------
   A.12 — BADGES
   -------------------------------------------------------------------------- */
.badge {
  display: inline-block; padding: 3px 10px; border-radius: 999px;
  font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.3px;
}
.badge.admin   { background: var(--violet-soft); color: var(--violet); }
.badge.finance { background: var(--success-soft); color: var(--success); }
.badge.finance_ba { background: var(--success-soft); color: var(--success); } /* Finance BA: hanya kelola BA Salah Tender */
.badge.it      { background: var(--warning-soft); color: var(--warning); }
.badge.user    { background: var(--info-soft); color: var(--info); }
.badge.diajukan   { background: var(--warning-soft); color: var(--warning); }
.badge.pending    { background: var(--warning-soft); color: var(--warning); }
.badge.disetujui  { background: var(--success-soft); color: var(--success); }
.badge.selesai    { background: var(--info-soft); color: var(--info); }
.badge.dibatalkan { background: var(--danger-soft); color: var(--danger); }
.badge.ditolak    { background: var(--danger-soft); color: var(--danger); }
.badge.aktif      { background: var(--success-soft); color: var(--success); }
.badge.rusak      { background: var(--danger-soft); color: var(--danger); }
.badge.diperbaiki { background: var(--warning-soft); color: var(--warning); }
.badge.nonaktif   { background: #eef0f6; color: var(--ink-500); }
/* Netral - dipakai label penghitung yang bukan status (mis. "1 Toko" di
   Klaim Kunjungan Toko), beda dari .nonaktif yang maknanya "tidak aktif". */
.badge.neutral    { background: var(--surface-alt); color: var(--ink-500); }

/* Status & prioritas tiket IT (Bagian 4 & 5 spec ticketing) - additive,
   dipetakan lowercase dari nilai TicketModel::STATUSES/PRIORITIES. */
.badge.baru       { background: var(--info-soft); color: var(--info); }
.badge.diterima   { background: var(--warning-soft); color: var(--warning); }
.badge.dikerjakan { background: var(--warning-soft); color: var(--warning); }
.badge.ditutup    { background: #eef0f6; color: var(--ink-500); }
.badge.rendah     { background: #eef0f6; color: var(--ink-500); }
.badge.normal     { background: var(--info-soft); color: var(--info); }
.badge.tinggi     { background: var(--warning-soft); color: var(--warning); }
.badge.kritis     { background: var(--danger-soft); color: var(--danger); }
.badge.sla-on_time { background: var(--success-soft); color: var(--success); }
.badge.sla-warning { background: var(--warning-soft); color: var(--warning); }
.badge.sla-overdue { background: var(--danger-soft); color: var(--danger); }

/* Status BA Salah Tender (Bagian 4 spec) - additive, dipetakan lowercase
   dari nilai WrongTenderModel::STATUSES. */
.badge.wt-new            { background: var(--info-soft); color: var(--info); }
.badge.wt-verified       { background: var(--success-soft); color: var(--success); }
.badge.wt-need_revision  { background: var(--warning-soft); color: var(--warning); }
.badge.wt-in_progress    { background: var(--warning-soft); color: var(--warning); }
.badge.wt-resolved       { background: var(--success-soft); color: var(--success); }
.badge.wt-closed         { background: #eef0f6; color: var(--ink-500); }
.badge.wt-rejected       { background: var(--danger-soft); color: var(--danger); }
.badge.wt-cancelled      { background: var(--danger-soft); color: var(--danger); }

/* Badge "Lokasi Kerja" berwarna - dipromosikan ke sini dari CSS lokal
   halaman Karyawan & Departemen (dulu ada 2 salinan identik). Skema
   warnanya SENGAJA punya slot lebih dari yang dipakai sekarang: app ini
   saat ini cuma benar-benar punya 2 lokasi kerja (HO/Store) - 'warehouse'
   & 'default' disiapkan untuk kategori lain KALAU suatu saat ditambah,
   bukan pura-pura ada datanya sekarang. */
.loc-badge {
  display: inline-block; padding: 3px 12px; border-radius: 999px;
  font-size: 11.5px; font-weight: 700;
}
.loc-badge--ho        { background: var(--violet-soft); color: var(--violet); }
.loc-badge--store     { background: var(--success-soft); color: var(--success); }
.loc-badge--warehouse { background: var(--warning-soft); color: var(--warning); }
.loc-badge--default   { background: #eef0f6; color: var(--ink-500); }

/* Badge "jumlah anggota" (mis. jumlah karyawan per departemen) - beda
   bentuk dari .badge/.loc-badge (persegi membulat, bukan pil penuh) supaya
   terbaca sebagai ANGKA/hitungan, bukan status. ui_icon('users') di
   dalamnya dari helper yang sama dgn ikon lain. */
.count-badge {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 4px 10px; border-radius: var(--radius-sm);
  background: var(--surface-alt); color: var(--ink-700);
  font-size: 12px; font-weight: 700; text-decoration: none;
  border: 1px solid var(--border); transition: background 0.12s var(--ease), border-color 0.12s var(--ease);
}
a.count-badge:hover { background: var(--accent-soft); border-color: var(--accent); color: var(--accent-dark); }
.count-badge .ui-icon { color: var(--ink-400); flex: none; }
a.count-badge:hover .ui-icon { color: var(--accent); }
.count-badge.is-zero { color: var(--ink-400); }
.count-badge.is-zero .ui-icon { color: var(--border-strong); }

/* --------------------------------------------------------------------------
   A.13 — ACTION BUTTONS (di dalam tabel)
   -------------------------------------------------------------------------- */
/* Target sentuh minimal 44x44 (rekomendasi mobile HIG; WCAG 2.2 AA minta
   24x24, yang dulu cuma lewat tipis). PENTING: ukuran DAN jarak dinaikkan
   bersamaan - kalau cuma areanya yang diperbesar sementara jaraknya tetap
   4-6px, area tap antar tombol saling tumpang-tindih dan salah klik justru
   jadi lebih sering, bukan lebih jarang. */
.action-btn {
  border: none; padding: 6px 12px; border-radius: var(--radius-sm); font-size: 12px;
  cursor: pointer; margin-right: 10px; font-weight: 700;
  min-height: 44px; min-width: 44px;
  display: inline-flex; align-items: center; justify-content: center;
  vertical-align: middle; box-sizing: border-box;
}
.action-btn:last-child { margin-right: 0; }
.action-btn.reset  { background: var(--warning-soft); color: var(--warning); }
.action-btn.reset:hover  { background: #fbe4bb; }
.action-btn.move   { background: var(--accent-soft); color: var(--accent-dark); }
.action-btn.move:hover   { background: var(--accent-soft-strong); }
.action-btn.delete { background: var(--danger-soft); color: var(--danger); }
.action-btn.delete:hover { background: #f9d3d3; }
.action-btn.view   { background: #eef2f7; color: #475569; }
.action-btn.view:hover   { background: #e2e8f0; }
/* tombol aksi hanya-ikon di dalam tabel (UI ringkas) - tetap 44x44 dari
   .action-btn di atas, ikonnya saja yang diperbesar biar proporsional. */
.action-btn.icon { padding: 6px; font-size: 16px; line-height: 1; margin-right: 6px; text-decoration: none; }
.action-btn.icon .ui-icon { display: block; }
/* Tombol yang PUNYA label teks: ikonnya cuma dekoratif, jadi ikut baris
   teks dengan jarak kecil - bukan .icon (yang dipakai tombol hanya-ikon). */
.action-btn.has-icon { gap: 6px; }
.action-btn .ui-icon { flex: none; }
/* Pembungkus aksi baris tabel. Gap 6px + target 44x44 dari .action-btn:
   ukuran dan jarak dinaikkan bersamaan supaya area tap tidak tumpang-tindih
   (lihat catatan di .action-btn). Flex dipakai supaya <form> pembungkus
   tombol Hapus sejajar dengan <a> di sebelahnya tanpa hack vertical-align. */
.row-actions { display: flex; align-items: center; gap: 6px; flex-wrap: nowrap; }
/* JANGAN diganti wrap: tombol 44px + gap 6px gampang melebihi lebar kolom,
   dan aksi yang membungkus jadi 2 baris bikin tinggi baris tabel loncat
   serta urutannya ambigu. Kalau sempit, .table-wrap yang scroll horizontal. */
.row-actions .action-btn,
.row-actions .inline-form,
.row-actions .inline-form .action-btn { margin-right: 0; }
/* Sel aksi yang rata kanan: flex mengabaikan text-align, jadi perataannya
   diambil alih justify-content supaya ikut header kolomnya. */
td[style*="text-align:right"] > .row-actions,
td[style*="text-align: right"] > .row-actions { justify-content: flex-end; }
/* Baris yang tidak punya aksi apa pun: placeholder sejajar tinggi tombol
   supaya tinggi baris tabel tidak loncat-loncat antar baris. */
.row-actions .row-actions-empty {
  display: inline-flex; align-items: center; min-height: 44px;
  font-size: 12px; color: var(--ink-400);
}
/* Tombol destruktif dibedakan tegas dari Edit/Lihat: sebelumnya "Hapus"
   dan "Edit" berukuran & berbentuk sama persis, hanya beda warna lembut. */
.action-btn.delete { box-shadow: inset 0 0 0 1px var(--danger); }
.inline-form { display: inline-block; vertical-align: middle; margin-right: 10px; }
.inline-form:last-child { margin-right: 0; }
.inline-form .action-btn { margin-right: 0; }

/* --------------------------------------------------------------------------
   A.13b — KEBAB MENU AKSI BARIS
   Kolom "Aksi" cuma menyisakan satu tombol tiga titik; aksinya pindah ke
   dropdown. Trade-off yang disadari: setiap aksi jadi butuh 2 klik dan tidak
   lagi terlihat sekilas. Kompensasinya di bawah ini - target 44x44, label
   teks penuh di dalam menu (bukan ikon telanjang), dan dukungan keyboard
   penuh, supaya yang hilang cuma kepadatan visual, bukan keterjangkauan.
   -------------------------------------------------------------------------- */
.row-actions { position: relative; }

.kebab-btn {
  background: none; border: none; cursor: pointer; color: var(--ink-500);
  width: 44px; height: 44px; border-radius: var(--radius-sm); padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
}
/* Lingkaran, bukan kotak: tombolnya berdiri sendiri di tengah kolom tanpa
   tetangga, jadi bentuk bulat membacanya sebagai satu titik aksi. */
.kebab-btn { border-radius: 999px; transition: background 0.12s var(--ease); }
.kebab-btn:hover { background: #e6e9f2; color: var(--ink-900); }
.kebab-btn[aria-expanded="true"] { background: #dde1ec; color: var(--ink-900); }

/* position: fixed - bukan absolute. Sel aksi ada di dalam .table-wrap yang
   overflow-x:auto; dropdown absolute akan terpotong di tepi tabel. Posisi
   persisnya dihitung JS dari rect tombolnya (lihat initRowMenus di app.js). */
.row-menu {
  position: fixed; z-index: 1400; min-width: 184px; padding: 6px;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-sm); box-shadow: 0 12px 32px rgba(15, 23, 41, 0.18);
  display: flex; flex-direction: column; gap: 2px;
}
/* Menu yang ternyata kosong (lihat initRowMenus): dikembalikan jadi teks
   biasa di dalam sel, bukan kartu mengambang. */
.row-menu.row-menu-inline {
  position: static; min-width: 0; padding: 0; background: none;
  border: 0; box-shadow: none;
}

/* Tombol/anchor aksi yang sama dipakai ulang di dalam menu - cuma
   tampilannya yang berubah jadi baris penuh berlabel. */
.row-menu .inline-form { display: block; margin: 0; width: 100%; }
.row-menu .action-btn {
  width: 100%; margin: 0; min-width: 0; min-height: 40px;
  justify-content: flex-start; gap: 10px; padding: 8px 10px;
  font-size: 13px; font-weight: 600; background: none; color: var(--ink-700);
  box-shadow: none; border-radius: 6px; text-align: left;
}
.row-menu .action-btn:hover { background: var(--surface-alt); color: var(--ink-900); }
.row-menu .action-btn .ui-icon { color: var(--ink-400); }
.row-menu .action-btn:hover .ui-icon { color: inherit; }

/* Aksi destruktif dibedakan warna, bukan cuma posisi - dan dipisah garis
   supaya tidak kena klik saat membidik item di atasnya. */
.row-menu .action-btn.delete,
.row-menu .action-btn.delete .ui-icon { color: var(--danger); }
.row-menu .action-btn.delete:hover { background: var(--danger-soft); color: var(--danger); }
/* :not(:first-child) - di menu yang isinya CUMA aksi destruktif (mis.
   "Batalkan pengajuan"), garis pemisah di paling atas cuma jadi coretan. */
.row-menu .row-menu-danger:not(:first-child) {
  margin-top: 4px; padding-top: 4px; border-top: 1px solid var(--border);
}
.row-menu-label { white-space: nowrap; }

.row-menu .action-btn[disabled] { opacity: .45; cursor: not-allowed; }
.row-menu .row-actions-empty { padding: 8px 10px; min-height: 0; }

/* Varian berlabel: trigger dropdown biasa (mis. "Export Data") yang pakai
   mesin buka/tutup/posisi kebab-menu yang sama persis (delegasi klik,
   position:fixed dijepit ke viewport, navigasi panah/Escape), tapi
   tampilannya tombol secondary berlabel + panah bawah, bukan tiga titik
   bulat. Tinggal tambahkan class ini DI SAMPING .kebab-btn. */
.kebab-btn.dropdown-btn {
  width: auto; height: auto; border-radius: var(--radius-sm); padding: 9px 14px;
  background: var(--surface); border: 1px solid var(--border-strong); gap: 8px;
  font-size: 13px; font-weight: 700; color: var(--ink-700);
}
.kebab-btn.dropdown-btn:hover { background: var(--surface-alt); color: var(--ink-700); border-color: var(--ink-400); }
.kebab-btn.dropdown-btn[aria-expanded="true"] { background: var(--surface-alt); border-color: var(--accent); color: var(--ink-700); }
.kebab-btn.dropdown-btn .ui-icon { flex: none; }

/* Layar sempit: menu jadi lembar yang menempel di bawah, bukan dropdown
   mungil yang gampang meleset saat ditekan jempol. */
@media (max-width: 560px) {
  .row-menu {
    left: 12px !important; right: 12px !important; width: auto; min-width: 0;
    top: auto !important; bottom: 12px; padding: 8px;
  }
  .row-menu .action-btn { min-height: 48px; font-size: 14px; }
}

/* Atribut [hidden] cuma bernilai `display: none` dari stylesheet browser,
   jadi kelas apa pun yang menyetel display (mis. .action-btn = inline-flex)
   MENIMPANYA dan elemennya tetap terlihat walau hidden=true. Ditegakkan
   sekali di sini supaya hidden bisa dipercaya di seluruh app. */
[hidden] { display: none !important; }

/* Teks khusus pembaca layar: tetap ada di accessibility tree, tapi tidak
   memakan ruang. Jangan diganti display:none / visibility:hidden - keduanya
   ikut mengeluarkannya dari pembacaan. */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
  border: 0;
}

/* --------------------------------------------------------------------------
   A.13c — FILTER BAR (di atas tabel)
   Input cari + select filter disatukan dalam satu kotak, bukan berderet
   sebagai kontrol lepas: keduanya menyaring tabel yang sama, jadi secara
   visual harus terbaca sebagai satu kendali.
   -------------------------------------------------------------------------- */
.filter-bar {
  display: flex; align-items: stretch; gap: 0; margin-bottom: 16px;
  border: 1px solid var(--border-strong); border-radius: var(--radius-sm);
  background: var(--surface); max-width: 640px; overflow: hidden;
  transition: border-color 0.12s var(--ease), box-shadow 0.12s var(--ease);
}
.filter-bar:focus-within {
  border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft);
}

.filter-bar .filter-search { position: relative; flex: 1; min-width: 0; display: flex; }
.filter-bar .filter-search .ui-icon {
  position: absolute; left: 12px; top: 50%; transform: translateY(-50%);
  color: var(--ink-400); pointer-events: none;
}
.filter-bar input[type="search"] {
  flex: 1; min-width: 0; border: 0; outline: 0; background: none;
  padding: 11px 12px 11px 38px; font-size: 13px; color: var(--ink-900);
  font-family: inherit;
}
/* Tombol "x" bawaan browser disembunyikan: sudah ada tombol bersih sendiri
   yang ikut mengosongkan filter DAN memuat ulang hasilnya. */
.filter-bar input[type="search"]::-webkit-search-cancel-button { display: none; }

.filter-bar .filter-clear {
  border: 0; background: none; cursor: pointer; color: var(--ink-400);
  width: 34px; display: none; align-items: center; justify-content: center;
}
.filter-bar .filter-clear:hover { color: var(--ink-900); }
.filter-bar.has-query .filter-clear { display: flex; }

.filter-bar select {
  border: 0; border-left: 1px solid var(--border); outline: 0;
  background: var(--surface-alt); padding: 11px 12px; font-size: 13px;
  color: var(--ink-700); font-family: inherit; cursor: pointer; flex: none;
}

/* Spinner kecil saat hasil sedang diambil - tanpa ini, mengetik di kolom
   cari tidak memberi tanda apa pun sampai tabelnya tiba-tiba berganti. */
.filter-bar .filter-spinner {
  width: 0; opacity: 0; flex: none; display: flex; align-items: center;
  justify-content: center; color: var(--ink-400);
  transition: width 0.12s var(--ease), opacity 0.12s var(--ease);
}
.filter-bar.is-loading .filter-spinner { width: 30px; opacity: 1; }
.filter-bar .filter-spinner .ui-icon { animation: filter-spin 0.7s linear infinite; }
@keyframes filter-spin { to { transform: rotate(360deg); } }

/* Hasil yang sedang dimuat ulang diredupkan, tidak disembunyikan: tabel yang
   hilang lalu muncul lagi bikin halaman melompat di setiap ketikan. */
.filter-target.is-loading { opacity: .55; transition: opacity 0.12s var(--ease); }

@media (prefers-reduced-motion: reduce) {
  .filter-bar .filter-spinner .ui-icon { animation: none; }
  .filter-target.is-loading { transition: none; }
}

/* Varian ringkas: dipakai saat form filter cuma butuh SATU input pencarian
   pendek + satu select (mis. Karyawan), bukan form banyak kontrol yang
   sengaja melebar penuh. .filter-bar biasa (block, width:auto -> mengisi
   lebar induk) bikin input ikut selebar itu walau isinya cuma "cari nama".
   inline-flex membuat lebar bar = jumlah lebar anaknya, bukan lebar induk. */
.filter-bar--compact { display: inline-flex; width: auto; max-width: 100%; }

/* Pagination standar (Okt 2026). Template-nya app/Views/pagers/humaris_full.php
   (semua $pager->links()); aturan sama disalin di sini untuk pagination yang
   dibuat manual (Departemen, Status Agen Toko) dengan class .hm-pager-list.
   .pagination-wrap = baris "Menampilkan X-Y dari Z data" + nomor halaman. */
.pagination-wrap { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 10px; margin-top: 16px; }
.pagination-info { font-size: 12.5px; color: var(--ink-500); }
.hm-pager-list { list-style: none; display: flex; flex-wrap: wrap; gap: 4px; margin: 0; padding: 0; }
.hm-pager-list a, .hm-pager-list span {
  display: inline-flex; align-items: center; justify-content: center; box-sizing: border-box;
  min-width: 36px; height: 36px; padding: 0 10px; border-radius: 8px;
  border: 1px solid var(--border-strong); background: var(--surface);
  color: var(--ink-700); font-size: 13px; font-weight: 600; line-height: 1; text-decoration: none;
}
.hm-pager-list a:hover { background: var(--surface-alt); border-color: var(--ink-400); }
.hm-pager-list .active a, .hm-pager-list .active span { background: var(--accent); border-color: var(--accent); color: #fff; }
.hm-pager-list .disabled a, .hm-pager-list .disabled span { opacity: .45; pointer-events: none; }
@media (max-width: 768px) { .pagination-wrap { flex-direction: column; align-items: flex-start; } }

/* Form filter 4 kolom + tombol (Tiket IT & BA Salah Tender sisi karyawan) -
   dulu grid inline tanpa breakpoint sehingga meluber di layar sempit. */
.filter-grid-5 {
  display: grid; grid-template-columns: minmax(0, 1.4fr) repeat(3, minmax(0, 1fr)) auto;
  gap: 14px; align-items: end;
}
.filter-grid-5 label { display: block; font-size: 12.5px; font-weight: 600; color: var(--ink-700); margin-bottom: 6px; }
.filter-grid-5 input, .filter-grid-5 select {
  width: 100%; min-height: 40px; padding: 9px 12px; font: inherit; font-size: 13px; color: var(--ink-900);
  background: var(--surface); border: 1px solid var(--border-strong); border-radius: 10px;
}
.filter-grid-5 input:focus, .filter-grid-5 select:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.filter-date-range { display: flex; gap: 6px; }
@media (min-width: 901px) {
  .filter-grid-5:has(.filter-date-range) {
    grid-template-columns: minmax(0, 1.3fr) repeat(2, minmax(0, 1fr)) minmax(0, 1.6fr) auto;
  }
}
.filter-date-range input { padding-left: 8px; padding-right: 8px; min-width: 0; }
@media (max-width: 900px) { .filter-grid-5 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px) { .filter-grid-5 { grid-template-columns: minmax(0, 1fr); } }
.filter-bar--compact .filter-search { flex: 0 1 360px; }

@media (max-width: 560px) {
  .filter-bar { flex-wrap: wrap; max-width: none; }
  .filter-bar--compact { display: flex; width: 100%; }
  .filter-bar--compact .filter-search { flex: 1 1 100%; }
  .filter-bar .filter-search { flex: 1 1 100%; }
  .filter-bar select { flex: 1 1 100%; border-left: 0; border-top: 1px solid var(--border); }
}

/* --------------------------------------------------------------------------
   A.14 — MODAL
   -------------------------------------------------------------------------- */
/* display:flex SELALU (bukan none/flex ditoggle lagi) - supaya opacity &
   transform di bawah ini bisa dianimasikan. Tersembunyi lewat opacity 0 +
   visibility:hidden + pointer-events:none (setara display:none untuk
   pembaca layar & urutan Tab), muncul halus begitu .show ditambahkan.
   Berlaku otomatis untuk SEMUA modal di app (modal konfirmasi hapus,
   modal generik Riwayat/QR Code, modal Tolak, dst) - satu tempat, tanpa
   ubah JS sama sekali (masih murni toggle class .show yang sudah ada). */
.modal-overlay {
  display: flex; position: fixed; inset: 0; background: rgba(10, 15, 30, 0.55);
  z-index: 1500; align-items: center; justify-content: center; padding: 16px;
  backdrop-filter: blur(2px);
  opacity: 0; visibility: hidden; pointer-events: none;
  transition: opacity 0.18s var(--ease), visibility 0s linear 0.18s;
}
.modal-overlay.show {
  opacity: 1; visibility: visible; pointer-events: auto;
  transition: opacity 0.18s var(--ease), visibility 0s linear 0s;
}
.modal-box {
  background: var(--surface); border-radius: var(--radius-lg); width: 100%; max-width: 640px;
  max-height: 85vh; overflow-y: auto; box-shadow: 0 24px 60px rgba(15,23,41,0.35);
  transform: scale(0.96) translateY(8px); opacity: 0;
  transition: transform 0.2s cubic-bezier(0.16, 1, 0.3, 1), opacity 0.18s var(--ease);
}
.modal-overlay.show .modal-box { transform: scale(1) translateY(0); opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  .modal-overlay, .modal-overlay.show, .modal-box, .modal-overlay.show .modal-box {
    transition: none;
  }
}
.modal-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 18px 20px; border-bottom: 1px solid var(--border);
  position: sticky; top: 0; background: var(--surface); border-radius: var(--radius-lg) var(--radius-lg) 0 0;
}
.modal-header h3 { margin: 0; font-size: 15.5px; color: var(--ink-900); }
/* 44x44 (sebelumnya 30px): ini satu-satunya tombol tutup modal. */
.modal-close-btn {
  background: var(--surface-alt); border: none; width: 44px; height: 44px; border-radius: var(--radius-sm);
  font-size: 20px; line-height: 1; color: var(--ink-500); cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center; flex: none;
}
.modal-close-btn:hover { background: #eef0f6; color: var(--ink-900); }
.modal-body { padding: 20px; }

/* --------------------------------------------------------------------------
   A.15 — PAGINATION
   -------------------------------------------------------------------------- */
.pagination { display: flex; gap: 6px; margin-top: 14px; flex-wrap: wrap; list-style: none; padding: 0; }
.pagination li a, .pagination li span {
  display: inline-block; padding: 6px 11px; border: 1px solid var(--border-strong); border-radius: var(--radius-sm);
  font-size: 12.5px; color: var(--ink-700); text-decoration: none;
}
.pagination li.active span { background: var(--accent); border-color: var(--accent); color: #fff; }
.pagination li a:hover { background: var(--surface-alt); }

/* --------------------------------------------------------------------------
   A.15b — TOGGLE SWITCH (mis. "Langsung setujui klaim ini")
   Alternatif visual untuk <input type="checkbox"> polos - dipakai ketika
   pilihannya jelas on/off tunggal (bukan grup pilihan), bukan pengganti
   checkbox app-wide.
   -------------------------------------------------------------------------- */
.toggle-switch { position: relative; display: inline-flex; align-items: center; gap: 10px; cursor: pointer; user-select: none; }
.toggle-switch input {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.toggle-switch-track {
  flex: none; width: 40px; height: 22px; border-radius: 999px; background: var(--border-strong);
  position: relative; transition: background 0.15s var(--ease);
}
.toggle-switch-track::after {
  content: ''; position: absolute; top: 2px; left: 2px; width: 18px; height: 18px; border-radius: 50%;
  background: #fff; box-shadow: 0 1px 2px rgba(15,23,41,.25); transition: transform 0.15s var(--ease);
}
.toggle-switch input:checked + .toggle-switch-track { background: var(--accent); }
.toggle-switch input:checked + .toggle-switch-track::after { transform: translateX(18px); }
.toggle-switch input:focus-visible + .toggle-switch-track { outline: 2px solid var(--accent); outline-offset: 2px; }
.toggle-switch-label { font-size: 13px; color: var(--ink-700); font-weight: 500; }

/* --------------------------------------------------------------------------
   A.16 — MOBILE OVERLAY (backdrop di belakang drawer sidebar)
   Elemen ini hanya nampak saat sidebar dalam mode drawer (lihat bagian B).
   -------------------------------------------------------------------------- */
.sidebar-backdrop {
  display: none;
  position: fixed; inset: 0;
  background: rgba(10, 15, 30, 0.5);
  z-index: 90;
}
.sidebar-backdrop.show { display: block; }


/* --------------------------------------------------------------------------
   A.17 — LOGIN PAGE
   Split-panel: kiri identitas brand (gelap, senada sidebar), kanan form.
   -------------------------------------------------------------------------- */
.login-shell {
  min-height: 100vh;
  display: grid;
  grid-template-columns: 1.05fr 1fr;
}
.login-brand {
  background: var(--side-bg);
  background-image:
    radial-gradient(circle at 18% 22%, rgba(23,179,163,0.35), transparent 45%),
    radial-gradient(circle at 82% 78%, rgba(23,179,163,0.18), transparent 40%);
  color: #fff;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: 48px;
}
.login-brand-top { display: flex; align-items: center; gap: 12px; }
.login-brand-mark {
  width: 40px; height: 40px; border-radius: 12px;
  background: linear-gradient(135deg, var(--accent), var(--accent-dark));
  display: flex; align-items: center; justify-content: center;
  color: #fff; font-weight: 800; font-size: 15px; font-family: 'Plus Jakarta Sans', sans-serif;
  flex-shrink: 0;
}
.login-brand-name { font-family: 'Plus Jakarta Sans', sans-serif; font-weight: 700; font-size: 16px; letter-spacing: 0.2px; }

.login-brand-mid { max-width: 380px; }
.login-brand-mid h2 {
  font-size: 30px; line-height: 1.25; font-weight: 800; margin: 0 0 14px;
  font-family: 'Plus Jakarta Sans', sans-serif;
}
.login-brand-mid p { font-size: 14px; line-height: 1.6; color: var(--side-text); margin: 0; }

.login-brand-features { display: flex; flex-direction: column; gap: 14px; margin-top: 28px; }
.login-brand-feature { display: flex; align-items: center; gap: 12px; font-size: 13px; color: #e6e9f2; }
.login-brand-feature .icon {
  width: 30px; height: 30px; border-radius: 9px; flex-shrink: 0;
  background: rgba(23,179,163,0.18); color: var(--accent);
  display: flex; align-items: center; justify-content: center;
}
.login-brand-feature .icon svg { width: 16px; height: 16px; }

.login-brand-bottom { font-size: 11.5px; color: #566079; }

.login-panel {
  display: flex; align-items: center; justify-content: center;
  padding: 32px; background: var(--bg);
}
.login-card {
  background: var(--surface);
  width: 100%;
  max-width: 380px;
  padding: 36px 32px;
  border-radius: var(--radius-lg);
  border: 1px solid var(--border);
  box-shadow: var(--shadow-md);
}
.login-card-mark-mobile { display: none; }
.login-card h1 { margin: 0 0 6px; font-size: 21px; font-weight: 800; color: var(--ink-900); font-family: 'Plus Jakarta Sans', sans-serif; }
.login-card p.subtitle { margin: 0 0 26px; font-size: 13px; color: var(--ink-500); }

.login-field { margin-bottom: 16px; }
.login-field label { display: block; font-size: 12.5px; font-weight: 700; color: var(--ink-700); margin-bottom: 6px; }
.login-input-wrap { position: relative; }
.login-input-wrap .icon {
  position: absolute; left: 12px; top: 50%; transform: translateY(-50%);
  width: 17px; height: 17px; color: var(--ink-400); pointer-events: none;
}
.login-input-wrap input {
  width: 100%; padding: 11px 12px 11px 38px;
  border: 1px solid var(--border-strong); border-radius: var(--radius-sm);
  font-size: 14px; font-family: inherit; background: var(--surface-alt);
}
.login-input-wrap input:focus {
  outline: none; border-color: var(--accent); background: var(--surface);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.login-toggle-pw {
  position: absolute; right: 10px; top: 50%; transform: translateY(-50%);
  background: none; border: none; cursor: pointer; color: var(--ink-400);
  width: 26px; height: 26px; display: flex; align-items: center; justify-content: center;
}
.login-toggle-pw svg { width: 17px; height: 17px; }

.login-submit-btn {
  width: 100%; padding: 12px; background: var(--accent); color: #fff;
  border: none; border-radius: var(--radius-sm); font-size: 14.5px; font-weight: 700;
  cursor: pointer; margin-top: 4px; transition: background 0.15s var(--ease);
}
.login-submit-btn:hover { background: var(--accent-dark); }

.login-message { margin-top: 16px; padding: 10px 12px; border-radius: var(--radius-sm); font-size: 13px; text-align: center; }
.login-message.error { background: var(--danger-soft); color: var(--danger); }
.login-message.success { background: var(--success-soft); color: var(--success); }

.login-footnote { margin-top: 24px; font-size: 11.5px; color: var(--ink-400); text-align: center; }

/* ==========================================================================
   B. MOBILE CSS
   Semua penyesuaian tampilan untuk layar kecil dikumpulkan di sini,
   terpisah dari CSS desktop di atas, supaya gampang dicari & diubah.
   ========================================================================== */

/* ----- Tablet / layar menengah (<= 1024px): sidebar sedikit lebih ramping ---- */
@media (max-width: 1024px) {
  :root { --sidebar-w: 232px; }
  .stat-cards { grid-template-columns: repeat(2, 1fr); }
  .form-grid { grid-template-columns: repeat(2, 1fr); }
  .form-grid button { grid-column: span 2; }
}

/* ----- Mobile (<= 780px): sidebar jadi drawer yang bisa dibuka/tutup ---- */
@media (max-width: 780px) {
  .hamburger-btn { display: inline-flex; }

  .sidebar {
    position: fixed;
    top: 0; left: 0;
    height: 100dvh;
    z-index: 100;
    width: 280px;
    transform: translateX(-100%);
    transition: transform 0.25s var(--ease);
    box-shadow: var(--shadow-side);
  }
  .sidebar.open { transform: translateX(0); }

  .main-area { width: 100%; }
  .topbar { padding: 0 16px; }
  .topbar-title { font-size: 14px; }
  .content { padding: 18px 16px 40px; }
  .content h1 { font-size: 19px; }

  .user-meta { display: none; }
  .logout-btn span.label-text { display: none; }
  .logout-btn { padding: 9px; }

  .stat-cards { grid-template-columns: 1fr 1fr; gap: 10px; }
  .stat-card { padding: 16px; min-height: 92px; }
  .stat-card .stat-value { font-size: 19px; }
  .stat-card .icon-bg { font-size: 32px; }

  .panel { padding: 16px; border-radius: var(--radius-md); }
  .panel-header-row { align-items: stretch; }
  .panel-header-row .primary-btn,
  .panel-header-row .secondary-btn { width: 100%; text-align: center; }

  .form-grid { grid-template-columns: 1fr; }
  .form-grid button { grid-column: 1; }

  .data-table { font-size: 12.5px; }
  .data-table thead th, .data-table tbody td { padding: 10px 12px; }
  .table-wrap { background-size: 14px 100%, 14px 100%, 10px 100%, 10px 100%; border-radius: var(--radius-sm); }

  .modal-box { max-width: 100%; max-height: 92dvh; }

  /* Jarak TIDAK diturunkan di mobile - justru di layar sentuh jarak antar
     tombol paling dibutuhkan. Aturan lama (margin-right 4px) membuat tombol
     Hapus praktis menempel ke Edit persis di perangkat yang paling rawan
     salah tap. min-height/min-width 44px diwarisi dari .action-btn. */
  .action-btn { padding: 7px 10px; margin-right: 10px; margin-bottom: 8px; }
}

/* ----- Mobile kecil (<= 420px) ---- */
@media (max-width: 420px) {
  .stat-cards { grid-template-columns: 1fr; }
  .sidebar-logo-text { font-size: 14px; }
}

/* ----- Login page: panel kiri disembunyikan di layar sempit, brand mark
   dipindah jadi kecil di atas kartu form ---- */
@media (max-width: 860px) {
  .login-shell { grid-template-columns: 1fr; }
  .login-brand { display: none; }
  .login-panel { padding: 24px 16px; }
  .login-card-mark-mobile {
    display: flex; align-items: center; justify-content: center; gap: 10px;
    margin-bottom: 22px;
  }
  .login-card-mark-mobile .login-brand-mark { width: 36px; height: 36px; font-size: 13px; }
  .login-card-mark-mobile .login-brand-name { color: var(--ink-900); }
}
@media (max-width: 420px) {
  .login-card { padding: 28px 22px; border-radius: var(--radius-md); }
}

/* ==========================================================================
   Search Dropdown (.ss-*) - dipasang lewat layouts/admin.php untuk semua
   <select name="employee_id"|"department_id"|"requested_by">, supaya bisa
   dicari dengan mengetik. Lihat komentar lengkap di layouts/admin.php.
   Warna/radius dipakai sama seperti input form lain di file ini
   (--border-strong, --radius-sm, --accent, --accent-soft, --ink-*).
   ========================================================================== */
.ss-wrap { position: relative; }
.ss-wrap select.ss-native-select {
  position: absolute; opacity: 0; height: 1px; width: 1px;
  overflow: hidden; pointer-events: none; margin: 0; padding: 0; border: 0;
}
.ss-input {
  width: 100%; box-sizing: border-box; padding: 10px 12px;
  border: 1px solid var(--border-strong); border-radius: var(--radius-sm);
  font-size: 13px; font-family: inherit; background: var(--surface); color: var(--ink-900);
}
.ss-input:focus {
  outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft);
}
.ss-list {
  display: none; position: absolute; z-index: 60; top: calc(100% + 4px);
  left: 0; right: 0; max-height: 230px; overflow-y: auto;
  background: var(--surface); border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm); box-shadow: var(--shadow-md);
}
.ss-list.ss-list-open { display: block; }
.ss-item { padding: 8px 12px; font-size: 13px; cursor: pointer; color: var(--ink-900); }
.ss-item:hover, .ss-item.ss-item-active { background: var(--accent-soft); }
.ss-empty { padding: 8px 12px; font-size: 13px; color: var(--ink-400); }
/* --------------------------------------------------------------------------
   A.20 — HELPDESK IT (Kelola Tiket IT & Kelola BA Salah Tender)
   Komponen bersama supaya kedua halaman konsisten - lihat
   review-ux-ui-helpdesk-it-dan-ba.md (bagian C, D, E).
   -------------------------------------------------------------------------- */

/* Ringkasan status compact & clickable (quick filter) - menggantikan
   .stat-card besar di halaman workspace admin, supaya tabel tetap jadi
   fokus utama. */
.summary-chips {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(116px, 1fr));
  gap: 8px;
  margin-bottom: 18px;
}
.summary-chip {
  display: flex; flex-direction: column; gap: 2px;
  padding: 9px 11px; border: 1px solid var(--border-strong);
  border-radius: 10px; background: var(--surface); text-decoration: none;
  transition: border-color 0.12s var(--ease), background 0.12s var(--ease);
}
.summary-chip:hover { border-color: var(--accent); background: var(--surface-alt); }
.summary-chip:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.summary-chip .sc-label {
  font-size: 11px; color: var(--ink-500); text-transform: uppercase;
  letter-spacing: 0.03em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.summary-chip .sc-value {
  font-size: 19px; font-weight: 800; color: var(--ink-900);
  font-family: 'Plus Jakarta Sans', sans-serif;
}
.summary-chip.is-active { border-color: var(--accent); background: var(--accent-soft); }
.summary-chip.is-alert { border-color: #f6cccc; }
.summary-chip.is-alert .sc-value { color: var(--danger); }

/* Baris jumlah hasil ("Menampilkan 2 dari 8 tiket"). */
.result-count { font-size: 12.5px; color: var(--ink-500); margin: 0 0 10px; }

/* Tombol Filter + Reset berdampingan. */
.filter-actions { display: flex; gap: 8px; align-self: end; }

/* Empty state tabel (bukan sekadar baris kosong). */
.empty-state { text-align: center; padding: 44px 20px; color: var(--ink-500); }
.empty-state h4 { margin: 0 0 6px; font-size: 15px; color: var(--ink-700); }
.empty-state p { margin: 0 0 16px; font-size: 13px; }

/* Panel filter: label konsisten + fokus terlihat. */
.filter-panel label {
  display: block; font-size: 12.5px; font-weight: 600; color: #4b5563; margin-bottom: 6px;
}
.filter-panel input, .filter-panel select {
  width: 100%; box-sizing: border-box; padding: 9px 12px;
  border: 1px solid #d1d5db; border-radius: 8px; font-size: 13px; font-family: inherit;
}
.filter-panel input:focus, .filter-panel select:focus {
  outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft);
}

/* No. Tiket / No. BA sebagai primary identifier yang bisa diklik. */
.row-id-link { font-weight: 700; color: var(--info); text-decoration: none; white-space: nowrap; }
.row-id-link:hover { text-decoration: underline; }

/* Kolom nominal rata kanan (Total Payment BA). */
.data-table td.num, .data-table th.num { text-align: right; font-variant-numeric: tabular-nums; }

/* Status lifecycle Tiket IT - warna SEMANTIK (bukan estetika), dan
   Diterima/Dikerjakan/Pending TIDAK lagi sama-sama oranye. */
.badge.tk-baru       { background: var(--info-soft); color: var(--info); }
.badge.tk-diterima   { background: var(--violet-soft); color: var(--violet); }
.badge.tk-dikerjakan { background: #dff3f4; color: #0e7490; }
.badge.tk-pending    { background: var(--warning-soft); color: var(--warning); }
.badge.tk-selesai    { background: var(--success-soft); color: var(--success); }
.badge.tk-ditutup    { background: #eef0f6; color: var(--ink-500); }
.badge.tk-dibatalkan { background: var(--danger-soft); color: var(--danger); }

/* BA "Diproses" = processing, dibedakan dari "Perlu Revisi" (warning). */
.badge.wt-in_progress { background: #dff3f4; color: #0e7490; }

/* Panel filter Helpdesk: kolom menyusut di layar sempit (laptop kecil / tablet). */
@media (max-width: 1100px) {
  .filter-panel form { grid-template-columns: repeat(2, 1fr) !important; }
  .filter-panel .filter-actions { grid-column: 1 / -1 !important; }
}
@media (max-width: 640px) {
  .filter-panel form { grid-template-columns: 1fr !important; }
  .summary-chips { grid-template-columns: repeat(2, 1fr); }
  .filter-panel .filter-actions { justify-content: stretch; }
  .filter-panel .filter-actions .primary-btn,
  .filter-panel .filter-actions .secondary-btn { flex: 1; text-align: center; }
}

/* HUMARIS logo glyph inside the brand chip (sidebar + login) */
.sidebar-logo-mark img, .login-brand-mark img { width: 72%; height: 72%; display: block; }

/* ----------------------------------------------------------------------
 * Panel filter absensi (.att-*) - DASAR BERSAMA.
 *
 * Class ini dipakai 5 halaman: Laporan Absensi Admin, Absensi Saya,
 * Absensi Toko, Perhitungan Gaji, dan Absen Kamera. Empat yang pertama
 * punya salinan sendiri di blok <style> masing-masing; Absen Kamera
 * TIDAK punya, jadi form filter & sub-label NIK-nya selama ini render
 * polos tanpa style sama sekali (.ck-admin-filter-grid di halaman itu
 * cuma mengatur grid-template-columns, yang tidak berefek tanpa
 * display:grid dari sini).
 *
 * Definisi di sini sengaja jadi BASELINE saja: blok <style> tiap halaman
 * berada setelah file ini di urutan dokumen, jadi spesifisitas sama =
 * yang di halaman tetap menang. Tampilan 4 halaman lama tidak berubah.
 * -------------------------------------------------------------------- */
.att-filter-grid { display: grid; grid-template-columns: 1fr auto; gap: 14px; align-items: end; }
.att-filter-grid label { display: block; font-size: 12.5px; font-weight: 600; color: #4b5563; margin-bottom: 6px; }
.att-filter-grid select, .att-filter-grid input {
  width: 100%; box-sizing: border-box; padding: 9px 12px;
  border: 1px solid #d1d5db; border-radius: 8px; font-size: 13px;
}
.att-date-range { display: flex; align-items: center; gap: 8px; }
.att-date-range span { font-size: 12.5px; color: #6b7280; }
.att-filter-submit { padding-bottom: 1px; }
.att-result-info { font-size: 12.5px; color: #6b7280; margin: 4px 0 14px; }
/* #6b7280 (5.1:1), bukan #9ca3af (2.5:1) seperti salinan lama - definisi
   baru tidak perlu ikut mewarisi kontras yang gagal WCAG AA. */
.att-nik-sub { display: block; font-size: 11px; color: #6b7280; font-weight: 400; }

@media (max-width: 900px) {
  .att-filter-grid { grid-template-columns: 1fr; }
}

/* ----------------------------------------------------------------------
 * Baris pencarian & badge mesin (.ml-*) - DASAR BERSAMA.
 *
 * Sama pola dengan blok .att-* di atas: dipakai Lokasi Mesin DAN Lokasi
 * Absen, tapi definisinya cuma ada di blok <style> halaman Lokasi Mesin,
 * jadi di Lokasi Absen form pencarian & badge-nya render polos.
 * Halaman Lokasi Mesin tetap menang lewat <style>-nya sendiri.
 * -------------------------------------------------------------------- */
.ml-search-row {
  display: flex; align-items: center; justify-content: flex-end;
  gap: 10px; margin: 18px 0 14px;
}
.ml-search-row label { font-size: 13px; color: #4b5563; font-weight: 600; }
.ml-search-row input {
  width: 100%; max-width: 320px; padding: 9px 12px;
  border: 1px solid #d1d5db; border-radius: 8px; font-size: 13px;
}
.ml-machine-badge {
  display: inline-block; padding: 3px 12px; border-radius: 999px;
  font-size: 11.5px; font-weight: 700; background: #eef2ff; color: #4f46e5;
}
/* #6b7280 (5.1:1) menggantikan #9ca3af (2.3:1 di atas #f3f4f6) - sama
   alasannya dengan .att-nik-sub di atas. */
.ml-machine-badge--empty { background: #f3f4f6; color: #6b7280; }

@media (max-width: 900px) {
  .ml-search-row { justify-content: flex-start; }
}

/* ----------------------------------------------------------------------
 * Pemilih tujuan balasan Tiket IT / BA (.tk-dest).
 *
 * Menggantikan 2 tombol submit kembar yang bersebelahan ("Kirim ke
 * Pelapor" / "Simpan Catatan Internal") - salah klik di sana mengirim
 * catatan internal ke pelapor dan tidak bisa ditarik. Sekarang tujuan
 * dipilih eksplisit dan label tombol kirim ikut berubah.
 * -------------------------------------------------------------------- */
.tk-dest {
  margin: 10px 0 0; padding: 10px 12px;
  border: 1px solid #e5e7eb; border-radius: 8px;
  display: flex; gap: 10px; flex-wrap: wrap;
}
.tk-dest legend { font-size: 12px; font-weight: 700; color: #4b5563; padding: 0 6px; }
.tk-dest-opt {
  display: flex; align-items: flex-start; gap: 8px; cursor: pointer;
  flex: 1 1 220px; padding: 8px 10px; border: 1px solid #e5e7eb;
  border-radius: 8px; background: #fff;
}
.tk-dest-opt span { display: flex; flex-direction: column; gap: 2px; }
.tk-dest-opt strong { font-size: 13px; color: #1f2937; font-weight: 700; }
.tk-dest-opt small { font-size: 11.5px; color: #6b7280; }
/* Opsi terpilih ditandai jelas - bukan cuma titik radio kecil. */
.tk-dest-opt:has(input:checked) { border-color: #4f46e5; background: #eef2ff; }
.tk-dest-opt--internal:has(input:checked) { border-color: #b45309; background: #fffbeb; }
.tk-dest-opt input { margin-top: 3px; width: 17px; height: 17px; flex: none; }
/* Tombol kirim ikut berganti warna saat tujuannya internal, supaya
   tidak terlihat sama dengan kirim-ke-pelapor. */
.primary-btn.tk-submit-internal { background: #b45309; }
.primary-btn.tk-submit-internal:hover { background: #92400e; }
