/* ===== Selisik — Wacana & Koordinasi Digital (Poppins, GELAP sebagai bawaan) ===== */
@font-face { font-family: "Poppins"; font-weight: 400; font-display: swap;
  src: url("../vendor/poppins/latin-400-normal.woff2") format("woff2"); }
@font-face { font-family: "Poppins"; font-weight: 500; font-display: swap;
  src: url("../vendor/poppins/latin-500-normal.woff2") format("woff2"); }
@font-face { font-family: "Poppins"; font-weight: 600; font-display: swap;
  src: url("../vendor/poppins/latin-600-normal.woff2") format("woff2"); }
@font-face { font-family: "Poppins"; font-weight: 700; font-display: swap;
  src: url("../vendor/poppins/latin-700-normal.woff2") format("woff2"); }

/* Tema GELAP adalah bawaan: ia tinggal di :root, sehingga halaman tampil gelap
   bahkan sebelum JavaScript apa pun berjalan. Tema terang menimpa lewat
   [data-theme="light"] yang dipasang skrip inline di <head> sebelum render.
   Palet mengikuti referensi: hitam pekat, oranye tajam, putih hangat. */
:root {
  /* gelap (bawaan) */
  color-scheme: dark;
  --bg: #0d0d0f; --surface: #161618; --surface-2: #1f1f23; --sidebar-bg: #111113;
  --ink: #f7f4f0; --ink-soft: #b5b0a9; --muted: #837f79;
  --line: #27272b; --line-2: #36363c;
  --primary: #ff7a1a; --primary-ink: #1a0d02; --primary-soft: #2e1a09;
  --amber: #e8b04b; --amber-soft: #2b2210; --danger: #f2695f; --danger-soft: #2c1615;
  --ok: #4fc98a; --ok-soft: #123023;
  --accent: #ff7a1a; --edge: #3a3a41; --node: #6e6a64; --danger-node: #f2695f;
  --shadow-sm: 0 1px 2px rgba(0,0,0,.5);
  --shadow: 0 1px 3px rgba(0,0,0,.5), 0 14px 34px rgba(0,0,0,.45);
  /* Pil navbar publik SELALU terang (krem) — di tema gelap maupun terang. Ia
     bagian dari identitas halaman publik, bukan permukaan yang ikut tema, jadi
     token --nav-* ini sengaja TIDAK ditimpa di :root[data-theme="light"].
     Dipisah dari --ink/--surface agar warnanya tak merembet ke komponen lain. */
  --nav-bg: #f7f4f0; --nav-ink: #17161a; --nav-ink-soft: #4d4a52; --nav-line: #ded8ce;
  --font: "Poppins", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, monospace;
  --radius: 18px;
  /* Container tunggal halaman publik: navbar, hero, seksi, footer.
     Lebarnya bertangga mengikuti breakpoint (cara Bootstrap), bukan satu nilai
     tetap: di bawah 576px ia fluid (100% lebar layar), lalu mengunci ke lebar
     tetap tiap breakpoint agar baris teks tidak ikut melar di layar lebar.
     Tangganya ada di blok "Tangga container" di bawah. */
  --container: 100%; --container-pad: clamp(20px, 5vw, 40px);
}
/* Tema terang memakai aksen BIRU, bukan oranye — oranye pekat di atas latar
   terang membaca sebagai peringatan, sementara di atas hitam ia membaca sebagai
   energi. Netralnya ikut didinginkan: biru di atas krem hangat bentrok suhu. */
:root[data-theme="light"] {
  color-scheme: light;
  --bg: #f4f6fa; --surface: #ffffff; --surface-2: #eef1f7; --sidebar-bg: #ffffff;
  --ink: #15181f; --ink-soft: #495264; --muted: #7b8496;
  --line: #e3e7f0; --line-2: #d2d9e6;
  --primary: #1d5fd1; --primary-ink: #ffffff; --primary-soft: #e6eefc;
  --amber: #9a6b0f; --amber-soft: #fbf0d9; --danger: #cb4034; --danger-soft: #fbe7e4;
  --ok: #1f8b5c; --ok-soft: #e0f3e9;
  --accent: #1d5fd1; --edge: #c3ccdd; --node: #97a1b5; --danger-node: #cb4034;
  --shadow-sm: 0 1px 2px rgba(16,22,38,.06);
  --shadow: 0 1px 3px rgba(16,22,38,.07), 0 12px 30px rgba(16,22,38,.08);
  /* --nav-* sengaja tidak ada di sini: pil navbar tetap krem di kedua tema.
     Di latar terang ia terbaca sebagai kartu mengambang — dipisahkan oleh
     --nav-line + --shadow, bukan oleh kontras nilai. Jangan ditimpa. */
}

/* ---------- Tangga container (breakpoint ala Bootstrap) ----------
   Ambang sm/md/lg/xl/xxl sengaja disamakan dengan Bootstrap supaya lebar
   halaman terasa familiar dan mudah dirujuk. Ditulis min-width agar bertambah
   naik dari basis fluid; nilai terakhir yang cocok yang menang. */
@media (min-width:  576px) { :root { --container:  540px; } }   /* sm  */
@media (min-width:  768px) { :root { --container:  720px; } }   /* md  */
@media (min-width:  992px) { :root { --container:  960px; } }   /* lg  */
@media (min-width: 1200px) { :root { --container: 1140px; } }   /* xl  */
@media (min-width: 1400px) { :root { --container: 1320px; } }   /* xxl */

* { box-sizing: border-box; }
[x-cloak] { display: none !important; }
html, body { background: var(--bg); }
body { margin: 0; color: var(--ink); font-family: var(--font); line-height: 1.6;
  -webkit-font-smoothing: antialiased; font-size: 15px; }
a { color: var(--primary); text-decoration: none; }
.mono { font-family: var(--mono); }
.small { font-size: 12.5px; }
.muted { color: var(--muted); }
.err { color: var(--danger); font-size: 13.5px; margin-top: 12px; font-weight: 500; }
h1, h2, h3 { letter-spacing: -.015em; }

/* ---------- App shell ---------- */
/* 268px, bukan 252: pada lebar lama subjudul merek membungkus jadi dua baris
   dan meter kuota kehabisan ruang untuk angkanya. */
.app { display: grid; grid-template-columns: 268px 1fr; min-height: 100vh; }

.sidebar { position: sticky; top: 0; align-self: start; height: 100vh; overflow-y: auto;
  background: var(--sidebar-bg); border-right: 1px solid var(--line);
  display: flex; flex-direction: column; gap: 6px; padding: 22px 18px; }
.brand-row { display: flex; align-items: center; gap: 6px; padding-bottom: 14px; }
.brand { display: flex; align-items: center; gap: 12px; padding: 6px 8px; flex: 1; min-width: 0; }
.rail-btn { flex: none; width: 30px; height: 30px; display: grid; place-items: center;
  border: 0; border-radius: 8px; background: none; color: var(--muted); cursor: pointer;
  font-size: 12px; transition: background .13s, color .13s; }
.rail-btn:hover { background: var(--surface-2); color: var(--ink); }
.brand-mark { width: 40px; height: 40px; flex: none; display: grid; place-items: center;
  background: var(--primary); color: var(--primary-ink); border-radius: 11px; font-size: 17px;
  box-shadow: 0 6px 16px color-mix(in srgb, var(--primary) 30%, transparent); }
.brand-text { display: flex; flex-direction: column; line-height: 1.2; font-weight: 500;
  min-width: 0; }
.brand-text b { font-weight: 700; }
/* Satu baris atau terpotong rapi — subjudul yang membungkus merusak tinggi
   baris merek dan mendorong seluruh menu turun. */
.brand-text small { color: var(--muted); font-size: 10.5px; font-weight: 500; margin-top: 2px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.nav { display: flex; flex-direction: column; gap: 2px; }
/* Kapsi seksi: satu definisi dipakai sidebar DAN palet perintah. */
.nav-cap { font-family: var(--mono); text-transform: uppercase; letter-spacing: .09em;
  font-size: 9.5px; color: var(--muted); margin: 16px 0 5px; padding-left: 13px; }
.nav-cap:first-child { margin-top: 2px; }
.nav-item { position: relative; display: flex; align-items: center; gap: 12px;
  padding: 10px 13px; border-radius: 10px; color: var(--ink-soft); font-weight: 500;
  font-size: 14px; transition: background .13s, color .13s; }
.nav-item i { width: 18px; flex: none; text-align: center; color: var(--muted); font-size: 15px; }
.nav-item:hover { background: var(--surface-2); color: var(--ink); }
.nav-item.active { background: var(--primary-soft); color: var(--primary); font-weight: 600; }
.nav-item.active i { color: var(--primary); }
/* Garis aksen kiri: latar lembut saja mudah tenggelam, terutama di tema gelap. */
.nav-item.active::before { content: ""; position: absolute; left: -18px; top: 7px; bottom: 7px;
  width: 3px; border-radius: 0 3px 3px 0; background: var(--primary); }
.nav-badge, .nav-kbd { margin-left: auto; }
.nav-kbd { font-family: var(--mono); font-size: 10px; color: var(--muted);
  border: 1px solid var(--line-2); border-radius: 5px; padding: 1px 5px; }

/* Tombol palet perintah. Sengaja berbentuk kolom cari, bukan item menu: ⌘K
   membuka palet, jadi lencananya harus menempel di sini — bukan di tautan
   Pencarian yang tak dipicu pintasan itu. */
.nav-search { display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 9px 12px; margin-bottom: 4px; border-radius: 10px; cursor: pointer;
  background: var(--surface-2); border: 1px solid var(--line-2); color: var(--muted);
  font-family: var(--font); font-size: 13px; text-align: left; }
.nav-search:hover { color: var(--ink); border-color: var(--primary); }
.nav-search i { font-size: 12.5px; }
.nav-search span { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; }

/* Mendorong footer ke dasar. Menggantikan margin-top:auto agar panel analisis
   berjalan bisa duduk tepat di bawah menu, bukan ikut terlempar ke bawah. */
.nav-spacer { flex: 1; min-height: 12px; }

/* Admin Django meninggalkan desain aplikasi — dipisah & diredam. */
.nav-aside { padding-top: 10px; border-top: 1px dashed var(--line-2); }
.nav-aside .nav-item { font-size: 13px; color: var(--muted); }
.nav-ext { margin-left: auto; font-size: 10px !important; }

/* ---------- Panel analisis berjalan (sidebar) ---------- */
.jobcard { margin-top: 14px; padding: 12px; border-radius: 12px;
  background: var(--surface); border: 1px solid var(--line);
  display: flex; flex-direction: column; gap: 8px; }
/* display pada kelas mengalahkan [hidden] bawaan browser — tanpa baris ini
   panel tetap tampak (kosong) padahal tak ada analisis yang berjalan. */
.jobcard[hidden] { display: none; }
.jc-top { display: flex; align-items: center; gap: 8px; }
.jc-dot { width: 7px; height: 7px; flex: none; border-radius: 999px; background: var(--primary);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary) 18%, transparent);
  animation: jc-pulse 1.8s ease-in-out infinite; }
@keyframes jc-pulse { 50% { opacity: .35; } }
.jc-top b { font-size: 11.5px; font-weight: 600; color: var(--ink-soft); }
.jc-x { margin-left: auto; border: 0; background: none; cursor: pointer; padding: 0 2px;
  color: var(--muted); font-size: 12px; }
.jc-x:hover { color: var(--danger); }
.jc-key { display: block; font-size: 13px; font-weight: 600; color: var(--ink);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.jc-key:hover { color: var(--primary); }
.jc-meta { display: flex; justify-content: space-between; gap: 8px;
  font-family: var(--mono); font-size: 10px; color: var(--muted);
  font-variant-numeric: tabular-nums; }
.jc-meta span:first-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Bar tipis dipakai panel analisis DAN meter kuota. */
.meter { height: 4px; border-radius: 999px; background: var(--surface-2); overflow: hidden; }
.meter > i { display: block; height: 100%; border-radius: 999px; background: var(--primary);
  transition: width .3s ease; }
.meter > i.ok { background: var(--ok); }
.meter > i.warn { background: var(--amber); }
.meter > i.danger { background: var(--danger); }

/* ---------- Meter kuota (footer sidebar) ---------- */
.quota { display: flex; flex-direction: column; gap: 6px; padding: 2px 6px 10px; }
.quota-row { display: flex; justify-content: space-between; gap: 8px;
  font-family: var(--mono); font-size: 10px; color: var(--muted);
  font-variant-numeric: tabular-nums; }
.quota-row b { color: var(--ink-soft); font-weight: 600; }
.quota-note { margin: 0; font-family: var(--mono); font-size: 10px; color: var(--ok); }


.sidebar-foot { margin-top: auto; padding: 12px 0 0; border-top: 1px solid var(--line); }
.theme-toggle { width: 100%; display: flex; align-items: center; justify-content: center; gap: 9px;
  background: var(--surface-2); border: 1px solid var(--line); color: var(--ink-soft);
  border-radius: 10px; padding: 10px; cursor: pointer; font-family: var(--font); font-size: 13.5px; font-weight: 500; }
.theme-toggle:hover { color: var(--primary); border-color: var(--primary); }

.main { min-width: 0; display: flex; flex-direction: column; }
.mainbar { position: sticky; top: 0; z-index: 5; display: flex; align-items: center; justify-content: space-between;
  gap: 16px; padding: 16px 30px; background: color-mix(in srgb, var(--bg) 88%, transparent);
  backdrop-filter: blur(8px); border-bottom: 1px solid var(--line); }
.page-title { font-size: 21px; font-weight: 600; margin: 0; }
.page-sub { color: var(--muted); font-size: 13px; margin: 2px 0 0; }
.content { padding: 26px 32px 64px; width: 100%; }

/* ---------- Buttons ---------- */
/* line-height WAJIB eksplisit: peramban memberi <button> line-height:normal
   sedangkan <a> mewarisi 1,6 dari body. Tanpa ini, tombol yang sama persis
   punya tinggi berbeda tergantung ditulis sebagai <a> atau <button>. */
/* Bentuk pil mengikuti referensi desain — dipakai konsisten oleh semua tombol. */
.btn-primary { display: inline-flex; align-items: center; gap: 8px; background: var(--primary);
  color: var(--primary-ink); border: 0; border-radius: 999px; padding: 10px 20px; font-family: var(--font);
  font-size: 14px; font-weight: 600; line-height: 1.5; cursor: pointer;
  transition: filter .14s, transform .1s;
  box-shadow: 0 6px 18px color-mix(in srgb, var(--primary) 28%, transparent); }
.btn-primary:hover { filter: brightness(1.06); transform: translateY(-1px); }
.btn-primary.sm { padding: 7px 14px; font-size: 13px; box-shadow: none; }

/* ---------- KPIs ---------- */
.kpis { display: grid; grid-template-columns: repeat(3, 1fr); gap: 15px; margin-bottom: 22px; }
.kpis.wide { grid-template-columns: repeat(4, 1fr); }
.kpi { display: flex; align-items: center; gap: 15px; background: var(--surface); border: 1px solid var(--line);
  border-radius: 14px; padding: 18px 20px; box-shadow: var(--shadow-sm); }
.kpi-ic { width: 44px; height: 44px; flex: none; display: grid; place-items: center; border-radius: 11px;
  background: var(--primary-soft); color: var(--primary); font-size: 18px; }
.kpi.warn .kpi-ic { background: var(--amber-soft); color: var(--amber); }
.kpi-num { display: block; font-size: 25px; font-weight: 700; line-height: 1; font-variant-numeric: tabular-nums; }
.kpi-lbl { color: var(--muted); font-size: 12.5px; }
.kpi.warn .kpi-num { color: var(--amber); }

/* ---------- Cards / blocks ---------- */
.card { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 24px; margin-bottom: 20px; box-shadow: var(--shadow-sm); }
.card-head { margin-bottom: 8px; }
.card h2 { font-size: 17px; font-weight: 600; margin: 0; display: flex; align-items: center; gap: 10px; }
.card h2 i, .card h3 i { color: var(--primary); font-size: .92em; }
.card h3 { font-size: 13px; color: var(--primary); margin: 0 0 8px; font-weight: 600; }
.block { margin: 28px 0; }
.block-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; }
.block-head h2 { font-size: 16px; font-weight: 600; margin: 0; }
.block-head i { color: var(--primary); }
.link-more { font-size: 13px; font-weight: 500; }

