/* ════════════════════════════════════════════════════════════════════════════
   GESIT V6.6 — CSS 4/4: FASE 3-4, UTILITAS & RESPONSIVE
   Isi   : Utilitas, responsive, komponen Fase 3, komponen Fase 4, perbaikan mobile, panel gagal boot, prefers-reduced-motion
   Urutan: file ke-4 dari 4 (urutan wajib dijaga — CSS bersifat cascade)
   ════════════════════════════════════════════════════════════════════════════ */

/* ── 17. UTILITAS ─────────────────────────────────────────────────────────── */
/* Catatan V6.4 — KELAS HOOK (tanpa gaya, JANGAN "diperbaiki"):
   .admin-col (kolom khusus admin, di-toggle via data-admin), .apa-qty (input
   kuantitas approval ATK, dibaca JS), .np-goset (tombol lompat ke Pengaturan,
   dicari via classList), .chip-foto (penanda tombol foto; gayanya dari
   .foto-thumb-wrap). Ini selektor fungsional untuk JavaScript.              */
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.mt-1 { margin-top: 6px; }  .mt-2 { margin-top: 12px; }  .mt-3 { margin-top: 20px; }
.mb-2 { margin-bottom: 12px; } .mb-3 { margin-bottom: 20px; }
.text-muted { color: var(--text-secondary); }
.text-center { text-align: center; }
.fw-bold { font-weight: 700; }
.hidden { display: none !important; }

/* ── 18. RESPONSIVE ───────────────────────────────────────────────────────── */
@media (max-width: 1024px) {
  .antrian-panel { grid-template-columns: 1fr; }
  .grid-2 { grid-template-columns: 1fr; }
  .grid-3 { grid-template-columns: 1fr; }
}

/* ── FASE 3: komponen generik tambahan ────────────────────────────────────── */

/* Daftar pasangan label–nilai di modal Detail */
.detail-list {
  display: grid;
  grid-template-columns: 130px 1fr;
  gap: 7px 14px;
  margin: 0;
  font-size: 13px;
}
.detail-list dt {
  color: var(--slate-500);
  font-weight: 600;
  font-size: 12px;
  padding-top: 1px;
}
.detail-list dd {
  margin: 0;
  color: var(--slate-800);
  min-width: 0;
  overflow-wrap: anywhere;
}
@media (max-width: 560px) {
  .detail-list { grid-template-columns: 1fr; gap: 2px; }
  .detail-list dd { margin-bottom: 8px; }
}

/* ── V7.1: PANEL INFO RINGKAS (Portal Magang/TAD & blok fakta kunci) ────────
   Mengganti tumpukan "kartu identitas + daftar label–nilai memanjang" yang
   boros layar dengan SATU panel padat dua lapis:
     • .info-strip — identitas (avatar · nama · meta · status) satu baris;
     • .info-grid  — fakta kunci sebagai sel-sel kecil label-di-atas-nilai,
       auto-menyusun 2–5 kolom mengikuti lebar layar (auto-fit).
   Hasil: informasi yang sama terbaca sekali pandang dengan ±40% tinggi
   lebih hemat, tanpa perlu menggulir. */
.info-strip {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding: 12px 16px;
}
.info-strip .info-avatar { width: 42px; height: 42px; font-size: 15px; flex: none; }
.info-ident { flex: 1; min-width: 150px; }
.info-nama { font-size: 15px; font-weight: 700; line-height: 1.25; }
.info-meta { font-size: 12px; color: var(--text-secondary); margin-top: 1px; }

