:root {
  /* Warna Utama (Biru korporat) */
  --color-primary: #0b4da2;
  --color-primary-dark: #06294f;
  --color-primary-darker: #041b38;
  --color-primary-light: #e8f0fb;
  --color-primary-lighter: #f2f7fd;

  /* Warna Netral (Putih & Abu-abu) */
  --color-bg: #f2f4f8;
  --color-surface: #ffffff;
  --color-border: #e3e7ee;
  --color-border-strong: #cdd4de;

  --color-text-primary: #1b2430;
  --color-text-secondary: #5c6b7a;
  --color-text-muted: #93a0af;
  --color-text-inverse: #ffffff;

  /* Warna Status / Semantik */
  --color-success: #16a34a;
  --color-success-bg: #e9f8ef;
  --color-warning: #d97706;
  --color-warning-bg: #fef3e2;
  --color-danger: #dc2626;
  --color-danger-bg: #fdeaea;
  --color-info: #2e86de;
  --color-info-bg: #eaf3fd;

  /* Tipografi */
  --font-display: "Plus Jakarta Sans", "Segoe UI", system-ui, sans-serif;
  --font-body: "Inter", "Segoe UI", system-ui, sans-serif;

  /* Ukuran & Spasi */
  --sidebar-width: 264px;
  --sidebar-width-collapsed: 76px;
  --navbar-height: 68px;
  --radius-sm: 8px;
  --radius-md: 12px;
  --radius-lg: 18px;
  --shadow-sm: 0 1px 2px rgba(6, 41, 79, 0.06);
  --shadow-md: 0 6px 20px rgba(6, 41, 79, 0.08);
  --shadow-lg: 0 16px 40px rgba(6, 41, 79, 0.14);
  --transition: 180ms cubic-bezier(0.4, 0, 0.2, 1);
}

/* --------------------------------------------------------------------------
   2. RESET & BASE
   -------------------------------------------------------------------------- */
* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

html {
  scroll-behavior: smooth;
}

body {
  font-family: var(--font-body);
  background: var(--color-bg);
  color: var(--color-text-primary);
  font-size: 14px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4, h5 {
  font-family: var(--font-display);
  color: var(--color-primary-darker);
  font-weight: 700;
  line-height: 1.25;
}

button {
  font-family: inherit;
  cursor: pointer;
}

input, select {
  font-family: inherit;
  font-size: inherit;
}

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

::selection {
  background: var(--color-primary-light);
  color: var(--color-primary-darker);
}

/* Scrollbar tipis untuk tampilan modern */
::-webkit-scrollbar {
  width: 8px;
  height: 8px;
}
::-webkit-scrollbar-track {
  background: transparent;
}
::-webkit-scrollbar-thumb {
  background: var(--color-border-strong);
  border-radius: 10px;
}
::-webkit-scrollbar-thumb:hover {
  background: var(--color-text-muted);
}

/* Fokus keyboard yang jelas (aksesibilitas) */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
  border-radius: 4px;
}

/* --------------------------------------------------------------------------
   3. LAYOUT UTAMA (Sidebar + Navbar + Konten)
   -------------------------------------------------------------------------- */
.app-shell {
  display: flex;
  min-height: 100vh;
}

/* ---- SIDEBAR ---- */
.sidebar {
  width: var(--sidebar-width);
  background: linear-gradient(180deg, var(--color-primary-dark) 0%, var(--color-primary-darker) 100%);
  color: var(--color-text-inverse);
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  z-index: 100;
  display: flex;
  flex-direction: column;
  transition: transform var(--transition), width var(--transition);
}

.sidebar-brand {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 20px 22px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}

.sidebar-brand img {
  width: 36px;
  height: 36px;
  flex-shrink: 0;
}

.sidebar-brand-text {
  overflow: hidden;
}

.sidebar-brand-text strong {
  display: block;
  font-family: var(--font-display);
  font-size: 15px;
  font-weight: 800;
  letter-spacing: 0.3px;
  white-space: nowrap;
}

.sidebar-brand-text span {
  display: block;
  font-size: 11px;
  color: rgba(255, 255, 255, 0.6);
  white-space: nowrap;
}

.sidebar-nav {
  flex: 1;
  overflow-y: auto;
  padding: 16px 12px;
}

.sidebar-section-label {
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.08em;
  color: rgba(255, 255, 255, 0.4);
  padding: 14px 12px 8px;
  text-transform: uppercase;
  white-space: nowrap;
}

.nav-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 11px 12px;
  border-radius: var(--radius-sm);
  color: rgba(255, 255, 255, 0.78);
  font-size: 13.5px;
  font-weight: 500;
  margin-bottom: 2px;
  transition: background var(--transition), color var(--transition);
  white-space: nowrap;
  position: relative;
  border: none;
  background: transparent;
  width: 100%;
  text-align: left;
}

.nav-item svg {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
}

.nav-item:hover {
  background: rgba(255, 255, 255, 0.08);
  color: #fff;
}

.nav-item.active {
  background: var(--color-primary);
  color: #fff;
  box-shadow: var(--shadow-sm);
}

.nav-item .nav-label {
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Nav group dengan anak halaman (submenu), misal: Dashboard Home > Murni / Lanjutan */
.nav-group {
  margin-bottom: 2px;
}

.nav-item-parent {
  display: flex;
  align-items: stretch;
  gap: 0;
}

.nav-item-parent .nav-item {
  flex: 1;
  margin-bottom: 0;
}

.nav-submenu-toggle {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  flex-shrink: 0;
  border: none;
  background: transparent;
  color: rgba(255, 255, 255, 0.55);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: background var(--transition), color var(--transition), transform var(--transition);
}

.nav-submenu-toggle:hover {
  background: rgba(255, 255, 255, 0.08);
  color: #fff;
}

.nav-submenu-toggle svg {
  width: 14px;
  height: 14px;
  transition: transform var(--transition);
}

.nav-submenu-toggle.open svg {
  transform: rotate(90deg);
}

.nav-submenu {
  display: none;
  flex-direction: column;
  padding-left: 14px;
  margin-top: 2px;
  border-left: 1px solid rgba(255, 255, 255, 0.12);
  margin-left: 18px;
}

.nav-submenu.open {
  display: flex;
}

.nav-item-sub {
  font-size: 12.5px;
  padding: 9px 12px;
  gap: 10px;
}

.nav-item-sub svg {
  width: 15px;
  height: 15px;
}

.app-shell.sidebar-collapsed .nav-submenu-toggle,
.app-shell.sidebar-collapsed .nav-submenu {
  display: none !important;
}

.kategori-badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 12px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}
.kategori-badge.badge-murni {
  background: rgba(11, 77, 162, 0.12);
  color: var(--color-primary);
}
.kategori-badge.badge-lanjutan {
  background: rgba(217, 119, 6, 0.14);
  color: #b45309;
}
.kategori-badge.badge-arsip {
  background: rgba(100, 116, 139, 0.14);
  color: #475569;
}
.kategori-badge.badge-realtime {
  background: rgba(22, 163, 74, 0.14);
  color: #15803d;
}

