/* ============================================================
   Japfa — Fabrikasi & Monitoring Perangkat IoT (mockup statis)
   Light theme · desktop-first ≥1280px · system font stack
   ============================================================ */
:root{
  --bg:#f4f5f7; --panel:#ffffff; --border:#e3e6ea; --border-2:#d5dae0;
  --text:#1d2329; --text-2:#4a5560; --muted:#7b8794;
  --accent:#d1332e; --accent-dark:#b02a26; --accent-soft:#fdeeed; --accent-border:#f4c7c5;
  --green:#1e8e3e; --green-soft:#e6f4ea; --green-border:#c6e5cf; --green-dot:#34a853;
  --amber:#9c5700; --amber-soft:#fef3e0; --amber-border:#f3ddb0; --amber-dot:#f9ab00;
  --red:#c5221f; --red-soft:#fce8e6; --red-border:#f5c6c3; --red-dot:#ea4335;
  --blue:#1a5fb4; --blue-soft:#e8f0fe; --blue-border:#c3d7f7; --blue-dot:#4285f4;
  --gray:#5f6b76; --gray-soft:#eef0f2; --gray-border:#dbe0e5; --gray-dot:#9aa4af;
  --dark:#343c44; --dark-soft:#e7e9ec;
  --panel-2:#fafbfc; --track:#eef0f3;
  --mono:ui-monospace,SFMono-Regular,Menlo,Consolas,"Liberation Mono",monospace;
  --shadow:0 1px 2px rgba(23,28,33,.06),0 1px 3px rgba(23,28,33,.05);
  --shadow-lg:0 12px 32px rgba(23,28,33,.18);
  --r:10px;
}
*{box-sizing:border-box}
html,body{margin:0;padding:0}
body{
  font:14px/1.5 -apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif;
  color:var(--text); background:var(--bg);
  -webkit-font-smoothing:antialiased;
}
a{color:var(--blue);text-decoration:none}
a:hover{text-decoration:underline}
h1,h2,h3{margin:0;font-weight:600}
.muted{color:var(--muted)}
.mono,.serial{font-family:var(--mono);font-size:.93em}
.serial{font-weight:600;color:var(--text-2)}
small{font-size:11.5px;color:var(--muted);font-weight:400}
.num{text-align:right;font-variant-numeric:tabular-nums}