/* ---------- Search console ---------- */
.searchbar { display: flex; align-items: center; gap: 11px; background: var(--bg);
  border: 1.5px solid var(--line-2); border-radius: 10px; padding: 0 14px; transition: border-color .15s, box-shadow .15s; }
.searchbar:focus-within { border-color: var(--primary); box-shadow: 0 0 0 3px var(--primary-soft); }
.searchbar > i { color: var(--muted); font-size: 14px; }
.searchbar input { flex: 1; border: 0; background: transparent; color: var(--ink); font-size: 14.5px;
  padding: 9px 0; line-height: 1.4; font-family: var(--font); outline: none; }

.src-label { font-family: var(--mono); font-size: 11px; text-transform: uppercase; letter-spacing: .07em;
  color: var(--muted); margin: 22px 0 11px; }
.src-label i { color: var(--primary); }
/* Pemilih sumber: daftar padat berkolom, bukan awan pil.
   Dengan 21 sumber, pil yang membungkus menghasilkan tepi kanan bergerigi dan
   tak ada urutan pindaian. Grid dengan jumlah baris eksplisit (--rows dari view)
   dipakai agar isian mengalir KE BAWAH dulu — membaca daftar outlet menurun
   lebih wajar daripada zig-zag. Multi-kolom CSS sempat dicoba dan ditinggalkan:
   kolomnya menyusut ke lebar intrinsik tombol, bukan separuh kartu. */
/* NB: JANGAN pakai nama .src-list di sini — kelas itu sudah dipakai kolom
   "sumber" pada tabel Riwayat dengan max-width:200px, yang diam-diam
   menyempitkan pemilih ini menjadi dua kolom selebar 110px. */
.src-picker { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  column-gap: 26px; margin-top: 2px; }
/* min-width:0 wajib: tanpanya kolom grid melebar mengikuti teks terpanjang dan
   ellipsis pada nama sumber tak pernah aktif. */
.src-picker-col { min-width: 0; display: flex; flex-direction: column; }
@media (max-width: 760px) { .src-picker { grid-template-columns: 1fr; } }

.src-opt { display: flex; align-items: center; gap: 11px; min-width: 0;
  padding: 7px 10px; border: 0; border-radius: 9px; background: none; cursor: pointer;
  font-family: var(--font); font-size: 13.5px; color: var(--ink-soft); text-align: left;
  transition: background .12s, color .12s; }
.src-opt:hover { background: var(--surface-2); color: var(--ink); }
.src-opt:focus-visible { outline: 2px solid var(--primary); outline-offset: -2px; }
.src-box { flex: none; width: 17px; height: 17px; border: 1.5px solid var(--line-2);
  border-radius: 5px; display: grid; place-items: center; font-size: 9px;
  color: transparent; transition: background .12s, border-color .12s, color .12s; }
.src-opt-ic { flex: none; width: 16px; text-align: center; color: var(--muted); font-size: 13px; }
.src-opt-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.src-opt-meta { flex: none; font-size: 10.5px; color: var(--muted); max-width: 42%;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.src-opt.on { color: var(--ink); font-weight: 500; }
.src-opt.on .src-box { background: var(--primary); border-color: var(--primary);
  color: var(--primary-ink); }
.src-opt.on .src-opt-ic { color: var(--primary); }

.console-actions { display: flex; align-items: center; justify-content: space-between;
  gap: 16px; margin-top: 24px; flex-wrap: wrap; }
.console-actions > .msg { max-width: 52ch; margin: 0; }

/* Maks/sumber menyatu di ujung kanan bilah pencarian: batas per-sumber adalah
   parameter kueri, jadi tempatnya di samping kata kunci — bukan di baris tombol. */
.searchbar-sep { flex: none; align-self: stretch; width: 1px; margin: 9px 0; background: var(--line-2); }
.searchbar-limit { flex: none; display: flex; align-items: center; gap: 8px; white-space: nowrap;
  font-family: var(--mono); font-size: 11.5px; color: var(--muted); }
.searchbar-limit > i { color: var(--muted); font-size: 13px; }
/* flex:none + lebar tetap menimpa `.searchbar input { flex:1 }`; keduanya
   berspesifisitas sama, jadi aturan ini menang karena tertulis belakangan. */
.searchbar-limit input { flex: none; width: 62px; text-align: center; background: var(--surface-2);
  border: 1px solid var(--line); color: var(--ink); border-radius: 8px; padding: 7px 8px;
  font-family: var(--mono); font-size: 13px; }
/* Pada layar sempit, label teksnya dilepas — ikon + angka sudah cukup. */
@media (max-width: 560px) { .searchbar-limit > span { display: none; } }

/* progress / radar */
.progress-panel { text-align: center; padding: 40px 20px; }
.radar { position: relative; width: 88px; height: 88px; margin: 0 auto 20px; display: grid; place-items: center; }
.radar i { font-size: 28px; color: var(--primary); z-index: 2; }
.radar span { position: absolute; inset: 0; border: 2px solid var(--primary); border-radius: 50%; opacity: 0;
  animation: ping 2.4s cubic-bezier(0,.2,.8,1) infinite; }
.radar span:nth-child(2) { animation-delay: .8s; } .radar span:nth-child(3) { animation-delay: 1.6s; }
@keyframes ping { 0% { transform: scale(.3); opacity: .6; } 100% { transform: scale(1); opacity: 0; } }
.progress-panel h3 { font-size: 18px; font-weight: 600; margin: 0 0 8px; color: var(--ink); }
.progress-panel > .msg--bare { min-height: 1.2em; }
.prog-track { height: 8px; background: var(--surface-2); border-radius: 999px; overflow: hidden; max-width: 440px; margin: 0 auto; }
.prog-fill { height: 100%; background: var(--primary); border-radius: 999px; transition: width .5s ease; position: relative; }
.prog-fill::after { content: ""; position: absolute; inset: 0;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,.45), transparent); animation: shimmer 1.3s infinite; }
@keyframes shimmer { 100% { transform: translateX(200%); } }
.prog-step { color: var(--muted); font-size: 12px; margin-top: 14px; }

/* recent cards */
.recent-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px,1fr)); gap: 13px; }
.recent-card { display: flex; flex-direction: column; gap: 7px; padding: 16px 18px; border-radius: 13px;
  background: var(--surface); border: 1px solid var(--line); box-shadow: var(--shadow-sm);
  transition: border-color .13s, transform .1s; }
.recent-card:hover { border-color: var(--primary); transform: translateY(-2px); }
.rk { color: var(--ink); font-weight: 600; font-size: 15px; }
.rm { color: var(--ink-soft); font-size: 12px; } .rm i { color: var(--muted); }
.rd { color: var(--muted); font-size: 11px; }

/* ---------- Lencana: SATU komponen untuk semua penanda ----------
   Menggantikan .plan-badge, .status-pill, .chip, .pill, .badge-coord,
   .badge-pill, .lex-count, .ai-sugg, dan .quota-badge — sebelumnya sembilan
   kelas untuk satu gagasan yang sama, dengan warna hijau ditulis literal dua
   kali. Varian warna bersifat SEMANTIK; kelas domain (status run, sentimen)
   ikut menumpang selektor yang sama agar tidak ada deklarasi ganda. */
.badge { display: inline-flex; align-items: center; gap: 6px; padding: 3px 9px;
  border-radius: 999px; font-size: 10.5px; font-weight: 600; line-height: 1.5;
  white-space: nowrap; background: var(--surface-2); color: var(--ink-soft); }
.badge i { font-size: .95em; }
/* display pada kelas mengalahkan [hidden] bawaan browser — tanpa baris ini
   lencana yang disembunyikan tetap tergambar sebagai pil kosong. */
.badge[hidden] { display: none; }
.badge--mono { font-family: var(--mono); font-weight: 400; }
.badge--lg { font-size: 11.5px; padding: 4px 12px; font-weight: 700; }

.badge--primary,
.badge.sent-positif                       { color: var(--primary); background: var(--primary-soft); }
.badge--ok,
.badge.done                               { color: var(--ok); background: var(--ok-soft); }
.badge--warn,
.badge.running, .badge.pending            { color: var(--amber); background: var(--amber-soft); }
.badge--danger,
.badge.sent-negatif, .badge.failed        { color: var(--danger); background: var(--danger-soft); }
/* .badge.cancelled & .badge.sent-netral memakai warna dasar (netral) */

/* ---------- Results ---------- */
.grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; }
.bars { display: flex; flex-direction: column; gap: 11px; margin-top: 14px; }
/* kolom nilai mengikuti isi: '642 · 84%' terpecah tiga baris pada 34px tetap */
.bar-row { display: grid; grid-template-columns: 132px 1fr auto; align-items: center; gap: 12px; }
.bar-label { font-size: 13px; text-transform: capitalize; }
.bar-track { background: var(--surface-2); border-radius: 999px; height: 12px; overflow: hidden; }
.bar-fill { height: 100%; width: var(--w); background: var(--primary); border-radius: 999px;
  animation: grow .9s cubic-bezier(.2,.7,.3,1) both; }
@keyframes grow { from { width: 0; } }
.bar-val { text-align: right; font-size: 12px; color: var(--muted);
  white-space: nowrap; min-width: 34px; }
/* garis acuan rata-rata korpus: 75 tak bermakna tanpa pembanding */
.bar-track.ref { position: relative; }
.bar-track.ref::after { content: ""; position: absolute; top: -3px; bottom: -3px;
  left: var(--ref); border-left: 2px dashed var(--muted); opacity: .7; }
.bar-ref-key { font-size: 11px; color: var(--muted); margin: 12px 0 0;
  display: flex; align-items: center; gap: 7px; }
.bar-ref-key em { display: inline-block; width: 16px; border-top: 2px dashed var(--muted); }

.graphwrap { margin-top: 12px; overflow-x: auto; }
.netgraph { width: 100%; height: auto; background: var(--bg); border-radius: 12px; border: 1px solid var(--line); }

.chips { display: flex; flex-wrap: wrap; gap: 6px; margin: 10px 0; }
.accounts { font-size: 11.5px; color: var(--muted); word-break: break-word; margin: 4px 0 0; }

.table-wrap { overflow-x: auto; }
table.posts { width: 100%; border-collapse: collapse; margin-top: 8px; font-size: 13.5px; min-width: 620px; }
.posts th { text-align: left; color: var(--muted); font-weight: 600; font-size: 11px; text-transform: uppercase;
  letter-spacing: .04em; border-bottom: 1px solid var(--line); padding: 11px 10px; }
.posts td { padding: 12px 10px; border-bottom: 1px solid var(--line); vertical-align: top; }
.posts tbody tr:hover td { background: var(--surface-2); }
.posts tr.clickable { cursor: pointer; }
.frame-cell { text-transform: capitalize; }
.num-cell { text-align: center; }
.text-cell { color: var(--ink-soft); }
.kw { font-weight: 600; }
.src { color: var(--primary); margin-left: 5px; }
.src-list { max-width: 200px; }


.theory ul { margin: 6px 0 0; padding-left: 18px; }
.theory li { font-size: 12.5px; color: var(--ink-soft); margin-bottom: 9px; }
.notes { margin-top: 16px; }

.empty { text-align: center; padding: 50px 20px; color: var(--muted); }
.empty i { font-size: 34px; color: var(--line-2); margin-bottom: 14px; }

/* ---------- Pesan ----------
   SATU komponen untuk setiap pemberitahuan kontekstual: pesan Django, catatan
   inline, peringatan metodologis, dan status proses langsung. Sebelumnya tujuh
   kelas terpisah (.alert/.caveat/.src-hint/.live-note/.queue-badge/
   .console-hint/.train-msg/.prog-msg) menggambar kotak yang sama dengan
   padding, ukuran huruf, dan bulatan sudut yang berlainan — pembaca membacanya
   sebagai tujuh jenis benda padahal semuanya satu: "sistem sedang bicara".
   Nada dan bentuk kini jadi modifier, sehingga menambah pesan baru tidak lagi
   berarti menambah kelas baru. */
.msg { display: flex; align-items: flex-start; gap: 11px; margin: 0 0 18px;
  padding: 12px 15px; border-radius: 11px; border: 1px solid var(--line);
  background: var(--surface-2); color: var(--ink-soft);
  font-size: 13.5px; line-height: 1.55; }
.msg > i:first-child { flex: none; font-size: 13px; margin-top: .2em; color: var(--muted); }
.msg > span { min-width: 0; }
.msg a { color: inherit; font-weight: 600; text-decoration: underline; }
.msg b { color: inherit; }

/* Nada — hanya paletnya yang berganti; geometri sengaja tidak ikut berubah
   supaya perbedaan warna terbaca sebagai tingkat kegentingan, bukan sebagai
   komponen yang berbeda. */
.msg--info    { background: var(--primary-soft); color: var(--primary);
  border-color: color-mix(in srgb, var(--primary) 32%, transparent); }
.msg--success { background: var(--ok-soft); color: var(--ok);
  border-color: color-mix(in srgb, var(--ok) 32%, transparent); }
.msg--warn    { background: var(--amber-soft); color: var(--amber);
  border-color: color-mix(in srgb, var(--amber) 35%, transparent); }
.msg--danger  { background: var(--danger-soft); color: var(--danger);
  border-color: color-mix(in srgb, var(--danger) 35%, transparent); }