/* Variasi summary grid untuk 6 kartu (dashboard Murni/Lanjutan) */
.summary-grid.cols-6 {
  grid-template-columns: repeat(6, 1fr);
}
@media (max-width: 1200px) {
  .summary-grid.cols-6 { grid-template-columns: repeat(3, 1fr); }
}
@media (max-width: 640px) {
  .summary-grid.cols-6 { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 420px) {
  .summary-grid.cols-6 { grid-template-columns: 1fr; }
}

/* Angka pada kartu summary 6-kolom dibuat lebih kecil supaya selalu muat
   dalam satu baris di kotaknya, meskipun nilai rupiahnya besar. */
.summary-grid.cols-6 .summary-card-value {
  font-size: 16px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.summary-grid.cols-6 .summary-card {
  padding: 16px;
}

.sidebar-footer {
  padding: 16px 20px;
  border-top: 1px solid rgba(255, 255, 255, 0.1);
  font-size: 11px;
  color: rgba(255, 255, 255, 0.45);
  white-space: nowrap;
}
.sidebar-live-status { display: flex; align-items: flex-start; gap: 9px; padding-bottom: 14px; margin-bottom: 14px; border-bottom: 1px solid rgba(255,255,255,.1); white-space: normal; }
.sidebar-live-status[hidden] { display: none !important; }
.sidebar-live-status .dot { flex: 0 0 auto; margin-top: 5px; }
.sidebar-live-status > div { display: grid; gap: 3px; min-width: 0; }
.sidebar-live-label { color: rgba(255,255,255,.85); font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; }
.sidebar-live-status .kpi-conn-text { color: rgba(255,255,255,.58); font-size: 10.5px; line-height: 1.45; white-space: normal; }
.sidebar-live-status.kpi-live .kpi-conn-text { color: #86efac; }
.sidebar-live-status.kpi-demo .kpi-conn-text { color: #fcd34d; }
.sidebar-copyright { font-size: 12px; color: rgba(255,255,255,.5); }

/* Sidebar collapsed (desktop toggle) */
.app-shell.sidebar-collapsed .sidebar {
  width: var(--sidebar-width-collapsed);
}
.app-shell.sidebar-collapsed .sidebar-brand-text,
.app-shell.sidebar-collapsed .sidebar-section-label,
.app-shell.sidebar-collapsed .nav-label,
.app-shell.sidebar-collapsed .sidebar-footer {
  display: none;
}
.app-shell.sidebar-collapsed .main-wrapper {
  margin-left: var(--sidebar-width-collapsed);
}

/* ---- MAIN WRAPPER ---- */
.main-wrapper {
  margin-left: var(--sidebar-width);
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  transition: margin-left var(--transition);
}

/* ---- NAVBAR ----
   Sengaja pakai position:sticky (bukan fixed). Dengan sticky, navbar tetap
   ikut alur dokumen normal (mengambil ruang selebar tingginya) sehingga
   konten/dropdown di bawahnya TIDAK PERNAH ketutupan/kepotong navbar di
   halaman manapun -- tidak perlu lagi hack margin-top manual per halaman.
   Navbar tetap menempel di atas viewport saat halaman di-scroll, sama
   seperti fixed, tapi tanpa efek "ketutupan" itu. */
.navbar {
  height: var(--navbar-height);
  background: var(--color-surface);
  border-bottom: 1px solid var(--color-border);
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 24px;
  position: sticky;
  top: 0;
  z-index: 90;
}

.navbar-left {
  display: flex;
  align-items: center;
  gap: 16px;
}

.navbar-toggle {
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  width: 38px;
  height: 38px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--color-text-secondary);
  transition: background var(--transition);
}
.navbar-toggle:hover {
  background: var(--color-primary-light);
  color: var(--color-primary);
}

.navbar-title h1 {
  font-size: 17px;
  font-weight: 700;
}

.navbar-title p {
  font-size: 12px;
  color: var(--color-text-secondary);
  margin-top: 1px;
}

.navbar-right {
  display: flex;
  align-items: center;
  gap: 14px;
}

.connection-badge {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 7px 12px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 600;
  background: var(--color-danger-bg);
  color: var(--color-danger);
}

.connection-badge.connected {
  background: var(--color-success-bg);
  color: var(--color-success);
}

.connection-badge .dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: currentColor;
}

.navbar-refresh {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 8px 14px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--color-border);
  background: var(--color-surface);
  color: var(--color-text-secondary);
  font-size: 12.5px;
  font-weight: 600;
  transition: all var(--transition);
}
.navbar-refresh:hover {
  border-color: var(--color-primary);
  color: var(--color-primary);
}
.navbar-refresh svg {
  width: 15px;
  height: 15px;
}
.navbar-refresh.loading svg {
  animation: spin 0.9s linear infinite;
}

/* ---- KONTEN / PAGE ---- */
.content {
  margin-top: 0;
  padding: 24px;
  flex: 1;
  position: relative;
}

/* Watermark logo PLN: posisinya fixed di tengah area konten (kanan sidebar),
   jadi tetap terlihat di tempat yang sama walau halaman digulir ke bawah.
   Panel/kartu di atasnya dibuat transparan agar logo ini tetap terlihat. */
.content::before {
  content: "";
  position: fixed;
  top: var(--navbar-height);
  left: var(--sidebar-width);
  right: 0;
  bottom: 0;
  background-image: url("assets/logo-pln.png");
  background-repeat: no-repeat;
  background-position: center center;
  background-size: 460px 460px;
  opacity: 0.12;
  pointer-events: none;
  z-index: 0;
  transition: left var(--transition);
}
.app-shell.sidebar-collapsed .content::before {
  left: var(--sidebar-width-collapsed);
}
@media (max-width: 900px) {
  .content::before {
    left: 0;
  }
}

.page {
  display: none;
  position: relative;
  z-index: 1;
}
.page.active {
  display: block;
}

.page-header {
  position: relative;
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 20px;
  flex-wrap: wrap;
  padding: 22px 24px;
  border-radius: var(--radius-lg);
  border: 1px solid var(--color-border);
  background: linear-gradient(135deg, rgba(232, 240, 251, 0.62) 0%, rgba(255, 255, 255, 0.7) 60%, rgba(232, 240, 251, 0.62) 100%);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}

.page-header h2 {
  font-size: 20px;
  margin-bottom: 4px;
}

.page-header p {
  color: var(--color-text-secondary);
  font-size: 13px;
}

.page-actions {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  justify-content: flex-end;
  max-width: 100%;
}
.page-actions .filter-select,
.page-actions select {
  flex: 0 1 auto;
  max-width: 100%;
}
@media (max-width: 640px) {
  .page-header {
    flex-direction: column;
    align-items: stretch;
  }
  .page-actions {
    justify-content: flex-start;
  }
  .page-actions .filter-select,
  .page-actions select {
    flex: 1 1 160px;
  }
}

/* --------------------------------------------------------------------------
   4. TOMBOL
   -------------------------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 9px 16px;
  border-radius: var(--radius-sm);
  font-size: 13px;
  font-weight: 600;
  border: 1px solid transparent;
  transition: all var(--transition);
  white-space: nowrap;
}
.btn svg {
  width: 15px;
  height: 15px;
}

.btn-primary {
  background: var(--color-primary);
  color: #fff;
  box-shadow: var(--shadow-sm);
}
.btn-primary:hover {
  background: var(--color-primary-dark);
  transform: translateY(-1px);
  box-shadow: var(--shadow-md);
}

.btn-outline {
  background: var(--color-surface);
  border-color: var(--color-border);
  color: var(--color-text-secondary);
}
.btn-outline:hover {
  border-color: var(--color-primary);
  color: var(--color-primary);
  background: var(--color-primary-lighter);
}

.btn-sm {
  padding: 6px 11px;
  font-size: 12px;
}

/* --------------------------------------------------------------------------
   5. CARD SUMMARY
   -------------------------------------------------------------------------- */
.summary-grid {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 16px;
  margin-bottom: 24px;
}

.summary-card {
  background: rgba(255, 255, 255, 0.68);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: 18px 20px;
  position: relative;
  overflow: hidden;
  transition: box-shadow var(--transition), transform var(--transition);
}
.summary-card:hover {
  box-shadow: var(--shadow-md);
  transform: translateY(-2px);
}

.summary-card::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 3px;
  background: var(--color-primary);
}