.info-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 1px;                       /* garis pemisah tipis via latar induk */
  background: var(--border);
  border-top: 1px solid var(--border);
  overflow: hidden;
  border-radius: 0 0 var(--radius-lg) var(--radius-lg); /* rapat ke dasar kartu */
}
.info-grid:empty { display: none; border-top: none; }
.info-cell { background: var(--slate-50); padding: 8px 12px; min-width: 0; }
.info-label {
  font-size: 10px; font-weight: 700; letter-spacing: .6px;
  text-transform: uppercase; color: var(--slate-400);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.info-value {
  font-size: 12.5px; font-weight: 600; color: var(--slate-700);
  margin-top: 1px; overflow-wrap: anywhere;
}
/* Varian berdiri sendiri — dipakai di dalam tab/modal tanpa strip identitas
   (mis. blok "Penempatan" di tab Data Saya). */
.info-grid.standalone {
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
}
@media (max-width: 480px) {
  .info-grid { grid-template-columns: repeat(2, 1fr); }
}

/* Select kecil di grid penyusunan jadwal shift */
.shift-select {
  padding: 5px 6px;
  font-size: 12px;
  min-width: 74px;
}

/* ── FASE 4: komponen tambahan ────────────────────────────────────────────── */

/* Kotak informasi ringkas dalam modal */
.alert {
  padding: 11px 13px; border-radius: var(--radius-md);
  font-size: 12.5px; line-height: 1.55; border: 1px solid transparent;
}
.alert b { font-weight: 700; }
.alert-info    { background: var(--brand-50);  color: var(--slate-700); border-color: rgba(20,184,166,.25); }
.alert-success { background: var(--success-bg); color: #166534; border-color: var(--success-bd); }
.alert-warning { background: var(--warning-bg); color: #92400e; border-color: #fde68a; }
.alert-danger  { background: var(--danger-bg);  color: #991b1b; border-color: #fecaca; }

/* Kalender bulanan (Agenda / Kalender Budaya) */
.cal-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px; margin-bottom: 12px; flex-wrap: wrap;
}
.cal-title { font-size: 15px; font-weight: 800; letter-spacing: -.2px; min-width: 150px; }
.cal-grid {
  display: grid; grid-template-columns: repeat(7, 1fr);
  gap: 6px;
}
.cal-dow {
  text-align: center; font-size: 10.5px; font-weight: 700;
  color: var(--slate-500); text-transform: uppercase; letter-spacing: .6px;
  padding: 4px 0 6px;
}
.cal-cell {
  background: var(--bg-card); border: 1px solid var(--border);
  border-radius: var(--radius-md); min-height: 82px; padding: 6px;
  display: flex; flex-direction: column; gap: 3px; overflow: hidden;
}
.cal-cell.is-out { opacity: .38; background: var(--slate-50); }
.cal-cell.is-today { border-color: var(--brand-500); box-shadow: 0 0 0 2px rgba(20,184,166,.14); }
.cal-cell .cal-date { font-size: 11.5px; font-weight: 700; color: var(--slate-500); }
.cal-cell.is-today .cal-date { color: var(--brand-700); }
.cal-ev {
  font-size: 10.5px; line-height: 1.25; padding: 2.5px 6px; border-radius: 6px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; cursor: default;
  background: var(--brand-50); color: var(--brand-700); border: 1px solid rgba(20,184,166,.25);
}
.cal-ev.ev-blue   { background: #eff6ff; color: #1d4ed8; border-color: #bfdbfe; }
.cal-ev.ev-amber  { background: var(--warning-bg); color: #92400e; border-color: #fde68a; }
.cal-ev.ev-violet { background: #f5f3ff; color: #6d28d9; border-color: #ddd6fe; }
.cal-ev.ev-rose   { background: #fff1f2; color: #be123c; border-color: #fecdd3; }
.cal-more { font-size: 10px; color: var(--slate-500); font-weight: 600; }

/* Checklist Eco Office */
.check-list { display: flex; flex-direction: column; gap: 7px; }
.check-item {
  display: flex; align-items: center; gap: 11px;
  padding: 10px 13px; border: 1.5px solid var(--border);
  border-radius: var(--radius-md); cursor: pointer;
  transition: border-color var(--dur-fast), background var(--dur-fast);
  font-size: 13px; user-select: none;
}
.check-item:hover { border-color: var(--brand-500); }
.check-item input { width: 17px; height: 17px; accent-color: var(--brand-600); flex: none; cursor: pointer; }
.check-item.is-checked { background: var(--brand-50); border-color: rgba(20,184,166,.45); }
.check-item .ck-no { font-size: 11px; font-weight: 700; color: var(--slate-400); width: 20px; flex: none; }
.eco-score-ring {
  width: 92px; height: 92px; border-radius: 50%;
  display: grid; place-items: center; margin: 0 auto;
  background: conic-gradient(var(--brand-500) calc(var(--pct, 0) * 1%), var(--slate-200) 0);
}
.eco-score-ring > div {
  width: 72px; height: 72px; border-radius: 50%; background: var(--bg-card);
  display: grid; place-items: center; font-weight: 800; font-size: 20px; color: var(--brand-700);
}

/* Leaderboard */
.rank-list { display: flex; flex-direction: column; }
.rank-item {
  display: flex; align-items: center; gap: 12px;
  padding: 11px 14px; border-bottom: 1px solid var(--border);
}
.rank-item:last-child { border-bottom: none; }
.rank-item .rk-no {
  width: 28px; height: 28px; border-radius: 50%; flex: none;
  display: grid; place-items: center; font-size: 12.5px; font-weight: 800;
  background: var(--slate-100); color: var(--slate-500);
}
.rank-item.rk-1 .rk-no { background: #fef3c7; color: #b45309; }
.rank-item.rk-2 .rk-no { background: #e2e8f0; color: #475569; }
.rank-item.rk-3 .rk-no { background: #ffedd5; color: #c2410c; }
.rank-item .rk-nama { flex: 1; font-size: 13px; font-weight: 600; min-width: 0; }
.rank-item .rk-sub { font-size: 11px; color: var(--slate-500); font-weight: 400; }
.rank-item .rk-val { font-size: 15px; font-weight: 800; color: var(--brand-700); }

/* Kotak tautan halaman publik */
.linkbox { display: flex; flex-direction: column; gap: 12px; }
.link-item {
  border: 1px solid var(--border); border-radius: var(--radius-md);
  padding: 12px 14px;
}
.link-item .lk-title { font-size: 13px; font-weight: 700; margin-bottom: 3px; display: flex; align-items: center; gap: 7px; }
.link-item .lk-title svg { width: 15px; height: 15px; color: var(--brand-600); }
.link-item .lk-desc { font-size: 11.5px; color: var(--slate-500); margin-bottom: 9px; }
.link-item .lk-row { display: flex; gap: 7px; }
.link-item .lk-row input {
  flex: 1; min-width: 0; font-size: 11.5px; padding: 8px 10px;
  font-family: 'SF Mono', Consolas, monospace; color: var(--slate-500);
}

/* V6.8: lencana Aktif/Nonaktif per tautan — tautan mati tidak lagi
   dibagikan tanpa sadar. Item nonaktif ditandai merah lembut. */
.link-item.is-off { border-color: var(--danger-bd); background: #fffafa; }
.link-item .lk-status {
  margin-left: auto; flex: none;
  font-size: 10px; font-weight: 800; letter-spacing: .4px; text-transform: uppercase;
  padding: 2px 8px; border-radius: var(--radius-full);
  border: 1px solid transparent;
}
.link-item .lk-status.is-on  { background: var(--success-bg); color: var(--success); border-color: var(--success-bd); }
.link-item .lk-status.is-off { background: var(--danger-bg);  color: var(--danger);  border-color: var(--danger-bd); }
.link-item .lk-off-note {
  font-size: 11.5px; color: var(--danger);
  background: var(--danger-bg); border: 1px dashed var(--danger-bd);
  border-radius: var(--radius-sm);
  padding: 6px 9px; margin-bottom: 9px;
}
.lk-manage { display: flex; justify-content: flex-end; margin-top: 2px; }

/* Nilai metrik ER sosmed */
.er-badge {
  display: inline-block; padding: 2px 8px; border-radius: var(--radius-full);
  font-size: 11px; font-weight: 700; background: var(--brand-50); color: var(--brand-700);
}

/* Item persetujuan: aksi bisa 4 tombol */
.approval-item .apv-actions { flex-wrap: wrap; justify-content: flex-end; }

@media (max-width: 768px) {
  .cal-grid { gap: 3px; }
  .cal-cell { min-height: 58px; padding: 4px; border-radius: var(--radius-sm); }
  .cal-ev { font-size: 9px; padding: 2px 4px; }
  .check-item { padding: 9px 11px; font-size: 12.5px; }
}


@media (max-width: 768px) {
  .sidebar { transform: translateX(-100%); box-shadow: var(--shadow-lg); }
  .sidebar.is-open { transform: translateX(0); }
  .main { margin-left: 0; }
  .topbar-menu-btn { display: grid; }
  .topbar { padding-left: 12px; padding-right: 12px; gap: 10px; }
  .topbar-clock { display: none; }
  .user-chip .user-meta { display: none; }
  .content { padding: 16px 14px calc(32px + var(--safe-bottom)); }
  .page-title { font-size: 18px; }
  .form-grid { grid-template-columns: 1fr; }
  .stats-grid { grid-template-columns: repeat(2, 1fr); gap: 10px; }
  .stat-card { padding: 14px; }
  .stat-card .stat-value { font-size: 22px; }
  /* V7.4 (katalog ATK terpotong — perbaikan akar): modal menjadi LEMBAR
     BAWAH yang menempel ke tepi bawah backdrop. Backdrop = fixed inset:0 =
     selalu setinggi layar yang BENAR-BENAR terlihat, jadi footer (bar
     keranjang + tombol Kirim) tak mungkin jatuh di balik address-bar —
     berbeda dari patokan 100vh/dvh lama yang meleset di banyak WebView.
     Tingginya juga dibatasi var(--vvh) (visualViewport dari Scripts_1)
     sehingga ikut menyusut saat keyboard terbuka ketika mencari barang. */
  .modal-backdrop { padding: 0; align-items: flex-end; }
  .modal {
    max-width: 100%;
    border-radius: var(--radius-xl) var(--radius-xl) 0 0;
    max-height: min(calc(100% - 12px), calc(var(--vvh, 200vh) - 12px));
    /* --kb (Scripts_1): keyboard iOS bersifat OVERLAY (layout viewport tak
       menyusut) — lembar diangkat setinggi keyboard agar tombol tetap
       terjangkau saat mengetik. Di Android nilainya ≈ 0 (tanpa efek). */
    margin-bottom: var(--kb, 0px);
  }
  .modal-body { padding: 14px 14px 16px; }
  .modal-header { padding: 14px 16px 12px; }
  .modal-footer {
    flex-direction: column-reverse;
    padding: 12px 16px calc(14px + var(--safe-bottom)); /* aman dari poni/garis gestur */
  }
  .modal-footer .btn { width: 100%; }
  /* Katalog ATK (V6.9): info keranjang di bawah tombol, kartu lebih rapat */
  .modal-footer.atk-foot > div { width: 100%; }
  .atk-cart-info { justify-content: center; }
  .atk-shop-grid { grid-template-columns: repeat(auto-fill, minmax(132px, 1fr)); gap: 8px; }
  .table thead th, .table tbody td { padding: 10px 12px; }
  .approval-item { flex-wrap: wrap; }
  .approval-item .apv-actions { width: 100%; }
  .approval-item .apv-actions .btn { flex: 1; }
}

@media (max-width: 420px) {
  .stats-grid { grid-template-columns: 1fr 1fr; }
  .page-actions .btn { flex: 1; }
  /* V7.0: di layar sempit auto-fill 132px jatuh ke SATU kolom gemuk /
     kartu terjepit — paksa dua kolom proporsional. */
  .atk-shop-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* (V7.0 dvh dihapus di V7.4 — tergantikan mekanisme lembar-bawah
   max-height:min(100%, --vvh) di atas: bekerja pada WebView tanpa dvh
   dan lebih akurat saat keyboard Android terbuka, karena dvh TIDAK
   ikut menyusut bersama keyboard sedangkan visualViewport ikut.) */

/* ── PERBAIKAN MOBILE ─────────────────────────────────────────────────────── */

/* iOS Safari melakukan zoom paksa saat fokus ke input dengan font < 16px —
   membuat halaman login "melompat" dan terasa rusak di HP. */
@media (pointer: coarse) {
  input.form-control, select.form-control, textarea.form-control { font-size: 16px; }
  .btn { min-height: 42px; }
}

/* Tinggi viewport dinamis: 100vh di HP kerap salah karena address-bar;
   dvh mengikuti tinggi nyata sehingga tombol login tidak terpotong. */
@supports (min-height: 100dvh) {
  .app-shell { min-height: 100dvh; }
  .main { min-height: 100dvh; }
  .login-page, .app-loading, .boot-fail { min-height: 100dvh; }
}

/* Menu yang disembunyikan oleh pembatasan role (mis. akun magang) */
.nav-item.is-scope-hidden, .nav-section.is-scope-hidden { display: none !important; }

/* ── PANEL GAGAL BOOT (anti layar putih) ─────────────────────────────────── */
.boot-fail {
  position: fixed; inset: 0; z-index: 95;
  display: none;
  align-items: center; justify-content: center;
  padding: 22px;
  background: linear-gradient(135deg, #0a1628, #0d3b3b);
}
.boot-fail.is-visible { display: flex; }
.boot-fail .bf-card {
  width: 100%; max-width: 380px;
  background: rgba(255,255,255,.06);
  border: 1px solid rgba(255,255,255,.14);
  border-radius: var(--radius-xl);
  padding: 28px 24px 22px;
  text-align: center; color: #e2e8f0;
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
}
.boot-fail .bf-icon {
  width: 54px; height: 54px; margin: 0 auto 14px;
  border-radius: var(--radius-lg); display: grid; place-items: center;
  background: rgba(251,191,36,.16); color: #fbbf24;
  border: 1px solid rgba(251,191,36,.4);
  font-weight: 800; font-size: 24px;
}
.boot-fail .bf-title { font-size: 16.5px; font-weight: 800; color: #fff; }
.boot-fail .bf-msg {
  font-size: 12.5px; color: rgba(226,232,240,.75);
  margin: 8px 0 16px; line-height: 1.55; overflow-wrap: anywhere;
}
.boot-fail .bf-btn {
  width: 100%; padding: 12px; border: none; border-radius: var(--radius-md);
  background: linear-gradient(135deg, var(--brand-500), var(--brand-600));
  color: #fff; font-weight: 700; font-size: 14px; font-family: inherit; cursor: pointer;
  box-shadow: 0 10px 24px rgba(20,184,166,.35);
}
.boot-fail .bf-btn:active { transform: translateY(1px); }
.boot-fail .bf-hint {
  margin-top: 14px; font-size: 11px; line-height: 1.6;
  color: rgba(226,232,240,.55);
}

/* ── MODE RINGAN PERANGKAT SENTUH (anti kedip & hemat GPU) ────────────────
   backdrop-filter di atas konten yang berubah-ubah adalah pemicu umum
   glitch/crash compositor pada WebView Android & Safari iOS lama.
   Di layar sentuh, efek kaca diganti latar semi-solid — beda visual tipis,
   beda beban render sangat besar. Efek hover juga tidak relevan di HP.   */
@media (pointer: coarse) {
  .modal-backdrop {
    backdrop-filter: none; -webkit-backdrop-filter: none;
    background: rgba(15,23,42,.62);
  }
  .boot-fail .bf-card {
    backdrop-filter: none; -webkit-backdrop-filter: none;
    background: rgba(13,24,41,.92);
  }
  .stat-card:hover { transform: none; box-shadow: var(--shadow-sm); }
  .btn-primary:hover:not(:disabled) { transform: none; filter: none; box-shadow: 0 2px 8px rgba(13,148,136,.3); }
}

/* ── TRANSISI HALUS & PROFESIONAL ─────────────────────────────────────────
   Prinsip: gerakan kecil (≤12px), durasi 250–400ms, kurva "ease-out-quint"
   agar terasa mahal tanpa memperlambat. Elemen daftar diberi stagger tipis. */
:root {
  --ease-smooth: cubic-bezier(.22, 1, .36, 1);   /* ease-out-quint */
  --ease-spring: cubic-bezier(.34, 1.4, .64, 1); /* sedikit pantul utk modal */
}

/* Pergantian halaman (view) — lebih lembut dari versi dasar */
.view.is-active { animation: viewInSmooth .38s var(--ease-smooth); }
@keyframes viewInSmooth {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* Pergantian tab panel — fade + geser tipis */
.tab-panel.is-active { animation: panelIn .32s var(--ease-smooth); }
@keyframes panelIn {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* Kartu statistik & kartu konten: entrance berjenjang halus */
.view.is-active .stat-card,
.tab-panel.is-active .stat-card { animation: cardIn .4s var(--ease-smooth) backwards; }
.view.is-active .stat-card:nth-child(1) { animation-delay: .02s; }
.view.is-active .stat-card:nth-child(2) { animation-delay: .06s; }
.view.is-active .stat-card:nth-child(3) { animation-delay: .10s; }
.view.is-active .stat-card:nth-child(4) { animation-delay: .14s; }
.view.is-active .stat-card:nth-child(5) { animation-delay: .18s; }
.view.is-active .stat-card:nth-child(6) { animation-delay: .22s; }
@keyframes cardIn {
  from { opacity: 0; transform: translateY(8px) scale(.985); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}

/* Baris tabel & item persetujuan: muncul lembut (bukan "menjeplak") */
.table tbody tr { animation: rowIn .28s var(--ease-smooth) backwards; }
.table tbody tr:nth-child(1)  { animation-delay: .015s; }
.table tbody tr:nth-child(2)  { animation-delay: .03s; }
.table tbody tr:nth-child(3)  { animation-delay: .045s; }
.table tbody tr:nth-child(4)  { animation-delay: .06s; }
.table tbody tr:nth-child(5)  { animation-delay: .075s; }
.table tbody tr:nth-child(6)  { animation-delay: .09s; }
.table tbody tr:nth-child(n+7){ animation-delay: .1s; }
@keyframes rowIn { from { opacity: 0; } to { opacity: 1; } }

.approval-item { animation: cardIn .34s var(--ease-smooth) backwards; }
.approval-item:nth-child(2) { animation-delay: .05s; }
.approval-item:nth-child(3) { animation-delay: .1s; }
.approval-item:nth-child(n+4) { animation-delay: .14s; }

/* Modal: kurva pegas tipis — terasa hidup namun tidak norak */
.modal { transition: transform .32s var(--ease-spring), opacity .22s var(--ease-smooth); }

/* Batang grafik tumbuh dari bawah saat panel dibuka */
.tab-panel.is-active .mini-chart .bar { animation: barGrow .5s var(--ease-smooth) backwards; }
@keyframes barGrow { from { transform: scaleY(.2); transform-origin: bottom; opacity: .4; } to { transform: scaleY(1); opacity: 1; } }

/* ── ANIMASI KEMUNCULAN DATA — PUSAT DATA & UTILITAS GENERIK (audit V6.6) ──
   Akar masalah regresi: dashboard V6.2 ("Pusat Data") memakai kelas generasi
   baru (pd-*) yang tidak tercakup selector animasi lama (.stat-card,
   .table tbody tr) sehingga data admin "menjeplak" tanpa transisi begitu
   skeleton diganti. Prinsip perbaikan JANGKA PANJANG:
   1) Node data di bawah ini DIBUAT ULANG oleh JS pada setiap render —
      animasi CSS pada elemen baru otomatis diputar ulang tanpa perlu JS,
      sama seperti mekanisme .stat-card yang sudah terbukti.
   2) Utilitas generik [data-anim] disediakan untuk komponen APA PUN di masa
      depan: cukup beri atribut pada kontainer, isinya muncul berjenjang —
      regresi serupa tidak perlu terulang dengan menulis animasi per kelas.
   Aturan global di bawah (pointer:coarse & prefers-reduced-motion) otomatis
   memangkas/mematikan seluruh gerakan ini. */

/* Denyut hari ini (chips) — muncul beruntun lembut */
#pdHariIni .pd-pill { animation: rowIn .3s var(--ease-smooth) backwards; }
#pdHariIni .pd-pill:nth-child(2) { animation-delay: .04s; }
#pdHariIni .pd-pill:nth-child(3) { animation-delay: .08s; }
#pdHariIni .pd-pill:nth-child(4) { animation-delay: .12s; }
#pdHariIni .pd-pill:nth-child(5) { animation-delay: .16s; }
#pdHariIni .pd-pill:nth-child(n+6) { animation-delay: .2s; }

/* Kartu KPI efektivitas — entrance berjenjang seperti .stat-card */
#pdKpi .pd-kpi { animation: cardIn .4s var(--ease-smooth) backwards; }
#pdKpi .pd-kpi:nth-child(2) { animation-delay: .06s; }
#pdKpi .pd-kpi:nth-child(3) { animation-delay: .12s; }
#pdKpi .pd-kpi:nth-child(4) { animation-delay: .18s; }

/* Grafik garis, donat, gauge, insight & legenda — konten dibuat ulang per render */
.pd-chart > *, #pdEfektif > *, .pd-donut-wrap > *,
.pd-gauges > *, #pdInsight > *, #pdTrenLegend > * {
  animation: rowIn .34s var(--ease-smooth) backwards;
}
.pd-gauges > :nth-child(2) { animation-delay: .06s; }
.pd-gauges > :nth-child(3) { animation-delay: .12s; }

/* Tabel Pusat Data (ringkasan modul & aktivitas terbaru) */
.pd-table tr { animation: rowIn .28s var(--ease-smooth) backwards; }
.pd-table tr:nth-child(2) { animation-delay: .03s; }
.pd-table tr:nth-child(3) { animation-delay: .06s; }
.pd-table tr:nth-child(4) { animation-delay: .09s; }
.pd-table tr:nth-child(5) { animation-delay: .12s; }
.pd-table tr:nth-child(n+6) { animation-delay: .14s; }

/* UTILITAS GENERIK — kontainer apa pun ber-atribut data-anim:
   anak-anaknya muncul berjenjang. Dipakai untuk komponen baru di masa depan. */
[data-anim] > * { animation: cardIn .36s var(--ease-smooth) backwards; }
[data-anim] > :nth-child(2) { animation-delay: .05s; }
[data-anim] > :nth-child(3) { animation-delay: .1s; }
[data-anim] > :nth-child(4) { animation-delay: .15s; }
[data-anim] > :nth-child(n+5) { animation-delay: .18s; }

/* Perangkat sentuh: pangkas stagger & gerakan agar hemat GPU (anti jank) */
@media (pointer: coarse) {
  .view.is-active .stat-card, .tab-panel.is-active .stat-card,
  .table tbody tr, .approval-item,
  #pdHariIni .pd-pill, #pdKpi .pd-kpi, .pd-table tr,
  .pd-chart > *, #pdEfektif > *, .pd-donut-wrap > *, .pd-gauges > *,
  #pdInsight > *, #pdTrenLegend > *,
  [data-anim] > * { animation-delay: 0s !important; animation-duration: .22s; }
  .view.is-active { animation-duration: .26s; }
  .tab-panel.is-active { animation-duration: .22s; }
}

/* Kurangi animasi bagi pengguna yang memintanya */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

/* ══ HALAMAN PENGATURAN & TOMBOL BANTUAN ══════════════════════════════════ */
.topbar-help-btn {
  width: 36px; height: 36px; border-radius: var(--radius-control); flex-shrink: 0;
  border: 1px solid var(--border); background: var(--surface, #fff);
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--slate-500, #64748b); cursor: pointer; margin-left: 10px;
  transition: color .15s, border-color .15s, transform .1s;
}
.topbar-help-btn:hover { color: var(--primary, #0d9488); border-color: var(--primary, #0d9488); }
.topbar-help-btn:active { transform: scale(.94); }

/* ══ TUR PANDUAN (TOUR GUIDE) ══════════════════════════════════════════════
   Sorotan memakai "spotlight" fixed dengan box-shadow raksasa — bebas dari
   masalah stacking context sidebar/kartu, aman untuk semua elemen. */
.tour-blocker { position: fixed; inset: 0; z-index: 9999; background: transparent; }
.tour-spot {
  position: fixed; z-index: 10000; border-radius: var(--radius-md); pointer-events: none;
  box-shadow: 0 0 0 9999px rgba(15, 23, 42, .55), 0 0 0 3px var(--primary, #0d9488);
  transition: top .28s ease, left .28s ease, width .28s ease, height .28s ease;
}
.tour-spot.tour-spot-center { box-shadow: 0 0 0 9999px rgba(15, 23, 42, .55); }
.tour-tip {
  position: fixed; z-index: 10001; width: min(350px, calc(100vw - 28px));
  background: var(--surface, #fff); border: 1px solid var(--border, #e2e8f0);
  border-radius: var(--radius-lg); padding: 16px 18px;
  box-shadow: 0 18px 50px rgba(2, 6, 23, .35);
}
.tour-tip-step {
  font-size: 10.5px; font-weight: 800; letter-spacing: .6px; text-transform: uppercase;
  color: var(--primary, #0d9488); margin-bottom: 3px;
}
.tour-tip-title { font-size: 15px; font-weight: 800; color: var(--text-primary, #0f172a); margin-bottom: 6px; }
.tour-tip-body  { font-size: 13px; line-height: 1.6; color: var(--slate-600, #475569); }
.tour-tip-body b { color: var(--text-primary, #0f172a); }
.tour-tip-actions { display: flex; gap: 8px; align-items: center; margin-top: 14px; }
.tour-tip-skip {
  margin-right: auto; background: none; border: none; cursor: pointer;
  font-size: 12px; color: var(--slate-400, #94a3b8); padding: 6px 2px;
}
.tour-tip-skip:hover { color: var(--danger, #dc2626); text-decoration: underline; }
.tour-btn {
  border-radius: var(--radius-control); padding: 7px 14px; font-size: 12.5px; font-weight: 700; cursor: pointer;
  border: 1px solid var(--border, #e2e8f0); background: var(--surface, #fff); color: var(--slate-600, #475569);
}
.tour-btn:disabled { opacity: .4; cursor: default; }
.tour-btn-primary { background: var(--primary, #0d9488); border-color: var(--primary, #0d9488); color: #fff; }
.tour-btn-primary:hover { filter: brightness(1.06); }

/* V6.7 — MODE HP: kartu menjadi BOTTOM SHEET (kelas .is-sheet dipasang JS).
   Selalu di jangkauan jempol, tidak pernah menutupi elemen yang disorot di
   posisi acak, dan isi panjang bisa digulir di dalam kartu. */
.tour-tip.is-sheet {
  top: auto !important; left: 10px !important; right: 10px; width: auto !important;
  bottom: calc(10px + env(safe-area-inset-bottom, 0px));
  border-radius: 18px;
  box-shadow: 0 -8px 40px rgba(2, 6, 23, .38), 0 18px 50px rgba(2, 6, 23, .3);
}
.tour-tip.is-sheet::before {
  content: ''; display: block; width: 40px; height: 4px; border-radius: var(--radius-full);
  background: var(--slate-200, #e2e8f0); margin: -4px auto 10px;
}
.tour-tip.is-sheet .tour-tip-body {
  max-height: 32vh; overflow-y: auto; -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain; padding-right: 2px;
}
.tour-tip.is-sheet .tour-tip-actions { margin-top: 12px; }
.tour-tip.is-sheet .tour-btn { padding: 10px 14px; min-height: 40px; }
@media (max-width: 640px) {
  .tour-tip { left: 14px; right: 14px; width: auto; }
}

/* ══ RENDER FOTO INLINE (thumbnail ringan + avatar) ═══════════════════════ */
.foto-thumb-wrap {
  display: inline-flex; padding: 0; border: none; background: none; cursor: zoom-in;
  border-radius: var(--radius-control); overflow: hidden; line-height: 0;
}
.foto-thumb {
  width: 44px; height: 44px; object-fit: cover; display: block;
  border-radius: var(--radius-control); border: 1px solid var(--border, #e2e8f0);
  background: var(--slate-100, #f1f5f9);
  transition: transform .15s ease, box-shadow .15s ease;
}
.foto-thumb-wrap:hover .foto-thumb {
  transform: scale(1.06);
  box-shadow: 0 3px 10px rgba(2, 6, 23, .22);
}
.avatar-foto {
  display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0;
  border-radius: 50%; overflow: hidden; border: 1px solid var(--border, #e2e8f0);
  background: var(--slate-100, #f1f5f9);
}
.avatar-foto img { width: 100%; height: 100%; object-fit: cover; display: block; }
.avatar-inisial {
  font-size: 12.5px; font-weight: 800; color: var(--primary, #0d9488);
  background: #e0f2fe; /* fallback */
  background: color-mix(in srgb, var(--primary, #0d9488) 12%, #fff);
  letter-spacing: .3px;
}

/* ── 24. PUSAT DATA (pd-*) — V6.4: kelas GLOBAL, dipakai lintas halaman ── */
    .pd-gap{margin-bottom:16px}
    .pd-pulse{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:14px}
    .pd-pill{display:inline-flex;align-items:center;gap:8px;font-size:12px;font-weight:600;
      padding:7px 13px;border-radius:var(--radius-full);background:var(--surface,#fff);
      border:1px solid var(--slate-200,#e2e8f0);color:var(--text-secondary,#64748b)}
    .pd-pill b{color:var(--text-primary,#0f172a);font-size:13px;font-variant-numeric:tabular-nums}
    .pd-pill .pd-dot{width:8px;height:8px;border-radius:50%;background:var(--brand-500,#14b8a6);flex:none}
    .pd-pill.warn .pd-dot{background:var(--warning)}
    .pd-pill.danger .pd-dot{background:var(--danger)}

    .pd-kpi-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(215px,1fr));gap:14px;margin-bottom:16px}
    .pd-kpi{position:relative;overflow:hidden;background:var(--surface,#fff);
      border:1px solid var(--slate-200,#e2e8f0);border-radius:var(--radius-lg);padding:15px 17px 14px 20px}
    .pd-kpi::before{content:'';position:absolute;top:0;left:0;bottom:0;width:4px;background:var(--pd-accent,#14b8a6)}
    .pd-kpi-top{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-bottom:9px}
    .pd-kpi-label{font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.7px;color:var(--text-secondary,#64748b)}
    .pd-kpi-ic{width:32px;height:32px;border-radius:var(--radius-control);display:grid;place-items:center;flex:none;
      background:#f0fdfa;/* fallback WebView lama */
      background:color-mix(in srgb,var(--pd-accent,#14b8a6) 12%,#fff);color:var(--pd-accent,#14b8a6)}
    .pd-kpi-ic svg{width:16px;height:16px}
    .pd-kpi-val{font-size:26px;font-weight:800;letter-spacing:-.4px;line-height:1.1;
      color:var(--text-primary,#0f172a);font-variant-numeric:tabular-nums}
    .pd-kpi-val small{font-size:13px;font-weight:700;color:var(--text-secondary,#64748b);margin-left:3px}
    .pd-kpi-foot{display:flex;align-items:center;gap:8px;margin-top:9px;flex-wrap:wrap}
    .pd-kpi-sub{font-size:11.5px;color:var(--text-secondary,#64748b)}
    .pd-delta{display:inline-flex;align-items:center;gap:3px;font-size:11.5px;font-weight:800;
      padding:3px 9px;border-radius:var(--radius-full);font-variant-numeric:tabular-nums;white-space:nowrap}
    .pd-delta.good{background:#dcfce7;color:#15803d}
    .pd-delta.bad{background:#fee2e2;color:#b91c1c}
    .pd-delta.flat{background:var(--slate-100,#f1f5f9);color:var(--text-secondary,#64748b)}

    .pd-chart svg{width:100%;height:auto;display:block}
    .pd-chart-title{font-size:11.5px;font-weight:700;color:var(--text-secondary,#64748b);margin:4px 0 2px}
    .pd-legend{display:flex;gap:12px;flex-wrap:wrap;font-size:11.5px;color:var(--text-secondary,#64748b)}
    .pd-legend .lg{display:inline-flex;align-items:center;gap:6px;font-weight:600}
    .pd-legend .sw{width:10px;height:10px;border-radius:3px;flex:none}

    .pd-donut-wrap{display:flex;align-items:center;gap:20px;flex-wrap:wrap}
    .pd-donut-wrap svg{flex:none}
    .pd-dlegend{flex:1;min-width:160px;display:flex;flex-direction:column;gap:8px}
    .pd-dlegend .row{display:flex;align-items:center;gap:8px;font-size:12.5px}
    .pd-dlegend .sw{width:10px;height:10px;border-radius:3px;flex:none}
    .pd-dlegend .lb{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--text-secondary,#64748b)}
    .pd-dlegend .vl{font-weight:700;font-variant-numeric:tabular-nums;color:var(--text-primary,#0f172a)}
    .pd-dlegend .pc{font-size:11px;color:var(--text-secondary,#94a3b8);font-variant-numeric:tabular-nums;min-width:34px;text-align:right}

    .pd-gauges{display:flex;flex-direction:column;gap:13px;margin-top:16px}
    .pd-gauge .top{display:flex;justify-content:space-between;align-items:baseline;gap:10px;font-size:12px;
      color:var(--text-secondary,#64748b);margin-bottom:5px}
    .pd-gauge .top b{color:var(--text-primary,#0f172a);font-variant-numeric:tabular-nums}
    .pd-track{height:8px;border-radius:var(--radius-full);background:var(--slate-100,#f1f5f9);overflow:hidden;display:flex}
    .pd-fill{height:100%;border-radius:var(--radius-full);background:var(--brand-500,#14b8a6);transition:width .6s ease}
    .pd-fill.warn{background:var(--warning)}
    .pd-fill.danger{background:var(--danger)}
    .pd-fill.seg{border-radius:0}

    .pd-table{width:100%;border-collapse:collapse;font-size:12.5px}
    .pd-table th{position:sticky;top:0;text-align:left;font-size:10.5px;font-weight:700;text-transform:uppercase;
      letter-spacing:.6px;color:var(--text-secondary,#64748b);padding:10px 16px;white-space:nowrap;
      background:var(--slate-50,#f8fafc);border-bottom:1px solid var(--slate-200,#e2e8f0)}
    .pd-table td{padding:9px 16px;border-bottom:1px solid var(--slate-100,#f1f5f9);vertical-align:middle;
      color:var(--text-primary,#0f172a)}
    .pd-table tr:last-child td{border-bottom:none}
    .pd-table .num{text-align:right;font-variant-numeric:tabular-nums;font-weight:600}
    .pd-table .mut{color:var(--text-secondary,#64748b)}
    .pd-table tr.pd-total td{font-weight:800;background:var(--slate-50,#f8fafc)}
    .pd-minibar{position:relative;height:6px;border-radius:var(--radius-full);background:var(--slate-100,#f1f5f9);min-width:64px}
    .pd-minibar i{position:absolute;top:0;left:0;bottom:0;border-radius:var(--radius-full);
      background:linear-gradient(90deg,#0d9488,#2dd4bf)}
    .pd-table-scroll{overflow-x:auto}

    .pd-insight{display:flex;gap:11px;padding:10px 2px;border-bottom:1px dashed var(--slate-200,#e2e8f0);
      font-size:13px;line-height:1.55;color:var(--text-primary,#0f172a)}
    .pd-insight:last-child{border-bottom:none}
    .pd-insight .ic{width:30px;height:30px;flex:none;border-radius:var(--radius-control);display:grid;place-items:center}
    .pd-insight .ic svg{width:15px;height:15px}
    .pd-insight.pos .ic{background:#dcfce7;color:#15803d}
    .pd-insight.neg .ic{background:#fee2e2;color:#b91c1c}
    .pd-insight.net .ic{background:var(--brand-50,#f0fdfa);color:var(--brand-600,#0d9488)}

    .pd-footnote{font-size:11.5px;color:var(--text-secondary,#94a3b8);margin-top:10px}
    .pd-empty{padding:26px 12px;text-align:center;color:var(--text-secondary,#64748b);font-size:13px}
    .pd-error{padding:22px;border:1px dashed #fca5a5;background:#fef2f2;color:#b91c1c;border-radius:var(--radius-lg);
      font-size:13px;line-height:1.6;margin-bottom:16px}
    .pd-skel-card{background:var(--surface,#fff);border:1px solid var(--slate-200,#e2e8f0);border-radius:var(--radius-lg);padding:16px}
    @media(max-width:760px){
      .pd-kpi-grid{grid-template-columns:repeat(auto-fit,minmax(158px,1fr))}
      .pd-kpi-val{font-size:22px}
      .pd-donut-wrap{justify-content:center}
    }

/* ════════════════════════════════════════════════════════════════════════════
   TOPBAR INFORMATIF (V6.7)
   Topbar tidak lagi menduplikasi judul + subjudul halaman (yang sudah tampil
   sebagai header di badan halaman). Slot kiri kini menampilkan tanggal + jam;
   saat halaman digulir dan header halaman keluar layar, slot berganti mulus
   menjadi judul halaman aktif (kelas .is-scrolled dari modul Topbar).
   ════════════════════════════════════════════════════════════════════════════ */
.topbar-context {
  position: relative;
  flex: 1;
  min-width: 0;
  height: 40px;
  display: flex;
  align-items: center;
}
.topbar-context .topbar-now,
.topbar-context .topbar-page {
  position: absolute; inset: 0;
  display: flex; align-items: center; gap: 10px;
  min-width: 0;
  transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.topbar-date {
  font-size: 13.5px; font-weight: 600; color: var(--slate-700);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.topbar-now .topbar-clock { margin: 0; } /* jam menempel di samping tanggal */
.topbar-page {
  opacity: 0; transform: translateY(7px); pointer-events: none;
  font-size: 15px; font-weight: 700; letter-spacing: -.1px;
}
.topbar-page .topbar-page-hint {
  font-size: 10.5px; font-weight: 700; letter-spacing: .6px;
  text-transform: uppercase; color: var(--text-muted); flex: none;
}
.topbar-page #topbarPageTitle {
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.topbar.is-scrolled .topbar-now  { opacity: 0; transform: translateY(-7px); pointer-events: none; }
.topbar.is-scrolled .topbar-page { opacity: 1; transform: none; }

/* Chip persetujuan menunggu — hanya kabag/admin (data-approver), klik = ke
   Pusat Persetujuan. Disembunyikan otomatis bila hitungan 0. */
.topbar-approval-chip {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 6px 12px;
  border-radius: var(--radius-full);
  border: 1px solid var(--warning-bd);
  background: var(--warning-bg);
  color: var(--warning);
  font-size: 12.5px; font-weight: 700;
  white-space: nowrap;
  transition: box-shadow var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.topbar-approval-chip:hover { box-shadow: var(--shadow-sm); transform: translateY(-1px); }
.topbar-approval-chip svg { width: 15px; height: 15px; }
.topbar-approval-chip .chip-count {
  min-width: 19px; height: 19px; padding: 0 5px;
  border-radius: var(--radius-full);
  background: var(--warning); color: #fff;
  display: grid; place-items: center;
  font-size: 11px; font-variant-numeric: tabular-nums;
}
.topbar-approval-chip .chip-label { font-weight: 600; }

@media (max-width: 768px) {
  /* Di HP: tanggal tetap tampil (jam sudah disembunyikan aturan lama);
     label chip dipadatkan menjadi angka saja agar muat. */
  .topbar-approval-chip .chip-label { display: none; }
  .topbar-date { font-size: 12.5px; }
  .topbar-page { font-size: 14px; }
}

/* ════════════════════════════════════════════════════════════════════════════
   25. V7.9 — MODERNISASI TAMPILAN "FOKUS BRAND"
   Menggantikan seluruh bagian V7.8: palet aneka warna per-halaman DIHAPUS.
   Prinsip warna kini SATU: keluarga brand BPJS (teal → hijau) untuk seluruh
   hiasan; warna lain HANYA muncul bila membawa makna status (kuning=menunggu,
   merah=masalah/destruktif, hijau=beres) — konsisten dengan badge & gauge lama.
   Isi:
   25.1 Nuansa kerangka: pendar teal halus latar & sidebar, topbar kaca
        (desktop), garis aksen judul halaman.
   25.2 Kartu, tab & ikon: chip ikon brand, tab aktif bertinta brand.
   25.3 KPI & statistik: cuci gradasi + SOROTAN KURSOR (pasangan JS Scripts_1).
   25.4 Grafik: batang berkilau, donat interaktif, meter bergradasi + kilau.
   25.5 ANTI-"EXCEL": semua tabel modul menjadi BARIS KAPSUL mengambang —
        tanpa garis grid, tiap baris kartu tipis membulat yang menyorot lembut.
   25.6 LINIMASA AKTIVITAS (.pd-feed): pengganti tabel log aktivitas.
   25.7 Panel & papan informasi: strip identitas bernuansa brand, sel fakta
        rapi; papan pimpinan tetap berwarna per STATUS (semantik).
   25.8 Pengaman layar sentuh & preferensi gerak minim.
   Setiap color-mix() SELALU didahului fallback polos (pola audit V6.x).
   ════════════════════════════════════════════════════════════════════════════ */

/* ── 25.1 NUANSA KERANGKA ────────────────────────────────────────────────── */
body {
  background:
    radial-gradient(880px 420px at 8% -80px,  rgba(45, 212, 191, .15), transparent 62%),
    radial-gradient(760px 380px at 94% -70px, rgba(22, 163, 74, .07),  transparent 60%),
    var(--bg-app);
}
.sidebar {
  background:
    radial-gradient(460px 300px at -15% -6%, rgba(20, 184, 166, .28), transparent 62%),
    radial-gradient(360px 240px at 118% 4%,  rgba(16, 185, 129, .12), transparent 60%),
    linear-gradient(180deg, #0c1a2b, #0b1626 55%, #0d2130);
}
.nav-item { position: relative; }
.nav-item.is-active {
  background: var(--bg-sidebar-active);
  background: linear-gradient(90deg, rgba(20, 184, 166, .24), rgba(20, 184, 166, .07));
}
.nav-item.is-active::before {
  content: '';
  position: absolute; left: 0; top: 7px; bottom: 7px; width: 3px;
  border-radius: var(--radius-full);
  background: linear-gradient(180deg, var(--brand-300), var(--brand-500));
}
.nav-item .nav-badge { background: rgba(20, 184, 166, .2); color: var(--brand-200); }
/* Garis rambut brand di dasar topbar — teal memudar, bukan pelangi */
.topbar::after {
  content: '';
  position: absolute; left: 0; right: 0; bottom: -1px; height: 2px;
  background: linear-gradient(90deg, var(--brand-500), var(--brand-300) 45%, transparent 85%);
  opacity: .6;
  pointer-events: none;
}
/* Topbar kaca — hanya perangkat berkursor presisi (desktop); HP tetap solid */
@media (pointer: fine) {
  .topbar {
    background: rgba(255, 255, 255, .84);
    backdrop-filter: saturate(1.35) blur(10px);
    -webkit-backdrop-filter: saturate(1.35) blur(10px);
  }
}
/* Garis aksen pendek di bawah judul halaman */
.page-title::after {
  content: '';
  display: block;
  width: 46px; height: 4px;
  margin-top: 7px;
  border-radius: var(--radius-full);
  background: linear-gradient(90deg, var(--brand-500), var(--brand-200));
}

/* ── 25.2 KARTU, TAB & IKON ──────────────────────────────────────────────── */
.card-header { background: linear-gradient(180deg, var(--slate-50), rgba(248, 250, 252, 0)); }
.card-title .card-icon {
  width: 27px; height: 27px; padding: 5.5px;
  border-radius: var(--radius-sm);
  color: var(--brand-600);
  background: var(--brand-50);
  background: linear-gradient(135deg, var(--brand-50), var(--brand-100));
  box-shadow: inset 0 0 0 1px rgba(20, 184, 166, .16);
}
/* (gaya tab berpindah ke §25.10 — TAB SEGMENTED ramah mobile) */

/* ── 25.3 KARTU KPI & STATISTIK + SOROTAN KURSOR ─────────────────────────── */
.stat-card {
  background: #fff;
  background: linear-gradient(150deg,
    color-mix(in srgb, var(--stat-accent, var(--brand-500)) 8%, #fff), #fff 56%);
}
.stat-card::before {
  background: var(--stat-accent, var(--brand-500));
  background: linear-gradient(180deg, var(--stat-accent, var(--brand-500)),
    color-mix(in srgb, var(--stat-accent, var(--brand-500)) 40%, #fff));
}
.stat-card .stat-value {
  color: color-mix(in srgb, var(--stat-accent, var(--brand-700)) 55%, var(--slate-900));
}
/* Aksen dekoratif lama yang berwarna-warni DIPETAKAN ULANG ke keluarga brand;
   amber/hijau/rose DIBIARKAN karena menyandang makna status di markup. */
.stat-blue   { --stat-accent: #0e7490; }
.stat-violet { --stat-accent: #0f766e; }
.pd-kpi {
  background: #fff;
  background: linear-gradient(150deg,
    color-mix(in srgb, var(--pd-accent, #14b8a6) 9%, #fff), #fff 58%);
}
.pd-kpi::before {
  background: var(--pd-accent, #14b8a6);
  background: linear-gradient(180deg, var(--pd-accent, #14b8a6),
    color-mix(in srgb, var(--pd-accent, #14b8a6) 38%, #fff));
}
.pd-kpi-val { color: color-mix(in srgb, var(--pd-accent, #0f766e) 50%, var(--slate-900)); }
/* Sorotan mengikuti kursor (nilai --mx/--my dipasok runtime kecil Scripts_1) */
@media (pointer: fine) {
  .pd-kpi:hover {
    background:
      radial-gradient(230px 230px at var(--mx, 50%) var(--my, 50%),
        rgba(20, 184, 166, .13), transparent 72%),
      linear-gradient(150deg,
        color-mix(in srgb, var(--pd-accent, #14b8a6) 9%, #fff), #fff 58%);
  }
  .stat-card:hover {
    background:
      radial-gradient(230px 230px at var(--mx, 50%) var(--my, 50%),
        rgba(20, 184, 166, .13), transparent 72%),
      linear-gradient(150deg,
        color-mix(in srgb, var(--stat-accent, var(--brand-500)) 8%, #fff), #fff 56%);
  }
}
/* Pil denyut hari ini: netral tetap putih; warn/danger bertinta (semantik) */
.pd-pill .pd-dot { box-shadow: 0 0 0 3px rgba(20, 184, 166, .16); }
.pd-pill.warn   { background: var(--warning-bg); border-color: var(--warning-bd); color: #92400e; }
.pd-pill.warn .pd-dot   { box-shadow: 0 0 0 3px rgba(217, 119, 6, .16); }
.pd-pill.danger { background: var(--danger-bg);  border-color: var(--danger-bd);  color: #991b1b; }
.pd-pill.danger .pd-dot { box-shadow: 0 0 0 3px rgba(220, 38, 38, .15); }

/* ── 25.4 GRAFIK: BATANG, DONAT & METER ──────────────────────────────────── */
/* V7.10: batang = TABUNG 3D — gradasi horizontal memberi lengkung silinder,
   tutup elips di puncak memberi kedalaman, bayangan bawah mengangkatnya. */
.mini-chart .bar {
  max-width: 44px;
  border-radius: 7px 7px 3px 3px;
  background: linear-gradient(90deg, var(--brand-200) 0%, var(--brand-400) 38%, var(--brand-700) 100%);
  box-shadow:
    inset 0 -3px 5px rgba(15, 23, 42, .16),
    inset 0 2px 2px rgba(255, 255, 255, .35),
    0 4px 10px -3px rgba(13, 148, 136, .4);
}
.mini-chart .bar::before {
  content: '';
  position: absolute; left: 0; right: 0; top: -3px; height: 7px;
  border-radius: 50%;
  background: linear-gradient(90deg, var(--brand-100), var(--brand-300) 55%, var(--brand-500));
  box-shadow: inset 0 1px 2px rgba(255, 255, 255, .65);
  pointer-events: none;
}
.mini-chart .bar::after {
  content: '';
  position: absolute; inset: 2px auto 0 9%; width: 16%;
  border-radius: var(--radius-full);
  background: linear-gradient(180deg, rgba(255, 255, 255, .5), rgba(255, 255, 255, 0) 80%);
  pointer-events: none;
}
.mini-chart .bar:hover { filter: saturate(1.12) brightness(1.05); }
/* Donat (pasangan mesin grafik Scripts_1): segmen lain meredup, sorotan menebal */
.pd-donut .pd-seg { transition: opacity .18s var(--ease), stroke-width .18s var(--ease); }
.pd-donut:has(.pd-seg:hover) .pd-seg { opacity: .38; }
.pd-donut .pd-seg:hover { opacity: 1; stroke-width: calc(var(--sw, 21px) + 3px); }
.pd-dlegend { gap: 4px; }
.pd-dlegend .row {
  position: relative;
  padding: 5px 8px 10px;
  border-radius: var(--radius-sm);
  transition: background .15s var(--ease);
}
.pd-dlegend .row:hover { background: var(--slate-50); }
.pd-dlegend .sw { border-radius: 4px; box-shadow: inset 0 0 0 1px rgba(15, 23, 42, .08); }
.pd-dlegend .meter {
  position: absolute; left: 8px; right: 8px; bottom: 4px; height: 3px;
  border-radius: var(--radius-full);
  background: var(--slate-100);
  overflow: hidden;
}
.pd-dlegend .meter i { display: block; height: 100%; border-radius: var(--radius-full); }
/* Meter/gauge: gradasi + KILAU yang menyapu perlahan (futuristik, transform-only) */
.pd-fill, .progress-bar { position: relative; overflow: hidden; }
.pd-fill            { background: linear-gradient(90deg, var(--brand-400), var(--brand-600)); }
.pd-fill.warn       { background: linear-gradient(90deg, #fbbf24, #d97706); }
.pd-fill.danger     { background: linear-gradient(90deg, #f87171, #dc2626); }
.progress-bar            { background: linear-gradient(90deg, var(--brand-400), var(--brand-600)); }
.progress-bar.is-warning { background: linear-gradient(90deg, #fbbf24, #d97706); }
.progress-bar.is-danger  { background: linear-gradient(90deg, #f87171, #dc2626); }
.pd-fill::after, .progress-bar::after {
  content: '';
  position: absolute; inset: 0;
  background: linear-gradient(105deg, transparent 32%, rgba(255, 255, 255, .5) 50%, transparent 68%);
  transform: translateX(-100%);
  animation: kilauGeser 3s ease-in-out infinite;
}
@keyframes kilauGeser { 55%, 100% { transform: translateX(100%); } }
.pd-track { background: var(--slate-100); box-shadow: inset 0 1px 2px rgba(15, 23, 42, .05); }
.pd-empty {
  border: 1px dashed var(--slate-200);
  border-radius: var(--radius-md);
  background: linear-gradient(180deg, var(--slate-50), #fff);
}
td > .pd-empty { border: none; background: none; }

/* ── 25.5 ANTI-"EXCEL": TABEL BARIS KAPSUL ───────────────────────────────────
   Berlaku ke SEMUA tabel modul (.table) & Pusat Data (.pd-table): garis grid
   dihapus, tiap baris menjadi kapsul membulat berjarak yang terangkat lembut
   saat hover — data tetap sejajar rapi (kolom tabel dipertahankan), tetapi
   tampilannya daftar modern, bukan lembar kerja. */
.table, .pd-table { border-collapse: separate; border-spacing: 0 8px; }
.table thead th {
  background: transparent;
  border-bottom: none;
  padding: 0 16px 0;
  color: var(--slate-400);
}
.pd-table th { background: var(--bg-surface); border-bottom: none; }
.table tbody td, .pd-table td {
  background: var(--bg-surface);
  border-top: 1px solid var(--slate-200);
  border-bottom: 1px solid var(--slate-200) !important; /* kalahkan aturan lama tr:last-child */
  transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.table tbody td:first-child, .pd-table td:first-child {
  border-left: 1px solid var(--slate-200);
  border-radius: var(--radius-md) 0 0 var(--radius-md);
}
.table tbody td:last-child, .pd-table td:last-child {
  border-right: 1px solid var(--slate-200);
  border-radius: 0 var(--radius-md) var(--radius-md) 0;
}
.table tbody tr:hover { background: transparent; } /* sorot pindah ke sel */
.table tbody tr:hover td,
.pd-table tr:not(.pd-total):hover td {
  background: var(--brand-50);
  background: color-mix(in srgb, var(--brand-500) 6%, #fff);
  border-color: var(--brand-300);
}
.pd-table tr.pd-total td { background: var(--slate-50); font-weight: 800; }
.table-wrap { border-radius: 0 0 var(--radius-lg) var(--radius-lg); padding: 0 12px; }
.card-body.flush .pd-table-scroll { padding: 0 12px; }

/* ── 25.6 LINIMASA AKTIVITAS (.pd-feed) ──────────────────────────────────── */
.pd-feed { padding: 8px 14px 10px; }
.feed-item { position: relative; display: flex; gap: 12px; }
.feed-rail { position: relative; width: 14px; flex: none; display: flex; justify-content: center; }
.feed-rail::before {
  content: '';
  position: absolute; top: 6px; bottom: -6px; width: 2px;
  border-radius: var(--radius-full);
  background: linear-gradient(180deg, var(--slate-200), var(--slate-100));
}
.feed-item:last-child .feed-rail::before { display: none; }
.feed-dot {
  position: relative; z-index: 1;
  width: 10px; height: 10px; margin-top: 8px;
  border-radius: 50%;
  color: var(--brand-500);
  background: currentColor;
  box-shadow: 0 0 0 3px var(--bg-surface), 0 0 0 4.5px var(--brand-100);
  box-shadow: 0 0 0 3px var(--bg-surface),
    0 0 0 4.5px color-mix(in srgb, currentColor 30%, #fff);
}
.feed-item.is-new .feed-dot { color: var(--brand-500); }
.feed-item.is-upd .feed-dot { color: #0e7490; }
.feed-item.is-ok  .feed-dot { color: var(--success); }
.feed-item.is-del .feed-dot { color: var(--danger); }
.feed-item.is-sys .feed-dot { color: var(--slate-400); }
.feed-body {
  flex: 1; min-width: 0;
  margin-bottom: 3px;
  padding: 6px 12px 9px;
  border-radius: var(--radius-md);
  border: 1px solid transparent;
  transition: background .15s var(--ease), border-color .15s var(--ease);
}
.feed-item:hover .feed-body {
  background: var(--brand-50);
  background: color-mix(in srgb, var(--brand-500) 5%, #fff);
  border-color: var(--brand-100);
}
.feed-head { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; font-size: 12.5px; }
.feed-user { font-weight: 700; color: var(--text-primary); }
.feed-mod {
  font-size: 9.5px; font-weight: 800; letter-spacing: .5px; text-transform: uppercase;
  padding: 1px 7px;
  border-radius: var(--radius-full);
  background: var(--brand-50); color: var(--brand-700);
  border: 1px solid var(--brand-100);
  white-space: nowrap;
}
.feed-time {
  margin-left: auto;
  font-size: 11px; color: var(--text-muted);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.feed-text { font-size: 12.5px; color: var(--text-secondary); margin-top: 2px; overflow-wrap: anywhere; }
.feed-text a { font-weight: 600; }
.feed-sub { font-size: 11px; color: var(--text-muted); margin-top: 3px; }
.feed-err {
  font-size: 11.5px; color: var(--danger);
  background: var(--danger-bg);
  border: 1px solid var(--danger-bd);
  border-radius: var(--radius-sm);
  padding: 5px 9px; margin-top: 6px;
  overflow-wrap: anywhere;
}
.feed-act { margin-top: 7px; }
.feed-head .badge { font-size: 10px; padding: 2px 8px; }

/* ── 25.7 PANEL & PAPAN INFORMASI ────────────────────────────────────────── */
.info-strip {
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  background:
    radial-gradient(340px 130px at 0% 0%, rgba(20, 184, 166, .12), transparent 72%),
    linear-gradient(180deg, var(--brand-50), #fff);
}
.info-strip .info-avatar,
.info-strip .user-avatar { box-shadow: 0 0 0 3px #fff, 0 0 0 5px var(--brand-200); }
/* Sel fakta kunci: rapikan (dulu latar garis induk tembus) — bersih & tenang,
   satu palang brand tipis; TANPA rotasi warna. */
.info-grid > .info-item {
  background: var(--slate-50);
  background: linear-gradient(180deg, #fff, var(--slate-50));
  padding: 9px 12px;
  border-left: 3px solid var(--brand-300);
}
.info-grid.standalone { overflow: hidden; }
/* Papan pimpinan: warna kartu mengikuti STATUS (makna, bukan hiasan);
   progressive enhancement :has() — browser lama tampil netral seperti semula */
.ket-card { border-left: 4px solid var(--slate-200); }
.ket-card:has(.st-kantor)   { border-left-color: var(--success); background: linear-gradient(90deg, var(--success-bg), #fff 46%); }
.ket-card:has(.st-kegiatan) { border-left-color: var(--info);    background: linear-gradient(90deg, var(--info-bg),    #fff 46%); }
.ket-card:has(.st-luar)     { border-left-color: var(--warning); background: linear-gradient(90deg, var(--warning-bg), #fff 46%); }
.ket-card:has(.st-cuti)     { border-left-color: var(--slate-400); }
.ket-card:has(.st-absen)    { border-left-color: var(--danger);  background: linear-gradient(90deg, var(--danger-bg),  #fff 46%); }
.brief-time {
  min-width: 0;
  padding: 2px 9px;
  border-radius: var(--radius-full);
  background: var(--brand-50);
  color: var(--brand-700);
}
.brief-sec-title svg {
  width: 22px; height: 22px; padding: 4.5px;
  border-radius: 7px;
  background: var(--brand-50);
  box-shadow: inset 0 0 0 1px rgba(20, 184, 166, .18);
}

/* ── 25.9 EFEK KEDALAMAN 3D ──────────────────────────────────────────────────
   Bahasa kedalaman satu keluarga: tepi kaca terang di puncak elemen, bayangan
   ambient bernada brand, dan (khusus desktop) KEMIRINGAN PERSPEKTIF kartu
   KPI/statistik mengikuti kursor (nilai --rx/--ry dipasok runtime Scripts_1).
   Semuanya transform/box-shadow — tanpa filter berat, aman WebView. */
/* Tepi kaca + bayangan berlapis pada permukaan utama */
.card, .stat-card, .pd-kpi, .pd-skel-card {
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .65),
    0 1px 2px rgba(15, 23, 42, .05),
    0 10px 26px -14px rgba(13, 148, 136, .2);
}
.modal {
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .6),
    var(--shadow-lg),
    0 24px 60px -24px rgba(13, 148, 136, .3);
}
/* Kemiringan perspektif kartu (desktop) — sudut dipasok runtime; saat kursor
   keluar, variabel dihapus → kartu kembali datar dengan transisi halus */
@media (pointer: fine) {
  .pd-kpi, .stat-card {
    transition: transform .18s var(--ease), box-shadow .22s var(--ease);
  }
  .pd-kpi:hover, .stat-card:hover {
    transform: perspective(760px) rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg)) translateY(-2px);
    box-shadow:
      inset 0 1px 0 rgba(255, 255, 255, .7),
      0 4px 10px rgba(15, 23, 42, .07),
      0 18px 38px -14px rgba(13, 148, 136, .32);
    will-change: transform;
  }
}
/* Donat melayang — bayangan kedalaman satu kali render, ringan */
.pd-donut { filter: drop-shadow(0 4px 6px rgba(15, 23, 42, .12)); }
/* Titik linimasa berbentuk bola (kilau sudut kiri-atas) */
.feed-dot {
  background: radial-gradient(circle at 32% 28%, rgba(255, 255, 255, .85), currentColor 68%);
}
/* Tombol utama: bevel kaca + efek DITEKAN saat aktif */
.btn-primary {
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .3), 0 2px 8px rgba(13, 148, 136, .3);
}
.btn-primary:active:not(:disabled) {
  transform: translateY(1px);
  box-shadow: inset 0 2px 5px rgba(0, 0, 0, .2);
  filter: brightness(.97);
}
/* Isi meter/gauge: permukaan cembung (sorot atas + bayang bawah) */
.pd-fill, .progress-bar {
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .4), inset 0 -1px 2px rgba(15, 23, 42, .18);
}
/* Lambang & avatar: sorot puncak agar tampak timbul */
.sidebar-brand .brand-mark, .user-avatar {
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .35), 0 3px 9px rgba(13, 148, 136, .32);
}

/* ── 25.10 TAB SEGMENTED — RAMAH MOBILE (& turunannya) ──────────────────────
   Tab garis-bawah lama menyulitkan di HP: target sentuh kecil, dan gulir
   horizontalnya tak terlihat sehingga tab di ujung "hilang". Kini:
   • TRACK kapsul dengan tab berbentuk PIL — tab aktif terisi gradasi brand
     (bevel 3D selaras §25.9), target sentuh min. 40px di HP;
   • BAYANGAN TEPI sebagai isyarat "masih ada tab di kanan/kiri" — trik
     background-attachment: penutup ber-attachment LOCAL ikut tergulir
     menutup bayangan (SCROLL) saat gulir sudah mentok di tepi itu;
   • scroll-snap + tab terpilih otomatis ditengahkan (initTabs, Scripts_2);
   • di HP track MENEMPEL di bawah topbar saat konten panjang digulir,
     sehingga pindah tab selalu terjangkau tanpa menggulir balik ke atas.
   Turunannya ikut diselaraskan: chip kategori ATK & chip Belum Presensi. */
.tabs {
  gap: 5px;
  padding: 5px;
  border: 1px solid var(--border);
  border-radius: var(--radius-full);
  background: var(--bg-surface);
  background:
    linear-gradient(90deg,  var(--bg-surface) 45%, rgba(255, 255, 255, 0)) left  / 32px 100% no-repeat local,
    linear-gradient(270deg, var(--bg-surface) 45%, rgba(255, 255, 255, 0)) right / 32px 100% no-repeat local,
    radial-gradient(14px 62% at left,  rgba(15, 23, 42, .16), transparent 72%) left  / 16px 100% no-repeat scroll,
    radial-gradient(14px 62% at right, rgba(15, 23, 42, .16), transparent 72%) right / 16px 100% no-repeat scroll,
    var(--bg-surface);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .7), 0 1px 3px rgba(15, 23, 42, .05);
  scroll-snap-type: x proximity;
  scroll-padding: 0 24px;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}
.tabs::-webkit-scrollbar { display: none; }
.tab {
  flex: none;
  border-bottom: none;
  border-radius: var(--radius-full);
  padding: 8px 15px;
  min-height: 36px;
  scroll-snap-align: start;
}
.tab:hover { background: var(--slate-100); color: var(--text-primary); }
.tab.is-active {
  color: #fff;
  background: linear-gradient(135deg, var(--brand-500), var(--brand-700));
  box-shadow: 0 2px 8px rgba(13, 148, 136, .35), inset 0 1px 0 rgba(255, 255, 255, .25);
}
@media (max-width: 768px) {
  .tabs {
    position: sticky;
    top: calc(var(--topbar-h) + var(--safe-top) + 8px);
    z-index: 30; /* di bawah topbar (40) & sidebar (60) */
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, .7), 0 8px 18px -10px rgba(15, 23, 42, .3);
  }
  .tab { padding: 9px 14px; min-height: 40px; font-size: 13px; }
}
/* Turunan 1: chip kategori katalog ATK — pil senada, gulir tanpa scrollbar */
.atk-shop-cats {
  scrollbar-width: none;
  scroll-snap-type: x proximity;
  padding-bottom: 4px;
}
.atk-shop-cats::-webkit-scrollbar { display: none; }
.atk-cat-chip { min-height: 34px; scroll-snap-align: start; }
.atk-cat-chip.is-active {
  background: linear-gradient(135deg, var(--brand-500), var(--brand-700));
  border-color: transparent;
  box-shadow: 0 2px 6px rgba(13, 148, 136, .3), inset 0 1px 0 rgba(255, 255, 255, .22);
}
/* Turunan 2: chip "Belum Presensi" — target sentuh nyaman di HP */
@media (max-width: 768px) {
  .belum-chip { min-height: 36px; }
  .atk-cat-chip { min-height: 38px; }
}

/* ── 25.8 PENGAMAN SENTUH & GERAK MINIM ──────────────────────────────────── */
@media (pointer: coarse) {
  .mini-chart .bar:hover { filter: none; }
  .pd-donut:has(.pd-seg:hover) .pd-seg { opacity: 1; }
  .pd-donut .pd-seg:hover { stroke-width: var(--sw, 21px); }
  .pd-fill::after, .progress-bar::after { animation: none; content: none; }
}
@media (pointer: coarse) {
  .pd-kpi:hover, .stat-card:hover { transform: none; }
  .pd-donut { filter: none; } /* drop-shadow SVG dihindari di WebView sentuh */
}
@media (prefers-reduced-motion: reduce) {
  .pd-donut .pd-seg, .pd-dlegend .row, .feed-body { transition: none; }
  .pd-fill::after, .progress-bar::after { animation: none; content: none; }
  .pd-kpi, .stat-card { transition: none; }
  .pd-kpi:hover, .stat-card:hover { transform: none; }
}