.msg--info > i:first-child, .msg--success > i:first-child,
.msg--warn > i:first-child, .msg--danger > i:first-child { color: inherit; }

/* Bentuk — dipakai bila pesan tidak mengisi selebar induknya. */
.msg--inline { display: inline-flex; align-items: center; }
.msg--inline > i:first-child { margin-top: 0; }
.msg--pill { display: inline-flex; align-items: center; border-radius: 999px;
  padding: 7px 14px; font-weight: 600; }
.msg--pill > i:first-child { margin-top: 0; }
/* Tanpa bingkai: untuk baris status yang berganti-ganti isi (progres, latihan
   model) — kotak berwarna yang berkedip tiap detik justru jadi gangguan. */
.msg--bare { padding: 0; background: none; border-color: transparent; border-radius: 0; }
.msg--center { justify-content: center; text-align: center; }

/* ---------- Responsive ---------- */
/* Tombol buka/tutup laci & scrim tidak ada di lebar desktop; keduanya hanya
   dihidupkan oleh media query di bawah. */
.nav-burger, .nav-close { display: none; }
.nav-burger { flex: none; width: 34px; height: 34px; place-items: center;
  border: 1px solid var(--line-2); border-radius: 10px; background: var(--surface);
  color: var(--ink-soft); font-size: 14px; cursor: pointer; }
.nav-burger:hover { color: var(--primary); border-color: var(--primary); }

@media (max-width: 900px) {
  /* Sidebar KELUAR dari alur halaman menjadi laci. Sebelumnya ia dipipihkan
     jadi baris horizontal — dan item terakhir terpotong begitu saja tanpa
     scroll, sehingga Konfigurasi/Akun tak bisa dijangkau sama sekali. */
  .app { grid-template-columns: 1fr; }
  .sidebar { position: fixed; top: 0; left: 0; bottom: 0; z-index: 60;
    width: 272px; height: 100vh; height: 100dvh;
    border-right: 1px solid var(--line);
    transform: translateX(-100%); transition: transform .22s ease; }
  :root[data-nav="open"] .sidebar { transform: none; box-shadow: var(--shadow); }
  .nav-scrim { position: fixed; inset: 0; z-index: 55;
    background: rgba(0, 0, 0, .5); backdrop-filter: blur(2px); }
  .nav-burger, .nav-close { display: grid; }
  #rail-toggle { display: none; }              /* mengecil tak berguna saat melayang */
  .mainbar { gap: 12px; }
  .mainbar, .content { padding-left: 18px; padding-right: 18px; }
}
@media (max-width: 720px) { .grid2 { grid-template-columns: 1fr; } .kpis, .kpis.wide { grid-template-columns: 1fr 1fr; } }
@media (max-width: 460px) { .kpis, .kpis.wide { grid-template-columns: 1fr; } }
/* ---------- Matured features ---------- */
.btn-outline { display: inline-flex; align-items: center; gap: 7px; background: var(--surface);
  color: var(--ink-soft); border: 1px solid var(--line-2); border-radius: 999px; padding: 7px 14px;
  font-family: var(--font); font-size: 13px; font-weight: 500; line-height: 1.5;
  cursor: pointer; transition: all .13s; }
.btn-outline:hover { color: var(--primary); border-color: var(--primary); background: var(--primary-soft); }
.btn-outline.sm { padding: 6px 12px; font-size: 12.5px; }

.bars-cap { font-size: 12px; font-weight: 600; color: var(--ink-soft); margin: 18px 0 10px; display: flex; align-items: center; gap: 8px; }
.bars-cap:first-of-type { margin-top: 8px; }
.bars-cap i { color: var(--primary); }
.bar-fill.alt { background: color-mix(in srgb, var(--primary) 62%, var(--muted)); }

/* advanced options */
.adv-toggle { background: none; border: 0; color: var(--primary); font-family: var(--font);
  font-size: 13px; font-weight: 600; cursor: pointer; padding: 0; margin-top: 22px; display: inline-flex; align-items: center; gap: 8px; }
.adv-toggle i { font-size: 11px; }
.adv { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; margin-top: 16px; padding: 18px;
  background: var(--surface-2); border-radius: 12px; }
.adv-field { display: flex; flex-direction: column; gap: 8px; font-size: 13px; }
.adv-field span b { color: var(--primary); font-family: var(--mono); }
.adv-field i { color: var(--muted); margin-right: 4px; }
.adv-field input[type=range] { width: 100%; accent-color: var(--primary); }
.adv-field small { font-size: 11px; }

/* filter bar (history) */
.filterbar { display: flex; gap: 10px; margin-bottom: 18px; align-items: stretch; }
.searchbar.compact { flex: 0 1 340px; padding: 0 14px; }
.searchbar.compact input { font-size: 14px; padding: 9px 0; }

/* history row actions */
.nowrap { white-space: nowrap; }
.row-actions { display: flex; gap: 6px; justify-content: flex-end; }
.ic-link { background: none; border: 0; cursor: pointer; color: var(--muted); font-size: 14px;
  width: 32px; height: 32px; border-radius: 8px; display: grid; place-items: center; }
.ic-link:hover { color: var(--primary); background: var(--surface-2); }
.ic-link.danger:hover { color: var(--danger); background: var(--danger-soft); }
.history .kw a { color: var(--ink); }
.history .kw a:hover { color: var(--primary); }

/* timeline */
.timeline { width: 100%; height: auto; }
.tl-axis { fill: var(--muted); font-size: 10px; font-family: var(--mono); }

/* device stats */
.device-stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; margin-top: 10px; }
.dev { text-align: center; background: var(--surface-2); border-radius: 12px; padding: 16px 8px; }
.dev-n { display: block; font-size: 24px; font-weight: 700; color: var(--primary); font-variant-numeric: tabular-nums; }
.dev-l { font-size: 11.5px; color: var(--muted); }

/* top accounts */
.acct-list { display: flex; flex-direction: column; margin-top: 6px; }
.acct { display: flex; justify-content: space-between; align-items: center; gap: 10px;
  padding: 10px 0; border-bottom: 1px solid var(--line); flex-wrap: wrap; }
.acct:last-child { border-bottom: 0; }
.acct-name { font-size: 13px; color: var(--ink); }
.acct-meta { font-size: 11.5px; color: var(--muted); }

/* interactive posts */
.posts-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }

/* print / PDF */
@media print {
  /* Bawaan aplikasi kini gelap — laporan cetak tetap harus di atas kertas putih,
     jadi tokennya dipaksa terang apa pun tema yang sedang dipakai di layar. */
  :root, :root[data-theme="light"] {
    color-scheme: light;
    --bg: #fff; --surface: #fff; --surface-2: #f4f2ee; --sidebar-bg: #fff;
    --ink: #000; --ink-soft: #333; --muted: #666;
    --line: #ccc; --line-2: #bbb;
    --primary: #b4470a; --primary-ink: #fff; --primary-soft: #f7e7db;
    --shadow-sm: none; --shadow: none;
  }
  .sidebar, .mainbar, .no-print, .adv-toggle, .theme-toggle { display: none !important; }
  .app { grid-template-columns: 1fr; }
  body { background: #fff; color: #000; }
  .card, .kpi { break-inside: avoid; box-shadow: none; border-color: #ccc; }
  .content { padding: 8px; }
  a { color: #000; }
}

@media (max-width: 720px) { .adv { grid-template-columns: 1fr; } .device-stats { grid-template-columns: 1fr 1fr 1fr; } }
@media (prefers-reduced-motion: reduce) { * { animation: none !important; transition: none !important; } }

/* ============ SaaS: public nav, landing, auth, account ============ */
body.public { display: block; }
.btn-text { color: var(--ink-soft); font-weight: 500; font-size: 13.5px; padding: 7px 12px; border-radius: 999px; }
.btn-text:hover { color: var(--primary); }
.btn-primary.lg { padding: 13px 26px; font-size: 15px; }
.btn-outline.full, .btn-primary.full { width: 100%; justify-content: center; }

/* Semua blok halaman publik memakai container yang sama; latar/garis tetap full-bleed. */
.container { width: 100%; max-width: var(--container); margin-inline: auto;
  padding-inline: var(--container-pad); }

/* Navbar sebagai pil mengambang (mengikuti referensi desain). .pubnav hanya
   menyediakan sticky + jarak dari tepi layar; badan pil digambar pada
   .pubnav-in, yang tetap memakai container .container — lebar & padding sisinya
   datang dari sana, sehingga merek sejajar dengan teks konten di bawahnya.
   Hanya padding-block yang ditambah di sini agar padding-inline tak tertimpa. */
.pubnav { position: sticky; top: 0; z-index: 20; padding: 16px 14px; }
.pubnav-in { display: flex; align-items: center; gap: 24px;
  padding-block: 9px; border-radius: 999px;
  background: color-mix(in srgb, var(--nav-bg) 92%, transparent);
  backdrop-filter: blur(12px); border: 1px solid var(--nav-line); box-shadow: var(--shadow); }
/* Isi pil memakai token --nav-* (bukan --ink/--line) karena latarnya selalu
   krem dan tidak ikut tema; tanpa ini teksnya terang di atas krem alias tak
   terbaca saat tema gelap. */
.pubnav .brand { padding: 0; }
.pubnav .brand-mark { width: 34px; height: 34px; font-size: 15px; border-radius: 999px; }
.pubnav .brand-text { color: var(--nav-ink); }
.pubnav-links { display: flex; gap: 26px; margin-left: 10px; }
.pubnav-links a, .pubnav .btn-text { color: var(--nav-ink-soft); font-weight: 500; font-size: 13.5px;
  text-transform: uppercase; letter-spacing: .06em; }
.pubnav-links a:hover, .pubnav .btn-text:hover { color: var(--primary); }
.pubnav-cta { margin-left: auto; display: flex; align-items: center; gap: 8px; }

/* Pemilih tema mengambang (kanan-bawah). Berbeda dari pil navbar, tombol ini
   IKUT tema: ia melayang di atas isi halaman, jadi harus menyatu dengannya.
   env(safe-area-inset-*) menjaga jarak dari home indicator di iOS. */
.theme-fab { position: fixed; z-index: 40;
  right: calc(20px + env(safe-area-inset-right, 0px));
  bottom: calc(20px + env(safe-area-inset-bottom, 0px));
  width: 44px; height: 44px; display: grid; place-items: center;
  border-radius: 999px; border: 1px solid var(--line); background: var(--surface);
  color: var(--ink-soft); font-size: 15px; cursor: pointer; box-shadow: var(--shadow);
  transition: color .15s, border-color .15s, transform .15s; }
.theme-fab:hover { color: var(--primary); border-color: var(--primary); transform: translateY(-2px); }
.theme-fab:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }

/* Garis oranye tipis menutup hero — penanda khas pada referensi desain. */
.hero-pub { padding: 64px 0 58px;
  border-bottom: 1px solid color-mix(in srgb, var(--primary) 55%, transparent); }
.hero-grid { display: grid; grid-template-columns: 1.15fr .85fr; gap: 40px; align-items: center; }
.hero-badge { margin-bottom: 20px; }
/* Poppins hanya dimuat sampai bobot 700; kesan "tebal" pada referensi dikejar
   lewat leading rapat + tracking negatif, bukan bobot sintetis 800. */
.hero-in h1 { font-size: clamp(34px, 5vw, 58px); font-weight: 700; line-height: 1.04;
  letter-spacing: -.03em; margin: 0 0 20px; text-wrap: balance; }
.hero-in em { font-style: normal; color: var(--primary); }
.hero-in .lede { font-size: 17px; color: var(--ink-soft); max-width: 52ch; margin: 0 0 26px; }
.hero-cta { display: flex; gap: 14px; flex-wrap: wrap; margin-bottom: 16px; }
.hero-panels { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.hp-card { background: var(--surface); border: 1px solid var(--line); border-radius: 15px;
  padding: 22px; box-shadow: var(--shadow); display: flex; flex-direction: column; gap: 4px; }
.hp-card i { font-size: 22px; color: var(--primary); margin-bottom: 8px; }
.hp-card span { font-size: 12px; color: var(--muted); text-transform: uppercase; letter-spacing: .05em; }
.hp-card b { font-size: 15px; }

.section { padding: 64px 0; }
.section.band { background: var(--surface-2); border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
.section-head { text-align: center; margin-bottom: 40px; }
.section-head h2 { font-size: clamp(25px, 3.6vw, 36px); font-weight: 700; margin: 0 0 8px;
  letter-spacing: -.025em; }
.feat-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; }
.feat { background: var(--surface); border: 1px solid var(--line); border-radius: 15px; padding: 24px; }
.feat i { font-size: 22px; color: var(--primary); background: var(--primary-soft); width: 46px; height: 46px;
  border-radius: 12px; display: grid; place-items: center; margin-bottom: 14px; }
.feat h3 { font-size: 16px; margin: 0 0 6px; }
.feat p { color: var(--ink-soft); font-size: 14px; margin: 0; }
.theory-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 30px; }
.theory-cols h3 { color: var(--primary); font-size: 16px; margin: 0 0 12px; }
.theory-cols ul { margin: 0; padding-left: 20px; color: var(--ink-soft); }
.theory-cols li { margin-bottom: 9px; }

.pricing { display: grid; grid-template-columns: repeat(2, 1fr); gap: 22px; }
.plan { position: relative; background: var(--surface); border: 1px solid var(--line); border-radius: 18px; padding: 30px; }
.plan.featured { border-color: var(--primary); box-shadow: 0 12px 34px color-mix(in srgb, var(--primary) 18%, transparent); }
.plan-tag { position: absolute; top: -12px; right: 24px; background: var(--primary); color: var(--primary-ink);
  font-size: 11px; font-weight: 700; padding: 4px 12px; border-radius: 999px; }
.plan-name { font-size: 15px; font-weight: 600; color: var(--muted); text-transform: uppercase; letter-spacing: .06em; margin: 0; }
.plan-price { font-size: 34px; font-weight: 700; margin: 8px 0 18px; }
.plan-price span { font-size: 14px; color: var(--muted); font-weight: 500; }
.plan ul { list-style: none; padding: 0; margin: 0 0 22px; }
.plan li { display: flex; align-items: center; gap: 10px; padding: 7px 0; font-size: 14px; color: var(--ink-soft); }
.plan li i { color: var(--primary); }

.cta-final { text-align: center; padding: 70px 0 90px; }
.cta-final h2 { font-size: clamp(24px, 3.6vw, 36px); font-weight: 700; margin: 0 0 24px; }

/* Footer publik: kolom merek yang lebih lebar + tiga kolom pendek, lalu baris
   penutup. Garis pemisah baris penutup digambar DI DALAM container agar ia
   berhenti sejajar teks, bukan memotong layar — pembeda khas footer yang rapi. */
.pubfoot { border-top: 1px solid var(--line); background: var(--surface); }
.pubfoot-in { padding-block: 0; }
.pubfoot-top { display: grid; grid-template-columns: 1.6fr .8fr 1.3fr .8fr; gap: 32px 40px;
  padding-block: 56px 40px; }
.pubfoot-brand .brand { padding: 0; display: inline-flex; flex: none; }
.pubfoot .brand-mark { width: 34px; height: 34px; font-size: 15px; border-radius: 10px; }
.pubfoot .brand-text { font-weight: 500; color: var(--ink); }
.pubfoot-lede { color: var(--ink-soft); font-size: 14px; max-width: 40ch; margin: 14px 0 16px; }
/* Blok biasa, bukan flex: barisnya harus mengalir & membungkus seperti kalimat. */
.pubfoot-ethic { color: var(--muted); font-size: 12.5px; line-height: 1.7; margin: 16px 0 0;
  max-width: 40ch; }
.pubfoot-ethic i { color: var(--ok); margin-right: 6px; }
.pubfoot-ethic code { font-family: var(--mono); font-size: .95em; }

/* Judul kolom sengaja kecil-kapital: ia label, bukan bacaan — hierarkinya harus
   di bawah tautan yang dinaunginya. */
.pubfoot-col h3 { font-size: 11.5px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .09em; color: var(--muted); margin: 8px 0 14px; }
.pubfoot-col ul { list-style: none; margin: 0; padding: 0; }
.pubfoot-col li { margin-bottom: 10px; font-size: 14px; }
.pubfoot-col a { color: var(--ink-soft); }
.pubfoot-col a:hover { color: var(--primary); }
/* Kolom Metode bukan tautan melainkan daftar istilah: nama metode sebagai
   label, sitasi di bawahnya — dua tingkat, jadi tak terbaca sebagai menu mati. */
.pubfoot-plain li { margin-bottom: 12px; }
.pubfoot-plain b { display: block; color: var(--ink-soft); font-weight: 600; font-size: 13px; }
.pubfoot-plain span { color: var(--muted); font-size: 12.5px; line-height: 1.5; }

.pubfoot-bottom { border-top: 1px solid var(--line); padding-block: 18px 26px;
  display: flex; justify-content: space-between; align-items: center; gap: 12px; flex-wrap: wrap; }
.pubfoot-bottom p { margin: 0; font-size: 12.5px; color: var(--muted); }

@media (max-width: 860px) { .pubfoot-top { grid-template-columns: 1fr 1fr; gap: 28px; } }
@media (max-width: 520px) { .pubfoot-top { grid-template-columns: 1fr; }
  .pubfoot-bottom { justify-content: flex-start; } }
/* Sisakan ruang di baris penutup selama .theme-fab masih bisa menutupinya.
   Di atas 1200px container sudah menyisakan margin sendiri, jadi tak perlu. */
@media (max-width: 1199px) { .pubfoot-bottom { padding-bottom: 78px; } }

/* auth */
.auth-wrap { min-height: calc(100vh - 140px); display: grid; place-items: center; padding: 40px 20px; }
.auth-card { width: 100%; max-width: 480px; background: var(--surface); border: 1px solid var(--line);
  border-radius: 18px; padding: 34px; box-shadow: var(--shadow); }
.auth-head { text-align: center; margin-bottom: 22px; }
.brand-mark.lg { width: 54px; height: 54px; font-size: 22px; margin: 0 auto 14px; }
.auth-head h1 { font-size: 22px; margin: 0 0 4px; }
.auth-form { display: flex; flex-direction: column; gap: 14px; }
.fld { display: flex; flex-direction: column; gap: 7px; }
.fld > span { font-size: 13px; font-weight: 500; color: var(--ink-soft); }
.fld > span i { color: var(--muted); margin-right: 5px; }
.auth-alt { text-align: center; margin: 18px 0 0; font-size: 14px; color: var(--muted); }
.fld small.err { margin-top: 2px; }

/* account */
.profile { margin: 0; display: flex; flex-direction: column; }
.profile > div { display: flex; justify-content: space-between; gap: 14px; padding: 12px 0; border-bottom: 1px solid var(--line); }
.profile > div:last-child { border-bottom: 0; }
.profile dt { color: var(--muted); font-size: 13px; margin: 0; }
.profile dd { margin: 0; font-size: 14px; font-weight: 500; }
.usage-top { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 10px; }
.usage-top .mono { font-size: 22px; font-weight: 700; }
.usage .prog-track { max-width: none; height: 10px; }
.usage p { margin: 12px 0 0; }
.usage-pro { color: var(--primary); font-weight: 600; }
.upgrade { margin-top: 20px; padding: 16px; background: var(--primary-soft); border-radius: 12px;
  display: flex; align-items: center; justify-content: space-between; gap: 14px; flex-wrap: wrap; }
.upgrade p { margin: 0; font-size: 14px; } .upgrade i { color: var(--primary); }

/* app shell: user chip + logout */
.user-chip { display: flex; align-items: center; gap: 11px; padding: 10px; border-radius: 11px; margin-bottom: 8px; }
.user-chip:hover { background: var(--surface-2); }
.user-av { width: 34px; height: 34px; flex: none; display: grid; place-items: center; border-radius: 9px;
  background: var(--primary); color: var(--primary-ink); font-weight: 700; font-size: 14px; }
.user-meta { display: flex; flex-direction: column; line-height: 1.3; overflow: hidden; }
.user-meta b { font-size: 13.5px; color: var(--ink); }
.user-meta small { font-size: 11px; color: var(--muted); }
.foot-actions { display: flex; gap: 8px; }
.theme-toggle.danger:hover { color: var(--danger); border-color: var(--danger); }

/* console quota badge */
.console-head-row { display: flex; align-items: flex-start; justify-content: space-between; gap: 14px; }

@media (max-width: 860px) {
  .hero-pub { padding-top: 44px; }
  .hero-grid { grid-template-columns: 1fr; gap: 30px; }
  .hero-panels { order: -1; }
  .pubnav-links { display: none; }
  .feat-grid { grid-template-columns: 1fr; }
  .theory-cols, .pricing { grid-template-columns: 1fr; }
}

/* ============ Form fields (auth & inputs) ============ */
.field { width: 100%; padding: 10px 13px; border: 1.5px solid var(--line-2); border-radius: 10px;
  background: var(--surface-2); color: var(--ink); font-size: 13.5px; font-family: var(--font);
  transition: border-color .15s, box-shadow .15s, background .15s; }
.field::placeholder { color: var(--muted); }
.field:focus { outline: none; border-color: var(--primary); background: var(--surface);
  box-shadow: 0 0 0 3px var(--primary-soft); }
.field:-webkit-autofill { -webkit-box-shadow: 0 0 0 40px var(--surface-2) inset; -webkit-text-fill-color: var(--ink); }

.fld > .fld-label { font-size: 12.5px; font-weight: 600; color: var(--ink-soft); display: block; }
.fld-hint { font-size: 11px; color: var(--muted); margin-top: 1px; }

.input-group { position: relative; display: flex; align-items: center; }
.input-group > .ig-icon { position: absolute; left: 13px; color: var(--muted); font-size: 13px;
  pointer-events: none; z-index: 1; }
.input-group .field { padding-left: 39px; }
.input-group.has-toggle .field { padding-right: 44px; }
.pw-toggle { position: absolute; right: 6px; background: none; border: 0; color: var(--muted);
  width: 32px; height: 32px; border-radius: 8px; cursor: pointer; display: grid; place-items: center; font-size: 14px; }
.pw-toggle:hover { color: var(--primary); background: var(--surface); }

.grid-2col { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
@media (max-width: 460px) { .grid-2col { grid-template-columns: 1fr; } }

.config-form .fld { margin-bottom: 14px; }
/* Catatan YouTube muncul/menghilang mengikuti pilihan sumber, jadi ia butuh
   jarak atas sendiri — di tempat lain .msg sudah dipisah oleh margin bawah. */
.src-group + .msg { margin-top: 12px; }
.progress-panel > .msg--pill { margin: 0 auto 14px; }
.progress-panel > .msg--pill b { font-family: var(--mono); }

/* ============ Tab hasil + panel CDA ============ */
.tabs { display: flex; gap: 4px; margin-bottom: 18px; border-bottom: 1px solid var(--line);
  overflow-x: auto; padding-bottom: 0; }
.tab { display: inline-flex; align-items: center; gap: 8px; padding: 11px 16px; white-space: nowrap;
  color: var(--ink-soft); font-size: 14px; font-weight: 500; border-bottom: 2px solid transparent;
  border-radius: 9px 9px 0 0; transition: color .13s, background .13s, border-color .13s; }
.tab i { color: var(--muted); font-size: 13px; }
.tab:hover { color: var(--ink); background: var(--surface-2); }
.tab.active { color: var(--primary); border-bottom-color: var(--primary); font-weight: 600; }
.tab.active i { color: var(--primary); }
.tab-more { margin: 14px 0 0; font-size: 13px; font-weight: 500; }

/* Varian rapat — dipakai bilah tab halaman Hasil, yang membawa sembilan bagian
   sekaligus. Dibuat modifier, bukan mengubah .tab, karena bilah lain (Konfigurasi,
   Scraping, editor resep) hanya berisi tiga sampai lima tab dan tidak punya
   masalah kepadatan yang sama. */
.tabs--compact .tab { padding: 9px 12px; gap: 6px; font-size: 12.5px; }
.tabs--compact .tab i { font-size: 11.5px; }

.polar { text-align: center; padding: 14px 0 18px; }
.polar-num { font-size: 40px; font-weight: 700; color: var(--primary); line-height: 1;
  font-variant-numeric: tabular-nums; }
.polar-lbl { font-size: 12px; color: var(--muted); margin-top: 6px; }
.device-stats.two { grid-template-columns: 1fr 1fr; }

/* ============ Dialog konfirmasi ============ */
.cdialog { border: 0; border-radius: 16px; padding: 28px; max-width: 420px; width: calc(100% - 32px);
  background: var(--surface); color: var(--ink); box-shadow: var(--shadow); text-align: center;
  font-family: var(--font); }
.cdialog::backdrop { background: rgba(0,0,0,.62); backdrop-filter: blur(3px); }
.cd-icon { width: 52px; height: 52px; margin: 0 auto 16px; display: grid; place-items: center;
  border-radius: 14px; background: var(--danger-soft); color: var(--danger); font-size: 21px; }
.cd-title { font-size: 18px; font-weight: 600; margin: 0 0 8px; }
.cd-message { font-size: 14px; color: var(--ink-soft); margin: 0 0 22px; line-height: 1.55; }
.cd-actions { display: flex; gap: 10px; justify-content: center; }
.cd-actions button { min-width: 120px; justify-content: center; }
.btn-primary.danger { background: var(--danger); box-shadow: 0 6px 18px color-mix(in srgb, var(--danger) 28%, transparent); }

/* ============ Leksikon ============ */
.lex-bar { display: flex; align-items: center; justify-content: space-between; gap: 14px;
  flex-wrap: wrap; margin: 0 0 18px; }
.lex-actions { display: flex; gap: 10px; }
.lex-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin-top: 12px; }
.lex-area { font-size: 13px; line-height: 1.6; resize: vertical; min-height: 74px; }
.nav-item.sub { padding-left: 30px; font-size: 13.5px; }
.nav-item.sub i { font-size: 13px; }

/* ============ Bar hapus semua (Riwayat) ============ */
.danger-bar { display: flex; align-items: center; justify-content: space-between; gap: 14px;
  flex-wrap: wrap; padding: 12px 16px; margin-bottom: 16px; border-radius: 11px;
  background: var(--danger-soft); border: 1px solid color-mix(in srgb, var(--danger) 25%, transparent); }
.danger-bar .muted { color: var(--danger); }
.danger-btn { color: var(--danger); border-color: color-mix(in srgb, var(--danger) 45%, transparent); background: var(--surface); }
.danger-btn:hover { color: #fff; background: var(--danger); border-color: var(--danger); }
.danger-btn i { color: inherit; }

@media (max-width: 720px) { .lex-grid { grid-template-columns: 1fr; } }

/* daftar status sumber (Konfigurasi > Sumber Data) */
.src-status { list-style: none; padding: 0; margin: 6px 0 0; }
.src-status li { display: flex; align-items: center; gap: 11px; padding: 10px 0;
  border-bottom: 1px solid var(--line); font-size: 13.5px; color: var(--ink-soft); }
.src-status li:last-child { border-bottom: 0; }
.src-status i { width: 20px; text-align: center; color: var(--primary); }

/* struktur wacana van Dijk */
.vd-level { padding-top: 6px; }
.vd-level + .vd-level { margin-top: 20px; border-top: 1px solid var(--line); padding-top: 18px; }
.vd-micro { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; margin-top: 12px; }
.vd-box { background: var(--surface-2); border-radius: 12px; padding: 14px 16px; }
.vd-box h4 { margin: 0 0 8px; font-size: 12px; text-transform: uppercase; letter-spacing: .05em;
  color: var(--primary); font-weight: 700; }
.vd-box ul { list-style: none; margin: 0; padding: 0; }
.vd-box li { font-size: 12.5px; color: var(--ink-soft); display: flex; justify-content: space-between;
  gap: 8px; padding: 4px 0; }
.vd-box li b { color: var(--ink); font-family: var(--mono); font-size: 12px; }
@media (max-width: 900px) { .vd-micro { grid-template-columns: 1fr 1fr; } }
@media (max-width: 520px) { .vd-micro { grid-template-columns: 1fr; } }

/* ============ Pemilih video YouTube ============ */
.yt-picker { padding-top: 4px; }
.yt-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 14px;
  flex-wrap: wrap; margin-bottom: 14px; }
.yt-head h3 { margin: 0 0 4px; font-size: 17px; font-weight: 600; }
.yt-head h3 i { color: #f0413e; }
.yt-list { display: flex; flex-direction: column; gap: 10px; max-height: 460px; overflow-y: auto;
  padding-right: 4px; }
.yt-item { display: flex; align-items: center; gap: 13px; padding: 10px 12px; border-radius: 12px;
  border: 1.5px solid var(--line); background: var(--surface); cursor: pointer; transition: all .13s; }
.yt-item:hover { border-color: var(--line-2); }
.yt-item.on { border-color: var(--primary); background: var(--primary-soft); }
.yt-item input { accent-color: var(--primary); width: 17px; height: 17px; flex: none; }
.yt-thumb { width: 110px; height: 62px; object-fit: cover; border-radius: 8px; flex: none;
  background: var(--surface-2); }
.yt-meta { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.yt-title { font-size: 14px; font-weight: 600; color: var(--ink); line-height: 1.35;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.yt-channel { font-size: 12px; color: var(--muted); }
.yt-stats { font-size: 11.5px; color: var(--ink-soft); }
.yt-stats i { color: var(--muted); }
.yt-stats b { color: var(--primary); }
.yt-actions { display: flex; align-items: center; justify-content: space-between; gap: 14px;
  margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--line); flex-wrap: wrap; }
.yt-btns { display: flex; gap: 10px; }
.btn-primary:disabled { opacity: .5; cursor: not-allowed; transform: none; }

/* ============ Tab Sumber Data (hasil) ============ */
.src-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 16px; margin-top: 12px; }
.src-card { border: 1px solid var(--line); border-radius: 13px; padding: 16px 18px; background: var(--bg); }
.src-card-head { display: flex; align-items: center; gap: 12px; margin-bottom: 12px; }
.src-card-head > div { display: flex; flex-direction: column; line-height: 1.3; min-width: 0; }
.src-card-head b { font-size: 14.5px; }
.src-ic { width: 38px; height: 38px; flex: none; display: grid; place-items: center; border-radius: 10px;
  background: var(--primary-soft); color: var(--primary); font-size: 16px; }
.src-share { margin-left: auto; font-size: 13px; font-weight: 700; color: var(--primary); }
.src-nums { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin-bottom: 10px; }
.src-nums .n { display: block; font-size: 19px; font-weight: 700; font-variant-numeric: tabular-nums; }
.src-nums .l { font-size: 10.5px; color: var(--muted); line-height: 1.3; display: block; }
.note-fail { color: var(--danger) !important; }

/* tambah video YouTube manual */
.yt-add { display: flex; gap: 10px; align-items: stretch; margin-bottom: 14px; }
.yt-add-bar { flex: 1 1 auto; }
.yt-add-bar > i { color: #f0413e; }
.btn-outline:disabled { opacity: .55; cursor: not-allowed; }

/* ============ Analitik framing & koordinasi lanjutan ============ */
.metric-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; margin-top: 12px; }
.met { background: var(--surface-2); border-radius: 10px; padding: 12px 10px; text-align: center; }
.met .n { display: block; font-size: 18px; font-weight: 700; font-variant-numeric: tabular-nums; }
.met .l { font-size: 10.5px; color: var(--muted); line-height: 1.3; }
.sig-notes { list-style: none; padding: 0; margin: 14px 0 0; }
.sig-notes li { font-size: 11.5px; color: var(--muted); padding: 3px 0; }
.sig-notes b { color: var(--ink-soft); }
.cl-facts { margin: 10px 0 0; display: flex; flex-wrap: wrap; gap: 6px 18px; }
.cl-facts > div { display: flex; gap: 7px; align-items: baseline; }
.cl-facts dt { font-size: 11px; color: var(--muted); margin: 0; }
.cl-facts dd { margin: 0; font-size: 11.5px; color: var(--ink); }
.cl-sample { margin: 10px 0 6px; font-size: 12.5px; color: var(--ink-soft); font-style: italic;
  border-left: 2px solid var(--line-2); padding-left: 10px; }
.ex-list { display: flex; flex-direction: column; gap: 12px; margin-top: 12px; }
.ex-item { border: 1px solid var(--line); border-radius: 11px; padding: 13px 15px; background: var(--bg); }
.ex-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 7px; }
.ex-text { margin: 0; font-size: 13px; color: var(--ink-soft); line-height: 1.55; }
@media (max-width: 900px) { .metric-grid { grid-template-columns: repeat(2, 1fr); } }

/* label & legenda di dalam graf koordinasi */
.ng-label { fill: var(--ink); font-size: 9.5px; font-family: var(--mono); font-weight: 600;
  paint-order: stroke; stroke: var(--surface); stroke-width: 2.5px; stroke-linejoin: round; }
.ng-legend { fill: var(--muted); font-size: 10px; font-family: var(--font); }

/* ============ Word cloud & sentimen ============ */
.wcloud { width: 100%; height: auto; background: var(--bg); border-radius: 12px;
  border: 1px solid var(--line); }
.wc-word { font-family: var(--font); }

.sent-bar { display: flex; height: 26px; border-radius: 8px; overflow: hidden; margin: 14px 0 12px;
  background: var(--surface-2); }
.sent-seg { transition: width .5s ease; }
.sent-seg.positif { background: var(--ok); }
.sent-seg.netral  { background: var(--line-2); }
.sent-seg.negatif { background: var(--danger); }
.sent-legend { display: flex; gap: 18px; flex-wrap: wrap; font-size: 12.5px; color: var(--ink-soft); }
.sl i { font-size: 8px; margin-right: 6px; }
.sl.positif i { color: var(--ok); } .sl.netral i { color: var(--line-2); }
.sl.negatif i { color: var(--danger); }
.sl { text-transform: capitalize; }
.pos-cell { color: var(--ok); font-weight: 600; }
.neg-cell { color: var(--danger); font-weight: 600; }

/* Model ML (konfigurasi) */
.switch-row { display: flex; align-items: flex-start; gap: 12px; cursor: pointer; }
.switch-row input { width: 18px; height: 18px; accent-color: var(--primary); margin-top: 2px; flex: none; }
.switch-row span { display: flex; flex-direction: column; gap: 2px; font-size: 14px; }
.train-steps { margin: 8px 0 0; padding-left: 20px; font-size: 12.5px; color: var(--ink-soft); }
.train-steps li { margin-bottom: 7px; }
.train-steps code { font-family: var(--mono); font-size: 11.5px; background: var(--surface-2);
  padding: 2px 7px; border-radius: 5px; }

/* ============ Graf koordinasi interaktif ============ */
.ng-toolbar { display: flex; align-items: center; justify-content: space-between; gap: 14px;
  flex-wrap: wrap; margin: 12px 0 10px; }
.ng-tools { display: flex; gap: 6px; }
.ic-btn { width: 34px; height: 34px; border-radius: 9px; border: 1px solid var(--line);
  background: var(--surface); color: var(--ink-soft); cursor: pointer; font-size: 13px; }
.ic-btn:hover { color: var(--primary); border-color: var(--primary); }
.ic-btn.round { border-radius: 999px; }
.ng-filters { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; }
.filt { font-family: var(--font); font-size: 11.5px; font-weight: 600; padding: 5px 11px;
  border-radius: 999px; border: 1px solid transparent; cursor: pointer; }
.filt.url { color: var(--accent); background: var(--primary-soft); }
.filt.sim { color: #8a6fd1; background: color-mix(in srgb, #8a6fd1 14%, transparent); }
.filt.time { color: var(--ink-soft); background: var(--surface-2); }
.filt.iso { color: var(--muted); background: var(--surface-2); }
.filt.off { opacity: .4; text-decoration: line-through; }

.ng-stage { position: relative; }
.netgraph { cursor: grab; touch-action: none; }
.netgraph.grabbing { cursor: grabbing; }
.ng-node { cursor: pointer; transition: opacity .12s; }
.ng-node:hover { stroke: var(--ink); stroke-width: 2; }
.ng-edge, .ng-label { transition: opacity .12s; }
.ng-node.dim, .ng-label.dim { opacity: .12; }
.ng-edge.dim { opacity: .05; }
.ng-edge.hot { stroke-width: 3; stroke-opacity: 1; }
.ng-edge.hidden, .ng-isolated.hidden { display: none; }
.ng-tip { position: absolute; left: 12px; top: 12px; background: var(--surface);
  border: 1px solid var(--line); border-radius: 9px; padding: 8px 12px; font-size: 12px;
  box-shadow: var(--shadow); opacity: 0; pointer-events: none; transition: opacity .12s;
  display: flex; flex-direction: column; gap: 2px; }
.ng-tip.on { opacity: 1; }
.ng-tip span { color: var(--muted); font-family: var(--mono); font-size: 11px; }

/* ---------- Paginasi ---------- */
.pager { display: flex; align-items: center; justify-content: center; gap: 8px;
  flex-wrap: wrap; margin: 20px 0 4px; }
.pg { display: inline-flex; align-items: center; gap: 7px; padding: 9px 14px; font-size: 13px;
  font-weight: 500; color: var(--ink-soft); background: var(--surface); border: 1px solid var(--line);
  border-radius: 10px; box-shadow: var(--shadow-sm); transition: border-color .13s, color .13s; }
.pg:hover { border-color: var(--primary); color: var(--primary); }
.pg.off { opacity: .4; pointer-events: none; }
.pg-info { font-size: 13px; color: var(--ink-soft); padding: 0 8px; }

/* ---------- Field ramping (bar filter) ---------- */
.field.slim { width: auto; padding: 7px 11px; font-size: 12.5px; border-radius: 9px; }
.inline-fld { display: flex; align-items: center; gap: 10px; margin: 0; }
.inline-fld .fld-label { margin: 0; white-space: nowrap; }
.posts-filterbar { flex-wrap: wrap; margin: 16px 0 4px; }

/* ---------- Anotasi ---------- */
/* Grid-nya menempel pada wadah dalam, bukan pada kartunya. Kartu boleh tumbuh
   isi (baris LLM, kesepakatan kappa) tanpa anak-anak baru itu ikut direbutkan
   ke dalam tiga kolom — kesalahan yang meremukkan kotak pilih dan tombol ekspor. */
.annot-head { display: flex; flex-direction: column; gap: 16px; }
.annot-grid { display: grid; grid-template-columns: 1fr 1.1fr auto; gap: 22px;
  align-items: center; }
.annot-pick { margin: 0; min-width: 0; }
/* flex:1 + min-width:0, bukan width:100%: di dalam .inline-fld yang flex, lebar
   persen tak punya acuan yang pasti dan kotak pilih bisa menyusut sampai hanya
   panahnya yang tersisa. */
.annot-pick .inline-fld .field { flex: 1 1 auto; min-width: 0; }
.annot-progress { min-width: 0; }
.ap-nums { font-size: 13.5px; color: var(--ink-soft); margin-bottom: 8px; }
.ap-nums b { color: var(--ink); font-size: 16px; }
.annot-export { display: flex; flex-direction: column; gap: 7px; align-items: flex-start;
  margin: 0; min-width: 0; }
/* CTA tak boleh melipat jadi tiga baris saat kolomnya sempit — lebih baik
   bilahnya menumpuk (lihat media query) daripada tombolnya berubah bentuk. */
.annot-export .btn-primary { white-space: nowrap; }
.annot-export small { font-size: 11.5px; line-height: 1.45; }

/* Baris sekunder: aksi LLM & kesepakatan kappa. Dipisah garis tipis supaya
   terbaca sebagai tambahan atas alur utama, bukan bagian dari kendalinya. */
.annot-aux { display: flex; flex-direction: column; gap: 10px;
  padding-top: 14px; border-top: 1px solid var(--line); }
.annot-aux .llm-strip { margin: 0; }
.annot-aux .msg { margin: 0; }

.tabs.sub { border-bottom: none; margin-bottom: 14px; gap: 6px; }

.annot-list { display: flex; flex-direction: column; gap: 14px; }
.annot-item { transition: border-color .15s; }
.annot-item.saved { border-color: color-mix(in srgb, var(--primary) 45%, var(--line)); }
.ai-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 10px; }
.ai-state { margin-left: auto; font-size: 11.5px; color: var(--muted); font-style: italic; }
.ai-text { margin: 0 0 14px; font-size: 14.5px; line-height: 1.65; color: var(--ink); }
.ai-labels { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 10px; }
.ai-chk { display: flex; gap: 10px; padding: 11px 13px; border: 1.5px solid var(--line);
  border-radius: 12px; cursor: pointer; background: var(--surface);
  transition: border-color .13s, background .13s; }
.ai-chk:hover { border-color: var(--line-2); }
.ai-chk.on { border-color: var(--primary); background: var(--primary-soft); }
.ai-chk input { margin-top: 3px; accent-color: var(--primary); flex: none; }
.ai-chk-body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.ai-chk-body b { font-size: 13.5px; font-weight: 600; }
.ai-chk-body small { font-size: 11.5px; color: var(--muted); line-height: 1.45; }
.ai-sugg { width: fit-content; margin-top: 4px; }   /* bentuk & warna dari .badge--warn */
.ai-src { font-size: 12px; margin-top: 12px; display: inline-block; }

/* ---------- Pelatihan dari web ---------- */
.train-flow { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 12px; }
.tf-step { display: flex; gap: 12px; padding: 14px 16px; border: 1.5px dashed var(--line-2);
  border-radius: 13px; background: var(--surface); }
.tf-step.ok { border-style: solid; border-color: var(--primary);
  background: var(--primary-soft); }
.tf-n { flex: none; width: 26px; height: 26px; border-radius: 50%; display: grid; place-items: center;
  background: var(--surface); color: var(--muted); font-size: 12px; font-weight: 700;
  border: 1px solid var(--line-2); }
.tf-step.ok .tf-n { background: var(--primary); color: var(--primary-ink); border-color: var(--primary); }
.tf-step b { font-size: 13.5px; display: block; }
.tf-step small { font-size: 11.5px; color: var(--ink-soft); line-height: 1.45; display: block; }
.train-run { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin-top: 18px; }
.train-log { margin-top: 16px; }
.train-log > .msg--bare { margin: 10px 0 0; }

/* ---------- Bandingkan ---------- */
.cmp-pick { display: flex; align-items: flex-end; gap: 16px; flex-wrap: wrap; margin: 0; }
.cmp-pick .inline-fld { flex-direction: column; align-items: flex-start; gap: 6px; flex: 1 1 240px; }
.cmp-pick .field { width: 100%; }
.cmp-vs { color: var(--muted); padding-bottom: 12px; }
.cmp-table .delta-up { color: var(--primary); } .cmp-table .delta-down { color: var(--amber); }
.cmp-overlap { display: flex; gap: 28px; }
.ov-stat { display: flex; flex-direction: column; }
.ov-stat b { font-size: 26px; font-weight: 700; letter-spacing: -.5px; }
.ov-stat span { font-size: 12px; color: var(--muted); }
.cmp-grid { align-items: start; }
.cmp-kpis { grid-template-columns: repeat(3, 1fr); margin-bottom: 16px; }
.cmp-tag { display: inline-grid; place-items: center; width: 24px; height: 24px; border-radius: 7px;
  background: var(--primary); color: var(--primary-ink); font-size: 12px; font-weight: 700;
  margin-right: 8px; vertical-align: middle; }

@media (max-width: 900px) {
  .annot-grid { grid-template-columns: 1fr; gap: 16px; }
  .cmp-grid { grid-template-columns: 1fr; }
}

/* ---------- Tab Koordinasi: pemisah sumber + tata letak 2 kolom ---------- */
.src-switch { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 16px; }
/* Pil navigasi — satu definisi untuk penyaring sumber DAN sub-tab dalam kartu,
   yang sebelumnya digambar dua kali dengan hasil nyaris sama. */
.src-pill, .tabs.sub .tab {
  display: inline-flex; align-items: center; gap: 8px; padding: 7px 13px; font-size: 13px;
  font-weight: 500; color: var(--ink-soft); background: var(--surface);
  border: 1px solid var(--line); border-bottom: 1px solid var(--line);
  border-radius: 999px; cursor: pointer; font-family: var(--font);
  transition: border-color .13s, color .13s, background .13s; }
.src-pill i, .tabs.sub .tab i { color: var(--muted); font-size: 12px; }
.src-pill .mono { font-size: 11.5px; color: var(--muted); }
.src-pill:hover, .tabs.sub .tab:hover { border-color: var(--line-2); color: var(--ink); background: var(--surface); }
.src-pill.active, .tabs.sub .tab.active {
  background: var(--primary-soft); border-color: var(--primary); color: var(--primary); font-weight: 600; }
.src-pill.active i, .src-pill.active .mono,
.tabs.sub .tab.active i { color: var(--primary); }

/* Kolom kiri lebih lebar: graf & lini waktu perlu ruang, metrik/sinyal padat. */
.grid-coord { display: grid; grid-template-columns: 1.55fr 1fr; gap: 20px;
  align-items: start; margin-bottom: 20px; }
.grid-coord > .card { margin-bottom: 0; min-width: 0; }
.grid-coord .metric-grid { grid-template-columns: repeat(2, 1fr); }

@media (max-width: 1180px) { .grid-coord { grid-template-columns: 1fr; } }

/* ---------- Klaster koordinasi: tabel ringkas + rincian per baris ---------- */
.cl-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 18px;
  flex-wrap: wrap; }
.cl-filters { display: flex; gap: 7px; flex-wrap: wrap; }

.cl-table { table-layout: auto; }
.cl-table .cl-caret { width: 30px; padding-right: 0; color: var(--muted); }
.cl-table .cl-caret i { transition: transform .15s; font-size: 11px; }
.cl-row { cursor: pointer; }
.cl-row:hover { background: var(--surface-2); }
.cl-row.open { background: var(--primary-soft); }
.cl-row.open .cl-caret i { transform: rotate(90deg); color: var(--primary); }
.cl-sig { white-space: nowrap; }
.cl-sig .chip { margin-right: 4px; }
.nowrap { white-space: nowrap; }

.cl-detail > td { background: var(--surface-2); padding: 0 !important; }
.cld { padding: 16px 18px 18px 48px; }
.cld .bars-cap { margin: 14px 0 6px; }
.cld .bars-cap:first-child { margin-top: 0; }
.cld .cl-facts { display: flex; gap: 26px; margin: 0; }
.cld .accounts { margin: 0; font-size: 11.5px; color: var(--ink-soft); line-height: 1.7;
  word-break: break-word; }
.cld .cl-sample { margin: 12px 0 0; font-size: 13.5px; font-style: italic;
  color: var(--ink-soft); border-left: 3px solid var(--line-2); padding-left: 12px; }


/* ---------- Aksi di mainbar + tombol dropdown ---------- */
.mainbar-actions { display: flex; align-items: center; gap: 10px; flex: none; }

.dropdown { position: relative; }
/* Disamakan dengan .btn-primary.sm: font 13,5/600, radius 11, tinggi total 39,6px.
   Padding vertikal 8px (bukan 9px) mengimbangi border 1px yang tak dimiliki
   tombol primer, sehingga tinggi keduanya persis sama. */
/* Padding 8px (bukan 9px) mengimbangi border 1px yang tak dimiliki tombol
   primer, sehingga tingginya sama persis. line-height kini diurus .btn-outline. */
.btn-outline.dd-toggle { white-space: nowrap; padding: 6px 14px; font-size: 13px;
  font-weight: 600; border-radius: 999px; color: var(--ink); }
.dd-toggle i:first-child { color: var(--primary); }
.dd-toggle.on { border-color: var(--primary); color: var(--primary); }
.dd-caret { font-size: 10px; margin-left: 2px; color: var(--muted);
  transition: transform .15s; }
.dd-caret.up { transform: rotate(180deg); }

.dd-menu { position: absolute; top: calc(100% + 8px); right: 0; z-index: 40; min-width: 248px;
  display: flex; flex-direction: column; padding: 6px; background: var(--surface);
  border: 1px solid var(--line); border-radius: 13px; box-shadow: var(--shadow); }
.dd-item { display: flex; align-items: center; gap: 12px; width: 100%; padding: 10px 12px;
  border: 0; border-radius: 9px; background: none; text-align: left; cursor: pointer;
  color: var(--ink); font-family: var(--font); transition: background .12s; }
.dd-item:hover { background: var(--surface-2); }
.dd-item > i { width: 18px; flex: none; text-align: center; color: var(--primary); font-size: 15px; }
.dd-item span { display: flex; flex-direction: column; min-width: 0; }
.dd-item b { font-size: 13.5px; font-weight: 600; }
.dd-item small { font-size: 11.5px; color: var(--muted); line-height: 1.4; }

@media (max-width: 720px) {
  .dd-toggle .dd-caret { display: none; }
  .mainbar-actions { gap: 7px; }
}

/* ---------- Chip tren pencarian (usulan kata kunci) ----------
   Diletakkan tepat di bawah kotak kata kunci karena itulah bidang yang hendak
   diisinya. Bentuknya sengaja BEDA dari chip sumber di bawahnya: yang ini
   mengisi satu kotak teks, yang itu menyalakan/mematikan pilihan — dua kelakuan
   berbeda tidak boleh terlihat sama. */
.trend-cats { display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin: 16px 0 0; }
.trend-bar { display: flex; align-items: flex-start; gap: 12px; flex-wrap: wrap;
  margin: 10px 0 4px; min-height: 30px; }
.trend-lbl { flex: none; font-size: 11.5px; font-weight: 600; color: var(--ink-soft); }
.trend-lbl i { color: var(--ok); margin-right: 6px; }
.trend-chips { flex: 1; min-width: 0; display: flex; flex-wrap: wrap; gap: 7px; }
.trend-chip { display: inline-flex; align-items: center; gap: 7px; padding: 5px 11px;
  border: 1px solid var(--line-2); border-radius: 999px; background: var(--surface);
  color: var(--ink-soft); font-family: var(--font); font-size: 12px; cursor: pointer;
  transition: border-color .13s, background .13s, color .13s; }
.trend-chip:hover { border-color: var(--primary); color: var(--primary);
  background: var(--primary-soft); }
.trend-chip.on { border-color: var(--primary); background: var(--primary-soft);
  color: var(--primary); font-weight: 600; }
.trend-chip small { font-size: 9.5px; color: var(--muted); }
.trend-chip.on small { color: inherit; }
.trend-caveat { margin: 8px 0 4px; }

/* ---------- Kelompok chip sumber di dashboard ---------- */
.src-group { margin-bottom: 14px; }
.src-group-head { display: flex; align-items: center; justify-content: space-between;
  gap: 12px; margin-bottom: 8px; }
/* Judul = tombol lipat. Dibuat tak menyerupai tombol agar barisnya tetap
   terbaca sebagai judul kelompok; keterklikannya ditandai kursor & anak panah. */
.sg-title { font-size: 12px; font-weight: 600; color: var(--ink-soft); display: inline-flex;
  align-items: center; gap: 7px; border: 0; background: none; padding: 3px 0;
  font-family: var(--font); text-align: left; cursor: pointer; }
.sg-title:hover { color: var(--ink); }
.sg-title:hover .sg-caret { color: var(--primary); }
.sg-title:focus-visible { outline: 2px solid var(--primary); outline-offset: 3px;
  border-radius: 6px; }
.sg-title i { color: var(--muted); font-size: 11px; }
.sg-caret { width: 9px; transition: transform .15s; }
.src-group:not(.closed) .sg-caret { transform: rotate(90deg); }
.src-group.closed .src-picker { display: none; }
/* Ditandai warna aksen, bukan abu-abu seperti hitungan total di sebelahnya:
   yang satu keterangan, yang satu peringatan bahwa ada pilihan tersembunyi. */
.sg-count { font-size: 10px; font-weight: 600; color: var(--primary);
  background: var(--primary-soft); padding: 2px 8px; border-radius: 999px; }

/* Jumlah akun pada pil sumber (tab Koordinasi). Diredam relatif ke jumlah
   unggahan di sebelahnya: ia keterangan pembatas, bukan ukuran besarnya data. */
.sp-acct { font-size: 9.5px; color: var(--muted); }
.src-pill.active .sp-acct { color: inherit; opacity: .75; }

/* ---------- Klaster narasi ----------
   Sengaja berbentuk daftar kartu, bukan graf seperti tab Koordinasi: yang
   dibaca di sini adalah ISI tiap alur cerita, dan graf simpul-artikel hanya
   menampilkan gumpalan yang tak bisa ditafsirkan. */
.nar-list { display: flex; flex-direction: column; gap: 14px; }
.nar-item { margin-bottom: 0; }
/* Lintas-outlet ditandai garis tepi kiri: itulah pembeda yang menjawab
   "siapa mengangkat cerita yang mana", jadi ia harus terlihat sebelum dibaca. */
.nar-item.cross { border-left: 3px solid var(--primary); }
.nar-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin-bottom: 10px; }
.nar-id { font-size: 11px; color: var(--muted); }
.nar-outlets { display: flex; gap: 6px; flex-wrap: wrap; }
.nar-meta { margin-left: auto; font-size: 11px; color: var(--muted); }
.nar-terms { margin-bottom: 10px; }
.nar-exemplar { font-size: 13px; line-height: 1.65; color: var(--ink-soft);
  background: var(--surface-2); border: 1px solid var(--line);
  border-radius: 11px; padding: 12px 14px; margin: 0 0 10px; }