.summary-card.card-realisasi::before { background: var(--color-success); }
.summary-card.card-sisa::before { background: var(--color-info); }
.summary-card.card-persen::before { background: var(--color-warning); }
.summary-card.card-jumlah::before { background: var(--color-primary-darker); }
.summary-card.card-info::before { background: var(--color-info); }

.summary-card-icon {
  width: 38px;
  height: 38px;
  border-radius: 10px;
  background: var(--color-primary-light);
  color: var(--color-primary);
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 12px;
}
.summary-card-icon svg { width: 19px; height: 19px; }

.card-realisasi .summary-card-icon { background: var(--color-success-bg); color: var(--color-success); }
.card-sisa .summary-card-icon { background: var(--color-info-bg); color: var(--color-info); }
.card-persen .summary-card-icon { background: var(--color-warning-bg); color: var(--color-warning); }
.card-jumlah .summary-card-icon { background: #eef1f6; color: var(--color-primary-darker); }
.card-info .summary-card-icon { background: var(--color-info-bg); color: var(--color-info); }

.summary-card-label {
  font-size: 12px;
  color: var(--color-text-secondary);
  font-weight: 600;
  margin-bottom: 6px;
}

.summary-card-value {
  font-family: var(--font-display);
  font-size: 21px;
  font-weight: 800;
  color: var(--color-primary-darker);
  letter-spacing: -0.3px;
  min-height: 26px;
}

.summary-card-value small {
  font-size: 12px;
  font-weight: 400;
  color: var(--color-text-muted);
}

.summary-card-sub {
  margin-top: 8px;
  font-size: 11.5px;
  color: var(--color-text-muted);
}

/* --------------------------------------------------------------------------
   6. PANEL / SECTION UMUM
   -------------------------------------------------------------------------- */
.panel {
  background: rgba(255, 255, 255, 0.68);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: 20px;
  margin-bottom: 20px;
}

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

.panel-header h3 {
  font-size: 15px;
}

.panel-header .panel-sub {
  font-size: 12px;
  color: var(--color-text-secondary);
  font-weight: 400;
  margin-top: 2px;
}

/* --------------------------------------------------------------------------
   7. GRID DASHBOARD (Chart + Progress)
   -------------------------------------------------------------------------- */
.dashboard-grid {
  display: grid;
  grid-template-columns: 1.4fr 1fr;
  gap: 20px;
  margin-bottom: 20px;
}

.dashboard-grid-2 {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 20px;
}

.chart-canvas-wrap {
  position: relative;
  height: 280px;
}

/* --------------------------------------------------------------------------
   8. PROGRESS ANGGARAN (Elemen signature: radial gauge)
   -------------------------------------------------------------------------- */
.progress-gauge-wrap {
  display: flex;
  align-items: center;
  gap: 22px;
  padding: 6px 0 14px;
}

.progress-ring {
  position: relative;
  width: 132px;
  height: 132px;
  flex-shrink: 0;
}
.progress-ring svg { transform: rotate(-90deg); }
.progress-ring circle {
  fill: none;
  stroke-width: 11;
}
.progress-ring .ring-bg { stroke: var(--color-bg); }
.progress-ring .ring-fg {
  stroke: var(--color-primary);
  stroke-linecap: round;
  transition: stroke-dashoffset 700ms cubic-bezier(0.4, 0, 0.2, 1);
}
.progress-ring-label {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}
.progress-ring-label strong {
  font-family: var(--font-display);
  font-size: 24px;
  color: var(--color-primary-darker);
}
.progress-ring-label span {
  font-size: 10.5px;
  color: var(--color-text-muted);
  font-weight: 600;
}

.progress-legend {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.progress-legend-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 12.5px;
}
.progress-legend-row .dot {
  width: 9px; height: 9px; border-radius: 3px; display: inline-block; margin-right: 8px;
}
.progress-legend-row .lbl { color: var(--color-text-secondary); display: flex; align-items: center; }
.progress-legend-row .val { font-weight: 700; color: var(--color-primary-darker); font-family: var(--font-display); }

.unit-progress-list {
  display: flex;
  flex-direction: column;
  gap: 14px;
  margin-top: 4px;
}
.unit-progress-item .up-head {
  display: flex;
  justify-content: space-between;
  font-size: 12.5px;
  margin-bottom: 6px;
}
.unit-progress-item .up-head span:first-child { color: var(--color-text-primary); font-weight: 600; }
.unit-progress-item .up-head span:last-child { color: var(--color-text-secondary); }
.up-bar-track {
  height: 8px;
  background: var(--color-bg);
  border-radius: 999px;
  overflow: hidden;
}
.up-bar-fill {
  height: 100%;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--color-primary) 0%, var(--color-info) 100%);
  transition: width 700ms cubic-bezier(0.4, 0, 0.2, 1);
}

/* --------------------------------------------------------------------------
   9. FILTER & SEARCH (Halaman Monitoring)
   -------------------------------------------------------------------------- */
.filter-bar {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: center;
  margin-bottom: 16px;
}

.search-box {
  position: relative;
  flex: 1 1 240px;
  min-width: 200px;
}
.search-box svg {
  position: absolute;
  left: 12px;
  top: 50%;
  transform: translateY(-50%);
  width: 16px;
  height: 16px;
  color: var(--color-text-muted);
}
.search-box input {
  width: 100%;
  padding: 9px 12px 9px 34px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
  color: var(--color-text-primary);
  transition: border-color var(--transition);
}
.search-box input:focus {
  border-color: var(--color-primary);
  outline: none;
}

.filter-select {
  padding: 9px 30px 9px 12px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: var(--color-surface) url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="10" height="6" viewBox="0 0 10 6"><path d="M1 1l4 4 4-4" stroke="%235C6B7A" stroke-width="1.5" fill="none" stroke-linecap="round"/></svg>') no-repeat right 12px center;
  appearance: none;
  color: var(--color-text-secondary);
  font-size: 12.5px;
  font-weight: 500;
  min-width: 130px;
  transition: border-color var(--transition);
}
.filter-select:focus {
  border-color: var(--color-primary);
  outline: none;
}

.filter-reset {
  color: var(--color-text-muted);
  font-size: 12px;
  font-weight: 600;
  padding: 9px 6px;
  white-space: nowrap;
}
.filter-reset:hover { color: var(--color-danger); }

/* --------------------------------------------------------------------------
   10. TABEL DATA
   -------------------------------------------------------------------------- */