/* ---------- App shell ---------- */
.app{display:flex;min-height:100vh}
.sidebar{
  width:228px;flex:0 0 228px;background:#20262c;color:#c6ccd2;
  display:flex;flex-direction:column;padding:18px 12px;gap:2px;
  position:sticky;top:0;height:100vh;
}
.brand{display:flex;gap:10px;align-items:center;padding:2px 8px 16px;border-bottom:1px solid #333b43;margin-bottom:14px}
.brand-mark{
  width:38px;height:38px;flex:0 0 38px;border-radius:9px;background:var(--accent);
  color:#fff;font-weight:800;font-size:20px;display:flex;align-items:center;justify-content:center;
  letter-spacing:.5px;
}
.brand-name{font-weight:700;color:#fff;font-size:15px;letter-spacing:2.5px}
.brand-sub{font-size:10.5px;color:#8d97a1;margin-top:1px}
.nav-label{font-size:10px;letter-spacing:1.4px;text-transform:uppercase;color:#77828c;padding:2px 10px 6px}
.nav-item{
  display:flex;align-items:center;gap:10px;padding:9px 10px;border-radius:8px;
  color:#c6ccd2;font-weight:500;font-size:13.5px;
}
.nav-item:hover{background:#2a3138;color:#fff;text-decoration:none}
.nav-item.active{background:var(--accent);color:#fff}
.nav-ico{width:18px;height:18px;display:inline-flex}
.nav-ico svg{width:18px;height:18px}
.sidebar-foot{margin-top:auto;font-size:10.5px;color:#77828c;line-height:1.6;padding:12px 10px 2px;border-top:1px solid #333b43}
.main{flex:1;min-width:0;display:flex;flex-direction:column}
.topbar{
  height:58px;background:var(--panel);border-bottom:1px solid var(--border);
  display:flex;align-items:center;justify-content:space-between;padding:0 26px;
  position:sticky;top:0;z-index:40;
}
.page-title{font-size:17px;font-weight:650}
.topbar-right{display:flex;align-items:center;gap:16px}
.user-chip{display:flex;align-items:center;gap:9px;padding:5px 12px 5px 6px;border:1px solid var(--border);border-radius:99px;background:var(--panel)}
.user-avatar{width:28px;height:28px;border-radius:50%;background:var(--dark);color:#fff;font-size:11px;font-weight:700;display:flex;align-items:center;justify-content:center}
.user-name{font-size:12.5px;font-weight:600;color:var(--text-2)}
.content{padding:24px 26px 90px;display:flex;flex-direction:column;gap:18px;max-width:1460px;width:100%;margin:0 auto}

/* ---------- Cards ---------- */
.card{background:var(--panel);border:1px solid var(--border);border-radius:var(--r);box-shadow:var(--shadow)}
.card-h{display:flex;align-items:baseline;gap:12px;flex-wrap:wrap;padding:14px 18px;border-bottom:1px solid var(--border)}
.card-title{font-size:14.5px;font-weight:650}
.card-sub{font-size:12px;color:var(--muted)}
.card-h .spacer{margin-left:auto}
.card-b{padding:16px 18px}
.stack{display:flex;flex-direction:column;gap:18px;min-width:0}
/* Dashboard-only: mempersempit kolom lalu menengahkannya, supaya kartu punya
   ruang kosong seimbang di kiri-kanan alih-alih melebar penuh ke 1460px. Sama
   properti flex/gap seperti .content agar jarak antar-kartu tak berubah.
   MENYIMPANG DARI DESAIN (mockup memakai lebar kolom penuh) — permintaan user. */
.dash-narrow{width:100%;max-width:1100px;margin:0 auto;display:flex;flex-direction:column;gap:18px}
.grid-dash{display:grid;grid-template-columns:1.3fr 1fr;gap:18px;align-items:start}
.grid-2{display:grid;grid-template-columns:1fr 1fr;gap:18px;align-items:start}
.grid-3{display:grid;grid-template-columns:repeat(3,1fr);gap:18px;align-items:start}

/* ---------- KPI tiles ---------- */
.kpi-row{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:14px}
.kpi{background:var(--panel);border:1px solid var(--border);border-radius:var(--r);box-shadow:var(--shadow);padding:14px 16px}
.kpi-label{font-size:11.5px;font-weight:600;letter-spacing:.4px;text-transform:uppercase;color:var(--muted)}
.kpi-value{font-size:27px;font-weight:700;letter-spacing:-.5px;margin-top:4px;font-variant-numeric:tabular-nums}
.kpi-note{font-size:11.5px;color:var(--muted);margin-top:3px}
.kpi-note b{color:var(--text-2);font-weight:600}
.kpi.k-accent{border-top:3px solid var(--accent)}
.kpi.k-green{border-top:3px solid var(--green-dot)}
.kpi.k-amber{border-top:3px solid var(--amber-dot)}
.kpi.k-red{border-top:3px solid var(--red-dot)}
.kpi.k-gray{border-top:3px solid var(--gray-dot)}
.kpi.k-blue{border-top:3px solid var(--blue-dot)}

/* ---------- Badges (single component, semantic colors) ---------- */
.badge{
  display:inline-flex;align-items:center;gap:6px;padding:2px 9px;border-radius:99px;
  font-size:11px;font-weight:650;letter-spacing:.2px;border:1px solid transparent;white-space:nowrap;
}
.badge .dot{width:6px;height:6px;border-radius:50%;background:currentColor;opacity:.9}
.b-aktif{background:var(--green-soft);color:var(--green);border-color:var(--green-border)}
.b-idle{background:var(--amber-soft);color:var(--amber);border-color:var(--amber-border)}
.b-nonaktif{background:var(--red-soft);color:var(--red);border-color:var(--red-border)}
.b-belum{background:var(--gray-soft);color:var(--gray);border-color:var(--gray-border)}
.b-locked{background:var(--dark-soft);color:var(--dark);border-color:var(--border-2)}
.b-demo{background:var(--blue-soft);color:var(--blue);border-color:var(--blue-border)}
.b-licensed{background:var(--green-soft);color:var(--green);border-color:var(--green-border)}
.b-pass{background:var(--green-soft);color:var(--green);border-color:var(--green-border)}
.b-fail{background:var(--red-soft);color:var(--red);border-color:var(--red-border)}
.b-sent{background:var(--green-soft);color:var(--green);border-color:var(--green-border)}
.b-unsent{background:var(--amber-soft);color:var(--amber);border-color:var(--amber-border)}
.b-neutral{background:var(--gray-soft);color:var(--gray);border-color:var(--gray-border)}

/* ---------- Buttons ---------- */
.btn{
  display:inline-flex;align-items:center;gap:7px;padding:8px 14px;border-radius:8px;
  border:1px solid var(--border-2);background:var(--panel);color:var(--text-2);
  font-size:13px;font-weight:600;cursor:pointer;text-decoration:none;line-height:1.2;
}
.btn:hover{background:var(--panel-2);border-color:#c3cad1;text-decoration:none}
.btn .ico{width:15px;height:15px;display:inline-flex}
.btn .ico svg{width:15px;height:15px}
.btn-primary{background:var(--accent);border-color:var(--accent);color:#fff}
.btn-primary:hover{background:var(--accent-dark);border-color:var(--accent-dark)}
.btn-ghost{border-color:transparent;background:transparent;color:var(--blue)}
.btn-ghost:hover{background:var(--blue-soft);border-color:transparent}
.btn-sm{padding:5px 10px;font-size:12px;border-radius:7px}
.btn[disabled],.btn.disabled{opacity:.55;cursor:not-allowed;background:var(--gray-soft);color:var(--muted);border-color:var(--border)}
.btn[disabled]:hover{background:var(--gray-soft);border-color:var(--border)}
.soon-tag{font-size:9.5px;font-weight:700;letter-spacing:.5px;background:var(--amber-soft);color:var(--amber);border:1px solid var(--amber-border);padding:1px 6px;border-radius:99px;margin-left:2px}

/* ---------- Tables ---------- */
.tblwrap{overflow-x:auto}
table.tbl{width:100%;border-collapse:collapse;font-size:13px}
.tbl th{
  text-align:left;font-size:11px;font-weight:650;letter-spacing:.5px;text-transform:uppercase;
  color:var(--muted);padding:9px 12px;border-bottom:1px solid var(--border);background:var(--panel-2);white-space:nowrap;
}
.tbl td{padding:10px 12px;border-bottom:1px solid var(--border);vertical-align:middle}
.tbl tbody tr:hover{background:var(--panel-2)}
.tbl tbody tr:last-child td{border-bottom:none}
.tbl .th-num,.tbl td.num{text-align:right;white-space:nowrap}
.tbl tfoot td{font-weight:650;background:var(--panel-2);border-top:2px solid var(--border-2)}
tr.row-total td{font-weight:700;background:var(--panel-2)}
.rowlink{cursor:pointer}
.expander{cursor:pointer;user-select:none}
.expander .chev{display:inline-block;transition:transform .15s ease;color:var(--muted);font-size:11px;margin-right:6px}
.expander.open .chev{transform:rotate(90deg)}
tr.expand-row{display:none}
tr.expand-row.open{display:table-row}
tr.expand-row>td{background:var(--panel-2);padding:14px 16px 16px;border-bottom:1px solid var(--border)}
.expand-inner{border:1px solid var(--border);border-radius:8px;background:var(--panel);padding:12px 14px}
.expand-inner h4{margin:0 0 8px;font-size:12.5px;color:var(--text-2)}

/* ---------- Filter bar / inputs ---------- */
.filterbar{display:flex;flex-wrap:wrap;gap:10px;align-items:center}
.inp,select.inp,textarea.inp{
  border:1px solid var(--border-2);border-radius:8px;background:var(--panel);color:var(--text);
  font:inherit;font-size:13px;padding:7px 10px;outline:none;
}
.inp:focus{border-color:var(--blue-dot);box-shadow:0 0 0 3px var(--blue-soft)}
select.inp{padding-right:26px}
textarea.inp{width:100%;resize:vertical;font-family:var(--mono);font-size:12.5px;line-height:1.7}
.search{min-width:220px}
.field{display:flex;flex-direction:column;gap:5px;margin-bottom:13px}
.field label{font-size:12px;font-weight:650;color:var(--text-2)}
.field .inp{width:100%}
.field .hint{font-size:11px;color:var(--muted)}
.req::after{content:" *";color:var(--accent)}
.form-grid{display:grid;grid-template-columns:1fr 1fr;gap:0 18px}
.toggle-panel{display:none}
.toggle-panel.show{display:block}
.pager{display:flex;align-items:center;gap:6px;font-size:12px;color:var(--muted)}
.pg{min-width:28px;height:28px;padding:0 8px;border:1px solid var(--border);border-radius:7px;background:var(--panel);font-size:12px;font-weight:600;color:var(--text-2);cursor:pointer;display:inline-flex;align-items:center;justify-content:center}
.pg:hover{border-color:#c3cad1}
.pg.cur{background:var(--dark);border-color:var(--dark);color:#fff}
.pg[disabled]{opacity:.45;cursor:default}

/* ---------- Tabs ---------- */
.tabs{display:flex;gap:2px;border-bottom:1px solid var(--border);padding:0 4px}
.tab{
  appearance:none;border:none;background:none;cursor:pointer;font:inherit;
  font-size:13.5px;font-weight:600;color:var(--muted);padding:11px 14px 10px;
  border-bottom:2.5px solid transparent;margin-bottom:-1px;
  text-decoration:none; /* dashboard feed renders .tab as <a> links (?feed=) */
}
.tab:hover{color:var(--text-2)}
.tab.active{color:var(--accent);border-bottom-color:var(--accent)}
.tab .count{font-size:11px;font-weight:650;background:var(--gray-soft);color:var(--gray);border-radius:99px;padding:1px 7px;margin-left:6px}
.pane{display:none}
.pane.active{display:flex;flex-direction:column;gap:18px}

/* ---------- Tokens & copy ---------- */
code.token{
  font-family:var(--mono);font-size:11.5px;background:var(--panel-2);border:1px solid var(--border);
  border-radius:6px;padding:3px 8px;color:var(--text-2);white-space:nowrap;
}
.copy-btn{
  width:26px;height:26px;flex:0 0 26px;display:inline-flex;align-items:center;justify-content:center;
  border:1px solid var(--border-2);border-radius:6px;background:var(--panel);color:var(--muted);cursor:pointer;
}
.copy-btn:hover{color:var(--blue);border-color:var(--blue-border);background:var(--blue-soft)}
.copy-btn svg{width:13px;height:13px}
.tok-row{display:flex;align-items:center;gap:8px}

/* ---------- Dashboard: funnel ---------- */
.funnel{display:flex;flex-direction:column;gap:2px}
.fstage{display:grid;grid-template-columns:180px 1fr 110px;gap:14px;align-items:center}
.fstage-label{font-size:12.5px;font-weight:650;color:var(--text-2);text-align:right;line-height:1.3}
.fstage-label small{display:block;font-weight:400;font-size:10.5px}
.fbar-track{background:var(--track);border-radius:5px;height:30px;overflow:hidden}
.fbar{
  height:30px;border-radius:5px;color:#fff;font-size:12px;font-weight:700;
  display:flex;align-items:center;padding-left:10px;min-width:34px;font-variant-numeric:tabular-nums;
}
.fbar.f1{background:#3c4650}
.fbar.f2{background:#55636f}
.fbar.f3{background:var(--blue-dot)}
.fbar.f4{background:var(--green-dot)}
.fbar.f5{background:var(--green)}
.fstage-count{font-size:12px;font-weight:700;font-variant-numeric:tabular-nums}
.fdrop{display:grid;grid-template-columns:180px 1fr 110px;gap:14px}
.fdrop-line{font-size:11px;color:var(--muted);padding:3px 0 3px 10px}
.fdrop-line .arrow{color:var(--gray-dot);margin-right:6px;font-weight:700}

/* ---------- Dashboard: bar chart ----------
   CARD SIZE follows the design export exactly: height 190px, as in
   design_handoff_dashboard/reference_styles.css. Do not retune it to suit the
   series length — card dimensions are design-owned.

   BAR THICKNESS deliberately deviates: the design's 44px cap was sized for its
   8 weekly columns, and at our 4 quarterly columns it left ~78% of the card
   empty (4 x 44 = 176px of ink in a ~786px card). 76px is chart-internal ink,
   not a card dimension, so widening it keeps the card design-exact while the
   chart stays readable.

   auth.quarterChartBarMaxPx caps the inline bar height in Go and must stay
   BELOW this height — the remainder is the room the value text above and the
   axis label below each bar need. Change one and change the other. */
.barchart{display:flex;align-items:flex-end;gap:14px;height:190px;padding:6px 6px 0}
.bar-col{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:flex-end;gap:5px;height:100%}
.bar{width:70%;max-width:76px;background:#55636f;border-radius:4px 4px 0 0}
.bar.hot{background:var(--accent)}
.bar.zero{height:2px;background:var(--gray-border);border-radius:1px}
.bar-val{font-size:11px;font-weight:700;color:var(--text-2);font-variant-numeric:tabular-nums}
.bar-x{font-size:10.5px;color:var(--muted);white-space:nowrap}

/* ---------- Dashboard: horizontal bar chart (quarterly) ----------
   Diambil verbatim dari desain (mockup/dashboard.html, 31 Jul 2026), yang
   mengganti chart kuartal dari batang vertikal ke horizontal. Bentuk ini jauh
   lebih cocok untuk kolom satu-kolom: panjang batang MEMAKAI lebar, bukan
   menyisakannya kosong seperti 4 batang vertikal dulu.
   Blok .barchart/.bar di atas kini tak dipakai halaman mana pun — dipertahankan
   karena desain juga masih menyimpannya. */
.hbarchart{display:flex;flex-direction:column;gap:14px;padding:6px 2px 2px}
.hbar-row{display:grid;grid-template-columns:56px 1fr 92px;gap:14px;align-items:center}
.hbar-label{font-size:12.5px;font-weight:700;color:var(--text-2);font-variant-numeric:tabular-nums}
.hbar-label small{display:block;font-weight:400;font-size:10px;color:var(--muted)}
.hbar-track{background:var(--track);border-radius:5px;height:28px;overflow:hidden}
.hbar{height:28px;border-radius:5px;background:#55636f;min-width:3px}
.hbar.hot{background:var(--accent)}
.hbar.zero{background:var(--gray-border)}
.hbar-meta{font-size:12px;font-weight:700;color:var(--text-2);font-variant-numeric:tabular-nums;white-space:nowrap}
.hbar-meta small{color:var(--muted);font-weight:500}
.chart-foot{display:flex;flex-wrap:wrap;gap:8px 22px;border-top:1px solid var(--border);margin-top:12px;padding-top:10px;font-size:11.5px;color:var(--muted)}
.chart-foot b{color:var(--text-2)}

/* ---------- Dashboard: categories & feed ---------- */
.cat-row{padding:10px 0}
.cat-top{display:flex;justify-content:space-between;align-items:baseline;margin-bottom:6px}
.cat-name{font-weight:650;font-size:13px}
.cat-name small{margin-left:6px}
.cat-count{font-weight:700;font-size:15px;font-variant-numeric:tabular-nums}
.meter{height:8px;background:var(--track);border-radius:99px;overflow:hidden;margin-bottom:5px}
.meter span{display:block;height:100%;background:var(--green-dot);border-radius:99px}
/* .feed-scroll: area gulir kartu Aktivitas Terbaru (T7.1b, infinite scroll).
   MENYIMPANG DARI DESAIN — mockup memajang 7 baris statis tanpa scroll; ini
   permintaan user, bukan fidelity. Murni CSS: tanpa JavaScript daftar tetap
   tampil dan tetap bisa digulir manual, hanya tak bertambah sendiri.
   Tab filter berada DI LUAR elemen ini supaya tak ikut bergulir. */
.feed-scroll{max-height:360px;overflow-y:auto}
/* Tab "Semua" tak punya halaman ke-2 — isinya tetap 7 baris berkuota (≈379px),
   jadi batas 360px hanya memunculkan scrollbar kecil tanpa guna di tab default.
   Menutup OPEN-ITEM T7.1b. Batas tab tunggal (yang memang di-stream) tak diubah. */
.feed-scroll[data-feed-kind="all"]{max-height:none}
/* Sentinel yang diamati IntersectionObserver; dibuat oleh JS, jadi tak ada
   elemen sisa di halaman tanpa JS. Diberi tinggi 1px karena target ber-area nol
   tak selalu dilaporkan sebagai intersecting. */
.feed-sentinel{height:1px}
.feed{list-style:none;margin:0;padding:0}
.feed li{display:flex;gap:11px;padding:10px 2px;border-bottom:1px solid var(--border)}
.feed li:last-child{border-bottom:none}
.fdot{width:8px;height:8px;flex:0 0 8px;border-radius:50%;margin-top:6px}
/* Aktivitas Terbaru dot palette (handoff README 5.7). Classes, not inline
   styles: html/template's CSS context rewrites an interpolated custom-property
   name to ZgotmplZ, which left every dot uncoloured. */
.fdot.dot-green{background:var(--green-dot)}
.fdot.dot-amber{background:var(--amber-dot)}
.fdot.dot-red{background:var(--red-dot)}
.fdot.dot-gray{background:var(--gray-dot)}
.fdot.dot-dark{background:var(--dark)}
.feed-text{font-size:12.5px;color:var(--text-2);line-height:1.45}
.feed-text b{color:var(--text)}
.feed-time{font-size:11px;color:var(--muted);margin-top:2px}

/* ---------- Steps (penjualan-baru) ---------- */
.stepcard .card-h{align-items:center}
.step-num{
  width:26px;height:26px;flex:0 0 26px;border-radius:50%;background:var(--dark);color:#fff;
  font-size:12.5px;font-weight:700;display:inline-flex;align-items:center;justify-content:center;margin-right:2px;
}
.stepcard.done .step-num{background:var(--green-dot)}
.chips{display:flex;flex-wrap:wrap;gap:8px}
.chip{
  display:inline-flex;align-items:center;gap:8px;border:1px solid var(--border-2);background:var(--panel-2);
  border-radius:8px;padding:6px 10px;font-size:12.5px;
}
.chip .x{color:var(--muted);cursor:pointer;font-weight:700;padding:0 2px}
.chip .x:hover{color:var(--red)}
.vlist{list-style:none;margin:10px 0 0;padding:0;display:flex;flex-direction:column;gap:6px}
.vlist li{display:flex;align-items:center;gap:9px;font-size:12.5px;font-family:var(--mono)}
.vmark{width:18px;height:18px;flex:0 0 18px;border-radius:50%;font-size:11px;font-weight:800;display:inline-flex;align-items:center;justify-content:center}
.v-ok .vmark{background:var(--green-soft);color:var(--green);border:1px solid var(--green-border)}
.v-err .vmark{background:var(--red-soft);color:var(--red);border:1px solid var(--red-border)}
.v-warn .vmark{background:var(--amber-soft);color:var(--amber);border:1px solid var(--amber-border)}
.vlist .note{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif;color:var(--muted);font-size:11.5px}
.result-banner{
  display:flex;gap:12px;align-items:flex-start;background:var(--green-soft);border:1px solid var(--green-border);
  color:var(--green);border-radius:var(--r);padding:14px 16px;font-size:13.5px;font-weight:600;
}
.result-banner small{display:block;color:var(--green);opacity:.85;font-weight:500;margin-top:2px}
.price-input{width:120px;text-align:right;font-variant-numeric:tabular-nums;font-family:var(--mono);font-size:12.5px}

/* ---------- Info notes ---------- */
.note{
  display:flex;gap:10px;align-items:flex-start;font-size:12px;color:var(--text-2);
  background:var(--blue-soft);border:1px solid var(--blue-border);border-radius:8px;padding:10px 13px;line-height:1.5;
}
.note.amber{background:var(--amber-soft);border-color:var(--amber-border);color:var(--amber)}
.note.gray{background:var(--gray-soft);border-color:var(--gray-border);color:var(--text-2)}
.note .ni{font-weight:800;flex:0 0 auto}

/* ---------- Opportunity KPI (konsumen-detail) ---------- */
.kpi.opp{background:var(--amber-soft);border-color:var(--amber-border)}
.kpi.opp .kpi-label,.kpi.opp .kpi-note{color:var(--amber)}
.kpi.opp .kpi-value{color:var(--amber)}

/* ---------- Profile / detail ---------- */
.detail-head{display:flex;align-items:center;gap:14px;flex-wrap:wrap}
.detail-head .serial-big{font-family:var(--mono);font-size:21px;font-weight:700}
.kv{display:grid;grid-template-columns:150px 1fr;gap:8px 14px;font-size:13px;margin:0}
.kv dt{color:var(--muted);font-size:12px;padding-top:1px}
.kv dd{margin:0;font-weight:500}
.cust-avatar{
  width:46px;height:46px;border-radius:50%;background:var(--dark);color:#fff;
  font-weight:700;font-size:16px;display:flex;align-items:center;justify-content:center;flex:0 0 auto;
}
.spark{display:block}
.event-list{list-style:none;margin:0;padding:0}
.event-list li{display:flex;gap:10px;padding:8px 0;border-bottom:1px solid var(--border);font-size:12.5px}
.event-list li:last-child{border-bottom:none}
.event-time{flex:0 0 118px;color:var(--muted);font-size:11.5px;padding-top:1px}

/* ---------- Sankey ---------- */
.sankey-wrap{overflow-x:auto}
.sankey-wrap svg{display:block;min-width:980px;width:100%;height:auto}
.sk-label{font-size:11px;fill:var(--text-2);font-weight:600;paint-order:stroke;stroke:#fff;stroke-width:3px;stroke-linejoin:round}
.sk-count{font-size:10px;fill:var(--muted);font-weight:600;paint-order:stroke;stroke:#fff;stroke-width:2.5px;stroke-linejoin:round}
.sk-legend{display:flex;flex-wrap:wrap;gap:8px 20px;font-size:11.5px;color:var(--muted);border-top:1px solid var(--border);margin-top:10px;padding-top:10px}
.sk-legend .sw{display:inline-block;width:10px;height:10px;border-radius:3px;margin-right:6px;vertical-align:-1px}

/* ---------- Asisten AI ---------- */
.ai-fab{
  position:fixed;right:24px;bottom:24px;z-index:80;width:54px;height:54px;border-radius:50%;
  background:var(--accent);border:none;color:#fff;cursor:pointer;box-shadow:0 6px 18px rgba(209,51,46,.4);
  display:flex;align-items:center;justify-content:center;
}
.ai-fab:hover{background:var(--accent-dark)}
.ai-fab svg{width:24px;height:24px}
.ai-overlay{position:fixed;inset:0;background:rgba(23,28,33,.38);z-index:90;display:none}
.ai-overlay.open{display:block}
.ai-panel{
  position:absolute;top:0;right:0;bottom:0;width:404px;max-width:94vw;background:var(--panel);
  box-shadow:var(--shadow-lg);display:flex;flex-direction:column;
}
.ai-head{display:flex;align-items:center;gap:11px;padding:14px 16px;border-bottom:1px solid var(--border)}
.ai-head-ico{width:34px;height:34px;flex:0 0 34px;border-radius:9px;background:var(--accent-soft);color:var(--accent);display:flex;align-items:center;justify-content:center}
.ai-head-ico svg{width:19px;height:19px}
.ai-title{font-size:14px;font-weight:700}
.ai-sub{font-size:11px;color:var(--muted)}
.ai-x{margin-left:auto;border:none;background:none;font-size:22px;line-height:1;color:var(--muted);cursor:pointer;padding:4px 8px;border-radius:6px}
.ai-x:hover{background:var(--gray-soft);color:var(--text)}
.ai-msgs{flex:1;overflow-y:auto;padding:16px 14px;display:flex;flex-direction:column;gap:14px;background:var(--panel-2)}
.ai-msg{display:flex;flex-direction:column;max-width:92%}
.ai-msg.user{align-self:flex-end;align-items:flex-end}
.ai-msg.bot{align-self:flex-start;align-items:flex-start}
.ai-bubble{border-radius:12px;padding:9px 13px;font-size:12.5px;line-height:1.5}
.ai-msg.user .ai-bubble{background:var(--accent-soft);border:1px solid var(--accent-border);color:#7c2320;border-bottom-right-radius:4px}
.ai-msg.bot .ai-bubble{background:var(--panel);border:1px solid var(--border);color:var(--text-2);border-bottom-left-radius:4px}
.ai-bubble code{font-family:var(--mono);font-size:11px;background:rgba(0,0,0,.05);padding:1px 5px;border-radius:4px}
.ai-decline{background:var(--amber-soft) !important;border-color:var(--amber-border) !important;color:var(--amber) !important}
.ai-time{font-size:10px;color:var(--muted);margin-top:4px;padding:0 3px}
.ai-card{background:var(--panel);border:1px solid var(--border);border-radius:10px;box-shadow:var(--shadow);padding:12px 13px;margin-top:8px;width:100%;font-size:12.5px}
.ai-card-top{display:flex;gap:10px;align-items:center;margin-bottom:9px}
.ai-card-name{font-weight:700;font-size:13px}
.ai-card-meta{font-size:11.5px;color:var(--muted)}
.ai-kv{display:grid;grid-template-columns:86px 1fr;gap:5px 10px;font-size:12px;margin:0;border-top:1px solid var(--border);padding-top:9px}
.ai-kv dt{color:var(--muted)}
.ai-kv dd{margin:0;font-weight:600;color:var(--text-2)}
.ai-card-link{display:inline-block;margin-top:9px;font-size:12px;font-weight:650}
.ai-card-cap{font-size:11px;color:var(--muted);margin:9px 0 0;line-height:1.5}
.ai-tok-row{display:flex;align-items:center;gap:8px;margin-bottom:9px}
.ai-wa{margin-top:2px}
.ai-wa .ico{color:#1faa53}
.ai-chips{display:flex;flex-wrap:wrap;gap:7px;padding:11px 14px;border-top:1px solid var(--border);background:var(--panel)}
.ai-chip{
  border:1px solid var(--border-2);background:var(--panel);border-radius:99px;padding:5px 12px;
  font-size:11.5px;font-weight:600;color:var(--text-2);cursor:pointer;
}
.ai-chip:hover{border-color:var(--blue-border);background:var(--blue-soft);color:var(--blue)}
.ai-input{display:flex;gap:9px;padding:11px 14px 14px;background:var(--panel)}
.ai-input input{flex:1;border:1px solid var(--border-2);border-radius:99px;padding:9px 15px;font:inherit;font-size:12.5px;outline:none}
.ai-input input:focus{border-color:var(--blue-dot);box-shadow:0 0 0 3px var(--blue-soft)}
.ai-send{width:38px;height:38px;flex:0 0 38px;border-radius:50%;border:none;background:var(--accent);color:#fff;cursor:pointer;display:flex;align-items:center;justify-content:center}
.ai-send:hover{background:var(--accent-dark)}
.ai-send svg{width:17px;height:17px}

/* ---------- Toast ---------- */
.toast{
  position:fixed;left:50%;bottom:26px;transform:translate(-50%,16px);z-index:200;
  background:#20262c;color:#fff;font-size:12.5px;font-weight:600;padding:10px 18px;border-radius:99px;
  box-shadow:var(--shadow-lg);opacity:0;pointer-events:none;transition:all .22s ease;
}
.toast.show{opacity:1;transform:translate(-50%,0)}

/* ---------- Login ---------- */
.login-body{
  min-height:100vh;display:flex;align-items:center;justify-content:center;
  background:linear-gradient(160deg,#f6f7f8 0%,#eceef1 55%,#e9e2e1 100%);
}
.login-card{width:392px;background:var(--panel);border:1px solid var(--border);border-radius:14px;box-shadow:0 18px 48px rgba(23,28,33,.12);padding:34px 34px 26px}
.login-brand{display:flex;gap:13px;align-items:center;margin-bottom:26px}
.login-brand .brand-mark{width:46px;height:46px;font-size:24px;border-radius:11px}
.login-title{font-size:19px;font-weight:800;letter-spacing:3px}
.login-sub{font-size:11.5px;color:var(--muted)}
.login-form .btn{width:100%;justify-content:center;padding:11px;font-size:14px;margin-top:4px}
.login-foot{font-size:11px;color:var(--muted);text-align:center;margin:20px 0 0;border-top:1px solid var(--border);padding-top:16px}

/* ---------- Invoice ---------- */
.invoice-body{background:#e8eaed;padding:26px 16px 60px}
.inv-actions{
  max-width:210mm;margin:0 auto 16px;display:flex;gap:10px;align-items:center;flex-wrap:wrap;
  background:var(--panel);border:1px solid var(--border);border-radius:10px;padding:10px 14px;box-shadow:var(--shadow);
}
.inv-sheet{
  max-width:210mm;min-height:280mm;margin:0 auto;background:var(--panel);box-shadow:0 4px 22px rgba(23,28,33,.14);
  padding:17mm 16mm 14mm;display:flex;flex-direction:column;
}
.inv-top{display:flex;justify-content:space-between;align-items:flex-start;border-bottom:3px solid var(--accent);padding-bottom:14px}
.inv-brand{display:flex;gap:11px;align-items:center}
.inv-title{text-align:right}
.inv-title h1{font-size:26px;letter-spacing:4px;font-weight:800}
.inv-meta{font-size:12px;color:var(--text-2);margin-top:4px;line-height:1.6}
.inv-parties{display:grid;grid-template-columns:1fr 1fr;gap:22px;padding:16px 0}
.inv-party h3{font-size:10.5px;letter-spacing:1.1px;text-transform:uppercase;color:var(--muted);margin-bottom:6px}
.inv-party .pname{font-weight:700;font-size:13.5px}
.inv-party p{margin:2px 0;font-size:12px;color:var(--text-2);line-height:1.55}
table.inv-tbl{width:100%;border-collapse:collapse;font-size:12px;margin-top:4px}
.inv-tbl th{text-align:left;font-size:10px;letter-spacing:.8px;text-transform:uppercase;color:var(--muted);border-bottom:1.5px solid var(--dark);padding:7px 8px;white-space:nowrap}
.inv-tbl td{padding:7px 8px;border-bottom:1px solid var(--border);vertical-align:top}
.inv-tbl .sub td{font-weight:650;background:var(--panel-2)}
.inv-tbl .grand td{font-weight:800;font-size:13.5px;border-top:2px solid var(--dark);border-bottom:none;background:var(--panel)}
.inv-token{font-family:var(--mono);font-size:10px;color:var(--text-2);word-break:break-all}
.inv-foot{margin-top:auto;border-top:1px solid var(--border);padding-top:12px;font-size:10.5px;color:var(--muted);line-height:1.65}
@page{size:A4;margin:0}
@media print{
  body.invoice-body{background:var(--panel);padding:0}
  .inv-actions,.no-print{display:none !important}
  .inv-sheet{box-shadow:none;max-width:none;min-height:auto;margin:0;padding:14mm 14mm 10mm}
}

/* ---------- Responsive (tablet) ---------- */
@media (max-width:1180px){
  .grid-dash,.grid-2,.grid-3{grid-template-columns:1fr}
  .sidebar{width:66px;flex-basis:66px;padding:14px 8px}
  .sidebar .brand-name,.sidebar .brand-sub,.sidebar .nav-item .txt,.sidebar .nav-label,.sidebar-foot{display:none}
  .sidebar .brand{justify-content:center;padding-bottom:12px}
  .nav-item{justify-content:center;padding:11px 0}
  .content{padding:18px 16px 90px}
  .fstage,.fdrop{grid-template-columns:130px 1fr 90px;gap:8px}
  .form-grid{grid-template-columns:1fr}
}

/* ---------- Responsive: penghalusan khusus DASHBOARD ----------
   Diambil dari rombakan responsif desain (mockup/styles.css, 30 Jul 2026), TAPI
   dibatasi pada selector yang hanya dipakai dashboard: .kpi-row, .fstage/.fdrop,
   .barchart. Rombakan penuh desain juga mengubah sidebar/topbar/.app,
   .grid-2/.grid-3, .form-grid, dan padding .content/.card-b per breakpoint —
   itu app-wide (Perangkat, Konsumen, Penjualan, Pembukuan) dan SENGAJA tidak
   diadopsi di sini, sesuai batas "ukuran layout dashboard saja".
   Blok @1180 di atas tetap berlaku lebih dulu; aturan di bawah menimpanya pada
   layar yang lebih sempit. */
@media (max-width:1360px){
  /* KPI dikunci 3-up supaya tile ke-5 tak pernah turun sendirian (4+1) */
  .kpi-row{grid-template-columns:repeat(3,1fr)}
}
@media (max-width:820px){
  .kpi-row{grid-template-columns:repeat(2,1fr)}
  .fstage,.fdrop{grid-template-columns:120px 1fr 78px;gap:8px}
}
@media (max-width:640px){
  .fstage,.fdrop{grid-template-columns:1fr;gap:3px}
  .fstage-label{text-align:left;line-height:1.35}
  .barchart{gap:6px}
}
@media (max-width:520px){
  .kpi-row{grid-template-columns:1fr}
}


/* ============================================================
   Dark mode (slate) · toggle via [data-theme="dark"] on <html>
   Light values above are unchanged — this only overrides for dark.
   ============================================================ */
.theme-toggle{
  width:34px;height:34px;flex:0 0 34px;border-radius:8px;border:1px solid var(--border-2);
  background:var(--panel);color:var(--text-2);cursor:pointer;display:inline-flex;
  align-items:center;justify-content:center;padding:0;transition:background .15s,border-color .15s,color .15s;
}
.theme-toggle:hover{background:var(--panel-2);border-color:var(--muted);color:var(--text)}
.theme-toggle svg{width:17px;height:17px}
.theme-toggle-float{position:fixed;top:14px;right:16px;z-index:120;box-shadow:var(--shadow-lg)}
@media print{.theme-toggle{display:none !important}}

:root[data-theme="dark"]{
  color-scheme:dark;
  --bg:#0e141d; --panel:#161e29; --border:#293546; --border-2:#374556;
  --text:#e7edf4; --text-2:#aeb9c6; --muted:#7d8a99;
  --accent:#f2564f; --accent-dark:#ff6a63; --accent-soft:#2c1513; --accent-border:#4c2622;
  --green:#5bc47f; --green-soft:#14241b; --green-border:#2a4635; --green-dot:#3fbf67;
  --amber:#e3a63d; --amber-soft:#2a2011; --amber-border:#4b3a1b; --amber-dot:#f9ab00;
  --red:#f0716d; --red-soft:#2c1615; --red-border:#4d2725; --red-dot:#f0554a;
  --blue:#6ba7f0; --blue-soft:#152332; --blue-border:#2a4258; --blue-dot:#5c9bf5;
  --gray:#9aa7b4; --gray-soft:#1b2430; --gray-border:#2e3a48; --gray-dot:#6b7885;
  --dark:#3a4759; --dark-soft:#222d3a;
  --panel-2:#1b2532; --track:#212d3b;
  --shadow:0 1px 2px rgba(0,0,0,.42),0 1px 3px rgba(0,0,0,.34);
  --shadow-lg:0 16px 40px rgba(0,0,0,.55);
}
:root[data-theme="dark"] .sidebar{background:#111824}
:root[data-theme="dark"] .b-locked{color:var(--text-2)}
:root[data-theme="dark"] .ai-msg.user .ai-bubble{color:#f4b8b4}
:root[data-theme="dark"] .ai-bubble code{background:rgba(255,255,255,.09)}
:root[data-theme="dark"] .sk-label,
:root[data-theme="dark"] .sk-count{stroke:var(--panel)}
:root[data-theme="dark"] .fbar.f1{background:#4a5a6d}
:root[data-theme="dark"] .fbar.f2{background:#647589}
:root[data-theme="dark"] .bar{background:#5e6e81}

/* Login: dark backdrop */
:root[data-theme="dark"] .login-body{background:radial-gradient(1100px 620px at 50% -8%,#1b2836 0%,#0e141d 62%)}

/* Invoice: dark desk, but the printable A4 sheet stays a light paper island */
:root[data-theme="dark"] .invoice-body{background:#0e141d}
:root[data-theme="dark"] .inv-sheet{
  color-scheme:light;
  --bg:#f4f5f7; --panel:#ffffff; --panel-2:#fafbfc; --track:#eef0f3;
  --border:#e3e6ea; --border-2:#d5dae0; --text:#1d2329; --text-2:#4a5560; --muted:#7b8794;
  --accent:#d1332e; --accent-dark:#b02a26; --accent-soft:#fdeeed; --accent-border:#f4c7c5;
  --green:#1e8e3e; --green-soft:#e6f4ea; --green-border:#c6e5cf; --green-dot:#34a853;
  --amber:#9c5700; --amber-soft:#fef3e0; --amber-border:#f3ddb0; --amber-dot:#f9ab00;
  --red:#c5221f; --red-soft:#fce8e6; --red-border:#f5c6c3; --red-dot:#ea4335;
  --blue:#1a5fb4; --blue-soft:#e8f0fe; --blue-border:#c3d7f7; --blue-dot:#4285f4;
  --gray:#5f6b76; --gray-soft:#eef0f2; --gray-border:#dbe0e5; --gray-dot:#9aa4af;
  --dark:#343c44; --dark-soft:#e7e9ec;
  background:#ffffff; color:#1d2329;
}

/* ============================================================
   Technorider app-shell extensions (T2.1)
   Everything above this line is the untouched Japfa mockup theme
   (styles.css, verbatim). Below: classes the mockup doesn't need
   because it has no "module not built yet" or plain-placeholder
   states, plus the pre-existing login/users-page bits from
   T1.3/T1.4 that predate the mockup import.
   ============================================================ */

/* ---------- Sidebar: nav items for modules not built yet ---------- */
.nav-item.disabled{cursor:default;color:#6f7a84}
.nav-item.disabled:hover{background:none;color:#6f7a84}
.nav-item.disabled .soon-tag{margin-left:auto}

/* ---------- Plain fallback (pages with no auth chrome, e.g. GET /) ---------- */
.plain-content{padding:24px 26px;max-width:1460px;margin:0 auto}
.placeholder{max-width:40rem}

/* ---------- Login extras (T1.3 — not part of the mockup's own login.html) ---------- */
.login-error{
  font-size:12.5px;color:var(--red);background:var(--red-soft);
  border:1px solid var(--red-border);border-radius:8px;padding:.6rem .75rem;margin:0 0 15px;
}
.pw-wrap{position:relative}
.pw-wrap input{padding-right:44px}
.pw-toggle{
  position:absolute;top:0;right:0;height:40px;width:42px;display:flex;align-items:center;
  justify-content:center;background:none;border:none;cursor:pointer;color:var(--muted);padding:0;
}
.pw-toggle:hover{color:var(--text-2)}
.login-form .btn{width:100%;justify-content:center;padding:11px;font-size:14px;margin-top:4px}

/* ---------- User management (T1.4 — CRUD pages, no mockup equivalent) ---------- */
.users-card,.user-form-card{max-width:56rem}
.user-form-card{max-width:28rem}
.page-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:1.25rem}
.page-head h1{margin:0;font-size:1.25rem}
.table{width:100%;border-collapse:collapse;font-size:.9rem}
.table th,.table td{text-align:left;padding:.6rem .5rem;border-bottom:1px solid var(--border)}
.table th{color:var(--muted);font-size:.75rem;text-transform:uppercase;letter-spacing:.04em}
.table-actions{display:flex;align-items:center;gap:.75rem}
.table-actions form{display:inline}
.table-empty{color:var(--muted);text-align:center;padding:1.5rem 0}
.status-dot{display:inline-block;width:.5rem;height:.5rem;border-radius:999px;margin-right:.3rem}
.status-dot--active{background:var(--green-dot)}
.status-dot--inactive{background:var(--muted)}
.field-checkbox label{display:flex;align-items:center;gap:.5rem;font-size:.85rem;font-weight:500;color:var(--text-2)}
.field-checkbox input{width:auto}
.user-form-back{margin-top:1rem;font-size:.8rem}