.nar-facts { display: flex; gap: 18px; flex-wrap: wrap; font-size: 11.5px;
  color: var(--muted); }
.nar-facts i { margin-right: 5px; }
.nar-facts b { color: var(--ink-soft); }
.theory-cites { list-style: none; padding: 0; margin: 0;
  display: flex; flex-direction: column; gap: 9px; }
.theory-cites li { font-size: 12.5px; color: var(--ink-soft); line-height: 1.6; }
.sg-actions { display: flex; gap: 12px; }
.sg-link { border: 0; background: none; padding: 0; cursor: pointer; font-family: var(--font);
  font-size: 11.5px; font-weight: 500; color: var(--primary); }
.sg-link:hover { text-decoration: underline; }

/* ---------- Inventaris sumber (halaman Scraping) ---------- */
.src-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(268px, 1fr)); gap: 10px; }
.src-row { display: flex; align-items: center; gap: 12px; padding: 12px 14px;
  border: 1px solid var(--line); border-radius: 12px; background: var(--surface-2); }
.src-row > i:first-child { width: 18px; text-align: center; color: var(--primary); font-size: 15px; }
.src-row.off { opacity: .55; }
.sr-body { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.sr-body b { font-size: 13.5px; font-weight: 600; }
.sr-body small { font-size: 11px; color: var(--muted); line-height: 1.4;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }


/* ---------- Mode rail: sidebar diciutkan (data-rail pada <html>) ----------
   Seluruh blok dibatasi ke lebar tertambat. Di bawah 901px sidebar sudah jadi
   laci melayang: ruang bukan lagi barang langka di sana, jadi menciutkannya
   hanya akan menyembunyikan label tanpa menghemat apa pun. Membatasinya di
   sini lebih murah daripada membatalkan tiap aturan satu per satu nanti. */
@media (min-width: 901px) {
  :root[data-rail="1"] .app { grid-template-columns: 74px 1fr; }
  :root[data-rail="1"] .sidebar { padding: 22px 12px; }
  :root[data-rail="1"] .brand-row { flex-direction: column; gap: 10px; padding-bottom: 12px; }
  :root[data-rail="1"] .brand { padding: 0; flex: none; }
  :root[data-rail="1"] .brand-text,
  :root[data-rail="1"] .nav-item > span,
  :root[data-rail="1"] .nav-kbd,
  :root[data-rail="1"] .nav-cap,
  :root[data-rail="1"] .nav-ext,
  :root[data-rail="1"] .nav-search span,
  :root[data-rail="1"] .jc-key,
  :root[data-rail="1"] .jc-meta,
  :root[data-rail="1"] .jc-top b,
  :root[data-rail="1"] .quota-row span,
  :root[data-rail="1"] .quota-note,
  :root[data-rail="1"] .user-meta,
  :root[data-rail="1"] .theme-toggle span { display: none; }
  :root[data-rail="1"] .nav-item { justify-content: center; padding: 12px 0; }
  :root[data-rail="1"] .nav-item.active::before { left: -12px; }
  :root[data-rail="1"] .nav-badge { position: absolute; top: 4px; right: 6px; margin: 0;
    padding: 0 5px; font-size: 9px; }
  :root[data-rail="1"] .nav-search { justify-content: center; padding: 9px 0; }
  :root[data-rail="1"] .nav-search .nav-kbd { display: none; }
  /* Panel analisis menyusut jadi titik + persen; sisanya pindah ke tooltip. */
  :root[data-rail="1"] .jobcard { padding: 9px 7px; gap: 6px; }
  :root[data-rail="1"] .jc-top { justify-content: center; }
  :root[data-rail="1"] .jc-x { margin: 0; }
  :root[data-rail="1"] .quota { padding: 2px 0 10px; }
  :root[data-rail="1"] .quota-row { justify-content: center; }
  :root[data-rail="1"] .user-chip { justify-content: center; padding: 8px 0; }
  :root[data-rail="1"] .foot-actions { flex-direction: column; }
  /* pemisah menggantikan kapsi seksi yang disembunyikan */
  :root[data-rail="1"] .nav-cap + .nav-item { margin-top: 10px;
    border-top: 1px solid var(--line); padding-top: 14px; }
  :root[data-rail="1"] .nav-cap:first-child + .nav-item { margin-top: 0; border-top: 0; padding-top: 12px; }
}

/* ---------- Palet perintah (⌘K) ---------- */
.palette { width: min(560px, 92vw); padding: 0; border: 1px solid var(--line);
  border-radius: 16px; background: var(--surface); color: var(--ink);
  box-shadow: var(--shadow); margin-top: 12vh; }
.palette::backdrop { background: rgba(0, 0, 0, .55); backdrop-filter: blur(2px); }
.pal-input { display: flex; align-items: center; gap: 11px; padding: 14px 16px;
  border-bottom: 1px solid var(--line); }
.pal-input i { color: var(--muted); }
.pal-input input { flex: 1; border: 0; background: none; outline: none; color: var(--ink);
  font-family: var(--font); font-size: 14.5px; }
.pal-list { max-height: 46vh; overflow-y: auto; padding: 8px; }
.pal-cap { margin: 8px 0 4px; padding-left: 10px; }
.pal-item.on { background: var(--surface-2); }
.pal-empty { padding: 22px; text-align: center; color: var(--muted); font-size: 13px; margin: 0; }

/* ---------- Editor resep scraping ----------
   Satu kolom bertab, bukan dua kolom bersanding: tiap tahap membawa pengujinya
   sendiri, jadi "ubah selector -> uji" terjadi di dalam satu tahap alih-alih
   melompat ke panel terpisah yang menguji dua tahap sekaligus. */
/* Selebar mainbar, tidak dipagari 940px: isi terlebar di halaman ini adalah
   hasil uji — tabel tautan panenan dan cuplikan HTML mentah — dan memotongnya
   di tengah layar lebar memaksa gulir mendatar justru pada saat pembaca sedang
   membandingkan selector dengan keluarannya. */
.recipe-form .card, .run-card { margin-bottom: 20px; }
.recipe-actions { display: flex; gap: 10px; flex-wrap: wrap; }
/* Tab dipasang pada <button> (bukan <a>) karena ia mengganti panel, bukan
   berpindah halaman — formulirnya satu dan tak boleh dimuat ulang. */
button.tab { border: 0; background: none; font-family: var(--font); cursor: pointer; }
.stage-lede { margin: 0 0 14px; }
.stage-err { margin-left: 2px; padding: 1px 7px; font-size: 10px; }

/* Daftar resep contoh — memakai bentuk baris yang sama dengan daftar resep di
   halaman Scraping, supaya "contoh" dan "milik saya" terbaca sejenis. */
.preset-list { display: flex; flex-direction: column; gap: 10px; }
.preset-item { color: var(--ink); transition: border-color .13s, background .13s; }
.preset-item:hover { border-color: var(--primary); background: var(--primary-soft); }
.preset-item.on { border-color: var(--primary); }
.preset-item.on > i:first-child { color: var(--ok); }
.preset-go { color: var(--muted); font-size: 11px; }
.preset-item:hover .preset-go { color: var(--primary); }
.preset-tag { font-family: var(--mono); font-size: 9.5px; text-transform: uppercase;
  letter-spacing: .07em; color: var(--ok); }
/* ---------- Vonis statistik & lonjakan ----------
   Hasil uji diberi bingkai tersendiri, bukan dilebur ke teks biasa: ia bukan
   catatan kaki melainkan kesimpulan, dan pembacanya harus tahu kapan angka di
   tabel di atasnya BOLEH ditafsirkan sebagai perbedaan. */
.stat-test { margin-top: 16px; padding: 14px 16px; border-radius: 12px;
  border: 1px solid var(--line); background: var(--surface-2); }
.stat-test.sig { border-color: color-mix(in srgb, var(--ok) 45%, transparent); }
.stat-test.nosig { border-color: color-mix(in srgb, var(--amber) 40%, transparent); }
.st-head { margin: 0 0 6px; font-size: 13.5px; font-weight: 600;
  display: flex; align-items: center; gap: 8px; }
.stat-test.sig .st-head i { color: var(--ok); }
.stat-test.nosig .st-head i { color: var(--amber); }
.stat-test .st-head i { color: var(--muted); }
.st-body { margin: 0; font-size: 13px; color: var(--ink-soft); line-height: 1.6; }
.st-cite { margin: 10px 0 0; font-family: var(--mono); font-size: 10.5px; color: var(--muted); }

.burst-verdict { display: flex; align-items: flex-start; gap: 9px; margin: 12px 0 0;
  font-size: 12.5px; color: var(--ink-soft); line-height: 1.6; }
.burst-verdict i { margin-top: 3px; color: var(--muted); font-size: 12px; }
.burst-verdict.hot i { color: var(--danger); }

/* Akun perantara: nama + bilah skor, diurutkan menurun. */
.broker-list { display: flex; flex-direction: column; gap: 9px; }
.broker { display: flex; align-items: center; gap: 12px; }
.broker-rank { flex: none; width: 16px; text-align: right; font-size: 10px; color: var(--muted); }
.broker-name { flex: 1; min-width: 0; font-size: 12.5px; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }
.broker-bar { flex: none; width: 34%; }
.broker-score { flex: none; width: 46px; text-align: right; font-size: 11px;
  color: var(--ink-soft); font-variant-numeric: tabular-nums; }

/* Tombol uji: ikon play kompak, menyatu di ujung kanan bidang inputnya —
   satu klik "sekarang jalankan" tepat di sebelah nilai yang diuji. */
.test-row { display: flex; gap: 8px; align-items: stretch; }
.test-row .field { flex: 1; min-width: 0; }
.test-run { flex: none; width: 38px; border: 0; border-radius: 9px; cursor: pointer;
  background: var(--primary); color: var(--primary-ink); font-size: 14px;
  display: grid; place-items: center; transition: filter .13s, transform .1s;
  box-shadow: 0 4px 12px color-mix(in srgb, var(--primary) 26%, transparent); }
.test-run:hover { filter: brightness(1.07); transform: translateY(-1px); }
.test-run:disabled { opacity: .55; cursor: not-allowed; transform: none; box-shadow: none; }
/* ---------- Hasil uji resep ----------
   Pertanyaan yang sedang dijawab panel ini selalu sama: "selector saya kena
   atau tidak?" Karena itu keluarannya dibuka dengan vonis berstatus, baru
   rinciannya — bukan tumpahan data yang harus ditafsirkan sendiri. */
.test-out { margin-top: 16px; padding-top: 16px; border-top: 1px solid var(--line); }

.tr-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 12px; }
.tr-status { display: inline-flex; align-items: center; gap: 8px; font-size: 13px; font-weight: 600; }
.tr-status i { font-size: 12.5px; }
.tr-status.ok i { color: var(--ok); }
.tr-status.warn i { color: var(--amber); }
.tr-status.bad i { color: var(--danger); }
.tr-meta { margin-left: auto; }