.table-scroll {
  overflow-x: auto;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
}

table.data-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 12.5px;
  min-width: 1100px;
}

.data-table thead th {
  background: var(--color-primary-lighter);
  color: var(--color-primary-darker);
  text-align: left;
  padding: 12px 14px;
  font-weight: 700;
  font-size: 11.5px;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  border-bottom: 1px solid var(--color-border);
  white-space: nowrap;
  position: sticky;
  top: 0;
  cursor: pointer;
  user-select: none;
}
.data-table thead th:hover { background: var(--color-primary-light); }

.data-table thead th .th-inner {
  display: flex;
  align-items: center;
  gap: 5px;
}
.data-table thead th .sort-icon {
  width: 11px;
  height: 11px;
  opacity: 0.35;
}
.data-table thead th.sorted-asc .sort-icon,
.data-table thead th.sorted-desc .sort-icon {
  opacity: 1;
  color: var(--color-primary);
}
.data-table thead th.sorted-desc .sort-icon { transform: rotate(180deg); }

.data-table tbody td {
  padding: 11px 14px;
  border-bottom: 1px solid var(--color-border);
  color: var(--color-text-primary);
  white-space: nowrap;
}

.data-table tbody tr {
  transition: background var(--transition);
}
.data-table tbody tr:hover {
  background: var(--color-primary-lighter);
}
.data-table tbody tr:last-child td { border-bottom: none; }

.cell-num { text-align: right; font-variant-numeric: tabular-nums; }
.cell-muted { color: var(--color-text-secondary); }

/* Tabel KPI berkolom sedikit (Ranking NKO, Perbandingan ULP) -- rule
   .data-table di atas punya min-width:1100px untuk tabel SKKI yang
   kolomnya banyak. Tanpa override ini, tabel kecil ikut dipaksa
   selebar 1100px dan jadi banyak ruang kosong di panel yang sempit. */
table.data-table.kpi-table-compact { min-width: 0; width: 100%; }
.kpi-table-compact thead th, .kpi-table-compact tbody td { white-space: normal; }

.status-badge {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 4px 10px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 700;
}
.status-badge .dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }

.status-selesai { background: var(--color-success-bg); color: var(--color-success); }
.status-proses { background: var(--color-warning-bg); color: var(--color-warning); }
.status-belum { background: var(--color-danger-bg); color: var(--color-danger); }

/* --------------------------------------------------------------------------
   11. PAGINATION
   -------------------------------------------------------------------------- */
.pagination-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: 16px;
  flex-wrap: wrap;
  gap: 10px;
}

.pagination-info {
  font-size: 12px;
  color: var(--color-text-secondary);
}

.pagination-controls {
  display: flex;
  align-items: center;
  gap: 6px;
}

.page-btn {
  min-width: 32px;
  height: 32px;
  padding: 0 8px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
  color: var(--color-text-secondary);
  font-size: 12.5px;
  font-weight: 600;
  display: flex;
  align-items: center;
  justify-content: center;
}
.page-btn:hover:not(:disabled) {
  border-color: var(--color-primary);
  color: var(--color-primary);
}
.page-btn.active {
  background: var(--color-primary);
  border-color: var(--color-primary);
  color: #fff;
}
.page-btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}
.page-btn svg { width: 14px; height: 14px; }

.page-size-select {
  padding: 6px 26px 6px 10px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  font-size: 12px;
  background: var(--color-surface);
}

/* --------------------------------------------------------------------------
   12. LOADING STATE (Skeleton + Spinner)
   -------------------------------------------------------------------------- */
.skeleton {
  position: relative;
  overflow: hidden;
  background: var(--color-bg);
  border-radius: 6px;
}
.skeleton::after {
  content: "";
  position: absolute;
  inset: 0;
  transform: translateX(-100%);
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.75), transparent);
  animation: shimmer 1.4s infinite;
}
@keyframes shimmer {
  100% { transform: translateX(100%); }
}

.skeleton-text {
  height: 12px;
  width: 60%;
  margin-bottom: 8px;
}
.skeleton-value {
  height: 22px;
  width: 80%;
}
.skeleton-row td { padding: 12px 14px; }

.loading-overlay {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  padding: 60px 20px;
  color: var(--color-text-secondary);
  font-size: 13px;
}
.spinner {
  width: 34px;
  height: 34px;
  border: 3px solid var(--color-border);
  border-top-color: var(--color-primary);
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* --------------------------------------------------------------------------
   13. EMPTY STATE
   -------------------------------------------------------------------------- */
.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 48px 20px;
  color: var(--color-text-secondary);
}
.empty-state svg {
  width: 56px;
  height: 56px;
  color: var(--color-border-strong);
  margin-bottom: 14px;
}
.empty-state h4 {
  font-size: 14px;
  color: var(--color-text-primary);
  margin-bottom: 4px;
}
.empty-state p {
  font-size: 12.5px;
  max-width: 320px;
  line-height: 1.6;
}
.empty-state-mini {
  padding: 30px 16px;
}
.empty-state-mini svg { width: 40px; height: 40px; }

/* --------------------------------------------------------------------------
   14. TOAST NOTIFIKASI
   -------------------------------------------------------------------------- */
.toast-container {
  position: fixed;
  bottom: 20px;
  right: 20px;
  z-index: 999;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.toast {
  background: var(--color-primary-darker);
  color: #fff;
  padding: 12px 18px;
  border-radius: var(--radius-sm);
  font-size: 12.5px;
  font-weight: 500;
  box-shadow: var(--shadow-lg);
  display: flex;
  align-items: center;
  gap: 10px;
  animation: fadeUp 250ms ease both;
  max-width: 320px;
}
.toast.toast-success { background: var(--color-success); }
.toast.toast-error { background: var(--color-danger); }

/* --------------------------------------------------------------------------
   15. ANIMASI
   -------------------------------------------------------------------------- */
@keyframes fadeUp {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: translateY(0); }
}

@media (prefers-reduced-motion: reduce) {
  * { animation-duration: 0.001ms !important; transition-duration: 0.001ms !important; }
}

/* --------------------------------------------------------------------------
   16. OVERLAY MOBILE (backdrop saat sidebar terbuka di layar kecil)
   -------------------------------------------------------------------------- */
.sidebar-backdrop {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(6, 41, 79, 0.45);
  z-index: 95;
}
.sidebar-backdrop.show { display: block; }

/* --------------------------------------------------------------------------
   17. RESPONSIVE
   -------------------------------------------------------------------------- */
@media (max-width: 1180px) {
  .summary-grid { grid-template-columns: repeat(3, 1fr); }
  .dashboard-grid { grid-template-columns: 1fr; }
}

@media (max-width: 900px) {
  .sidebar {
    transform: translateX(-100%);
    width: var(--sidebar-width);
  }
  .app-shell.sidebar-open .sidebar {
    transform: translateX(0);
    box-shadow: var(--shadow-lg);
  }
  .main-wrapper { margin-left: 0; }
  .app-shell.sidebar-collapsed .main-wrapper { margin-left: 0; }
  .summary-grid { grid-template-columns: repeat(2, 1fr); }
  .dashboard-grid-2 { grid-template-columns: 1fr; }
}

