* {
  box-sizing: border-box;
}

:root {
  --bg: #0a0a0a;
  --bg2: #101010;
  --card: #161616;
  --card2: #1b1b1b;
  --border: #262626;
  --text: #f2f2f2;
  --muted: #9a9a9a;
  --accent: #7cb518;
  --accent2: #a3e635;
  --green: #a3e635;
  --red: #f87171;
  --yellow: #fbbf24;
  --purple: #a78bfa;
}

body {
  margin: 0;
  font-family: Inter, Muli, 'Segoe UI', sans-serif;
  background: var(--bg);
  color: var(--text);
  font-size: 14px;
}

a {
  color: var(--accent2);
}

.hidden {
  display: none !important;
}

/* login */
.login-wrap {
  position: relative;
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #0a0a0a;
  padding: 24px;
  overflow: hidden;
}
.login-bg {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(720px 420px at 12% 8%, rgba(163, 230, 53, 0.16), transparent 62%),
    radial-gradient(760px 520px at 88% 92%, rgba(124, 181, 24, 0.12), transparent 62%),
    radial-gradient(1000px 700px at 50% 45%, #151515, #0a0a0a 72%);
}
.login-bg::after {
  content: '';
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(rgba(255, 255, 255, 0.028) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255, 255, 255, 0.028) 1px, transparent 1px);
  background-size: 38px 38px;
  -webkit-mask-image: radial-gradient(circle at 50% 42%, #000 0%, transparent 78%);
  mask-image: radial-gradient(circle at 50% 42%, #000 0%, transparent 78%);
}
/* Kartu login dua kolom: kiri keterangan, kanan formulir. Di layar sempit
   kolomnya ditumpuk supaya formulir tetap selebar layar ponsel. */
.login-card {
  position: relative;
  width: 100%;
  max-width: 780px;
  display: grid;
  grid-template-columns: 310px 1fr;
  background: linear-gradient(180deg, #1a1a1a 0%, #141414 100%);
  border: 1px solid #2a2a2a;
  border-radius: 22px;
  overflow: hidden;
  box-shadow: 0 30px 90px rgba(0, 0, 0, 0.65), 0 0 0 1px rgba(163, 230, 53, 0.04) inset, 0 0 60px rgba(163, 230, 53, 0.06);
}
.login-aside {
  padding: 40px 30px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  background: radial-gradient(420px 280px at 18% 12%, rgba(163, 230, 53, 0.15), transparent 66%), #101010;
  border-right: 1px solid #262626;
}
.login-main {
  padding: 40px 34px 32px;
}
.login-main h2 {
  margin: 0 0 20px;
  font-size: 16px;
  letter-spacing: 2px;
  text-transform: uppercase;
  color: #f5f5f5;
  font-weight: 800;
}
.logo-mark {
  width: 58px;
  height: 58px;
  border-radius: 50%;
  margin: 0 0 18px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 900;
  font-size: 20px;
  letter-spacing: 1px;
  color: #0c1200;
  background: linear-gradient(135deg, #b6f24a 0%, #7cb518 100%);
  box-shadow: 0 0 0 6px rgba(163, 230, 53, 0.08), 0 0 44px rgba(163, 230, 53, 0.35);
  /* overflow:hidden wajib begitu logo dipasang: kotak ini bulat, dan gambar
     persegi yang tidak dipotong akan meluber keluar lingkarannya. */
  position: relative;
  overflow: hidden;
}
/* Logo menutupi inisial, bukan menggantikannya — kalau alamatnya salah,
   onerror melepas gambarnya dan inisial di bawahnya sudah siap. */
/* object-fit:contain, bukan cover: kotak ini dipakai operator untuk logo apa pun,
   dan logo berbentuk kata (wordmark) yang lebar akan terpotong jadi beberapa
   huruf tengah saja kalau dipaksa memenuhi kotak. Untuk logo persegi hasilnya
   sama persis — contain hanya berbeda saat rasionya memang tidak sama. */
.logo-mark img {
  position: absolute;
  /* Jarak 8px dari tepi: kotaknya bulat, dan logo persegi yang menempel ke tepi
     lengkung akan terlihat terpotong sudutnya meski gambarnya utuh. */
  top: 8px;
  left: 8px;
  right: 8px;
  bottom: 8px;
  width: auto;
  height: auto;
  object-fit: contain;
  display: block;
}

/* Inisial disembunyikan hanya setelah logonya benar-benar tampil — kelasnya
   dipasang dari onload, jadi alamat yang salah meninggalkan inisialnya utuh.
   Yang dibuat tembus pandang adalah warnanya, bukan simpul teksnya yang dihapus:
   inisial itu cadangan yang harus tetap ada di DOM. */
.logo-mark.ada-logo {
  color: transparent;
}
.login-card h1 {
  margin: 0 0 6px;
  font-size: 20px;
  letter-spacing: 3px;
  color: #f5f5f5;
  font-weight: 800;
}
.login-card p.sub {
  margin: 0 0 22px;
  color: var(--muted);
  font-size: 11px;
  letter-spacing: 2px;
  text-transform: uppercase;
}
.login-points {
  margin: 0;
  padding: 0;
  list-style: none;
}
.login-points li {
  position: relative;
  padding-left: 18px;
  margin-bottom: 9px;
  font-size: 12.5px;
  line-height: 1.5;
  color: #8a8a8a;
}
.login-points li::before {
  content: '';
  position: absolute;
  left: 2px;
  top: 7px;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #7cb518;
}
.captcha-row {
  display: flex;
  gap: 10px;
  align-items: stretch;
}
.captcha-row input {
  flex: 1 1 auto;
  min-width: 0;
  text-transform: uppercase;
  letter-spacing: 3px;
  font-weight: 700;
}
.captcha-box {
  flex: 0 0 auto;
  width: 170px;
  height: 48px;
  padding: 0;
  line-height: 0;
  border: 1px solid #2c2c2c;
  border-radius: 12px;
  background: #0d0d0d;
  cursor: pointer;
  overflow: hidden;
  transition: border-color 0.15s;
}
.captcha-box:hover {
  border-color: #7cb518;
}
.captcha-box img {
  display: block;
  width: 170px;
  height: 48px;
}
.captcha-box.busy {
  opacity: 0.45;
  pointer-events: none;
}
.login-main .hint {
  margin-top: 6px;
  font-size: 11.5px;
}
/* Di ponsel sempit baris captcha ditumpuk: kotak input jadi sempit kalau
   gambarnya tetap dipaksa selebar 170px di sebelahnya. */
@media (max-width: 460px) {
  .captcha-row {
    flex-wrap: wrap;
  }
  .captcha-row input {
    flex: 1 1 100%;
  }
  /* Tingginya harus ikut melar, bukan tetap 48px. Kalau hanya lebarnya yang
     dipaksa 100%, SVG-nya (preserveAspectRatio "meet") diskalakan agar muat
     tinggi, sehingga kode captcha hanya menempati 170px di tengah kotak yang
     jauh lebih lebar — kelihatan kosong di kiri-kanan. aspect-ratio membuat
     kotaknya mengikuti perbandingan 170:48 milik SVG, jadi gambarnya mengisi
     penuh dan sekaligus ikut membesar di layar ponsel. */
  .captcha-box {
    width: 100%;
    height: auto;
    aspect-ratio: 170 / 48;
  }
  .captcha-box img {
    width: 100%;
    height: 100%;
  }
}
@media (max-width: 720px) {
  .login-card {
    grid-template-columns: 1fr;
    max-width: 430px;
  }
  .login-aside {
    padding: 26px 24px 22px;
    border-right: 0;
    border-bottom: 1px solid #262626;
  }
  .login-card p.sub {
    margin-bottom: 16px;
  }
  .login-points li:last-child {
    margin-bottom: 0;
  }
  .login-main {
    padding: 24px 24px 26px;
  }
}
.field {
  margin-bottom: 14px;
}
.field label {
  display: block;
  font-size: 12px;
  color: var(--muted);
  margin-bottom: 6px;
}
input,
select,
textarea {
  width: 100%;
  padding: 11px 14px;
  border-radius: 12px;
  border: 1px solid #2c2c2c;
  background: #0d0d0d;
  color: var(--text);
  font-size: 14px;
  outline: none;
  transition: border-color 0.15s, box-shadow 0.15s;
}
input::placeholder {
  color: #565656;
}
input:focus,
select:focus {
  border-color: #7cb518;
  box-shadow: 0 0 0 3px rgba(163, 230, 53, 0.12);
}
.btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  border: 0;
  border-radius: 999px;
  padding: 10px 18px;
  font-size: 13px;
  font-weight: 700;
  cursor: pointer;
  background: linear-gradient(135deg, #8ed11f 0%, #6ba60f 100%);
  color: #0c1200;
  transition: 0.15s;
  letter-spacing: 0.2px;
}
.btn:hover {
  filter: brightness(1.07);
  box-shadow: 0 0 24px rgba(163, 230, 53, 0.25);
}
/* Tombol yang mati harus TERLIHAT mati.
 *
 * Tanpa aturan ini, tombol ber-atribut `disabled` tampil sama persis dengan
 * yang aktif: di halaman Billing, agent melihat tombol "Buat Tagihan" menyala
 * hijau padahal bayar otomatis belum aktif untuknya, dan tidak ada reaksi apa
 * pun saat diklik. Diamnya tombol itu terbaca sebagai kerusakan, bukan sebagai
 * fitur yang belum dinyalakan. */
.btn:disabled,
.btn[disabled] {
  opacity: 0.45;
  cursor: not-allowed;
  filter: none;
  box-shadow: none;
}
.btn.secondary {
  background: #1e1e1e;
  color: var(--text);
  border: 1px solid #2e2e2e;
}
.btn.secondary:hover {
  background: #262626;
  box-shadow: none;
}
.btn.danger {
  background: #b91c1c;
}
.btn.danger:hover {
  background: #dc2626;
}
.btn.small {
  padding: 5px 10px;
  font-size: 12px;
}
.btn.wide {
  width: 100%;
  justify-content: center;
  padding: 12px;
}
.err {
  color: var(--red);
  font-size: 13px;
  margin-top: 10px;
  text-align: center;
  min-height: 18px;
}

/* layout */
.layout {
  display: flex;
  min-height: 100vh;
}
.sidebar {
  width: 236px;
  flex: 0 0 236px;
  background: #0e0e0e;
  border-right: 1px solid #1f1f1f;
  display: flex;
  flex-direction: column;
  position: sticky;
  top: 0;
  height: 100vh;
}
.brand {
  padding: 22px 18px 18px;
  font-weight: 800;
  letter-spacing: 2px;
  color: #f2f2f2;
  font-size: 16px;
  border-bottom: 1px solid #1f1f1f;
}
.brand::before {
  content: '';
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--accent2);
  margin-right: 9px;
  box-shadow: 0 0 14px rgba(163, 230, 53, 0.75);
}
/* Kalau ada logo, titik aksen di atas digantikan gambarnya — dua penanda merek
   berdampingan justru terlihat seperti kesalahan. */
.brand.ada-logo::before {
  content: none;
}
.brand .brand-mark {
  display: inline-block;
  /* Tinggi tetap, lebar mengikuti gambar: wordmark yang dipaksa masuk kotak
     18x18 akan gepeng. max-width menahannya supaya nama situs tidak terdorong
     keluar, dan object-fit:contain menjaga rasionya saat batas itu kena. */
  height: 18px;
  width: auto;
  max-width: 96px;
  border-radius: 5px;
  object-fit: contain;
  vertical-align: -4px;
  margin-right: 9px;
}
.brand small {
  display: block;
  color: var(--muted);
  font-size: 10px;
  letter-spacing: 3px;
  margin-top: 3px;
}
.nav {
  padding: 10px;
  flex: 1;
  overflow-y: auto;
}
.nav a {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  border-radius: 12px;
  color: var(--muted);
  text-decoration: none;
  font-weight: 500;
  font-size: 13.5px;
  margin-bottom: 3px;
  border: 1px solid transparent;
}
.nav a:hover {
  background: #181818;
  color: var(--text);
}
.nav a.active {
  background: rgba(163, 230, 53, 0.1);
  color: #cdf76e;
  border-color: rgba(163, 230, 53, 0.25);
}
.nav .ico {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: #1c1c1c;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 11px;
  flex: 0 0 28px;
}
.nav a.active .ico {
  background: linear-gradient(135deg, #b6f24a, #7cb518);
  color: #0c1200;
}
.side-foot {
  border-top: 1px solid var(--border);
  padding: 14px;
  font-size: 12px;
  color: var(--muted);
}
.side-foot b {
  color: var(--text);
  display: block;
  margin-bottom: 2px;
}
.btn-logout {
  width: 100%;
  margin-top: 12px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 9px 12px;
  border-radius: 8px;
  border: 1px solid rgba(248, 113, 113, 0.3);
  background: rgba(248, 113, 113, 0.08);
  color: #fca5a5;
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: 0.3px;
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}
.btn-logout:hover {
  background: #dc2626;
  border-color: #dc2626;
  color: #ffffff;
}
.btn-logout:active {
  transform: translateY(1px);
}
.main {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
}
.topbar {
  height: 62px;
  border-bottom: 1px solid #1d1d1d;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 24px;
  background: rgba(12, 12, 12, 0.78);
  backdrop-filter: blur(10px);
  position: sticky;
  top: 0;
  z-index: 20;
}
.topbar h2 {
  margin: 0;
  font-size: 17px;
}
.topbar .bal {
  display: flex;
  gap: 18px;
  align-items: center;
  font-size: 13px;
  color: var(--muted);
}
.topbar .bal b {
  color: var(--green);
  font-size: 15px;
}
.content {
  padding: 22px;
  flex: 1;
}

/* cards & tables */
.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 14px;
  margin-bottom: 20px;
}
.card {
  background: linear-gradient(180deg, #1a1a1a 0%, #141414 100%);
  border: 1px solid var(--border);
  border-radius: 18px;
  padding: 20px;
}
.card .lbl {
  color: var(--muted);
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 1px;
  margin-bottom: 8px;
}
.card .val {
  font-size: 24px;
  font-weight: 700;
}
/* Nama agent bukan angka: panjangnya tidak bisa ditebak, jadi ukurannya
 * diturunkan dari .val dan dibiarkan membungkus. Nama yang turun ke baris kedua
 * jauh lebih baik daripada nama yang meluber keluar kartunya. */
.card .val.ident-name {
  font-size: 18px;
  line-height: 1.3;
  word-break: break-word;
}
.card .val.green {
  color: var(--green);
}
.card .val.yellow {
  color: var(--yellow);
}
.card .val.purple {
  color: var(--purple);
}
.card .val.red {
  color: var(--red);
}
/* Baris TOTAL pada tabel laporan. Warnanya dibalik supaya terbaca sebagai
 * penutup tabel, bukan sebagai satu baris data biasa yang ikut tergulung. */
/* Tanggal panjang seperti "17/9/2026, 21.48.15" pecah di tengah angka kalau
 * kolomnya sempit ("21.4 / 8.15"), jadi sel waktu dipaksa satu baris. */
.nowrap {
  white-space: nowrap;
}
table tfoot th {
  background: var(--card2);
  border-top: 2px solid var(--border);
  color: var(--text);
  font-weight: 700;
  position: sticky;
  bottom: 0;
}
.panel-box {
  background: linear-gradient(180deg, #191919 0%, #141414 100%);
  border: 1px solid var(--border);
  border-radius: 18px;
  margin-bottom: 18px;
  overflow: hidden;
}
.panel-box .head {
  padding: 14px 18px;
  border-bottom: 1px solid var(--border);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  flex-wrap: wrap;
}
.panel-box .head h3 {
  margin: 0;
  font-size: 15px;
}
.panel-box .body {
  padding: 16px 18px;
}
.toolbar {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  align-items: center;
}
.toolbar input,
.toolbar select {
  width: auto;
  min-width: 140px;
  padding: 8px 10px;
}
table {
  width: 100%;
  border-collapse: collapse;
}
th,
td {
  text-align: left;
  padding: 10px 12px;
  border-bottom: 1px solid var(--border);
  font-size: 13px;
  vertical-align: middle;
}
th {
  color: var(--muted);
  font-weight: 600;
  font-size: 11.5px;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  white-space: nowrap;
}
tr:hover td {
  background: rgba(255, 255, 255, 0.015);
}
/*
 * Warna baris menurut role, hanya di tabel Agen & Downline dan hanya untuk
 * super admin (lihat renderAgents). Warnanya sengaja sangat tipis — 7% — karena
 * ini penanda, bukan hiasan: yang dibaca tetap teks kolomnya, dan baris yang
 * terlalu pekat justru membuat angka saldo susah dibaca di latar gelap.
 *
 * Garis tepi kiri 3px adalah pembeda utamanya. Ia cukup terlihat saat mata
 * menyapu tabel dari kiri, tanpa mengubah warna latar sebanyak yang dibutuhkan
 * blok penuh — dan tetap terbaca kalau suatu saat latar barisnya dihilangkan.
 * Warnanya mengikuti lencana role yang bersangkutan: ungu super admin, biru
 * head agent, hijau agent.
 */
tr.role-super_agent > td:first-child {
  box-shadow: inset 3px 0 0 var(--purple);
}
tr.role-head_agent > td:first-child {
  box-shadow: inset 3px 0 0 #25b6d8;
}
tr.role-agent > td:first-child {
  box-shadow: inset 3px 0 0 var(--accent);
}
tr.role-super_agent td {
  background: rgba(167, 139, 250, 0.07);
}
tr.role-head_agent td {
  background: rgba(37, 182, 216, 0.06);
}
tr.role-agent td {
  background: rgba(163, 230, 53, 0.04);
}
/* Hover dinaikkan sedikit di atas warna role-nya; tanpa ini efek hover bawaan
   tertimpa dan barisnya terasa mati saat disapu mouse. */
tr.role-super_agent:hover td,
tr.role-head_agent:hover td,
tr.role-agent:hover td {
  background: rgba(255, 255, 255, 0.055);
}
.table-wrap {
  overflow-x: auto;
}
.badge {
  display: inline-block;
  padding: 3px 9px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.3px;
}
.badge.green {
  background: rgba(52, 211, 153, 0.14);
  color: var(--green);
}
.badge.red {
  background: rgba(248, 113, 113, 0.14);
  color: var(--red);
}
.badge.yellow {
  background: rgba(251, 191, 36, 0.14);
  color: var(--yellow);
}
.badge.blue {
  background: rgba(37, 182, 216, 0.14);
  color: var(--accent2);
}
.badge.gray {
  background: rgba(139, 160, 191, 0.14);
  color: var(--muted);
}
.badge.purple {
  background: rgba(167, 139, 250, 0.14);
  color: var(--purple);
}
.empty {
  text-align: center;
  color: var(--muted);
  padding: 26px;
  font-size: 13px;
}
.mono {
  font-family: 'JetBrains Mono', Consolas, monospace;
  font-size: 12px;
}
.grid2 {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
}
.actions {
  display: flex;
  gap: 5px;
  flex-wrap: wrap;
}
.stat-line {
  display: flex;
  justify-content: space-between;
  padding: 7px 0;
  border-bottom: 1px dashed var(--border);
  font-size: 13px;
}
.stat-line:last-child {
  border: 0;
}
.stat-line span:first-child {
  color: var(--muted);
}

/* ---- form pengaturan ---- */

/* Judul pengelompokan di dalam satu kotak pengaturan. Jarak atasnya lebih besar
 * daripada jarak antar-field supaya kelompoknya terbaca sebagai bagian, bukan
 * sebagai field lain. */
.group-title {
  margin: 22px 0 12px;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--border);
  font-size: 12px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
}
.group-title:first-child {
  margin-top: 0;
}

/* Saklar on/off. Label-nya tetap ditampilkan karena input checkbox saja tidak
 * cukup jelas dibaca sebagai "aktif/mati" pada pengaturan yang berdampak uang. */
.switch-row {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  cursor: pointer;
  font-size: 14px;
  color: var(--text);
  margin-bottom: 0;
}
.switch-row input[type='checkbox'] {
  width: 18px;
  height: 18px;
  padding: 0;
  margin: 0;
  accent-color: var(--accent);
  cursor: pointer;
}
.switch-row span {
  color: var(--text);
}

/* Pemilih warna dan kotak teksnya ditampilkan berdampingan: pemilihnya enak
 * untuk memilih, kotak teksnya perlu untuk menempel kode warna dari pedoman
 * merek. Keduanya menulis ke pengaturan yang sama. */
.color-row {
  display: flex;
  gap: 10px;
  align-items: center;
}
.color-row input[type='color'] {
  width: 56px;
  height: 42px;
  padding: 3px;
  flex: 0 0 auto;
  cursor: pointer;
}

/* modal */
.modal-back {
  position: fixed;
  inset: 0;
  background: rgba(4, 8, 16, 0.7);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 100;
  padding: 16px;
}
.modal {
  background: linear-gradient(180deg, #1a1a1a, #151515);
  border: 1px solid #2c2c2c;
  border-radius: 20px;
  width: 100%;
  max-width: 520px;
  max-height: 90vh;
  overflow-y: auto;
  box-shadow: 0 30px 90px rgba(0, 0, 0, 0.7);
}
.modal.wide {
  max-width: 760px;
}
.modal .m-head {
  padding: 16px 20px;
  border-bottom: 1px solid var(--border);
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.modal .m-head h3 {
  margin: 0;
  font-size: 15px;
}
.modal .m-body {
  padding: 18px 20px;
}
.modal .m-foot {
  padding: 14px 20px;
  border-top: 1px solid var(--border);
  display: flex;
  justify-content: flex-end;
  gap: 8px;
}
.x-close {
  cursor: pointer;
  color: var(--muted);
  font-size: 18px;
  line-height: 1;
  background: none;
  border: 0;
}
.x-close:hover {
  color: var(--red);
}

/* toast */
#toast {
  position: fixed;
  right: 18px;
  bottom: 18px;
  z-index: 200;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.toast-item {
  background: #1b1b1b;
  border: 1px solid #2c2c2c;
  border-left: 4px solid var(--accent2);
  padding: 12px 16px;
  border-radius: 12px;
  font-size: 13px;
  min-width: 240px;
  max-width: 360px;
  box-shadow: 0 14px 40px rgba(0, 0, 0, 0.55);
  animation: slideIn 0.2s ease;
  /* Judul dan pesannya adalah <b> dan <span> — keduanya inline, dan di DOM
     keduanya bersebelahan tanpa spasi. Sebagai satu baris, judulnya menempel
     ke pesannya sendiri ("Topup berhasil5.000 coin masuk…"). Ditumpuk, lalu
     diberi jarak. */
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.toast-item b {
  font-size: 12.5px;
  letter-spacing: 0.2px;
  color: var(--text);
}
.toast-item > span {
  color: var(--muted);
  line-height: 1.5;
  /* Pesan panjang (mis. ringkasan sync) boleh turun baris; yang tidak boleh
     adalah satu kata panjang tanpa spasi mendorong kotaknya melebar. */
  overflow-wrap: anywhere;
}
.toast-item.ok {
  border-left-color: var(--green);
}
.toast-item.err {
  border-left-color: var(--red);
}
@keyframes slideIn {
  from {
    opacity: 0;
    transform: translateX(20px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

.copy-box {
  background: #0d0d0d;
  border: 1px dashed #2e2e2e;
  border-radius: 12px;
  padding: 10px 14px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 10px;
  margin-bottom: 8px;
}
.copy-box .mono {
  word-break: break-all;
}
pre.code {
  background: #0c0c0c;
  border: 1px solid #242424;
  border-radius: 14px;
  padding: 14px;
  overflow-x: auto;
  font-size: 12px;
  line-height: 1.55;
  font-family: 'JetBrains Mono', Consolas, monospace;
  color: #b9c9a4;
}
.tabs {
  display: flex;
  gap: 6px;
  margin-bottom: 14px;
  flex-wrap: wrap;
}
.tabs button {
  background: #161616;
  border: 1px solid var(--border);
  color: var(--muted);
  padding: 8px 16px;
  border-radius: 999px;
  cursor: pointer;
  font-size: 12.5px;
  font-weight: 600;
}
.tabs button.active {
  background: rgba(163, 230, 53, 0.12);
  color: #cdf76e;
  border-color: rgba(163, 230, 53, 0.4);
}
.pasaran-card {
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 18px;
  margin-bottom: 12px;
  background: linear-gradient(180deg, #181818, #131313);
}
.pasaran-card .pc-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
}
.pasaran-card h4 {
  margin: 0 0 4px;
  font-size: 15px;
}
.pasaran-card .sub {
  color: var(--muted);
  font-size: 12px;
}
.countdown {
  font-family: 'JetBrains Mono', monospace;
  font-size: 20px;
  color: var(--yellow);
  font-weight: 700;
}
.countdown.closed {
  color: var(--red);
}
.hint {
  color: var(--muted);
  font-size: 12px;
  line-height: 1.5;
}
/* Peringatan yang menempel pada sebuah tindakan: dipakai saat saklar yang
 * hendak dinyalakan tidak akan berpengaruh karena syarat lain belum terpenuhi. */
.hint.warn {
  color: var(--yellow, #e0af68);
  background: rgba(224, 175, 104, 0.1);
  border: 1px solid rgba(224, 175, 104, 0.35);
  border-radius: 8px;
  padding: 10px 12px;
}
.live-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(185px, 1fr));
  gap: 12px;
}
.live-market {
  background: linear-gradient(180deg, #181818, #121212);
  border: 1px solid #262626;
  border-radius: 14px;
  padding: 14px;
}
.live-market .lm-top {
  display: flex;
  gap: 6px;
  margin-bottom: 9px;
}
.live-market .lm-name {
  font-weight: 700;
  font-size: 13.5px;
  margin-bottom: 3px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.live-market .lm-sub {
  color: var(--muted);
  font-size: 11px;
  margin-bottom: 9px;
}
.live-market .lm-timer {
  font-size: 17px;
}
@media (max-width: 860px) {
  .layout {
    flex-direction: column;
  }
  .sidebar {
    width: 100%;
    flex: none;
    height: auto;
    position: static;
  }
  .nav {
    display: flex;
    overflow-x: auto;
    padding: 8px;
  }
  .nav a {
    white-space: nowrap;
    margin-bottom: 0;
  }
  .side-foot {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 4px 12px;
    border-top: 0;
    padding: 10px 14px;
  }
  .side-foot b {
    display: inline;
    margin-bottom: 0;
  }
  .side-foot span {
    flex: 1;
  }
  .btn-logout {
    width: auto;
    margin-top: 0;
    padding: 7px 12px;
  }
  .content {
    padding: 14px;
  }
  .grid2 {
    grid-template-columns: 1fr;
  }
  .topbar .bal {
    gap: 10px;
    font-size: 12px;
  }
}

@media (max-width: 640px) {
  .topbar {
    height: auto;
    padding: 10px 14px;
    flex-wrap: wrap;
    gap: 6px;
  }
  .topbar h2 {
    font-size: 15px;
  }
  .topbar .bal {
    flex-wrap: wrap;
  }
  .content {
    padding: 10px;
  }
  .panel-box .head {
    padding: 12px;
  }
  .panel-box .body {
    padding: 12px;
  }
  .toolbar input,
  .toolbar select {
    min-width: 0;
    flex: 1 1 100%;
  }
  pre.code {
    white-space: pre-wrap;
    word-break: break-word;
  }
  .copy-box {
    flex-wrap: wrap;
  }
  .copy-box .mono {
    flex: 1 1 100%;
  }
  .modal .m-body {
    padding: 14px;
  }
  .modal .m-foot {
    flex-wrap: wrap;
    justify-content: stretch;
  }
  .modal .m-foot .btn {
    flex: 1;
    justify-content: center;
  }
  .table-wrap {
    -webkit-overflow-scrolling: touch;
  }
  #toast {
    left: 12px;
    right: 12px;
  }
  .toast-item {
    min-width: 0;
  }
}

/* ===== Referensi API =====
   Satu method = satu <details>. Yang terlihat sekaligus hanya nama, penanda
   sifatnya, dan ringkasan satu baris; rinciannya dibuka sesuai kebutuhan.
   Dua puluh lima kartu terbuka sekaligus membuat halaman ini tidak terbaca. */
.api-method {
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--card2);
  margin-bottom: 8px;
  overflow: hidden;
}
.api-method > summary {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  padding: 11px 14px;
  cursor: pointer;
  list-style: none;
}
/* Penanda buka-tutup digambar sendiri supaya tidak bergantung pada segitiga
   bawaan peramban, yang bentuknya berbeda-beda dan tidak bisa diberi warna. */
.api-method > summary::-webkit-details-marker {
  display: none;
}
.api-method > summary::before {
  content: '\25B8';
  color: var(--muted);
  font-size: 11px;
  transition: transform 0.15s;
}
.api-method[open] > summary::before {
  transform: rotate(90deg);
}
.api-method > summary:hover {
  background: var(--card);
}
.api-method[open] > summary {
  border-bottom: 1px solid var(--border);
}
.api-name {
  font-size: 13.5px;
  font-weight: 600;
  color: var(--accent2);
}
.api-ringkas {
  flex: 1 1 240px;
  min-width: 0;
  color: var(--muted);
  font-size: 12px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Begitu dibuka, ringkasan boleh membungkus — dipotong lagi justru menyembunyikan
   keterangan yang sedang dibaca. Di layar sempit ini praktis selalu berlaku. */
.api-method[open] .api-ringkas {
  white-space: normal;
}
.api-flag {
  font-size: 10px;
  letter-spacing: 0.4px;
  text-transform: uppercase;
  padding: 2px 7px;
  border-radius: 20px;
  border: 1px solid var(--border);
  white-space: nowrap;
}
.api-flag.aman {
  color: var(--green);
  border-color: rgba(163, 230, 53, 0.35);
}
.api-flag.ubah {
  color: var(--yellow);
  border-color: rgba(251, 191, 36, 0.4);
}
.api-flag.role {
  color: var(--purple);
  border-color: rgba(167, 139, 250, 0.4);
}
.api-detail {
  padding: 14px;
}
.api-lbl {
  color: var(--muted);
  font-size: 11px;
  letter-spacing: 0.5px;
  margin-bottom: 6px;
}
.api-verb {
  display: inline-block;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.4px;
  padding: 2px 7px;
  border-radius: 5px;
  background: var(--card2);
  color: var(--muted);
  border: 1px solid var(--border);
}
.api-verb.v-get {
  color: var(--green);
}
.api-verb.v-post {
  color: var(--yellow);
}
.api-verb.v-put {
  color: var(--purple);
}
.api-verb.v-delete {
  color: var(--red);
}
/* Rujukan silang dari tabel REST ke rincian methodnya. Bukan tautan sungguhan
   (lihat catatan di panel.js), jadi bentuknya dibuat seperti istilah yang bisa
   diklik — garis bawah putus-putus, bukan garis penuh milik <a>. */
.api-link {
  color: var(--accent2);
  cursor: pointer;
  text-decoration: underline dotted;
  text-underline-offset: 3px;
}
.api-link:hover {
  color: var(--accent);
}