/* Daftar tautan: satu baris satu tautan, jalur artikel di depan karena itulah
   yang berbeda antar-baris; hostnya diredam supaya tidak berulang 12 kali. */
.tr-links { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column;
  max-height: 236px; overflow-y: auto; border: 1px solid var(--line); border-radius: 11px;
  background: var(--surface-2); }
.tr-link { display: flex; align-items: center; gap: 10px; width: 100%; padding: 8px 11px;
  border: 0; border-bottom: 1px solid var(--line); background: none; cursor: pointer;
  text-align: left; font-family: var(--font); color: var(--ink-soft); }
.tr-links li:last-child .tr-link { border-bottom: 0; }
.tr-link:hover, .tr-link:focus-visible { background: var(--primary-soft); color: var(--primary); }
.tr-n { flex: none; width: 18px; text-align: right; font-family: var(--mono); font-size: 10px;
  color: var(--muted); font-variant-numeric: tabular-nums; }
.tr-path { flex: 1; min-width: 0; font-family: var(--mono); font-size: 11.5px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tr-host { flex: none; font-size: 10px; color: var(--muted); }
.tr-go { flex: none; font-size: 9.5px; opacity: 0; transition: opacity .12s; }
.tr-link:hover .tr-go, .tr-link:focus-visible .tr-go { opacity: 1; }

/* Vonis per selector — inti panel ini: empat target, kena atau tidak. */
.tr-checks { display: grid; grid-template-columns: repeat(auto-fit, minmax(108px, 1fr));
  gap: 8px; margin-bottom: 14px; }
.tr-check { display: flex; flex-direction: column; gap: 3px; padding: 9px 11px;
  border: 1px solid var(--line); border-radius: 10px; background: var(--surface-2); }
.tr-check small { font-family: var(--mono); font-size: 9.5px; text-transform: uppercase;
  letter-spacing: .07em; color: var(--muted); }
.tr-check b { display: flex; align-items: center; gap: 6px; font-size: 12.5px; font-weight: 600;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tr-check b i { flex: none; font-size: 11px; }
.tr-check.ok b i { color: var(--ok); }
.tr-check.miss { border-color: color-mix(in srgb, var(--amber) 42%, transparent); }
.tr-check.miss b { color: var(--amber); }
.tr-check.off b { color: var(--muted); font-weight: 500; }

.tr-title { font-size: 14px; font-weight: 600; line-height: 1.45; margin: 0 0 10px; }
.tr-body { font-size: 12.5px; color: var(--ink-soft); line-height: 1.65; margin: 0;
  max-height: 186px; overflow-y: auto; background: var(--surface-2); padding: 12px 14px;
  border: 1px solid var(--line); border-radius: 11px; }
.tr-more { margin: 12px 0 0; font-size: 11.5px; }
.tr-more summary { cursor: pointer; color: var(--muted); list-style: revert; }
.tr-more summary:hover { color: var(--ink); }
.tr-more dt { font-size: 11px; }
.tr-more dd { font-size: 11.5px; text-align: right; word-break: break-word; }
.tr-more ul { margin: 8px 0 0; padding-left: 18px; color: var(--muted);
  display: flex; flex-direction: column; gap: 4px; }

/* ---------- Tabel uji isi ----------
   Selector isi dinilai dari beberapa konten sekaligus, bukan satu: satu baris
   per konten, satu kolom per selector, sehingga kolom yang gagal terbaca
   sebagai garis vertikal kosong — pola yang hilang bila hasilnya ditumpuk
   sebagai kartu satu per satu. */
.test-n { flex: none; width: auto; padding-right: 30px; }
.tr-table-wrap { overflow-x: auto; border: 1px solid var(--line); border-radius: 11px; }
.tr-table { width: 100%; border-collapse: collapse; font-size: 12.5px; }
.tr-table th { text-align: left; padding: 9px 12px; background: var(--surface-2);
  font-family: var(--mono); font-size: 9.5px; text-transform: uppercase;
  letter-spacing: .07em; color: var(--muted); font-weight: 600;
  border-bottom: 1px solid var(--line); white-space: nowrap; }
.tr-table td { padding: 10px 12px; border-bottom: 1px solid var(--line);
  vertical-align: top; }
.tr-table tbody tr:last-child td { border-bottom: 0; }
.tr-table tbody tr:hover { background: var(--surface-2); }
.tr-table tbody tr.bad { background: color-mix(in srgb, var(--danger) 7%, transparent); }
.tr-t-n { font-family: var(--mono); font-size: 10px; color: var(--muted); width: 1%; }
/* Judul boleh melebar, isi tidak: cuplikan yang tak dibatasi akan mendorong
   kolom lain keluar layar dan justru menyembunyikan yang sedang dibandingkan. */
.tr-t-title { display: block; font-size: 12.5px; font-weight: 600; line-height: 1.4;
  max-width: 34ch; }
.tr-t-url { display: block; margin-top: 3px; font-size: 10px; color: var(--muted);
  max-width: 34ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tr-t-exc { margin-top: 3px; font-size: 11px; color: var(--muted);
  line-height: 1.45; max-width: 40ch; overflow: hidden;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; }
.tr-t-none { color: var(--amber); font-size: 11.5px; }
.tr-t-err { color: var(--danger); font-size: 11.5px; }
.tr-t-err i { margin-right: 6px; }
.tr-t-act { width: 1%; text-align: right; }
.tr-t-go { border: 1px solid var(--line-2); background: var(--surface); color: var(--muted);
  width: 28px; height: 28px; border-radius: 8px; cursor: pointer; font-size: 11px; }
.tr-t-go:hover { border-color: var(--primary); color: var(--primary); background: var(--primary-soft); }
.tr-t-go:disabled { opacity: .55; cursor: not-allowed; }
.tr-t-ok { color: var(--ok); font-size: 12px; }
.tr-table code { font-size: 11.5px; word-break: break-all; }

/* ---------- Fitur berbantuan LLM ----------
   Selalu berpasangan: satu tombol pemicu + satu kalimat yang menjelaskan bahwa
   keluarannya usulan, bukan keputusan. Pasangan itu dijadikan satu kelas supaya
   fitur LLM berikutnya tidak bisa lupa membawa penjelasannya. */
.llm-strip { display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  margin: 12px 0 4px; }
.llm-strip .fld-hint { flex: 1; min-width: 220px; margin: 0; }
/* Pemilih penyedia: didorong ke ujung, diredam. Ia kendali yang jarang disentuh
   — kebanyakan orang memakai bawaannya — jadi ia tak boleh bersaing perhatian
   dengan tombol pemicunya. */
.llm-pick { flex: none; margin-left: auto; display: inline-flex; align-items: center;
  gap: 8px; font-size: 11px; color: var(--muted); }
.llm-pick .field { font-size: 11.5px; padding: 6px 10px; }
.llm-row .llm-acts { flex: none; display: flex; gap: 6px; margin-left: auto; }
.llm-row .tr-t-go { display: inline-grid; place-items: center; }
.llm-row.on { border-color: var(--primary); }

/* Prosa hasil generasi: lebar baca dibatasi, dan sengaja TIDAK menyerupai
   kartu hasil hitungan di sekitarnya — pembaca harus bisa membedakan angka yang
   dihitung dari kalimat yang disusun ulang. */
.llm-prose { border-left: 3px solid var(--primary); padding: 2px 0 2px 16px;
  margin: 14px 0; max-width: 72ch; }
.llm-prose p { font-size: 14px; line-height: 1.7; color: var(--ink-soft); margin: 0 0 12px; }
.llm-prose p:last-child { margin-bottom: 0; }

/* Perbandingan LLM vs anotator, pada kartu anotasi. */
.ai-llm { margin-top: 14px; padding: 11px 14px; border-radius: 11px;
  border: 1px solid color-mix(in srgb, var(--amber) 40%, transparent);
  background: var(--amber-soft); display: flex; flex-direction: column; gap: 8px; }
.ai-llm.agree { border-color: color-mix(in srgb, var(--ok) 40%, transparent);
  background: var(--ok-soft); }
.ai-llm-head { display: flex; align-items: center; gap: 9px; font-size: 12.5px;
  font-weight: 600; color: var(--amber); }
.ai-llm.agree .ai-llm-head { color: var(--ok); }
.ai-llm-head small { color: var(--muted); font-weight: 400; font-size: 10px; margin-left: auto; }
.ai-llm-labels { display: flex; flex-wrap: wrap; gap: 6px; }
.ai-llm-why { font-size: 11.5px; color: var(--ink-soft); font-style: italic; }
.ai-llm-pending { margin: 14px 0 0; font-size: 11.5px; color: var(--muted); }
.ai-llm-pending i { margin-right: 6px; }
.ai-diff small { opacity: .8; font-weight: 400; margin-left: 4px; }

/* Panel kesepakatan κ. Terbuka secara bawaan — ia hasil, bukan pengaturan;
   melipatnya berarti angka yang paling menentukan justru tersembunyi. */
.kappa-panel { border: 1px solid var(--line); border-radius: 12px;
  padding: 12px 14px; background: var(--surface-2); }
.kappa-panel > summary { cursor: pointer; list-style: revert; }
.kappa-panel[open] > summary { margin-bottom: 12px; }
.kappa-head { display: inline-flex; align-items: center; gap: 9px; flex-wrap: wrap;
  font-size: 13px; font-weight: 600; color: var(--ink-soft); }
.kappa-head > i { color: var(--muted); }
.kappa-head small { font-weight: 400; font-size: 11px; }
.kappa-num { font-family: var(--mono); font-size: 15px; }
.kappa-num.ok { color: var(--ok); }
.kappa-num.warn { color: var(--amber); }
.kappa-num.bad { color: var(--danger); }
.kappa-num.muted { color: var(--muted); }
.kappa-panel .llm-strip { margin-bottom: 0; }

.lex-out { margin-top: 10px; }
.lex-out:empty { margin-top: 0; }

/* Kandidat istilah leksikon: kotak centang, bukan penerapan langsung. */
.lex-sugg { display: flex; flex-wrap: wrap; gap: 8px; margin: 12px 0; }
.lex-cand { display: inline-flex; align-items: center; gap: 8px; padding: 7px 12px;
  border: 1px solid var(--line-2); border-radius: 999px; background: var(--surface);
  font-size: 12.5px; cursor: pointer; transition: border-color .13s, background .13s; }
.lex-cand:hover { border-color: var(--primary); }
.lex-cand input { accent-color: var(--primary); }
.lex-cand.on { border-color: var(--primary); background: var(--primary-soft);
  color: var(--primary); font-weight: 600; }
.lex-cand small { color: var(--muted); font-size: 10.5px; }
.lex-cand.on small { color: inherit; }

.recipe-grid { grid-template-columns: 1fr; }
.recipe-row { gap: 14px; }
.recipe-run-form { display: flex; gap: 7px; align-items: center; margin-left: auto; }
.recipe-run-form .field.slim { width: 150px; }
.run-form { display: flex; flex-direction: column; gap: 10px; }
@media (max-width: 720px) {
  .recipe-row { flex-wrap: wrap; }
  .recipe-run-form { margin-left: 0; width: 100%; }
  .recipe-run-form .field.slim { flex: 1; width: auto; }
}

/* Bidang khusus Playwright: disembunyikan/ditampilkan oleh editor resep saat
   mesin diganti, dan diberi latar agar terbaca sebagai blok bersyarat. */
.pw-only { background: var(--surface-2); border-radius: 12px; padding: 14px 16px; margin-top: 12px; }
.pw-only[hidden] { display: none; }

/* ============================================================
   Auth split (login & register) — panel kiri gelap tetap
   (identitas merek, premium) + panel kanan formulir ikut tema.
   ============================================================ */
body.auth-body { display: block; background: var(--bg); }
.auth-split { min-height: 100vh; display: grid; grid-template-columns: 1.05fr 1fr; }

.auth-aside {
  position: relative; overflow: hidden; color: #f4f2ee;
  padding: 42px 48px; display: flex; flex-direction: column; gap: 28px;
  background:
    radial-gradient(90% 80% at 12% 8%, rgba(255,122,26,.22), transparent 60%),
    radial-gradient(70% 60% at 100% 100%, rgba(255,122,26,.10), transparent 55%),
    linear-gradient(160deg, #17161a 0%, #0c0b0d 100%);
}
:root[data-theme="light"] .auth-aside {
  background:
    radial-gradient(90% 80% at 12% 8%, rgba(41,110,229,.30), transparent 60%),
    radial-gradient(70% 60% at 100% 100%, rgba(41,110,229,.14), transparent 55%),
    linear-gradient(160deg, #10233f 0%, #0a1626 100%);
}
.auth-aside::after {   /* garis kisi halus untuk tekstur */
  content: ""; position: absolute; inset: 0; opacity: .5; pointer-events: none;
  background-image: linear-gradient(rgba(255,255,255,.03) 1px, transparent 1px),
                    linear-gradient(90deg, rgba(255,255,255,.03) 1px, transparent 1px);
  background-size: 34px 34px;
}
.auth-aside > * { position: relative; z-index: 1; }
.auth-aside-top { display: flex; align-items: center; justify-content: space-between; }
.auth-brand .brand-text b { color: #fff; font-size: 18px; }
.auth-aside .brand-mark { background: var(--primary); color: var(--primary-ink); }
.auth-badge { background: rgba(255,255,255,.08); color: #f4f2ee; border: 1px solid rgba(255,255,255,.16); }
.auth-aside-mid { margin-top: auto; }
.auth-tag { font-size: clamp(26px, 3vw, 38px); line-height: 1.18; margin: 0 0 16px; font-weight: 700;
  letter-spacing: -.02em; color: #fff; }
.auth-lede { font-size: 15px; line-height: 1.7; color: rgba(244,242,238,.72); max-width: 44ch; margin: 0 0 24px; }
.auth-points { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 12px; }
.auth-points li { font-size: 14px; color: rgba(244,242,238,.9); display: flex; align-items: center; gap: 11px; }
.auth-points i { color: var(--primary); font-size: 15px; }
:root[data-theme="light"] .auth-points i { color: #6ea8ff; }
:root[data-theme="light"] .auth-aside .brand-mark { background: #6ea8ff; color: #08131f; }
.auth-aside-foot { margin-top: auto; }
.auth-aside-foot p { font-size: 12.5px; color: rgba(244,242,238,.6); margin: 0; line-height: 1.7; }
.auth-aside-foot code { font-family: var(--mono); font-size: .95em; }

.auth-main { display: flex; flex-direction: column; justify-content: center; align-items: center;
  padding: 40px 24px; background: var(--bg); }
.auth-main-in { width: 100%; max-width: 400px; }
.auth-form-head { margin-bottom: 24px; }
.auth-eyebrow { display: inline-block; font-size: 11.5px; font-weight: 700; letter-spacing: .08em;
  text-transform: uppercase; color: var(--primary); background: var(--primary-soft);
  padding: 4px 11px; border-radius: 999px; margin-bottom: 14px; }
.auth-form-head h1 { font-size: 26px; margin: 0 0 6px; letter-spacing: -.02em; }
.auth-form-head p { margin: 0; font-size: 14px; }
.auth-copyright { margin: 34px 0 0; font-size: 12px; color: var(--muted); }
.auth-foot-note { margin-top: 18px; font-size: 12.5px; color: var(--muted); line-height: 1.6;
  display: flex; align-items: center; gap: 8px; }
.auth-foot-note i { color: var(--ok); }
.btn-primary.lg { padding: 12px 22px; font-size: 14.5px; }

@media (max-width: 900px) {
  .auth-aside { display: none; }
  .auth-split { grid-template-columns: 1fr; }
  .auth-main { min-height: 100vh; }
}

/* ============================================================
   Konsol Admin (dashboard kustom)
   ============================================================ */
.con-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px;
  margin-bottom: 22px; flex-wrap: wrap; }
.con-title { font-size: 20px; margin: 0 0 4px; }

.kpi-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; margin-bottom: 16px; }
.kpi { background: var(--surface); border: 1px solid var(--line); border-radius: 14px; padding: 18px;
  display: grid; grid-template-columns: auto 1fr; grid-template-rows: auto auto; gap: 2px 14px;
  align-items: center; box-shadow: var(--shadow-sm); }
.kpi-ic { grid-row: 1 / span 2; width: 46px; height: 46px; border-radius: 12px; display: grid;
  place-items: center; font-size: 18px; }
.kpi-ic.ic-a { color: var(--primary); background: var(--primary-soft); }
.kpi-ic.ic-b { color: var(--amber); background: var(--amber-soft); }
.kpi-ic.ic-c { color: var(--ok); background: var(--ok-soft); }
.kpi-ic.ic-d { color: var(--danger); background: var(--danger-soft); }
.kpi-num { font-size: 26px; font-weight: 700; line-height: 1.1; letter-spacing: -.02em; }
.kpi-lbl { font-size: 12.5px; color: var(--muted); }
.kpi-sub { grid-column: 2; font-size: 11.5px; color: var(--ink-soft); font-weight: 500; }
.kpi-sub i { color: var(--ok); font-size: .9em; margin-right: 3px; }

.con-mini { display: flex; flex-wrap: wrap; gap: 8px 20px; padding: 12px 16px; margin-bottom: 20px;
  background: var(--surface); border: 1px solid var(--line); border-radius: 12px; }
.con-mini .mini { font-size: 13px; color: var(--ink-soft); display: flex; align-items: center; gap: 7px; }
.con-mini .mini b { color: var(--ink); }
.con-mini .dot { width: 8px; height: 8px; border-radius: 999px; background: var(--muted); flex: none; }
.con-mini .dot.ok { background: var(--ok); } .con-mini .dot.warn { background: var(--amber); }
.con-mini .dot.danger { background: var(--danger); }

.con-panels { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.con-card { background: var(--surface); border: 1px solid var(--line); border-radius: 14px;
  overflow: hidden; box-shadow: var(--shadow-sm); }
.con-card-head { display: flex; align-items: center; justify-content: space-between;
  padding: 15px 18px; border-bottom: 1px solid var(--line); }
.con-card-head h2 { font-size: 14px; margin: 0; display: flex; align-items: center; gap: 8px; }
.con-card-head h2 i { color: var(--muted); }
.con-link { font-size: 12.5px; color: var(--primary); font-weight: 500; }
.con-link i { font-size: .85em; }

.con-tablewrap { overflow-x: auto; }
.con-table { width: 100%; border-collapse: collapse; font-size: 13.5px; }
.con-table th { text-align: left; font-size: 11px; font-weight: 700; letter-spacing: .04em;
  text-transform: uppercase; color: var(--muted); padding: 11px 18px; border-bottom: 1px solid var(--line);
  background: var(--surface-2); white-space: nowrap; }
.con-table td { padding: 12px 18px; border-bottom: 1px solid var(--line); vertical-align: middle; }
.con-table tr:last-child td { border-bottom: 0; }
.con-table--rows tbody tr:hover { background: var(--surface-2); }
.con-table .ta-r { text-align: right; }
.ct-user { display: flex; align-items: center; gap: 11px; }
.ct-av { width: 32px; height: 32px; flex: none; border-radius: 9px; display: grid; place-items: center;
  background: var(--primary); color: var(--primary-ink); font-weight: 700; font-size: 13px; }
.ct-user b { display: block; font-size: 13.5px; }
.ct-user small { display: block; font-size: 11.5px; }
.ct-key { font-size: 13.5px; } .block { display: block; }
.ct-empty { text-align: center; color: var(--muted); padding: 26px 0; }
.ct-super { color: var(--amber); font-weight: 600; }

.con-filter { display: flex; align-items: center; gap: 12px; margin-bottom: 16px; flex-wrap: wrap; }
.con-search { flex: 1; min-width: 220px; max-width: 360px; }
.con-roletabs { display: inline-flex; background: var(--surface-2); border: 1px solid var(--line);
  border-radius: 999px; padding: 3px; gap: 2px; }
.con-roletabs .rt { font-size: 12.5px; font-weight: 500; color: var(--ink-soft); padding: 6px 14px;
  border-radius: 999px; }
.con-roletabs .rt.on { background: var(--surface); color: var(--primary); box-shadow: var(--shadow-sm); }
.con-actform { display: inline; } .con-actform .btn-outline.danger:hover { color: var(--danger); border-color: var(--danger); background: var(--danger-soft); }

.con-foot-links { margin-top: 18px; }
.con-adminlink { display: inline-flex; align-items: center; gap: 10px; font-size: 13.5px; color: var(--ink-soft);
  padding: 12px 16px; border: 1px dashed var(--line-2); border-radius: 12px; background: var(--surface); }
.con-adminlink:hover { color: var(--primary); border-color: var(--primary); }
.con-adminlink small { color: var(--muted); font-size: 12px; }

@media (max-width: 1100px) { .kpi-grid { grid-template-columns: repeat(2, 1fr); } .con-panels { grid-template-columns: 1fr; } }
@media (max-width: 560px) { .kpi-grid { grid-template-columns: 1fr; } }

/* ============================================================
   Penyempurnaan responsif mobile (lintas-halaman)
   ============================================================ */
/* Jaring pengaman: tak ada elemen nyasar yang boleh menggeser SELURUH halaman
   ke samping. `clip` (bukan hidden) tak menciptakan konteks gulir baru, jadi
   position:sticky pada .mainbar tetap bekerja; kontainer .table-wrap / graphwrap
   yang overflow-x:auto tetap bisa digulir sendiri di dalamnya. */
html { overflow-x: clip; }

/* Judul di mainbar dipangkas dengan elipsis alih-alih mendorong tombol keluar
   layar (mis. judul hasil yang memuat kata kunci panjang). */
.mainbar-title { min-width: 0; flex: 1 1 auto; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }
.mainbar-actions { min-width: 0; }

@media (max-width: 600px) {
  /* Tombol aksi di mainbar menyusut jadi ikon saja agar cukup ruang untuk judul.
     Aksinya tetap terjangkau; labelnya disembunyikan, bukan tombolnya. */
  .mainbar .btn-lbl { display: none; }
  .mainbar-actions .btn-primary.sm,
  .mainbar-actions .btn-outline.sm { padding-left: 11px; padding-right: 11px; }
  .mainbar-actions > .btn-primary.sm > i,
  .mainbar-actions > .btn-outline.sm > i { margin: 0; }
  .mainbar { padding: 12px 14px; }
  .content { padding: 18px 14px 56px; }
  .page-title, .con-title { font-size: 18px; }
}

/* ---------- Konsol Admin di ponsel ---------- */
@media (max-width: 640px) {
  .con-head { flex-direction: column; align-items: flex-start; }
  /* Filter menumpuk rapi: kotak cari penuh selebar baris, tab peran satu baris. */
  .con-filter { gap: 10px; }
  .con-search { flex: 1 1 100%; max-width: none; }
  .con-roletabs { width: 100%; justify-content: space-between; }
  .con-filter > .btn-outline.sm { width: 100%; justify-content: center; }
  /* Sembunyikan kolom kurang-kritis pada tabel kelola pengguna agar muat tanpa
     gulir horizontal: Paket (3) & Bergabung (5). Sisanya: Pengguna, Peran,
     Analisis, Aksi. Tabel dashboard (.con-table biasa) tetap dapat digulir. */
  .con-table--rows th:nth-child(3), .con-table--rows td:nth-child(3),
  .con-table--rows th:nth-child(5), .con-table--rows td:nth-child(5) { display: none; }
  .con-table--rows th, .con-table--rows td { padding-left: 12px; padding-right: 12px; }
  .con-actform .btn-outline.sm { white-space: nowrap; }
}

/* Kartu KPI konsol: di ponsel sangat sempit, ikon + angka tetap sebaris rapi. */
@media (max-width: 380px) {
  .kpi { padding: 14px; gap: 2px 11px; }
  .kpi-ic { width: 40px; height: 40px; font-size: 16px; }
  .kpi-num { font-size: 22px; }
}