@media (max-width: 600px) {
  .summary-grid { grid-template-columns: 1fr; }
  .navbar { padding: 0 14px; }
  .content { padding: 16px; }
  table.data-table { min-width: 900px; }
  .navbar-title p { display: none; }
}

/* --------------------------------------------------------------------------
   18. PRINT (Laporan / Cetak)
   -------------------------------------------------------------------------- */
@media print {
  .sidebar, .navbar, .filter-bar, .page-actions, .pagination-bar, .navbar-toggle,
  .toast-container, .sidebar-backdrop { display: none !important; }
  .main-wrapper { margin-left: 0 !important; }
  .content { margin-top: 0 !important; padding: 0 !important; }
  body { background: #fff; }
  .panel, .summary-card { box-shadow: none !important; border: 1px solid #ccc !important; }
  .page { display: block !important; }
  table.data-table { min-width: 100% !important; font-size: 11px; }
}

/* --------------------------------------------------------------------------
   19. TOP 10 LIST (Dashboard)
   -------------------------------------------------------------------------- */
.top10-list {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.top10-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 8px;
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: background var(--transition);
}
.top10-item:hover { background: var(--color-primary-lighter); }
.top10-item:not(:last-child) { border-bottom: 1px solid var(--color-border); }
.top10-rank {
  flex: 0 0 24px;
  height: 24px;
  border-radius: 50%;
  background: var(--color-primary-light);
  color: var(--color-primary-darker);
  font-size: 11px;
  font-weight: 800;
  display: flex;
  align-items: center;
  justify-content: center;
}
.top10-info {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
}
.top10-title {
  font-size: 12.5px;
  font-weight: 600;
  color: var(--color-text-primary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.top10-sub {
  font-size: 11px;
  color: var(--color-text-muted);
}
.top10-value {
  flex: 0 0 auto;
  font-size: 12.5px;
  font-weight: 700;
  color: var(--color-primary-darker);
  font-family: var(--font-display);
}

/* --------------------------------------------------------------------------
   20. RIWAYAT UPDATE (Dashboard)
   -------------------------------------------------------------------------- */
.riwayat-body {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.riwayat-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 0;
  border-bottom: 1px solid var(--color-border);
  font-size: 12.5px;
}
.riwayat-row:last-child { border-bottom: none; }
.riwayat-label { color: var(--color-text-secondary); }
.riwayat-value { font-weight: 700; color: var(--color-text-primary); font-family: var(--font-display); }

/* --------------------------------------------------------------------------
   21. PROGRESS AI TABS
   -------------------------------------------------------------------------- */
.progress-tabs {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}
.progress-tab {
  padding: 9px 18px;
  border-radius: var(--radius-sm);
  background: var(--color-bg);
  color: var(--color-text-secondary);
  font-size: 12.5px;
  font-weight: 700;
  border: 1px solid transparent;
  transition: all var(--transition);
}
.progress-tab:hover { color: var(--color-primary); }
.progress-tab.active {
  background: var(--color-primary);
  color: #fff;
}

/* --------------------------------------------------------------------------
   22. TABEL: BARIS BISA DIKLIK (Detail Anggaran / Rekap)
   -------------------------------------------------------------------------- */
.row-clickable { cursor: pointer; }

/* --------------------------------------------------------------------------
   23. MODAL DETAIL ANGGARAN
   -------------------------------------------------------------------------- */
.detail-modal {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: none;
  align-items: center;
  justify-content: center;
  padding: 20px;
}
.detail-modal.show { display: flex; }
.detail-modal-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(6, 41, 79, 0.55);
  animation: fadeUp 180ms ease both;
}
.detail-modal-panel {
  position: relative;
  background: var(--color-surface);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  width: 100%;
  max-width: 620px;
  max-height: 85vh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  animation: fadeUp 220ms ease both;
}
.detail-modal-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  padding: 20px 24px;
  border-bottom: 1px solid var(--color-border);
}
.detail-modal-header h3 {
  font-size: 16px;
  margin-bottom: 6px;
}
.detail-modal-sub {
  display: flex;
  align-items: center;
  gap: 10px;
}
.detail-percent {
  font-size: 12px;
  color: var(--color-text-secondary);
  font-weight: 600;
}
.detail-modal-close {
  flex: 0 0 auto;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: var(--color-bg);
  color: var(--color-text-secondary);
  display: flex;
  align-items: center;
  justify-content: center;
}
.detail-modal-close:hover { background: var(--color-danger-bg); color: var(--color-danger); }
.detail-modal-close svg { width: 16px; height: 16px; }
.detail-modal-body {
  padding: 8px 24px 20px;
  overflow-y: auto;
}
.detail-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 11px 0;
  border-bottom: 1px solid var(--color-border);
  font-size: 12.5px;
}
.detail-row:last-child { border-bottom: none; }
.detail-label { color: var(--color-text-secondary); flex: 0 0 45%; }
.detail-value { color: var(--color-text-primary); font-weight: 600; text-align: right; flex: 1; }

@media print {
  .detail-modal { display: none !important; }
}
/* ==========================================================================
   MODULE: KPI MONITORING UP3 CIREBON (app switcher + halaman KPI)
   ========================================================================== */

/* --- App switcher button (garis 3) di atas sidebar --- */
.app-switcher-btn {
  display: flex;
  align-items: center;
  gap: 10px;
  width: calc(100% - 24px);
  margin: 14px 12px 0;
  padding: 10px 12px;
  background: var(--color-primary-darker);
  color: #fff;
  border: none;
  border-radius: var(--radius-md);
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 12.5px;
  cursor: pointer;
  transition: var(--transition);
}
.app-switcher-btn:hover { background: var(--color-primary-dark); }
.app-switcher-btn #currentAppLabel {
  flex: 1;
  text-align: left;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.app-switcher-caret { opacity: .8; flex-shrink: 0; }
.sidebar-collapsed .app-switcher-btn #currentAppLabel,
.sidebar-collapsed .app-switcher-btn .app-switcher-caret { display: none; }

/* --- Modal pemilih dashboard --- */
.app-switcher-modal {
  position: fixed; inset: 0; z-index: 300;
  display: none; align-items: center; justify-content: center;
}
.app-switcher-modal.show { display: flex; }
.app-switcher-backdrop {
  position: absolute; inset: 0;
  background: rgba(6, 41, 79, 0.45);
  backdrop-filter: blur(2px);
}
.app-switcher-panel {
  position: relative;
  background: var(--color-surface);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  width: min(520px, 92vw);
  padding: 22px 24px 26px;
}
.app-switcher-panel-header {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 16px;
}
.app-switcher-panel-header h3 { font-size: 17px; }
.app-switch-cards {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
}
@media (max-width: 560px) {
  .app-switch-cards { grid-template-columns: 1fr; }
}
.app-switch-card {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 12px;
  padding: 18px 16px;
  border: 1.5px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  cursor: pointer;
  text-align: left;
  transition: var(--transition);
  font-family: inherit;
}
.app-switch-card:hover { border-color: var(--color-primary); box-shadow: var(--shadow-sm); }
.app-switch-card.active { border-color: var(--color-primary); background: var(--color-primary-lighter); }
.app-switch-icon {
  width: 42px; height: 42px;
  border-radius: 12px;
  display: flex; align-items: center; justify-content: center;
}
.app-switch-text strong { display: block; font-size: 14px; color: var(--color-text-primary); margin-bottom: 2px; }
.app-switch-text span { font-size: 12px; color: var(--color-text-secondary); }

/* --- Filter bar global khusus halaman KPI ---
   Sekarang navbar sudah position:sticky (ikut alur dokumen), jadi filter bar
   ini otomatis muncul TEPAT DI BAWAH navbar tanpa perlu margin-top manual.
   Filter bar-nya sendiri dibuat sticky juga (nempel persis di bawah navbar,
   top: navbar-height) supaya filter Periode/ULP tetap kelihatan & bisa
   dipakai walau halaman di-scroll ke bawah -- pola umum dashboard monitoring
   profesional. */
.kpi-filter-bar {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
  padding: 12px 28px;
  background: var(--color-surface);
  border-bottom: 1px solid var(--color-border);
  position: sticky;
  top: var(--navbar-height);
  z-index: 80;
}
.kpi-filter-group { display: flex; align-items: center; gap: 8px; }
.kpi-filter-group label { font-size: 12px; color: var(--color-text-secondary); font-weight: 600; white-space: nowrap; }
.kpi-loss-value { color: var(--color-danger) !important; }
.kpi-conn-badge {
  margin-left: auto;
  display: inline-flex; align-items: center; gap: 7px;
  padding: 6px 12px;
  border-radius: 20px;
  font-size: 11.5px; font-weight: 600;
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  color: var(--color-text-secondary);
}
.kpi-conn-badge .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--color-text-muted); }
.kpi-conn-badge.kpi-live .dot { background: var(--color-success); }
.kpi-conn-badge.kpi-live { color: var(--color-success); border-color: var(--color-success); background: var(--color-success-bg); }
.kpi-conn-badge.kpi-demo .dot { background: var(--color-warning); }
.kpi-conn-badge.kpi-demo { color: var(--color-warning); border-color: var(--color-warning); background: var(--color-warning-bg); }
.sidebar-footer .sidebar-live-status.kpi-conn-badge,
.sidebar-footer .sidebar-live-status.kpi-conn-badge.kpi-live,
.sidebar-footer .sidebar-live-status.kpi-conn-badge.kpi-demo {
  width: 100%; margin: 0 0 14px; padding: 0 0 14px; border-width: 0 0 1px;
  border-style: solid; border-color: rgba(255,255,255,.1); border-radius: 0;
  background: transparent;
}

/* --- Kartu ringkas indikator (Overview) --- */
.kpi-mini-card {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-left: 4px solid var(--color-primary);
  border-radius: var(--radius-md);
  padding: 14px 16px;
  box-shadow: var(--shadow-sm);
  min-height: 116px;
  cursor: pointer;
  transition: box-shadow .12s ease, transform .12s ease;
}
.kpi-mini-card:hover { box-shadow: var(--shadow-md); transform: translateY(-1px); }
.kpi-mini-label { font-size: 11.5px; color: var(--color-text-secondary); font-weight: 600; margin-bottom: 6px; }
.kpi-mini-value { font-family: var(--font-display); font-size: 20px; font-weight: 700; color: var(--color-text-primary); }
.kpi-mini-value span { font-size: 12px; font-weight: 500; color: var(--color-text-muted); }
.kpi-mini-sub { font-size: 11.5px; color: var(--color-text-secondary); margin-top: 6px; }

/* --- Baris tabel yang bisa diklik untuk masuk ke data detailnya --- */
.kpi-row-clickable { cursor: pointer; transition: background .1s ease; }
.kpi-row-clickable:hover { background: var(--color-primary-light); }

/* --- Badge status (hijau/kuning/merah/hitam) --- */
.kpi-badge {
  display: inline-block;
  padding: 3px 10px;
  border-radius: 20px;
  font-size: 11px;
  font-weight: 700;
}
.kpi-badge-na { background: var(--color-bg); color: var(--color-text-muted); }

/* --- Overlay loading (dipasang otomatis oleh kpi.js ke halaman KPI aktif
   selagi data dari Google Sheets belum selesai diambil) --- */
.kpi-loading-overlay {
  position: absolute;
  inset: 0;
  background: rgba(242, 244, 248, .92);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  z-index: 40;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity .15s ease;
  border-radius: var(--radius-md);
}
.kpi-loading-overlay.show {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
}
.kpi-spinner {
  width: 42px;
  height: 42px;
  border-radius: 50%;
  border: 4px solid var(--color-border);
  border-top-color: var(--color-primary);
  animation: kpi-spin .8s linear infinite;
}
@keyframes kpi-spin {
  to { transform: rotate(360deg); }
}
.kpi-loading-text {
  font-size: 13px;
  font-weight: 600;
  color: var(--color-text-secondary);
}

/* --- Empty state: data KPI belum terbaca dari Google Sheets --- */
.kpi-nodata {
  position: absolute;
  top: 74px;
  left: 20px;
  right: 20px;
  z-index: 20;
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 16px 18px;
  border: 1px solid #e7c26b;
  background: linear-gradient(180deg, #fffdf4, #fff9e0);
  border-radius: 12px;
  color: var(--color-text-primary);
  box-shadow: var(--shadow-sm);
}
.kpi-nodata-icon { font-size: 22px; line-height: 1.15; }
.kpi-nodata-title { font-weight: 700; font-size: 14px; margin-bottom: 5px; }
.kpi-nodata-sub { font-size: 12.5px; line-height: 1.6; color: var(--color-text-secondary); max-width: 760px; }
.kpi-nodata-sub code { background: rgba(0, 0, 0, .07); padding: 1px 5px; border-radius: 4px; font-size: 12px; }

/* --- Peta Sebaran ULP (Overview) --- */
.kpi-map-layout {
  display: grid;
  grid-template-columns: 240px 1fr;
  gap: 16px;
  align-items: stretch;
}
@media (max-width: 900px) {
  .kpi-map-layout { grid-template-columns: 1fr; }
}
.kpi-map-total-card {
  background: linear-gradient(160deg, var(--color-success) 0%, #0f7a38 100%);
  color: var(--color-text-inverse);
  border-radius: var(--radius-md);
  padding: 18px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  box-shadow: var(--shadow-sm);
}
.kpi-map-total-card .kpi-map-total-label {
  font-size: 13px;
  font-weight: 800;
  letter-spacing: .04em;
  text-transform: uppercase;
}
.kpi-map-total-card .kpi-map-total-sub {
  font-size: 11px;
  opacity: .85;
  margin-top: -6px;
}
.kpi-map-total-card .kpi-map-total-row {
  display: flex;
  justify-content: space-between;
  font-size: 12px;
  background: rgba(255,255,255,.14);
  border-radius: 8px;
  padding: 6px 10px;
}
.kpi-map-total-card .kpi-map-total-row b { font-size: 13px; }
.kpi-map-metric-box {
  background: rgba(255,255,255,.14);
  border-radius: 10px;
  padding: 9px 11px;
}
.kpi-map-metric-label {
  font-size: 11px;
  font-weight: 700;
  opacity: .9;
}
.kpi-map-metric-label span { font-weight: 500; opacity: .8; }
.kpi-map-metric-value {
  font-family: var(--font-display);
  font-size: 22px;
  font-weight: 800;
  line-height: 1.25;
  margin: 2px 0 4px;
}
.kpi-map-metric-value span { font-size: 12px; font-weight: 600; opacity: .85; }
.kpi-map-delta { font-size: 10.5px; font-weight: 700; border-radius: 6px; padding: 2px 6px; display: inline-block; }
.kpi-map-delta-up { background: rgba(22,163,74,.28); color: #eafff1; }
.kpi-map-delta-down { background: rgba(220,38,38,.32); color: #fff0f0; }
.kpi-map-delta-flat { background: rgba(255,255,255,.18); color: #fff; }
.kpi-map-total-card .kpi-map-badge-loss {
  display: flex;
  justify-content: space-between;
  align-items: center;
  background: var(--color-danger);
  border-radius: 8px;
  padding: 8px 10px;
  font-size: 12px;
}
.kpi-map-total-card .kpi-map-badge-loss b { font-size: 14px; }

.kpi-map-canvas {
  position: relative;
  width: 100%;
  aspect-ratio: 3 / 2; /* sama persis dgn rasio gambar peta 1536x1024, supaya posisi pin (%) pas tanpa distorsi/crop */
  height: auto;
  min-height: 280px;
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border);
  overflow: visible; /* popup pin boleh melebihi batas kanvas */
  background: #eef2f7;
}
/* Latar peta = foto/gambar poster asli, dibungkus wrapper terpisah supaya
   cuma gambarnya yang dipotong rapi sesuai radius, sedangkan pin & popup
   (di luar wrapper ini) tetap bebas overflow. */
.kpi-map-bg-wrap {
  position: absolute;
  inset: 0;
  border-radius: inherit;
  overflow: hidden;
  z-index: 0;
}
.kpi-map-bg-img {
  width: 100%;
  height: 100%;
  object-fit: cover; /* aman: rasio wrapper == rasio gambar asli, jadi tidak ada crop */
  display: block;
}
.kpi-map-img-missing {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 20px;
  font-size: 12px;
  color: var(--color-text-secondary);
  background: var(--color-primary-lighter);
}
.kpi-map-img-missing code { background: rgba(0,0,0,.07); padding: 1px 5px; border-radius: 4px; }
.kpi-map-fallback-note {
  position: absolute;
  top: 8px; left: 8px; right: 8px;
  z-index: 3;
  background: rgba(255,255,255,.92);
  border: 1px solid var(--color-border);
  border-radius: 8px;
  padding: 6px 10px;
  font-size: 10.5px;
  color: var(--color-text-secondary);
}
.kpi-map-pin {
  position: absolute;
  transform: translate(-50%, -50%);
  cursor: pointer;
  z-index: 2;
  text-align: center;
  pointer-events: auto;
  outline: none;
}
/* Pin sedang di-hover/fokus dinaikkan di atas SEMUA pin lain (bukan cuma
   tetangganya) supaya popup-nya tidak pernah tertutup pin lain, apa pun
   urutan DOM-nya. */
.kpi-map-pin:hover,
.kpi-map-pin:focus-within {
  z-index: 50;
}
/* Pin milik kita sendiri (bukan pin bawaan foto peta). Backdrop putih solid
   menutupi pin nomor statis yang tercetak di gambar, supaya yang benar-benar
   terlihat cuma pin kita — warna & angka ranking-nya ikut berubah tiap ganti
   filter Bulan karena ranking NKO tiap ULP memang beda-beda tiap bulan.
   Ukurannya sengaja dibuat PAS/kecil dan diposisikan hanya menutupi ikon pin
   nomor lama di atas titik jangkar (bukan meluas ke bawah), supaya TIDAK
   menutupi tulisan nama ULP yang tercetak di bawah pin pada gambar peta asli. */
.kpi-map-pin-mask {
  position: absolute;
  top: -30px; left: -15px;
  width: 30px; height: 30px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 0 0 2px rgba(0,0,0,.06);
}
.kpi-map-pin-marker {
  position: absolute;
  top: -32px; left: -13px;
  width: 26px; height: 26px;
  border-radius: 50% 50% 50% 0;
  background: var(--pin-color, #0b4da2);
  transform: rotate(-45deg);
  border: 2px solid #fff;
  box-shadow: var(--shadow-md);
  transition: transform .12s ease, box-shadow .12s ease;
}
.kpi-map-pin:hover .kpi-map-pin-marker,
.kpi-map-pin:focus-within .kpi-map-pin-marker {
  transform: rotate(-45deg) scale(1.12);
  box-shadow: 0 0 0 5px rgba(11,77,162,.16), var(--shadow-md);
}
.kpi-map-pin-rank {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  transform: rotate(45deg);
  color: #fff;
  font-size: 11px;
  font-weight: 800;
  line-height: 1;
}
.kpi-map-popcard {
  position: absolute;
  top: 8px; /* offset manual dari titik pin — tidak ada chip label lagi di
               canvas supaya tidak menutupi/dobel dengan nama ULP yang sudah
               tercetak di gambar peta aslinya */
  left: 50%;
  transform: translateX(-50%);
  width: 186px;
  max-width: min(186px, 62vw);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: 10px;
  box-shadow: var(--shadow-md);
  padding: 8px 10px;
  font-size: 11px;
  z-index: 3;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity .12s ease, transform .12s ease;
  text-align: left;
}
.kpi-map-pin:hover .kpi-map-popcard,
.kpi-map-pin:focus-within .kpi-map-popcard {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
}
/* Pin di sisi kiri/kanan kanvas -> popup diratakan ke sisi yang sama (bukan
   selalu center) supaya tidak kepotong tepi kanvas. Pin di baris bawah
   (y besar) -> popup dibuka ke ATAS pin, bukan ke bawah, supaya tidak
   kepotong batas bawah kanvas / ketutup kartu total di sebelahnya. */
.kpi-map-pin-align-left .kpi-map-popcard { left: 0; transform: translateX(-6%); }
.kpi-map-pin-align-right .kpi-map-popcard { left: auto; right: 0; transform: translateX(6%); }
.kpi-map-pin-align-left:hover .kpi-map-popcard,
.kpi-map-pin-align-left:focus-within .kpi-map-popcard { transform: translateX(-6%); }
.kpi-map-pin-align-right:hover .kpi-map-popcard,
.kpi-map-pin-align-right:focus-within .kpi-map-popcard { transform: translateX(6%); }
.kpi-map-pin-flip-top .kpi-map-popcard { top: auto; bottom: 20px; }
.kpi-map-pop-title {
  font-weight: 700;
  font-size: 11.5px;
  color: var(--color-text-primary);
  margin-bottom: 4px;
  border-bottom: 1px solid var(--color-border);
  padding-bottom: 4px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 6px;
}
.kpi-map-pop-score {
  color: #fff;
  font-size: 10px;
  font-weight: 800;
  border-radius: 5px;
  padding: 1px 6px;
}
.kpi-map-pop-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 4px 6px;
  margin-bottom: 4px;
}
.kpi-map-pop-item { background: var(--color-bg); border-radius: 6px; padding: 3px 5px; cursor: pointer; }
.kpi-map-pop-item:hover { background: var(--color-primary-light); }
.kpi-map-pop-item span { display: block; font-size: 9.5px; color: var(--color-text-muted); font-weight: 600; }
.kpi-map-pop-item b { font-size: 12px; color: var(--color-text-primary); }
.kpi-map-pop-foot {
  display: flex;
  justify-content: space-between;
  font-size: 10px;
  color: var(--color-text-secondary);
}
.kpi-map-pop-addr {
  display: block;
  margin-top: 5px;
  padding-top: 5px;
  border-top: 1px dashed var(--color-border);
  font-size: 9.5px;
  color: var(--color-primary);
  line-height: 1.35;
  text-decoration: none;
  cursor: pointer;
}
.kpi-map-pop-addr:hover { text-decoration: underline; }

.kpi-bagian-header td {
  background: var(--color-primary-light);
  color: var(--color-primary-dark);
  font-weight: 800;
  font-size: 11.5px;
  text-transform: uppercase;
  letter-spacing: .03em;
  padding: 8px 10px;
}

.kpi-grafik-grid {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 14px;
  align-items: stretch;
}
@media (max-width: 1400px) { .kpi-grafik-grid { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 900px) { .kpi-grafik-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 620px) { .kpi-grafik-grid { grid-template-columns: 1fr; } }

.kpi-grafik-grid-2 { grid-template-columns: repeat(2, 1fr); }
@media (max-width: 760px) { .kpi-grafik-grid-2 { grid-template-columns: 1fr; } }
.kpi-mini-panel { padding: 14px; min-width: 0; }
.kpi-mini-panel-title {
  font-size: 11.5px;
  font-weight: 700;
  color: var(--color-primary-darker);
  margin-bottom: 8px;
  line-height: 1.35;
}

.kpi-detail-table td.num, .data-table td.num { text-align: right; font-variant-numeric: tabular-nums; }
.kpi-group-row td {
  background: var(--color-primary-light);
  font-weight: 700;
  color: var(--color-primary-darker);
  font-size: 12.5px;
  padding-top: 8px;
  padding-bottom: 8px;
}

@media (max-width: 900px) {
  .kpi-filter-bar { padding: 10px 16px; }
  .kpi-conn-badge { margin-left: 0; }
}
.kpi-dir-icon {
  display: inline-block;
  width: 16px; text-align: center;
  font-weight: 700;
  color: var(--color-text-muted);
}

/* --- Kotak "Keterangan" (arah indikator + kategori Baik/Hati-hati/Awas),
   dirender terpisah dari baris tabel data ULP. --- */
.kpi-legend-box {
  margin-top: 14px;
  background: var(--color-bg);
  border: 1px solid var(--color-border, #e3e7ee);
  border-radius: 12px;
  padding: 14px 18px;
}
.kpi-legend-box .kpi-legend-title {
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--color-primary-darker);
  margin-bottom: 10px;
}
.kpi-legend-box .kpi-legend-total {
  font-size: 11.5px;
  color: var(--color-text-secondary);
  margin-bottom: 10px;
}
.kpi-legend-list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 6px 20px;
}
.kpi-legend-item {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  font-size: 12.5px;
  color: var(--color-text-secondary);
  line-height: 1.4;
}
.kpi-legend-item .kpi-legend-icon {
  flex: 0 0 auto;
  font-weight: 700;
}
@media (max-width: 900px) {
  .kpi-legend-list { grid-template-columns: 1fr; }
}

/* ========================================================================== 
   MOBILE LAYOUT — dashboard tetap terstruktur pada layar ponsel
   ========================================================================== */
@media (max-width: 600px) {
  html, body { max-width: 100%; overflow-x: hidden; }
  .sidebar { width: min(var(--sidebar-width), 86vw); }
  .main-wrapper { width: 100%; min-width: 0; }

  .navbar { height: var(--navbar-height); padding: 0 10px; gap: 8px; }
  .navbar-left { min-width: 0; flex: 1; }
  .navbar-title { min-width: 0; }
  .navbar-title h1 { font-size: 15px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .navbar-right { gap: 6px; flex: 0 0 auto; }
  .navbar-right .connection-badge { display: none; }
  .navbar-refresh { width: 36px; height: 36px; padding: 0; justify-content: center; }
  .navbar-refresh span { display: none; }

  .content { width: 100%; padding: 10px; overflow: hidden; }
  .content::before { background-size: min(72vw, 280px) auto; opacity: .07; }
  .page, .panel, .dashboard-grid, .dashboard-grid-2 { min-width: 0; max-width: 100%; }
  .panel { padding: 14px; border-radius: 10px; }
  .panel-header { gap: 8px; margin-bottom: 12px; }
  .panel-header h3 { font-size: 14px; line-height: 1.35; }
  .panel-sub { font-size: 11px; line-height: 1.45; }

  .page-header { padding: 14px; margin-bottom: 12px; gap: 12px; border-radius: 10px; }
  .page-header h2 { font-size: 17px; line-height: 1.3; }
  .page-actions { width: 100%; display: grid; grid-template-columns: 1fr; gap: 8px; }
  .page-actions .filter-select,
  .page-actions select,
  .filter-select { width: 100% !important; max-width: 100% !important; min-width: 0 !important; }

  /* Menimpa grid dua kolom yang ditulis inline di HTML. */
  .dashboard-grid,
  .dashboard-grid-2,
  .summary-grid,
  .summary-grid.cols-6,
  .kpi-grafik-grid,
  .kpi-grafik-grid-2 { grid-template-columns: minmax(0, 1fr) !important; gap: 12px; }

  .kpi-filter-bar { position: sticky; top: var(--navbar-height); width: 100%; padding: 8px 10px; gap: 8px; }
  .kpi-filter-group { width: 100%; display: grid; grid-template-columns: 1fr; gap: 5px; }
  .kpi-filter-group label { white-space: normal; }
  .kpi-filter-group .filter-select { width: 100%; }

  .chart-canvas-wrap { height: 230px !important; min-height: 0; }
  .kpi-mini-panel { padding: 12px; }
  .kpi-mini-panel-title { font-size: 11px; }

  .kpi-map-layout { gap: 12px; }
  .kpi-map-total-card { padding: 14px; }
  .kpi-map-canvas { min-height: 210px; border-radius: 10px; }
  .kpi-map-popcard { width: 160px; padding: 7px; }
  .kpi-map-pop-grid { grid-template-columns: 1fr; }

  .table-scroll { width: 100%; max-width: 100%; border-radius: 8px; overscroll-behavior-x: contain; -webkit-overflow-scrolling: touch; }
  table.data-table { min-width: 760px; font-size: 11.5px; }
  table.data-table.kpi-table-compact { min-width: 520px; }
  table.data-table.kpi-detail-table { min-width: 960px; }
  .data-table thead th, .data-table tbody td { padding: 9px 10px; }

  .kpi-legend-box { padding: 12px; }
  .kpi-legend-list { grid-template-columns: minmax(0, 1fr); }
  .kpi-legend-item { font-size: 11.5px; }

  .app-switcher-panel { width: calc(100vw - 20px); max-height: calc(100dvh - 20px); overflow-y: auto; }
  .detail-modal-panel, .kpi-modal-panel { width: calc(100vw - 20px); max-width: none; max-height: calc(100dvh - 20px); }
}

@media (max-width: 380px) {
  .content { padding: 8px; }
  .panel, .page-header { padding: 12px; }
  .chart-canvas-wrap { height: 210px !important; }
  .kpi-map-canvas { min-height: 190px; }
}
