:root{
  /* ---- palet dasar (mode gelap / tema laboratorium) ---- */
  --bg:#070B12;
  --bg-2:#0A1018;
  --panel:rgba(16,23,36,.93);
  --panel-2:rgba(20,29,44,.72);
  --line:rgba(94,234,212,.10);
  --line-strong:rgba(150,214,197,.18);
  --ink:#E6EEF8;
  --ink-2:#9FB0C7;
  --ink-3:#6C7D95;
  --ink-strong:#f3fdf9;
  /* Warna judul kartu (h2). Di tema gelap harus terang; di tema terang hitam pekat. */
  --head-ink:#FFFFFF;
  --code-ink:#FFFFFF;
  --cyan:#2dd4a7;
  --violet:#14a38b;
  --green:#34D399;
  --amber:#FBBF24;
  --red:#F87171;
  --radius:16px;
  --radius-sm:10px;
  --shadow:0 18px 40px -22px rgba(0,0,0,.9);
  --mono:ui-monospace,SFMono-Regular,"SF Mono",Menlo,Consolas,"Liberation Mono",monospace;
  /* ---- permukaan & latar ---- */
  --body-bg:
    radial-gradient(900px 500px at 8% -10%, rgba(45,212,167,.14), transparent 60%),
    radial-gradient(800px 500px at 100% 0%, rgba(20,163,139,.16), transparent 55%),
    radial-gradient(700px 600px at 50% 120%, rgba(16,185,129,.10), transparent 60%),
    linear-gradient(180deg,var(--bg) 0%, var(--bg-2) 100%);
  --sidebar-bg:linear-gradient(180deg,rgba(12,18,28,.94),rgba(9,14,22,.92));
  --topbar-bg:linear-gradient(180deg,rgba(8,13,20,.92),rgba(8,13,20,.72));
  --strip-bg:rgba(8,13,20,.75);
  --grid-c:rgba(150,214,197,.045);
  --sheen:linear-gradient(160deg,rgba(255,255,255,.05),transparent 42%);
  --pop-bg:rgba(12,18,28,.99);
  --input-bg:rgba(6,11,18,.72);
  /* ---- tint & garis ---- */
  --tint:rgba(150,214,197,.06);
  --tint-2:rgba(150,214,197,.04);
  --tint-3:rgba(150,214,197,.03);
  --tint-hover:rgba(150,214,197,.05);
  --th-bg:rgba(150,214,197,.06);
  --foot-bg:rgba(45,212,167,.06);
  --row-border:rgba(150,214,197,.07);
  --track:rgba(150,214,197,.09);
  --chip-bg:rgba(150,214,197,.05);
  --warn-row:rgba(251,191,36,.06);
  /* ---- komponen ---- */
  --nav-active-bg:linear-gradient(100deg,rgba(45,212,167,.16),rgba(20,163,139,.14));
  --nav-active-border:rgba(45,212,167,.32);
  --tab-active-bg:linear-gradient(180deg,rgba(45,212,167,.16),rgba(45,212,167,.04));
  --brand-bg:linear-gradient(140deg,rgba(45,212,167,.22),rgba(20,163,139,.28));
  --brand-border:rgba(45,212,167,.35);
  --brand-fg:#e7fbf5;
  --brand-accent:#2dd4a7;
  --brand-shadow:0 0 22px -6px rgba(45,212,167,.45), inset 0 0 14px -6px rgba(255,255,255,.35);
  --avatar-bg:linear-gradient(140deg,rgba(45,212,167,.3),rgba(20,163,139,.35));
  --avatar-border:rgba(150,214,197,.25);
  --avatar-fg:#E6EEF8;
  --btn-bg:rgba(150,214,197,.07);
  --btn-bg-hover:rgba(150,214,197,.14);
  --btn-border-hover:rgba(150,214,197,.32);
  --primary-grad:linear-gradient(100deg,#0e7c6b,#0f8a73);
  --primary-shadow:0 12px 28px -14px rgba(45,212,167,.85);
  --focus-border:rgba(45,212,167,.62);
  --focus-ring:rgba(45,212,167,.16);
  --input-hover:rgba(150,214,197,.30);
  --input-disabled:rgba(150,214,197,.04);
  --input-invalid:rgba(248,113,113,.85);
  --stepper-bg:rgba(150,214,197,.10);
  --stepper-bg-hover:rgba(45,212,167,.28);
  --stepper-fg:var(--ink-2);
  --select-caret:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%239FB0C7' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  --select-caret-size:16px;
  --search-icon:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%239FB0C7' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='m20 20-3.6-3.6'/%3E%3C/svg%3E");
  color-scheme:dark;
  --preview-bg:rgba(45,212,167,.06);
  --preview-bd:rgba(45,212,167,.2);
  --bar-fill:linear-gradient(180deg,rgba(45,212,167,.95),rgba(20,163,139,.55));
  --bar-shadow:0 0 16px -4px rgba(45,212,167,.6);
  --stepnum-bg:linear-gradient(140deg,rgba(45,212,167,.25),rgba(20,163,139,.3));
  --stepnum-bd:rgba(45,212,167,.35);
  --stepnum-fg:#e7fbf5;
  --kpi-warn-glow:0 0 26px -16px rgba(251,191,36,.7);
  /* ---- status & peran ---- */
  --role-admin-bg:rgba(20,163,139,.18); --role-admin-fg:#bdf2e2; --role-admin-bd:rgba(20,163,139,.4);
  --role-operator-bg:rgba(45,212,167,.14); --role-operator-fg:#b8f3df; --role-operator-bd:rgba(45,212,167,.34);
  --ok-bg:rgba(52,211,153,.15); --ok-fg:#B6F5DC; --ok-bd:rgba(52,211,153,.35);
  --warn-bg:rgba(251,191,36,.16); --warn-fg:#FFE7A8; --warn-bd:rgba(251,191,36,.35);
  --err-bg:rgba(248,113,113,.15); --err-fg:#FFC9C9; --err-bd:rgba(248,113,113,.33);
  --err-bg-hover:rgba(248,113,113,.22);
  --info-bg:rgba(20,163,139,.16); --info-fg:#c4f4e6; --info-bd:rgba(20,163,139,.35);
  --off-bg:rgba(148,163,184,.14); --off-fg:#9FB0C7; --off-bd:rgba(148,163,184,.28);
  --alert-ok-bg:rgba(52,211,153,.12); --alert-ok-fg:#C7F7E4; --alert-ok-bd:rgba(52,211,153,.32);
  --alert-err-bg:rgba(248,113,113,.12); --alert-err-fg:#FFD4D4; --alert-err-bd:rgba(248,113,113,.34);
  --note-border:rgba(45,212,167,.4);
}
*{box-sizing:border-box}
html,body{margin:0;padding:0}
body{
  font-family:Inter,system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;
  /* Gradien dipasang pada lapisan fixed, BUKAN background-attachment:fixed —
     supaya menggulir halaman tidak memicu pengecatan ulang seluruh latar. */
  background:var(--bg);
  color:var(--ink);
  font-size:14.5px;
  line-height:1.5;
  min-height:100vh;
}
.lab-bg{
  position:fixed;inset:0;z-index:0;pointer-events:none;
  background:var(--body-bg);contain:strict;
}
.lab-grid{
  position:fixed;inset:0;pointer-events:none;z-index:0;opacity:.5;contain:strict;
  background-image:linear-gradient(var(--grid-c) 1px,transparent 1px),linear-gradient(90deg,var(--grid-c) 1px,transparent 1px);
  background-size:52px 52px;
  mask-image:radial-gradient(circle at 50% 20%,#000 20%,transparent 85%);
}
a{color:var(--cyan);text-decoration:none}
h1,h2,h3{margin:0;font-weight:650;letter-spacing:-.01em}
h1{font-size:1.12rem}
h2{font-size:1rem}
h3{font-size:.9rem}
p{margin:0 0 10px}
code{font-family:var(--mono);font-size:.85em;color:var(--cyan)}
.mono{font-family:var(--mono);font-variant-numeric:tabular-nums}
.muted{color:var(--ink-2)}
.small{font-size:.78rem}
.accent{color:var(--cyan)}
.pos{color:var(--green)}
.neg{color:var(--red)}
.ta-r{text-align:right}
.ta-c{text-align:center}

/* ---------------------------- Shell / sidebar ---------------------------- */
/* 264px (dulu 254px): memberi ruang agar judul grup panjang seperti
   "Rekam Medis Elektronik" tetap SATU BARIS tanpa dipotong. */
.shell{position:relative;z-index:1;display:grid;grid-template-columns:264px 1fr;min-height:100vh}
/* Lapisan gelap untuk menutup menu samping saat di HP — WAJIB display:none di
   layar lebar: kalau tidak, ia menjadi item grid pertama dan mendorong
   .sidebar/.main ke kolom yang salah (seluruh tata letak rusak). */
.sidebar-scrim{display:none}
.sidebar{
  display:flex;flex-direction:column;gap:18px;padding:20px 16px;
  background:var(--sidebar-bg);
  border-right:1px solid var(--line);
  position:sticky;top:0;height:100vh;
}
.brand{display:flex;align-items:center;gap:12px}
.brand-mark{
  width:42px;height:42px;flex:0 0 42px;border-radius:13px;display:grid;place-items:center;
  background:var(--brand-bg);
  border:1px solid var(--brand-border);color:var(--brand-fg);font-weight:700;font-family:var(--mono);
  box-shadow:var(--brand-shadow);
}
.brand-mark span{color:var(--brand-accent);font-size:.7em;vertical-align:sub}
.brand-lg .brand-mark{width:52px;height:52px;flex-basis:52px;font-size:1.15rem;border-radius:16px}
.brand-text strong{display:block;font-size:1.02rem;letter-spacing:.01em}
.brand-text small{display:block;color:var(--ink-3);font-size:.72rem;max-width:170px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.nav{display:flex;flex-direction:column;gap:3px;overflow-y:auto;flex:1}
/* Judul grup kini memakai UKURAN & bobot yang sama dengan teks menu di dalamnya
   (lihat blok "SIDEBAR AKORDEON" di bagian akhir berkas untuk definisi lengkap). */
.nav-group{margin:12px 0 4px}
.nav-group:first-child{margin-top:0}
.nav-link{
  display:flex;align-items:center;gap:10px;padding:9px 11px;border-radius:var(--radius-sm);
  color:var(--ink-2);font-size:.87rem;border:1px solid transparent;transition:.16s;
}
.nav-link svg{width:17px;height:17px;fill:currentColor;opacity:.85;flex:0 0 17px}
.nav-link:hover{background:var(--tint-hover);color:var(--ink)}
.nav-link.is-active{
  background:var(--nav-active-bg);
  border-color:var(--nav-active-border);color:var(--ink-strong);
  box-shadow:inset 3px 0 0 var(--cyan);
}
.sidebar-foot{display:flex;flex-direction:column;gap:10px;border-top:1px solid var(--line);padding-top:14px}
.user-chip{display:flex;align-items:center;gap:10px}
.avatar{
  width:34px;height:34px;border-radius:50%;display:grid;place-items:center;font-weight:700;font-size:.82rem;
  background:var(--avatar-bg);border:1px solid var(--avatar-border);color:var(--avatar-fg);
}
.user-meta strong{display:block;font-size:.82rem}
.role{
  display:inline-block;font-size:.66rem;letter-spacing:.04em;text-transform:uppercase;font-weight:700;
  padding:2px 7px;border-radius:20px;border:1px solid transparent;
}
.role-admin{background:var(--role-admin-bg);color:var(--role-admin-fg);border-color:var(--role-admin-bd)}
.role-operator{background:var(--role-operator-bg);color:var(--role-operator-fg);border-color:var(--role-operator-bd)}

/* ---------------------------------- Main --------------------------------- */
.main{display:flex;flex-direction:column;min-width:0}
.topbar{
  display:flex;align-items:center;gap:14px;padding:16px 26px;position:sticky;top:0;z-index:5;
  background:var(--topbar-bg);
  border-bottom:1px solid var(--line);
}
.topbar-title{display:flex;flex-direction:column;gap:2px;flex:1;min-width:0}
.topbar > [data-sidebar-toggle]{order:-1}
.topbar-title h1{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.clock{font-family:var(--mono);font-size:.72rem;color:var(--ink-3)}
.topbar-main{display:flex;align-items:center;gap:14px;flex:1 1 auto;min-width:0}
.topbar-actions{display:flex;gap:8px;flex-wrap:wrap}
/* Tombol AKSI halaman (mis. "+ Pembelian") — di desktop sejajar di kanan topbar */
.page-actions{display:flex;gap:8px;flex-wrap:wrap;align-items:center}
.page-actions:empty{display:none}
.content{display:flex;flex-direction:column;gap:24px;padding:24px 26px 46px;max-width:1400px;width:100%}
/* Deretan kartu KPI diberi jeda TAMBAHAN dari isi di bawahnya. Tanpa ini kartu
   ringkasan "menempel" dengan kartu/tabel berikutnya (keluhan pemilik: di Mutasi
   Stok, Bahan Baku, dan menu lain). Berlaku otomatis di semua modul karena
   `kpi_cards()` selalu menghasilkan `.kpi-grid`. */
.content > .kpi-grid{margin-bottom:12px}

/* ------------------------ JUDUL SEKSI (tanpa kartu) ---------------------- */
/* Dipakai `section_head()`: judul daftar yang TIDAK dibungkus .lab-card, supaya
   kartu-kartu item di bawahnya tampil benar-benar mengambang (mis. tab Bahan
   Baku dan daftar Supplier). Bentuknya mengikuti .card-head agar konsisten. */
.section-head{
  display:flex;align-items:flex-start;justify-content:space-between;gap:16px;flex-wrap:wrap;
  padding:0 2px;
}
.section-head-main{display:flex;flex-direction:column;gap:4px;min-width:0}
.section-head h2{
  display:flex;align-items:center;gap:10px;flex-wrap:wrap;
  font-size:1.04rem;color:var(--head-ink);
}
.section-head .muted.small{max-width:70ch}
.section-head-actions{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
@media (max-width:640px){
  .section-head{gap:8px}
  .section-head h2{font-size:.98rem}
  .section-head-actions{width:100%}
}

/* ---------------------------------- Cards -------------------------------- */
.lab-card{
  background:var(--panel);
  border:1px solid var(--line);
  border-radius:var(--radius);
  padding:20px;
  box-shadow:var(--shadow);
  /* Tanpa backdrop-filter: pada halaman dengan puluhan kartu, setiap blur
     memaksa komposit ulang tiap frame dan membuat gulir tersendat. */
  position:relative;
  overflow:visible;
}
.lab-card::before{
  content:"";position:absolute;inset:0;border-radius:inherit;pointer-events:none;
  background:var(--sheen);
}
.card-head{display:flex;align-items:flex-start;justify-content:space-between;gap:16px;flex-wrap:wrap;margin-bottom:16px}
.card-head h2{display:flex;align-items:center;gap:9px}
.card-head .muted{margin-top:2px;display:block}
.card-foot{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;margin-top:14px;border-top:1px solid var(--line);padding-top:12px}
.count-chip{
  font-size:.68rem;font-family:var(--mono);color:var(--cyan);background:rgba(45,212,167,.12);
  border:1px solid rgba(45,212,167,.28);border-radius:20px;padding:1px 9px;font-weight:600;
}
.badge{font-size:.7rem;padding:4px 10px;border-radius:20px;font-weight:600}
.badge-soft{background:var(--tint);border:1px solid var(--line-strong);color:var(--ink-2)}
/* Label kecil netral di dalam baris tabel (mis. "dari Pengeluaran") */
.pill-soft{background:var(--tint);border:1px solid var(--line-strong);color:var(--ink-2)}
tr.is-locked{background:var(--tint-3)}
.kpi-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:18px}
.kpi-grid.compact{grid-template-columns:repeat(auto-fit,minmax(min(196px,100%),1fr))}
.kpi{display:flex;flex-direction:column;gap:6px;padding:18px}
.kpi-warn{border-color:var(--warn-bd);box-shadow:var(--kpi-warn-glow)}
.kpi-label{font-size:.72rem;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-2);font-weight:600}
.kpi-value{font-size:1.6rem;font-family:var(--mono);font-variant-numeric:tabular-nums;letter-spacing:-.02em}
.kpi-value small{font-size:.72rem;color:var(--ink-2);font-family:inherit}
.kpi-foot{font-size:.74rem;color:var(--ink-2)}
.kpi-foot a{color:var(--cyan)}
.grid-2{display:grid;grid-template-columns:repeat(auto-fit,minmax(360px,1fr));gap:20px}
/* Kartu detail yang isinya panjang (rincian bahan + lampiran nota) ditumpuk
   ATAS-BAWAH dengan jarak lega — bersampingan membuat tabel rincian terpotong
   dan lampiran tampak menempel pada tabel. */
.detail-stack{display:flex;flex-direction:column;gap:22px}
.stack{display:flex;flex-direction:column;gap:14px}
.sub-head{display:flex;align-items:center;justify-content:space-between;gap:12px;margin:6px 0 -4px}
.mini-stats{display:flex;gap:26px;flex-wrap:wrap;margin-bottom:14px;padding:12px 14px;background:var(--tint-2);border:1px solid var(--line);border-radius:var(--radius-sm)}
.mini-stats strong{display:block;font-size:1rem}
.metric-row{display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:14px;padding:14px;border:1px solid var(--line);border-radius:var(--radius-sm);background:var(--tint-2);margin-bottom:14px}
.metric-row.wide{grid-template-columns:repeat(auto-fit,minmax(130px,1fr))}
.metric-row span{display:block;font-size:.7rem;text-transform:uppercase;letter-spacing:.08em;color:var(--ink-2)}
.metric-row strong{font-size:1rem}

/* ---------------------------------- Tables ------------------------------- */
.table-wrap{overflow-x:auto;border-radius:var(--radius-sm);border:1px solid var(--line)}
table.data{width:100%;border-collapse:collapse;font-size:.86rem;min-width:660px}
table.data thead th{
  background:var(--th-bg);color:var(--ink-2);font-size:.7rem;text-transform:uppercase;letter-spacing:.09em;
  text-align:left;padding:11px 12px;font-weight:650;white-space:nowrap;border-bottom:1px solid var(--line-strong);
}
table.data td{padding:11px 12px;border-bottom:1px solid var(--row-border);vertical-align:middle}
table.data tbody tr:hover{background:var(--tint-hover)}
table.data tfoot th{background:var(--foot-bg);font-family:var(--mono);font-size:.82rem;padding:11px 12px;border-top:1px solid var(--line-strong)}
table.data.compact{min-width:520px;font-size:.82rem}
table.data.compact td,table.data.compact thead th{padding:8px 10px}
table.data th.ta-r,table.data td.ta-r{text-align:right}
table.data th.ta-c,table.data td.ta-c{text-align:center}
table.data th[scope],table.data tbody th{color:var(--ink-2);font-weight:600;text-align:left}
.row-warn{background:var(--warn-row)}
.row-off{opacity:.5}
.empty{padding:20px;text-align:center;color:var(--ink-3);font-size:.85rem}
.pill{display:inline-block;font-size:.68rem;padding:3px 9px;border-radius:20px;font-weight:700;letter-spacing:.03em;text-transform:lowercase;border:1px solid transparent;white-space:nowrap}
.pill-berjalan{background:var(--warn-bg);color:var(--warn-fg);border-color:var(--warn-bd)}
.pill-selesai{background:var(--ok-bg);color:var(--ok-fg);border-color:var(--ok-bd)}
.pill-batal{background:var(--err-bg);color:var(--err-fg);border-color:var(--err-bd)}
.pill-masuk,.pill-produksi{background:var(--ok-bg);color:var(--ok-fg);border-color:var(--ok-bd)}
.pill-keluar{background:var(--err-bg);color:var(--err-fg);border-color:var(--err-bd)}
.pill-penyesuaian{background:var(--info-bg);color:var(--info-fg);border-color:var(--info-bd)}
.pill-warn{background:var(--warn-bg);color:var(--warn-fg);border-color:var(--warn-bd);margin-left:6px}
.pill-off{background:var(--off-bg);color:var(--off-fg);border-color:var(--off-bd);margin-left:6px}

/* ---------------------------------- Forms -------------------------------- */
.field{display:flex;flex-direction:column;gap:6px;font-size:.8rem}
.field>span{color:var(--ink-2);font-weight:600;letter-spacing:.02em}
/* ========================= KONTROL FORM (MODERN) ========================
   Satu set aturan untuk textbox, combobox (select), spinbutton (number),
   date, search, textarea — dipakai di seluruh menu & sub menu.
   - appearance:none + chevron SVG sendiri  -> tampilan select seragam
   - color-scheme                            -> widget asli (kalender, scrollbar) ikut tema
   - :focus-visible                          -> ring fokus modern, tetap ramah keyboard
   - :user-invalid                           -> penanda isian belum benar
   - spinbutton diganti stepper sendiri (.num-wrap) oleh assets/app.js
   ======================================================================== */
/* Selector ini sengaja luas: SEMUA textbox/combobox/spinbutton/tanggal di aplikasi
   (termasuk yang berada di dalam sel tabel, popup, dan kartu mutasi) memakai
   tampilan yang sama. Kontrol khusus (checkbox/radio/file/tombol) dikecualikan. */
/* Memakai :where() (spesifisitas 0) supaya aturan komponen/tabel dan blok
   penegasan di akhir file selalu bisa menimpanya tanpa perlu !important. */
:where(input,select,textarea):not(:where([type=checkbox],[type=radio],[type=file],[type=hidden],[type=submit],[type=button],[type=reset],[type=image],[type=range],[type=color])){
  background:var(--input-bg);border:1px solid var(--line-strong);color:var(--ink);
  border-radius:var(--radius-sm);padding:10px 12px;font-size:.87rem;font-family:inherit;
  width:100%;line-height:1.35;min-height:40px;box-shadow:none;
  transition:border-color .14s ease,box-shadow .14s ease,background-color .14s ease;
  -webkit-appearance:none;appearance:none;
}
textarea{resize:vertical;min-height:84px}
/* combobox: panah sendiri supaya konsisten di semua browser */
select{
  background-image:var(--select-caret);
  background-repeat:no-repeat;
  background-position:right 10px center;
  background-size:var(--select-caret-size);
  padding-right:32px;
  cursor:pointer;
}
select option{background:var(--pop-bg);color:var(--ink)}
select optgroup{background:var(--pop-bg);color:var(--ink-3);font-style:normal;font-weight:600}
/* hover & fokus */
:where(input,select,textarea):not(:where([type=checkbox],[type=radio],[type=file],[type=hidden],[type=submit],[type=button],[type=reset],[type=image],[type=range],[type=color])):hover:not(:disabled):not(:focus){border-color:var(--input-hover)}
:where(input,select,textarea):not(:where([type=checkbox],[type=radio],[type=file],[type=hidden],[type=submit],[type=button],[type=reset],[type=image],[type=range],[type=color])):focus{outline:none;border-color:var(--focus-border);box-shadow:0 0 0 3px var(--focus-ring)}
:where(input,select,textarea):not(:where([type=checkbox],[type=radio],[type=file],[type=hidden],[type=submit],[type=button],[type=reset],[type=image],[type=range],[type=color])):focus-visible{outline:none;box-shadow:0 0 0 3px var(--focus-ring)}
/* keadaan mati & hanya-baca */
:where(input,select,textarea):disabled{background:var(--input-disabled);color:var(--ink-3);cursor:not-allowed;border-color:var(--line)}
:where(input,textarea)[readonly]{background:var(--input-disabled);border-style:dashed;cursor:default}
/* isian belum sesuai aturan */
:where(input,select,textarea):user-invalid{border-color:var(--input-invalid)}
:where(input,select,textarea):user-invalid:focus{box-shadow:0 0 0 3px rgba(248,113,113,.18)}
/* placeholder */
:where(input,textarea)::placeholder{color:var(--ink-3);opacity:.85}
/* kotak centang & tombol pilihan: tampilan asli dipertahankan, hanya diwarnai */
:where(input[type=checkbox],input[type=radio]){
  width:18px;height:18px;min-height:18px;max-height:18px;padding:0;margin:0;
  accent-color:var(--cyan);cursor:pointer;flex:0 0 auto;
  -webkit-appearance:auto;appearance:auto;border-radius:4px;box-shadow:none;
  transition:box-shadow .14s ease;
}
:where(input[type=checkbox],input[type=radio]):focus-visible{outline:none;box-shadow:0 0 0 3px var(--focus-ring)}
:where(input[type=radio]){border-radius:50%}
/* tanggal & pencarian */
input[type=date],input[type=time],input[type=datetime-local]{
  font-family:var(--mono);font-size:.83rem;
}
input[type=date]::-webkit-calendar-picker-indicator,
input[type=time]::-webkit-calendar-picker-indicator{
  cursor:pointer;opacity:.55;transition:opacity .14s ease;
}
input[type=date]::-webkit-calendar-picker-indicator:hover{opacity:1}
input[type=search]::-webkit-search-cancel-button{cursor:pointer;filter:grayscale(1) opacity(.7)}
/* isian otomatis browser jangan mengubah warna latar */
input:-webkit-autofill,textarea:-webkit-autofill{
  -webkit-text-fill-color:var(--ink);
  -webkit-box-shadow:0 0 0 1000px var(--input-bg) inset;
  transition:background-color 9999s ease-out;
}
.field-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:16px}
.span-2{grid-column:span 2}
.form-card{max-width:100%}
.form-actions{display:flex;gap:10px;flex-wrap:wrap;margin-top:4px}
.check{flex-direction:row;align-items:center;gap:8px}
.check span{color:var(--ink-2)}
.search{display:flex;gap:10px;align-items:flex-end;flex-wrap:wrap}
/* Kolom pencarian dikecualikan dari padding umum di bawah — padding kirinya
   dipakai untuk ruang ikon kaca pembesar (lihat blok "PENCARIAN HIDUP").
   Tanpa pengecualian ini, padding-left jadi 10px sedangkan ikon berakhir di 29px
   sehingga ikon menimpa tulisan placeholder (bug nyata). */
.search input:not([type=checkbox]):not([type=radio]):not([type=search]),
.search select{width:auto;min-width:130px;padding:8px 10px;font-size:.82rem}
/* kotak centang di baris pencarian tidak boleh ikut melar */
.search input[type=checkbox],.search input[type=radio]{width:18px;min-width:18px;padding:0}
.search input[type=search]{min-width:200px}
.search.wide{align-items:center}
.field.inline{flex-direction:row;align-items:center;gap:8px}
.quick-range{display:flex;gap:8px;flex-wrap:wrap;margin-left:auto}
.chip{font-size:.74rem;padding:5px 11px;border-radius:20px;border:1px solid var(--line-strong);color:var(--ink-2);background:var(--chip-bg)}
.chip:hover{border-color:rgba(45,212,167,.5);color:var(--ink)}
.filter-card{padding:16px 20px}
/* Kolom pencarian pada kartu filter dibuat selebar mungkin (maksimal), bukan kotak kecil */
.filter-card .search{width:100%;gap:12px}
.filter-card .search input[type=search]{
  flex:1 1 320px;min-width:220px;width:auto;font-size:.87rem;padding:10px 14px;
}
.filter-card .search select{flex:0 0 auto}
.filter-card .search .field.inline{flex:0 0 auto}
.filter-card .search .view-choice{display:flex;align-items:center;gap:8px;flex:0 0 auto}
.filter-card .search .view-choice>span{
  font-size:.8rem;color:var(--ink-2);font-weight:600;white-space:nowrap;
}
.filter-card .search .view-choice select{min-width:150px}
.filter-card .search .btn[type=submit]{flex:0 0 auto}
.filter-hint{flex:1 1 180px;font-size:.76rem;color:var(--ink-2)}
@media (max-width:760px){
  .filter-card .search input[type=search]{flex:1 1 100%}
  .filter-card .search .view-choice{width:100%}
  .filter-card .search .view-choice select{flex:1 1 auto;width:auto}
}
.recipe-row select,.recipe-row input{padding:8px 10px;font-size:.82rem}

/* input berkas memakai gaya khusus di kartu lampiran */
input[type=file]{-webkit-appearance:auto;appearance:auto;padding:0;min-height:0;border:0;background:transparent;box-shadow:none}

/* ---------------------- Spinbutton (input angka) ---------------------- */
/* Pembungkus + tombol −/+ dibuat oleh assets/app.js. Bila JS tidak aktif,
   spinbutton asli browser tetap tampil karena hanya disembunyikan di dalam
   .num-wrap (penanda bahwa penggantinya benar-benar ada). */
.num-wrap{position:relative;display:block;width:100%;min-width:0}
.num-stepper{
  position:absolute;top:50%;right:5px;transform:translateY(-50%);
  display:flex;flex-direction:column;gap:2px;z-index:2;
}
.num-stepper button{
  width:20px;height:15px;padding:0;display:grid;place-items:center;
  border:1px solid transparent;border-radius:5px;background:var(--stepper-bg);
  color:var(--stepper-fg);font-family:inherit;font-size:11px;line-height:1;cursor:pointer;
  transition:background-color .12s ease,color .12s ease,transform .08s ease;
}
.num-stepper button:hover{background:var(--stepper-bg-hover);color:var(--ink-strong)}
.num-stepper button:active{transform:scale(.92)}
.num-stepper button:disabled{opacity:.35;cursor:not-allowed}
.num-wrap>input{width:100%;padding-right:32px;text-align:inherit}
/* hanya sembunyikan spinbutton asli bila stepper kita sudah terpasang */
.num-wrap>input[type=number]{-webkit-appearance:textfield;appearance:textfield}
.num-wrap>input[type=number]::-webkit-outer-spin-button,
.num-wrap>input[type=number]::-webkit-inner-spin-button{-webkit-appearance:none;appearance:none;margin:0}
.num-wrap>input[type=number]{-moz-appearance:textfield}
/* input hanya-baca: stepper tidak berguna */
.num-wrap>input:read-only~.num-stepper{display:none}
.num-wrap>input:disabled~.num-stepper{display:none}
@media (max-width:900px){
  .num-stepper button{width:24px;height:18px;font-size:12px}
  .num-wrap>input{padding-right:36px}
}
.mini-pop{position:relative;display:inline-block}
.mini-pop>summary{list-style:none;cursor:pointer}
.mini-pop>summary::-webkit-details-marker{display:none}
.pop-body{
  position:absolute;right:0;top:calc(100% + 8px);z-index:20;width:290px;padding:16px;
  background:var(--pop-bg);border:1px solid var(--line-strong);border-radius:var(--radius);
  box-shadow:0 24px 50px -20px rgba(0,0,0,.95);text-align:left;
}
.pop-body .field{margin-bottom:10px}
.danger-pop{margin-top:14px;display:block}
.danger-pop .pop-body{left:0;right:auto}
.preview-box{display:grid;grid-template-columns:repeat(3,1fr);gap:12px;padding:14px;border-radius:var(--radius-sm);background:var(--preview-bg);border:1px solid var(--preview-bd);margin-top:18px}
.preview-box span{display:block;font-size:.68rem;text-transform:uppercase;letter-spacing:.07em;color:var(--ink-2)}
.preview-box strong{font-size:.98rem}

/* --------------------------------- Buttons ------------------------------- */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:7px;
  padding:9px 15px;border-radius:var(--radius-sm);border:1px solid var(--line-strong);
  background:var(--btn-bg);color:var(--ink);font-size:.83rem;font-family:inherit;font-weight:600;
  cursor:pointer;transition:.15s;white-space:nowrap;
}
.btn:hover{background:var(--btn-bg-hover);border-color:var(--btn-border-hover)}
.btn-primary{
  background:var(--primary-grad);border-color:transparent;color:#f3fdf9;
  box-shadow:var(--primary-shadow);
}
.btn-primary:hover{filter:brightness(1.1);background:var(--primary-grad)}
.btn-danger{background:var(--err-bg);border-color:var(--err-bd);color:var(--err-fg)}
.btn-danger:hover{background:var(--err-bg-hover)}
.btn-ghost{background:transparent}
.btn-sm{padding:8px 12px;font-size:.78rem;min-height:34px}
.btn-block{width:100%}
.row-actions{display:flex;gap:7px;justify-content:center;flex-wrap:wrap}
.icon-btn{background:var(--tint);border:1px solid var(--line-strong);border-radius:10px;padding:8px;cursor:pointer}
.icon-btn svg{width:18px;height:18px;fill:var(--ink)}
.link{color:var(--cyan);font-weight:600}

/* --------------------------------- Alerts -------------------------------- */
.alert{display:flex;align-items:center;gap:10px;padding:12px 16px;border-radius:var(--radius-sm);font-size:.85rem;border:1px solid transparent}
.alert svg{width:18px;height:18px;flex:0 0 18px}
.alert-ok{background:var(--alert-ok-bg);border-color:var(--alert-ok-bd);color:var(--alert-ok-fg)}
.alert-ok svg{fill:#34D399}
.alert-err{background:var(--alert-err-bg);border-color:var(--alert-err-bd);color:var(--alert-err-fg)}
.alert-err svg{fill:#F87171}
/* Peringatan yang tidak menghentikan halaman (mis. akun yang sesuai belum ada) */
.alert-warn{background:var(--warn-bg);border-color:var(--warn-bd);color:var(--warn-fg);font-size:.8rem}
.alert-list{display:flex;flex-direction:column;gap:10px}
.alert-row{display:flex;align-items:center;gap:12px;padding:11px 13px;border:1px solid var(--line);border-radius:var(--radius-sm);background:var(--tint-3)}
.alert-row div{flex:1}
.alert-row small{display:block;color:var(--ink-2);font-size:.76rem}
.dot{width:9px;height:9px;border-radius:50%;flex:0 0 9px;display:inline-block}
.dot-amber{background:var(--amber);box-shadow:0 0 10px rgba(251,191,36,.8)}
.dot-cyan{background:var(--cyan);box-shadow:0 0 10px rgba(45,212,167,.8)}
.dot-green{background:var(--green);box-shadow:0 0 10px rgba(52,211,153,.8)}
.dot-red{background:var(--red);box-shadow:0 0 10px rgba(248,113,113,.8)}

/* ---------------------------------- Charts ------------------------------- */
.bar-chart{display:flex;align-items:flex-end;gap:8px;height:170px;padding:8px 4px 0;border-bottom:1px solid var(--line-strong)}
.bar-col{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:flex-end;gap:6px;height:100%}
.bar-fill{
  width:100%;max-width:34px;border-radius:6px 6px 0 0;
  background:var(--bar-fill);
  box-shadow:var(--bar-shadow);min-height:3px;transition:.2s;
}
.bar-col:hover .bar-fill{filter:brightness(1.2)}
.bar-x{font-size:.66rem;color:var(--ink-3);font-family:var(--mono)}
.chart-axis{display:flex;justify-content:space-between;margin-top:8px;font-size:.72rem;color:var(--ink-3);font-family:var(--mono)}
.rank-list{display:flex;flex-direction:column;gap:14px}
.rank-head{display:flex;justify-content:space-between;gap:10px;font-size:.84rem}
.rank-bar{height:8px;border-radius:20px;background:var(--track);overflow:hidden;margin:6px 0 4px}
.rank-bar i{display:block;height:100%;background:linear-gradient(90deg,#2dd4a7,#14a38b);border-radius:20px}

/* --------------------------------- Recipes ------------------------------- */
.recipe-list{display:grid;grid-template-columns:repeat(auto-fit,minmax(420px,1fr));gap:20px}
.recipe-card{display:flex;flex-direction:column}
.note-line{font-size:.82rem;color:var(--ink-2);border-left:2px solid var(--note-border);padding-left:10px;margin:0 0 12px}
.recipe-detail summary{
  cursor:pointer;font-size:.8rem;color:var(--cyan);font-weight:600;padding:8px 0;
}
.recipe-detail[open] summary{margin-bottom:8px}

/* -------------------------------- Timeline ------------------------------- */
.timeline{display:flex;flex-direction:column;gap:9px;font-size:.83rem;color:var(--ink-2);padding:14px;border-radius:var(--radius-sm);border:1px solid var(--line);background:var(--tint-3)}
.timeline strong{color:var(--ink)}
.process-flow{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:18px}
.step{display:flex;gap:14px;padding:16px;border:1px solid var(--line);border-radius:var(--radius-sm);background:var(--tint-3)}
.step-num{
  width:32px;height:32px;flex:0 0 32px;border-radius:10px;display:grid;place-items:center;font-family:var(--mono);font-weight:700;
  background:var(--stepnum-bg);border:1px solid var(--stepnum-bd);color:var(--stepnum-fg);
}
.step p{margin:6px 0 0;font-size:.82rem;color:var(--ink-2)}

/* ---------------------------------- Tabs --------------------------------- */
.tab-bar{display:flex;gap:8px;flex-wrap:wrap;border-bottom:1px solid var(--line);padding-bottom:0}
.tab{padding:10px 16px;font-size:.85rem;font-weight:600;color:var(--ink-2);border:1px solid transparent;border-bottom:none;border-radius:var(--radius-sm) var(--radius-sm) 0 0}
.tab:hover{color:var(--ink);background:var(--tint-hover)}
.tab.is-active{color:var(--ink-strong);background:var(--tab-active-bg);border-color:var(--nav-active-border)}

/* --------------------------------- Login --------------------------------- */
.login-body{display:flex;align-items:center;justify-content:center;min-height:100vh;padding:72px 20px 40px}
.banner-strip{
  position:fixed;top:0;left:0;right:0;pointer-events:none;display:flex;gap:40px;justify-content:center;flex-wrap:wrap;
  padding:10px;font-size:.72rem;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-3);
  background:var(--strip-bg);border-bottom:1px solid var(--line);z-index:3;
}
.strip-item span{font-family:var(--mono);color:var(--cyan);margin-right:6px}
.login-wrap{position:relative;z-index:2;display:flex;align-items:center;justify-content:center;width:100%}
.login-card{position:relative;width:min(420px,100%)}
.login-card h2{margin-bottom:6px}
.login-help{margin:6px 0 0;text-align:center}
.login-card-top{display:flex;justify-content:flex-end;margin:0 0 14px}
.login-card-top .btn-theme{padding:7px 12px}

.btn-theme{gap:8px}
.btn-theme svg{width:16px;height:16px;fill:currentColor;flex:0 0 16px}
.btn-theme .ico-moon{display:none}
html[data-theme="light"] .btn-theme .ico-sun{display:none}
html[data-theme="light"] .btn-theme .ico-moon{display:block}
.theme-label{font-size:.76rem;font-weight:600;letter-spacing:.02em}
::placeholder{color:var(--ink-3);opacity:1}

/* ---------------------------- Tema Terang (Light) ------------------------ */
html[data-theme="light"]{
  --bg:#F4F6FC;
  --bg-2:#EAEEF9;
  --panel:rgba(255,255,255,.94);
  --panel-2:rgba(255,255,255,.62);
  --line:rgba(30,60,53,.10);
  --line-strong:rgba(30,60,53,.16);
  --ink:#16203A;
  --ink-2:#4E5B76;
  --ink-3:#616D89;
  --ink-strong:#0B1530;
  --head-ink:#000000;
  --code-ink:#000000;
  --cyan:#0b6a5c;
  --violet:#0b5f52;
  --green:#047857;
  --amber:#B45309;
  --red:#B91C1C;
  --shadow:0 16px 34px -24px rgba(24,52,46,.45);
  --body-bg:
    radial-gradient(900px 520px at 6% -10%, rgba(14,124,107,.16), transparent 60%),
    radial-gradient(820px 520px at 100% 0%, rgba(20,163,139,.16), transparent 58%),
    radial-gradient(700px 600px at 50% 118%, rgba(16,185,129,.12), transparent 62%),
    linear-gradient(180deg,var(--bg) 0%, var(--bg-2) 100%);
  --sidebar-bg:linear-gradient(180deg,rgba(255,255,255,.94),rgba(244,247,255,.92));
  --topbar-bg:linear-gradient(180deg,rgba(255,255,255,.94),rgba(255,255,255,.72));
  --strip-bg:rgba(255,255,255,.82);
  --grid-c:rgba(30,60,53,.06);
  --sheen:linear-gradient(160deg,rgba(255,255,255,.55),transparent 45%);
  --pop-bg:rgba(255,255,255,.98);
  --input-bg:rgba(255,255,255,.92);
  --tint:rgba(30,60,53,.05);
  --tint-2:rgba(30,60,53,.035);
  --tint-3:rgba(30,60,53,.03);
  --tint-hover:rgba(30,60,53,.05);
  --th-bg:rgba(30,60,53,.05);
  --foot-bg:rgba(14,124,107,.07);
  --row-border:rgba(30,60,53,.08);
  --track:rgba(30,60,53,.10);
  --chip-bg:rgba(30,60,53,.045);
  --warn-row:rgba(245,158,11,.10);
  --nav-active-bg:linear-gradient(100deg,rgba(14,124,107,.13),rgba(15,138,115,.11));
  --nav-active-border:rgba(14,124,107,.30);
  --tab-active-bg:linear-gradient(180deg,rgba(14,124,107,.14),rgba(14,124,107,.03));
  --brand-bg:linear-gradient(140deg,#0e7c6b,#0f8a73);
  --brand-border:transparent;
  --brand-fg:#FFFFFF;
  --brand-accent:#e6faf4;
  --brand-shadow:0 12px 24px -12px rgba(14,124,107,.75);
  --avatar-bg:linear-gradient(140deg,rgba(14,124,107,.20),rgba(15,138,115,.18));
  --avatar-border:rgba(14,124,107,.26);
  --avatar-fg:#0b3b34;
  --btn-bg:rgba(30,60,53,.05);
  --btn-bg-hover:rgba(30,60,53,.10);
  --btn-border-hover:rgba(30,60,53,.24);
  --primary-grad:linear-gradient(100deg,#0e7c6b,#0f8a73);
  --primary-shadow:0 12px 26px -14px rgba(14,124,107,.75);
  --focus-border:rgba(14,124,107,.55);
  --focus-ring:rgba(14,124,107,.16);
  --input-hover:rgba(30,60,53,.32);
  --input-disabled:rgba(30,60,53,.05);
  --input-invalid:rgba(220,38,38,.85);
  --stepper-bg:rgba(30,60,53,.08);
  --stepper-bg-hover:rgba(14,124,107,.20);
  --stepper-fg:var(--ink-2);
  --select-caret:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%234E5B76' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  --select-caret-size:16px;
  --search-icon:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%234E5B76' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='m20 20-3.6-3.6'/%3E%3C/svg%3E");
  color-scheme:light;
  --preview-bg:rgba(14,124,107,.07);
  --preview-bd:rgba(14,124,107,.22);
  --bar-fill:linear-gradient(180deg,#12a184,#14a38b);
  --bar-shadow:0 0 14px -5px rgba(18,161,132,.5);
  --stepnum-bg:linear-gradient(140deg,rgba(14,124,107,.22),rgba(15,138,115,.20));
  --stepnum-bd:rgba(14,124,107,.28);
  --stepnum-fg:#0b3b34;
  --kpi-warn-glow:0 0 22px -16px rgba(245,158,11,.9);
  --role-admin-bg:rgba(15,138,115,.12); --role-admin-fg:#0b5f52; --role-admin-bd:rgba(15,138,115,.28);
  --role-operator-bg:rgba(14,124,107,.12); --role-operator-fg:#0b6a5c; --role-operator-bd:rgba(14,124,107,.28);
  --ok-bg:rgba(16,185,129,.13); --ok-fg:#04674A; --ok-bd:rgba(16,185,129,.28);
  --warn-bg:rgba(245,158,11,.15); --warn-fg:#8A5200; --warn-bd:rgba(245,158,11,.32);
  --err-bg:rgba(239,68,68,.12); --err-fg:#9B1C1C; --err-bd:rgba(239,68,68,.28);
  --err-bg-hover:rgba(239,68,68,.2);
  --info-bg:rgba(15,138,115,.12); --info-fg:#0b5f52; --info-bd:rgba(15,138,115,.28);
  --off-bg:rgba(100,116,139,.12); --off-fg:#475569; --off-bd:rgba(100,116,139,.24);
  --alert-ok-bg:rgba(16,185,129,.10); --alert-ok-fg:#065F46; --alert-ok-bd:rgba(16,185,129,.28);
  --alert-err-bg:rgba(239,68,68,.10); --alert-err-fg:#9B1C1C; --alert-err-bd:rgba(239,68,68,.26);
  --note-border:rgba(14,124,107,.45);
}
html[data-theme="light"] .lab-grid{opacity:.7}

/* --------------------------------- Mobile -------------------------------- */
.only-mobile{display:none}
@media (max-width:1040px){
  .login-wrap{padding:0 4px}
}
@media (max-width:900px){
  .shell{grid-template-columns:1fr}
  .btn-theme .theme-label{display:none}
  .btn-theme{padding:8px}
  .sidebar{
    /* 280px (dulu 262px): judul grup "Rekam Medis Elektronik" butuh ruang lebih
       supaya tetap SATU BARIS (tanpa terpotong) di layar HP. */
    position:fixed;top:0;left:0;bottom:0;width:280px;z-index:40;height:100vh;
    transform:translateX(-102%);transition:transform .22s ease;
  }
  .sidebar.is-open{transform:none}
  .only-mobile{display:inline-flex}
  .content{padding:18px 16px 40px}
  .topbar{padding:12px 16px}
  .span-2{grid-column:span 1}
  .recipe-list{grid-template-columns:1fr}
  .preview-box{grid-template-columns:1fr}
}

/* ============================ MODUL PEMBELIAN ============================ */
.badge-restricted{
  background:var(--warn-bg);color:var(--warn-fg);border:1px solid var(--warn-bd);
  font-size:.68rem;padding:3px 9px;border-radius:20px;font-weight:600;
}
.head-chips{display:flex;gap:8px;flex-wrap:wrap;align-items:center}
.totals-grid{grid-template-columns:repeat(auto-fit,minmax(180px,1fr));margin-top:16px}
.total-card{
  display:flex;flex-direction:column;gap:2px;padding:14px 16px;border-radius:var(--radius-sm);
  background:var(--preview-bg);border:1px solid var(--preview-bd);
}
.total-card span{font-size:.7rem;text-transform:uppercase;letter-spacing:.08em;color:var(--ink-3)}
.total-card strong{font-size:1.25rem;font-family:var(--mono)}
.total-card small{font-family:var(--mono);font-size:.7rem}
.upload-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:18px}
.upload-box{
  display:flex;flex-direction:column;align-items:flex-start;gap:8px;padding:18px;border-radius:var(--radius-sm);
  border:1px dashed var(--line-strong);background:var(--tint-3);
}
.upload-box svg{width:26px;height:26px;fill:var(--cyan)}
.upload-box strong{font-size:.92rem}
.upload-box input[type=file]{
  width:100%;font-size:.78rem;color:var(--ink-2);background:var(--input-bg);border:1px solid var(--line-strong);
  border-radius:var(--radius-sm);padding:8px 10px;
}
.upload-box input[type=file]::file-selector-button{
  font-family:inherit;font-size:.78rem;margin-right:10px;padding:6px 12px;border-radius:8px;cursor:pointer;
  border:1px solid var(--line-strong);background:var(--btn-bg);color:var(--ink);font-weight:600;
}
.upload-box input[type=file]::file-selector-button:hover{background:var(--btn-bg-hover)}
.preview-row{display:flex;gap:10px;flex-wrap:wrap;width:100%}
.preview-row.is-filled{margin-top:6px;padding-top:10px;border-top:1px solid var(--line)}
.photo-preview{display:flex;flex-direction:column;gap:4px;width:96px;margin:0}
.photo-preview img{width:96px;height:76px;object-fit:cover;border-radius:10px;border:1px solid var(--line-strong)}
.photo-preview figcaption{font-size:.66rem;color:var(--ink-3);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.photo-strip{display:flex;gap:14px;flex-wrap:wrap;margin-bottom:16px}
.photo-item{margin:0;display:flex;flex-direction:column;gap:6px;width:150px}
.photo-item img{width:150px;height:112px;object-fit:cover;border-radius:var(--radius-sm);border:1px solid var(--line-strong)}
.photo-item figcaption{display:flex;flex-direction:column;gap:4px;font-size:.72rem}
.photo-item .check{font-size:.72rem}
.photo-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(160px,1fr));gap:14px}
.photo-card{
  display:flex;flex-direction:column;gap:8px;padding:10px;border-radius:var(--radius-sm);
  border:1px solid var(--line-strong);background:var(--tint-3);color:var(--ink);
}
.photo-card img{width:100%;height:140px;object-fit:cover;border-radius:10px}
.photo-card:hover{border-color:var(--focus-border)}
.photo-name{font-size:.74rem;color:var(--ink-2);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.doc-thumb{
  display:grid;place-items:center;min-height:76px;border-radius:10px;border:1px solid var(--line-strong);
  background:var(--tint);font-size:.75rem;color:var(--ink-2);
}
.doc-thumb.big{min-height:140px}
.restricted-note{
  display:flex;gap:14px;align-items:flex-start;border-color:var(--warn-bd)!important;
}
.restricted-note svg{width:26px;height:26px;flex:0 0 26px;fill:var(--amber)}
.chip-row{display:flex;gap:8px;flex-wrap:wrap}
.chip-money{border-color:var(--ok-bd);color:var(--ok-fg);background:var(--ok-bg)}
.chip-warn{border-color:var(--warn-bd);color:var(--warn-fg);background:var(--warn-bg)}

/* ======================= HALAMAN ROLE / PERAN ============================ */
.perm-group{margin-bottom:20px;padding-bottom:16px;border-bottom:1px solid var(--line)}
.perm-group:last-of-type{border-bottom:none}
.perm-group-head{display:flex;align-items:center;justify-content:space-between;gap:14px;flex-wrap:wrap;margin-bottom:12px}
.perm-group-head h3{font-size:.86rem;letter-spacing:.02em}
.perm-list{display:grid;grid-template-columns:repeat(auto-fit,minmax(310px,1fr));gap:10px}
.perm-item{
  display:flex;gap:10px;align-items:flex-start;padding:11px 13px;border-radius:var(--radius-sm);
  border:1px solid var(--line);background:var(--tint-3);cursor:pointer;transition:.14s;
}
.perm-item:hover{border-color:var(--focus-border);background:var(--tint-2)}
.perm-item input{margin-top:3px;flex:0 0 auto}
.perm-text{display:flex;flex-direction:column;gap:2px;min-width:0}
.perm-text strong{font-size:.85rem}
.perm-text small{font-size:.73rem;color:var(--ink-2)}
.perm-text code{font-size:.68rem;color:var(--ink-3)}
.perm-item:has(input:checked){border-color:var(--ok-bd);background:var(--ok-bg)}
.perm-item:has(input:checked) .perm-text strong{color:var(--ok-fg)}
.perm-money:has(input:checked){border-color:var(--warn-bd);background:var(--warn-bg)}
.perm-money:has(input:checked) .perm-text strong{color:var(--warn-fg)}
.matrix-table th[scope=row]{font-weight:500;font-size:.79rem;color:var(--ink);text-align:left;white-space:normal}
.matrix-table .matrix-group th{
  background:var(--foot-bg);font-size:.72rem;text-transform:uppercase;letter-spacing:.1em;color:var(--ink-2);
}
.role-cards{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:18px}
.role-card{padding:16px;border-radius:var(--radius-sm);border:1px solid var(--line);background:var(--tint-3)}
.role-card-head{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:6px}
.role-card p{margin:0 0 10px;font-size:.78rem}
.forbidden-card{max-width:640px;display:flex;flex-direction:column;gap:12px;align-items:flex-start}
.forbidden-icon{
  width:52px;height:52px;border-radius:14px;display:grid;place-items:center;
  background:var(--warn-bg);border:1px solid var(--warn-bd);
}
.forbidden-icon svg{width:28px;height:28px;fill:var(--amber)}
.role-admin{background:var(--role-admin-bg);color:var(--role-admin-fg);border-color:var(--role-admin-bd)}
.role-operator{background:var(--role-operator-bg);color:var(--role-operator-fg);border-color:var(--role-operator-bd)}
.role-gudang,.role-finance,.role-manajer{
  background:var(--info-bg);color:var(--info-fg);border-color:var(--info-bd);
}
@media (max-width:640px){
  .perm-list{grid-template-columns:1fr}
  .photo-item,.photo-item img{width:100%}
}

/* ====================== SATUAN / KONVERSI & WARNA BANTU ================== */
.factor-input.is-auto{background:rgba(45,212,167,.10);border-color:rgba(45,212,167,.35);color:var(--ink)}
.factor-hint{display:block;font-size:.66rem;margin-top:2px}
.stock-used{color:var(--ink-2)}
.unit-badge{
  display:inline-block;font-size:.68rem;padding:2px 8px;border-radius:20px;
  border:1px solid var(--line-strong);background:var(--tint);color:var(--ink-2);font-family:var(--mono);
}
.usage-line{font-size:.72rem;color:var(--ink-3)}
.small-note{font-size:.72rem;color:var(--ink-2)}

/* ========================= IMBALAN / TIMELINE BATCH ====================== */
.rework-badge{background:var(--info-bg);color:var(--info-fg);border-color:var(--info-bd)}
.log-list{display:flex;flex-direction:column;gap:10px;max-height:340px;overflow-y:auto;padding-right:4px}
.log-item{display:flex;gap:10px;font-size:.8rem;padding-bottom:10px;border-bottom:1px solid var(--line)}
.log-item:last-child{border-bottom:none;padding-bottom:0}
.log-item .log-time{font-family:var(--mono);font-size:.7rem;color:var(--ink-2);white-space:nowrap;min-width:118px}
.log-item .log-body{flex:1}
.log-item .log-who{font-size:.72rem;color:var(--ink-2)}
.move-chip{display:inline-flex;align-items:center;gap:6px}
.qty-strong{font-family:var(--mono);font-weight:600}
.stock-flow{display:flex;gap:14px;flex-wrap:wrap;align-items:center;padding:12px 14px;border:1px solid var(--line);border-radius:var(--radius-sm);background:var(--tint-3)}
.stock-flow div{font-size:.78rem}
.stock-flow b{display:block;font-family:var(--mono);font-size:1rem;color:var(--ink)}

/* ============================ LAMPIRAN FOTO ============================= */
.photo-thumb{
  width:54px;height:42px;object-fit:cover;border-radius:8px;border:1px solid var(--line-strong);
  cursor:zoom-in;display:block;
}
.photo-thumb-btn{border:none;background:none;padding:0;cursor:zoom-in;line-height:0}
.photo-missing{
  width:54px;height:42px;border-radius:8px;border:1px dashed var(--warn-bd);background:var(--warn-bg);
  display:grid;place-items:center;font-size:.6rem;text-align:center;color:var(--warn-fg);cursor:pointer;padding:2px;
}
/* ============ TOMBOL LAMPIRAN (TANPA POPUP — JANGAN DIUBAH KE POPUP) ======
   Dulu widget ini memakai menu popup berisi pilihan "Kamera" / "Galeri". Menu itu
   diposisikan absolut sehingga keluar dari kotak kartu, sedangkan kartu di dalam
   `.sheet-body` memakai `content-visibility:auto` (implisit `contain: paint`) yang
   MEMOTONG semua isi yang keluar dari kotaknya — akibatnya menunya tak terlihat dan
   tak bisa ditekan (bug nyata di banyak modul: lampiran/kamera "tidak jalan").
   Sekarang: dua tombol langsung (masing-masing <label> membungkus satu input file)
   tanpa posisi absolut & tanpa JavaScript, jadi tidak ada yang bisa terpotong. */
.attach-widget{display:inline-flex;flex-direction:column;gap:8px;max-width:100%}
.attach-actions{display:flex;align-items:center;gap:8px;flex-wrap:wrap;min-width:0}
.attach-actions .attach-label{flex:1 1 auto;min-width:0}
.attach-actions .btn-attach{display:inline-flex;align-items:center;gap:7px;cursor:pointer}
.attach-actions .btn-attach svg{width:15px;height:15px;fill:currentColor;flex:0 0 15px}
.attach-preview{display:flex;gap:8px;align-items:center;flex-wrap:wrap}
.attach-preview:empty{display:none}
.attach-preview img{width:64px;height:48px;object-fit:cover;border-radius:8px;border:1px solid var(--line-strong)}
.attach-preview .btn-clear{font-size:.72rem}
/* Input berkas cukup disembunyikan SECARA VISUAL (ukuran 1px, opacity 0) tetapi
   TIDAK `pointer-events:none` — pointer-events:none membuat sebagian peramban HP
   gagal meneruskan penekanan label ke input (pemilih berkas/kamera tidak terbuka). */
.file-input-hidden{position:absolute;width:1px;height:1px;opacity:0;overflow:hidden;margin:-1px;clip-path:inset(50%)}
@media (max-width:640px){
  .attach-actions{gap:8px}
  .attach-actions .btn-attach{flex:1 1 auto;justify-content:center;min-height:42px}
  .attach-actions .attach-label{flex:1 1 100%}
}

/* ========================== MODAL LAMPIRAN FOTO ========================= */
.modal-backdrop{
  position:fixed;inset:0;z-index:80;background:rgba(4,8,14,.82);
  display:none;align-items:center;justify-content:center;padding:24px;
}
.modal-backdrop.is-open{display:flex}
.modal-card{
  width:min(940px,100%);max-height:92vh;overflow:auto;background:var(--pop-bg);
  border:1px solid var(--line-strong);border-radius:var(--radius);box-shadow:0 30px 70px -30px rgba(0,0,0,.95);
}
.modal-head{display:flex;align-items:flex-start;justify-content:space-between;gap:14px;padding:18px 20px;border-bottom:1px solid var(--line)}
.modal-head h3{margin:0;font-size:.98rem}
.modal-head small{color:var(--ink-3);font-size:.74rem;font-family:var(--mono)}
.modal-body{padding:18px 20px;display:grid;grid-template-columns:minmax(0,1.4fr) minmax(240px,1fr);gap:20px}
.modal-body.single{grid-template-columns:1fr}
.modal-figure{margin:0;display:flex;flex-direction:column;gap:10px;align-items:center}
.modal-figure img{max-width:100%;max-height:56vh;border-radius:var(--radius-sm);border:1px solid var(--line-strong);background:#000}
.modal-figure .broken{
  width:100%;min-height:220px;border-radius:var(--radius-sm);border:1px dashed var(--warn-bd);
  background:var(--warn-bg);display:grid;place-items:center;text-align:center;padding:24px;color:var(--warn-fg);font-size:.85rem;
}
.modal-meta{display:flex;flex-direction:column;gap:10px;font-size:.82rem}
.meta-row{display:flex;justify-content:space-between;gap:12px;padding:9px 12px;border:1px solid var(--line);border-radius:var(--radius-sm);background:var(--tint-3)}
.meta-row span{color:var(--ink-3);font-size:.75rem}
.meta-row strong{font-weight:600;text-align:right}
.modal-foot{display:flex;justify-content:space-between;gap:12px;padding:14px 20px;border-top:1px solid var(--line);flex-wrap:wrap}
/* ---- POP-UP NOTIFIKASI (penyimpanan belum berhasil / peringatan penting) ---- */
.notice-card{width:min(520px,100%);border-color:var(--warn-bd)}
#app-notice[data-kind="err"] .notice-card{border-color:var(--err-bd)}
.notice-list{margin:0;padding-left:18px;display:flex;flex-direction:column;gap:8px;font-size:.86rem}
.notice-list li::marker{color:var(--warn-fg)}
#app-notice[data-kind="err"] .notice-list li::marker{color:var(--err-fg)}
.notice-backdrop{z-index:90}
@media (max-width:760px){
  .modal-body{grid-template-columns:1fr}
  .modal-backdrop{padding:12px}
}

/* ===================== KEPUTUSAN HASIL PRODUKSI (QC) ==================== */
.outcome-list{display:flex;flex-direction:column;gap:10px}
.outcome-item{
  display:flex;gap:10px;align-items:flex-start;padding:12px 14px;border:1px solid var(--line);
  border-radius:var(--radius-sm);background:var(--tint-3);cursor:pointer;
}
.outcome-item:hover{border-color:var(--focus-border)}
.outcome-item input{margin-top:3px}
.outcome-item span{display:flex;flex-direction:column;gap:2px}
.outcome-item strong{font-size:.86rem}
.outcome-item small{font-size:.74rem;color:var(--ink-2)}
.outcome-item:has(input:checked){border-color:var(--ok-bd);background:var(--ok-bg)}
.outcome-item:nth-child(2):has(input:checked){border-color:var(--info-bd);background:var(--info-bg)}
.outcome-item:nth-child(2):has(input:checked) strong{color:var(--info-fg)}
.outcome-item:nth-child(3):has(input:checked){border-color:var(--err-bd);background:var(--err-bg)}
.outcome-item:nth-child(3):has(input:checked) strong{color:var(--err-fg)}
.pack-row select,.pack-row input{padding:7px 9px;font-size:.8rem}
.pack-hint{display:block;font-size:.66rem}

/* ===================== THUMBNAIL LAMPIRAN & KARTU ======================= */
.thumb-row{display:flex;gap:6px;justify-content:center;align-items:center;flex-wrap:wrap}
.photo-card.as-button{
  width:100%;text-align:left;font-family:inherit;font-size:inherit;cursor:zoom-in;
}
.photo-card.as-button:hover{border-color:var(--focus-border)}
.photo-card img{cursor:zoom-in}

/* ===================== MUTASI STOK & KARTU PRODUK ======================= */
.row-system{background:var(--tint-3)}
.row-system td{opacity:.92}

/* Kartu produk jadi (tampilan maksimal) */
.product-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(430px,1fr));gap:22px}
.product-card{display:flex;flex-direction:column;gap:16px}
.product-head{display:flex;align-items:flex-start;justify-content:space-between;gap:16px}
.product-head h2{font-size:1.06rem}
.product-code{font-family:var(--mono);font-size:.74rem;color:var(--ink-3)}
.product-hero{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(132px,1fr));gap:14px;padding:16px;
  border-radius:var(--radius-sm);border:1px solid var(--line);background:var(--tint-3);
}
.product-hero > div span{display:block;font-size:.68rem;text-transform:uppercase;letter-spacing:.08em;color:var(--ink-2)}
.product-hero > div b{display:block;font-family:var(--mono);font-size:1.24rem;margin-top:3px}
.product-hero > div small{font-size:.7rem;color:var(--ink-2)}
.batch-list{display:flex;flex-direction:column;gap:10px}
.batch-line{
  display:grid;grid-template-columns:minmax(0,1.3fr) repeat(3,minmax(72px,auto));gap:10px;align-items:center;
  padding:10px 12px;border:1px solid var(--line);border-radius:var(--radius-sm);background:var(--tint-3);font-size:.8rem;
}
.batch-line .bcode{font-family:var(--mono);font-size:.76rem}
.batch-line .bqty{text-align:right;font-family:var(--mono)}
.batch-line .bqty small{display:block;color:var(--ink-2);font-size:.66rem}
.variance-note{
  display:flex;gap:10px;align-items:flex-start;padding:11px 13px;border-radius:var(--radius-sm);
  border:1px solid var(--warn-bd);background:var(--warn-bg);font-size:.78rem;color:var(--warn-fg);
}
.variance-note svg{width:18px;height:18px;flex:0 0 18px;fill:var(--amber)}
.mutasi-card{display:flex;flex-direction:column;gap:12px}
.unit-choice{display:flex;flex-wrap:wrap;gap:8px}
.unit-choice label{
  display:flex;gap:7px;align-items:center;padding:9px 12px;border:1px solid var(--line-strong);
  border-radius:var(--radius-sm);background:var(--tint-3);cursor:pointer;font-size:.8rem;
}
.unit-choice label:has(input:checked){border-color:var(--nav-active-border);background:var(--nav-active-bg);color:var(--ink-strong)}
.unit-choice small{color:var(--ink-2);font-size:.7rem}
@media (max-width:760px){
  .product-grid{grid-template-columns:1fr}
  .batch-line{grid-template-columns:1fr 1fr;gap:6px}
  .batch-line .bqty{text-align:left}
}

/* ======================= KARTU MENGAMBANG (SHEET) ====================== */
/* Dipakai untuk SEMUA penginputan baru: form dibuka sebagai satu kartu
   mengambang di atas halaman dengan latar diblur. */
/* Kartu mengambang: kartu = kolom flex setinggi layar; HANYA isi kartu yang
   menggulir, sehingga kepala & kaki kartu selalu terlihat (tidak "stuck"). */
.sheet-backdrop{
  position:fixed;inset:0;z-index:70;
  background:rgba(4,8,14,.62);
  display:none;align-items:center;justify-content:center;
  padding:20px;contain:strict;overscroll-behavior:contain;
}
.sheet-backdrop.is-open{display:flex}
html[data-theme="light"] .sheet-backdrop{background:rgba(28,40,70,.34)}
.sheet-card{
  width:min(1080px,100%);max-height:calc(100dvh - 40px);
  display:flex;flex-direction:column;min-height:0;
  background:var(--pop-bg);border:1px solid var(--line-strong);
  border-radius:var(--radius);
  box-shadow:0 8px 20px -14px rgba(0,0,0,.72);
  /* Tanpa animasi masuk pada KARTU. Terukur: adanya `animation` pada
     `.sheet-card` (walau hanya opacity dan sudah selesai) membuat isi kartu
     dicat ulang tiap frame saat digulir → 4 frame jatuh per 57 frame.
     Fade-in dipindah ke LATAR (`.sheet-backdrop.is-open`), yang jauh lebih
     murah dan secara visual tetap halus. */
  animation:none;contain:layout paint;
}
/* ⚠️ JANGAN memberi `animation` pada `.sheet-backdrop`/`.sheet-card`.
   Terukur: adanya animasi (walau hanya opacity & sudah selesai) membuat
   compositor mengecat ulang tumpukan kartu setiap frame saat isi kartu digulir
   → 4–14 frame jatuh. Tanpa animasi: 0 frame jatuh (desktop & HP 390px). */
/* ⚠️ Animasi masuk kartu HANYA mengubah OPACITY (bukan transform).
   Keyframes lama memakai `transform:translateY(12px) scale(.99)`; transform
   memaksa kartu berada di layer terpisah dan setelah animasi selesai
   kombinasinya dengan `contain:layout paint` membuat isi kartu dicat ulang
   setiap frame saat digulir — terukur 4 frame jatuh per 57 frame, dan pada
   layar HP 390px 14 dari 49 frame. Dengan fade saja: 0 frame jatuh
   (3x pengukuran desktop + mobile). Jangan kembalikan transform di sini. */
@keyframes sheetCardIn{from{opacity:.55}to{opacity:1}}
.sheet-card.narrow{width:min(620px,100%)}
.sheet-card.wide{width:min(1320px,100%)}
.sheet-head{
  display:flex;align-items:flex-start;justify-content:space-between;gap:16px;
  padding:16px 20px;border-bottom:1px solid var(--line);flex:0 0 auto;
  background:var(--pop-bg);border-radius:var(--radius) var(--radius) 0 0;
}
.sheet-head h2{font-size:1.04rem;color:var(--ink-strong)}
.sheet-head .muted{display:block;margin-top:3px}
.sheet-body{
  padding:18px 20px;display:flex;flex-direction:column;gap:16px;
  flex:1 1 auto;min-height:0;overflow-y:auto;overscroll-behavior:contain;
  -webkit-overflow-scrolling:touch;
}
/* Latar diblur HANYA pada lapisan ini. Dulu blur 5px pada seluruh layar tetap
   membebani compositor saat isi kartu digulir (ukuran: rata-rata 30,4 ms/frame,
   10 frame jatuh pada kartu nota) — sekarang blur dibuat lebih tipis + gradasi
   gelap agar kesan "kaca" tetap ada tapi tetap lancar. */
/* ⚠️ JANGAN pasang `backdrop-filter` di sini. Blur seluas layar memaksa komposit
   ulang setiap frame sehingga menggulir isi kartu terasa "nge-frame" (terukur
   rata-rata 22,2 ms/frame dengan 5 frame jatuh; setelah blur dihapus turun ke
   ~16 ms/frame tanpa frame jatuh). Kesan kaca tetap didapat dari gradien redup
   di bawah ini + latar kartu yang pekat (--pop-bg). */
.sheet-backdrop::before{
  content:"";position:absolute;inset:0;
  /* WARNA DATAR, bukan radial-gradient. Gradien seluas layar harus dicat ulang
     tiap frame saat isi kartu digulir (terukur 4–6 frame jatuh per 60 frame);
     dengan warna datar hasilnya 0 frame jatuh dan tampilan gelapnya sama. */
  background:rgba(4,8,14,.46);
  pointer-events:none;contain:strict;
}
html[data-theme="light"] .sheet-backdrop::before{
  background:rgba(28,40,70,.30);
}
/* Selama menggulir, blur latar dimatikan supaya compositor tidak bekerja tiap
   frame (kartu panjang: 50,6 ms → ~16 ms per frame). Tampilan saat diam tetap
   sama karena kelas ini hanya hidup selama gulir berlangsung. */
body.is-scrolling .sheet-backdrop::before{
  -webkit-backdrop-filter:none;backdrop-filter:none;
}
.sheet-card{position:relative;z-index:1}
.sheet-foot{
  display:flex;gap:10px;flex-wrap:wrap;align-items:center;justify-content:flex-end;
  padding:13px 20px;border-top:1px solid var(--line);flex:0 0 auto;
  background:var(--pop-bg);border-radius:0 0 var(--radius) var(--radius);
}
.sheet-open-btn{cursor:pointer}
body.sheet-locked{overflow:hidden}

/* Kode di dalam KARTU (kode produk, kode batch, kode nota, kode supplier, kode
   bahan, kode resep) memakai --code-ink: HITAM PEKAT di tema terang dan putih di
   tema gelap — hitam di atas latar gelap tidak terbaca, jadi warnanya memang harus
   berbeda per tema (pola sama seperti --head-ink pada judul kartu). */
.lab-card .bcode,
.lab-card h2.mono,
.lab-card .purchase-head h2,
.lab-card .supplier-head h2,
.lab-card .code-ink,
.lab-card .chip.mono,
.lab-card .chip .mono,
.lab-card .pill.mono,
.lab-card .pill.code,
.lab-card td.code-ink,
.lab-card .supplier-code,
.lab-card .recipe-code{
  color:var(--code-ink);
}
.lab-card .chip.mono,.lab-card .chip .mono{background:var(--chip-bg)}

/* Judul kartu dibuat tegas (hitam di tema terang, nyaris putih di tema gelap) */
/* Semua judul kartu (h2) memakai --head-ink: hitam pekat di tema terang,
   putih di tema gelap (hitam di atas latar gelap tidak terbaca). */
h2,.card-head h2,.product-head h2,.recipe-card .card-head h2,.sheet-head h2,
.lab-card > .card-head > h2,.lab-card > .card-head > div > h2,.modal-head h3,
.forbidden-card h2,.product-card h2{
  color:var(--head-ink);font-weight:700;
}
html[data-theme="light"]{ --ink-strong:#04102A; }
.card-head .muted small,.card-head span.muted{color:var(--ink-2)}

/* KPI yang bisa diklik (menu kategori) */
.kpi-link{text-decoration:none;transition:.16s}
.kpi-link:hover{border-color:var(--focus-border);transform:translateY(-1px)}
.kpi-active{border-color:var(--nav-active-border);background:var(--nav-active-bg)}

/* ================= TABEL KOMPOSISI RESEP (REDESAIN) ==================== */
.recipe-table{min-width:0;table-layout:fixed;width:100%}
.recipe-table thead th{
  font-size:.66rem;letter-spacing:.06em;padding:10px 8px;white-space:normal;line-height:1.25;
  vertical-align:bottom;
}
.recipe-table td{padding:9px 8px;vertical-align:top}
.recipe-table .col-bahan{width:23%}
.recipe-table .col-qty{width:9%}
.recipe-table .col-unit{width:13%}
.recipe-table .col-factor{width:12%}
.recipe-table .col-used{width:11%}
.recipe-table .col-price{width:11%}
.recipe-table .col-sub{width:14%}
.recipe-table .col-note{width:12%}
.recipe-table .col-act{width:5%}
.recipe-table tfoot th{font-size:.8rem;padding:11px 10px}
.cell-stack{display:flex;flex-direction:column;gap:5px;min-width:0}
.cell-stack .hint{font-size:.66rem;color:var(--ink-2);line-height:1.3}
.recipe-table input,.recipe-table select,.recipe-table .unit-input{
  width:100%;padding:8px 9px;font-size:.82rem;min-width:0;
}
.recipe-table .factor-input{font-family:var(--mono)}
.recipe-table .num-cell{text-align:right;font-family:var(--mono);font-size:.83rem;padding-top:12px;white-space:nowrap}
.recipe-table .num-cell small{display:block;font-size:.66rem;color:var(--ink-2);font-family:inherit}
.recipe-table .money-cell{text-align:right;font-family:var(--mono);font-size:.83rem;padding-top:12px;white-space:nowrap}
.recipe-table tbody tr{border-bottom:1px solid var(--row-border)}
.recipe-table tbody tr:hover{background:var(--tint-hover)}
.recipe-table .mat-select{font-size:.8rem}
.recipe-table .btn-del{padding:6px 10px;line-height:1}
@media (max-width:900px){
  .recipe-table{min-width:820px}
}

/* angka uang & jumlah pada tabel resep: jangan sampai terpotong/wrap */
.recipe-table .money-cell,.recipe-table .num-cell{overflow-wrap:anywhere;line-height:1.35}
.recipe-table .money-cell{font-variant-numeric:tabular-nums}

/* ============ PEMBELIAN NON-PRODUKSI (kategori di menu Pembelian) ======= */
/* Baris nota berbentuk KARTU, bukan baris tabel lebar: kolom melipat otomatis
   sehingga nyaman dipakai dari HP (permintaan pemilik — modul ini paling sering
   dipakai lewat ponsel). */
.expense-lines{display:grid;gap:14px}
.expense-lines-body{display:grid;gap:14px}
.exp-line{
  display:grid;gap:12px;padding:14px 16px;border:1px solid var(--line);
  border-radius:var(--radius-sm);background:var(--tint-3);
}
.exp-line-head{display:flex;align-items:center;justify-content:space-between;gap:10px}
.exp-line-head .exp-line-num{text-transform:uppercase;letter-spacing:.12em;font-size:.64rem;font-weight:600}
.exp-line-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:12px}
.exp-line-grid .field.span-2{grid-column:1 / -1}
.exp-line-foot{display:flex;align-items:baseline;justify-content:space-between;gap:10px;
  padding-top:10px;border-top:1px dashed var(--line-strong)}
.exp-line-sub{font-variant-numeric:tabular-nums}
/* Chip saran harga: ringkas, bisa diklik untuk memakai harganya. */
.exp-suggest{display:flex;flex-wrap:wrap;gap:8px;align-items:center}
.exp-suggest:empty{display:none}
.chip-use{
  margin-left:8px;padding:1px 7px;border-radius:20px;border:1px solid var(--line-strong);
  background:var(--btn-bg);color:var(--ink-strong);font:inherit;font-size:.68rem;font-weight:600;cursor:pointer;
}
.chip-use:hover{background:var(--btn-bg-hover)}
/* Daftar saran pembelian (satu kolom, nyaman di HP) */
.suggest-list{display:grid;gap:12px}
.suggest-row{
  display:flex;align-items:center;gap:14px;justify-content:space-between;
  padding:12px 14px;border:1px solid var(--line);border-radius:var(--radius-sm);background:var(--tint-3);
}
.suggest-main{display:flex;flex-direction:column;gap:4px;min-width:0}
.suggest-main strong{font-size:.86rem}
.suggest-chips{display:flex;flex-wrap:wrap;gap:6px;margin-top:2px}
.suggest-chips .chip{font-size:.7rem}
@media (max-width:640px){
  .exp-line{padding:12px 13px}
  .exp-line-grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}
  .exp-line-grid .field:first-child{grid-column:1 / -1}
  .suggest-row{align-items:flex-start;flex-direction:column}
  .suggest-row > .btn{width:100%;justify-content:center}
}
/* ---- Daftar SARAN PEMBELIAN (tab tersendiri) ----
   Baris ringkas & padat: nama + meta (supplier/langgal/frekuensi) + harga, dengan
   tombol "Beli Lagi". Satu kolom supaya nyaman dipakai dari HP. */
.order-list{display:grid;gap:10px}
.order-row{
  display:grid;grid-template-columns:minmax(0,1fr) auto auto;gap:14px;align-items:center;
  padding:12px 14px;border:1px solid var(--line);border-radius:var(--radius-sm);background:var(--tint-3);
}
.order-main{display:flex;flex-direction:column;gap:5px;min-width:0}
.order-name{display:flex;align-items:center;gap:8px;font-size:.86rem;font-weight:600;color:var(--ink-strong)}
.order-name .tag-jasa{
  font-size:.62rem;text-transform:uppercase;letter-spacing:.06em;font-weight:700;
  padding:2px 7px;border-radius:20px;border:1px solid var(--info-bd);background:var(--info-bg);color:var(--info-fg);
}
.order-meta{display:flex;flex-wrap:wrap;gap:10px;font-size:.72rem;color:var(--ink-2)}
.order-price{display:flex;flex-direction:column;align-items:flex-end;gap:2px;text-align:right}
.order-price strong{font-size:.9rem}
.order-price small{font-size:.68rem}
@media (max-width:760px){
  .order-row{grid-template-columns:minmax(0,1fr) auto;gap:8px 12px}
  .order-price{grid-column:1;align-items:flex-start;text-align:left;flex-direction:row;flex-wrap:wrap;gap:8px}
  .order-btn{grid-column:2;grid-row:1 / span 2;align-self:center}
}

/* Ringkasan item pada kartu daftar non-produksi
   TIGA kolom: nama item · JUMLAH (qty + satuan) · nilai (permintaan pemilik).
   Nilai tetap rata kanan, kolom jumlah di tengah. */
.expense-preview{list-style:none;margin:12px 0 0;padding:0;display:flex;flex-direction:column;gap:6px}
.expense-preview li{display:grid;grid-template-columns:minmax(0,1fr) minmax(64px,auto) auto;gap:10px;
  align-items:baseline;
  font-size:.8rem;padding:7px 10px;border-radius:var(--radius-sm);background:var(--tint-3);border:1px solid var(--line)}
.expense-preview li span{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.expense-preview li b{flex:0 0 auto;white-space:nowrap}
/* Kolom JUMLAH: tegas (bukan abu-abu) tapi lebih ringan dari nominal. */
.expense-preview li b.li-qty{text-align:right;font-weight:600;color:var(--ink-2)}
.expense-preview li > b:last-child{text-align:right}
/* Kartu total (subtotal/diskon/pajak/total) di kartu rincian */
.total-card.is-total{border-color:var(--accent-line,var(--line-strong))}

/* ====================== KARTU BATCH PRODUKSI ============================= */
.batch-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(440px,1fr));gap:22px}
.batch-card .product-hero{grid-template-columns:repeat(auto-fit,minmax(120px,1fr))}
.batch-card .chip-row .chip{font-size:.7rem}
@media (max-width:760px){
  .batch-grid{grid-template-columns:1fr}
}


/* ==========================================================================
   PENEGASAN KONTROL FORM (ditaruh paling akhir agar tidak ditimpa aturan
   tabel/komponen yang lebih dulu ditulis). Mengatur combobox (select) dan
   spinbutton (input angka) yang berada di dalam tabel, popup, maupun kartu.
   ========================================================================== */
table.data select,
table.data input[type=number],
.recipe-table select,
.recipe-table input[type=number],
.pop-body select,
.pop-body input[type=number],
.pack-row select,
.pack-row input[type=number]{
  min-height:36px;
}
/* combobox: hilangkan panah bawaan, pakai chevron sendiri */
select{
  -webkit-appearance:none;appearance:none;
  background-image:var(--select-caret);
  background-repeat:no-repeat;
  background-position:right 9px center;
  background-size:var(--select-caret-size);
  padding-right:30px;
  cursor:pointer;
}
table.data select,.pop-body select,.pack-row select{padding-right:28px}
/* select berkutip kelas khusus (mis. .unit-input) menang atas aturan tabel */
.recipe-table select.unit-input,.recipe-table select.mat-select,
table.data select.unit-input,table.data select.mat-select{padding-right:28px}
.num-wrap>input.qty-input,.num-wrap>input.qty-pick,.num-wrap>input.pack-qty{padding-right:30px}
/* spinbutton: ruang untuk stepper −/+ di sisi kanan */
.num-wrap>input{padding-right:30px}
.num-wrap>input[type=number]{text-align:right}
.num-wrap>input.ta-l,.num-wrap>input.text-left{text-align:left}
/* input tanggal di dalam tabel: ikut ukuran kontrol lain */
table.data input[type=date]{min-height:36px;padding:7px 9px;font-size:.8rem}
/* textarea mengikuti bahasa visual kontrol lain */
textarea{background:var(--input-bg);border:1px solid var(--line-strong);color:var(--ink);
  border-radius:var(--radius-sm);font-family:inherit;font-size:.87rem;padding:10px 12px;
  width:100%;resize:vertical;min-height:84px;
  transition:border-color .14s ease,box-shadow .14s ease}
textarea:focus{outline:none;border-color:var(--focus-border);box-shadow:0 0 0 3px var(--focus-ring)}

/* ============ JUDUL KARTU PRODUK / BATCH (termasuk h2.mono) ==============
   Judul kartu Produk Jadi & Batch Produksi dibuat tegas: hitam pekat di tema
   terang (--head-ink = #000000), dan tetap terang di tema gelap — hitam di atas
   latar gelap kontrasnya ~1,2:1 sehingga tidak terbaca. */
.lab-card.product-card h2,
.lab-card.product-card h2.mono,
.lab-card.product-card.batch-card h2,
.lab-card.product-card.batch-card h2.mono,
.product-head h2,
.product-head h2.mono{
  color:var(--head-ink);font-weight:700;
}

/* ================== RINGKASAN SINKRONISASI & RIWAYAT ==================== */
.sync-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(132px,1fr));gap:12px;margin-bottom:14px}
.sync-grid>div{padding:11px 13px;border:1px solid var(--line);border-radius:var(--radius-sm);background:var(--tint-3)}
.sync-grid>div span{display:block;font-size:.68rem;text-transform:uppercase;letter-spacing:.07em;color:var(--ink-2)}
.sync-grid>div b{display:block;font-family:var(--mono);font-size:1.02rem;margin-top:3px;color:var(--ink-strong)}
.sync-grid>div small{font-size:.68rem;color:var(--ink-2)}
.sync-ok{border-color:var(--ok-bd)!important;background:var(--ok-bg)!important}
.sync-warn{border-color:var(--warn-bd)!important;background:var(--warn-bg)!important}
.hist-head{
  display:flex;align-items:center;justify-content:space-between;gap:10px;flex-wrap:wrap;
  margin:16px 0 8px;padding-bottom:6px;border-bottom:1px solid var(--line);
}
.hist-head h4{margin:0;font-size:.82rem;letter-spacing:.02em;color:var(--ink-strong)}
.hist-head .muted{font-size:.72rem}
.move-list{display:flex;flex-direction:column;gap:8px}
.move-item{
  /* Kolom status dibuat `auto` (bukan lebar tetap 96px): label status bisa panjang
     ("Menunggu Persetujuan" = 125px), dan dengan kolom tetap teksnya MELUBER menimpa
     nomor RP/PO di sebelahnya (bug tumpang tindih yang dilaporkan pemilik). */
  display:grid;grid-template-columns:118px auto minmax(0,1fr) auto;gap:10px;align-items:center;
  padding:9px 11px;border:1px solid var(--line);border-radius:var(--radius-sm);background:var(--tint-3);font-size:.79rem;
}
/* Status di baris ringkas tidak boleh melebar tanpa batas (mis. nama status panjang). */
.move-item > .pill{justify-self:start;max-width:100%}
.move-item .mv-time{font-family:var(--mono);font-size:.72rem;color:var(--ink-2)}
.move-item .mv-main{min-width:0}
.move-item .mv-main strong{display:block;font-size:.81rem;color:var(--ink-strong)}
.move-item .mv-main small{display:block;color:var(--ink-2);font-size:.7rem}
.move-item .mv-qty{text-align:right;font-family:var(--mono);white-space:nowrap}
.move-item .mv-qty small{display:block;font-size:.68rem;color:var(--ink-2);font-family:inherit}
.move-item.is-batch{border-color:var(--ok-bd)}
.move-item.is-other{border-color:var(--warn-bd);background:var(--warn-row)}
@media (max-width:760px){
  .move-item{grid-template-columns:minmax(0,1fr) auto;gap:6px;align-items:start}
  .move-item .mv-time{grid-column:1 / -1}
  /* Status berada di kolom kanan (sejajar tombol) supaya tidak menumpuk teks. */
  .move-item > .pill{grid-column:2;grid-row:1;justify-self:end}
  .move-item .mv-main{grid-column:1 / -1}
}

/* ============ DAFTAR MUTASI STOK = SATU KARTU PER MUTASI ==================
   Permintaan pemilik: daftar mutasi di HP harus membentuk SATU KARTU per mutasi
   (dulu tabel lebar yang harus digeser kiri-kanan), mengikuti tampilan "Riwayat
   Mutasi Batch" pada kartu Batch Produksi (.move-item.is-batch).
   Isi tetap lengkap supaya penelusuran mutasi di kemudian hari tidak kehilangan
   apa pun: jenis mutasi, waktu, item + kode, jumlah + satuan, NILAI, Rujukan
   (nota/batch/manual), asal baris, keterangan, lampiran foto, pencatat, dan
   penanda "pernah diubah". */
.stock-move-list{display:flex;flex-direction:column;gap:10px}
.smv-card{
  display:grid;gap:8px;padding:11px 13px;border:1px solid var(--line);
  border-radius:var(--radius-sm);background:var(--tint-3);font-size:.79rem;
}
.smv-card.is-locked{border-style:dashed}
.smv-head{display:flex;flex-wrap:wrap;align-items:center;gap:6px 12px}
.smv-head .smv-time{font-family:var(--mono);font-size:.72rem;color:var(--ink-2)}
.smv-head .smv-src{font-size:.72rem;color:var(--ink-2)}
.smv-body{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:10px;align-items:start}
.smv-item{min-width:0}
.smv-item strong{display:block;font-size:.86rem;color:var(--ink-strong)}
.smv-item small{display:block;font-size:.72rem;color:var(--ink-2)}
.smv-item .smv-note{font-style:italic}
/* Kolom KANAN kartu mutasi: pil jenis mutasi (Masuk / Keluar / …) sejajar DI ATAS
   jumlah. Dipindah ke sini dari kepala kartu (permintaan pemilik) supaya arah
   stok langsung terbaca satu pandangan dengan angkanya. */
.smv-right{display:flex;flex-direction:column;align-items:flex-end;gap:5px;min-width:0}
.smv-right .pill{align-self:flex-end}
.smv-right .badge{align-self:flex-end}
.smv-qty{text-align:right;font-family:var(--mono);white-space:nowrap;font-size:.9rem}
.smv-qty .smv-unit{font-size:.76rem;color:var(--ink-2)}
.smv-qty small{display:block;font-size:.7rem;font-family:inherit;color:var(--ink-2)}
.smv-meta{display:flex;flex-wrap:wrap;gap:4px 16px;font-size:.72rem;color:var(--ink-2)}
.smv-meta strong{color:var(--code-ink)}
.smv-foot{display:flex;flex-wrap:wrap;align-items:center;gap:8px}
.smv-foot .row-actions{margin-left:auto}
.smv-foot form{margin:0}
.smv-locked{font-size:.72rem;color:var(--ink-3)}
.smv-photo .photo-thumb{width:46px;height:46px}
@media (max-width:760px){
  .smv-card{padding:12px;gap:9px}
  /* Tombol aksi memenuhi lebar kartu di HP supaya mudah ditekan (target sentuh). */
  .smv-foot .row-actions{margin-left:0;width:100%}
  .smv-foot .row-actions .btn{flex:1 1 auto;justify-content:center}
}

/* ==================== RINCIAN BIAYA TAMBAHAN BATCH ======================= */
/* Biaya tambahan diisi satu per satu (tenaga kerja, listrik, transport, …)
   lewat kartu mengambang "+ Tambah Biaya"; tiap baris punya jenis, jumlah,
   keterangan, dan bisa dihapus. Ditaruh paling akhir agar tidak tertimpa
   aturan tabel/komponen yang lebih dulu ditulis.
   Catatan spesifisitas (pernah kena): `table.data.compact` menetapkan
   min-width 520px & padding sel dengan bobot 0,2 — jadi seluruh aturan di sini
   memakai `table.data.cost-table` (0,2) supaya benar-benar menimpa. */
.is-hidden{display:none!important}
/* lebar kolom tetap (table-layout:fixed) supaya pilihan panjang tidak
   melebarkan tabel keluar dari kartu */
table.data.cost-table{table-layout:fixed;width:100%;min-width:0;font-size:.82rem}
table.data.cost-table .col-jenis{width:34%}
table.data.cost-table .col-jumlah{width:29%}
table.data.cost-table .col-act{width:42px}
table.data.cost-table td{padding-top:9px;padding-bottom:9px;vertical-align:top}
table.data.cost-table .cost-pick,
table.data.cost-table .cost-label,
table.data.cost-table .cost-note,
table.data.cost-table .cost-amount{width:100%;max-width:none;min-width:0}
table.data.cost-table .cost-label{margin-top:6px}
table.data.cost-table tfoot th{font-size:.8rem}
/* di layar sempit tiap baris biaya ditumpuk (label kolom disembunyikan) agar
   kolom jenis biaya + jumlah tetap lega */
@media (max-width:760px){
  table.data.cost-table,
  table.data.cost-table tbody,
  table.data.cost-table tfoot,
  table.data.cost-table tr.cost-row{display:block;width:auto;min-width:0}
  table.data.cost-table thead{display:none}
  table.data.cost-table tr.cost-row{padding:10px 0;border-bottom:1px solid var(--row-border)}
  table.data.cost-table tr.cost-row:last-child{border-bottom:none}
  table.data.cost-table td{display:block;width:auto;padding:3px 0;border:none}
  table.data.cost-table tfoot tr{display:flex;gap:10px;align-items:center;justify-content:space-between;padding:8px 0}
  table.data.cost-table tfoot th{width:auto}
  table.data.cost-table td.ta-c{text-align:left}
}

/* Kolom yang tidak relevan untuk jenis mutasi tertentu (mis. batch saat opname) */
.field.is-dim{opacity:.5}
.field.is-dim select{cursor:not-allowed}

/* ================== BARIS ALAT (toolbar) & PENCARIAN ==================== */
/* Pencarian/filter/tombol tindakan ditaruh di baris ini — BUKAN di dalam
   .card-head (flex-nya bikin kontrol berdesakan & info hasil filter menumpuk
   dengan judul kartu).
   Aturan ukuran (menggantikan aturan lama yang membuat kolom cari kecil):
     - kolom pencarian SELALU tumbuh mengisi ruang kosong  → flex:1 1 260px,
     - dropdown/tanggal punya basis sendiri supaya rapi membungkus,
     - tombol & centang tidak ikut melar.
   Di layar ≤640px semuanya ditumpuk penuh (kontrol 1–2 per baris). */
.toolbar{
  display:flex;flex-wrap:wrap;gap:14px;align-items:center;
  margin:0 0 18px;padding:14px 16px;border:1px solid var(--line);
  border-radius:var(--radius-sm);background:var(--tint-3);
}
.toolbar > *{min-width:0;max-width:100%}
/* Pengaman: bila .toolbar masih berada di dalam .card-head (flex), paksa jadi
   baris penuh supaya tidak diperas jadi ~160px oleh flex-shrink. */
.card-head > .toolbar{flex:1 1 100%;width:100%;min-width:0;margin-bottom:0}
.toolbar > form,
.toolbar > .search{flex:1 1 100%;min-width:0}
.toolbar .live-count{margin-top:-4px}
.toolbar .btn{flex:0 0 auto;white-space:nowrap}

.search{display:flex;flex-wrap:wrap;gap:10px;align-items:center;width:100%;min-width:0}
.search > *{min-width:0;max-width:100%}
/* kolom pencarian: mengambil seluruh sisa ruang */
.search input[type=search],
.search input[type=text].search-input,
.search input.q-search{
  flex:1 1 260px;width:auto;min-width:0;
}
.search select{flex:0 1 210px;width:auto;min-width:0}
.search input[type=date]{flex:0 1 auto;width:auto;min-width:0}
.search .field.inline{flex:0 1 auto}
.search .check{flex:0 0 auto}
.search .view-choice{flex:0 0 auto;display:flex;align-items:center;gap:8px}
.search .view-choice>span{font-size:.8rem;color:var(--ink-2);font-weight:600;white-space:nowrap}
.search .view-choice select{min-width:150px;flex:0 0 auto}
.search .btn[type=submit],.search .btn[type=button]{flex:0 0 auto}
.filter-hint{flex:1 1 100%;font-size:.76rem;color:var(--ink-2)}
/* hasil filter hidup selalu baris sendiri di dalam toolbar */
.live-count{
  flex:1 1 100%;font-size:.72rem;color:var(--ink-2);
  display:flex;align-items:center;gap:6px;
}
@media (max-width:900px){
  .search select{flex:0 1 180px}
}
@media (max-width:640px){
  .toolbar{padding:12px;gap:10px;margin-bottom:14px;display:block}
  /* Di HP baris pencarian memakai GRID (bukan flex): dengan flex, `flex-basis:100%`
     membuat kontainer melebar mengikuti konten — dropdown dengan pilihan panjang
     (mis. daftar item di Mutasi Stok) menyeret seluruh kartu sampai 800px
     (bug nyata). Grid + min-width:0 mengunci semuanya pada lebar layar. */
  .search{
    display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
    gap:8px;width:100%;align-items:center;
  }
  .search>*{width:100%;min-width:0;max-width:100%}
  .search input[type=search]{grid-column:1 / -1}
  .search .btn[type=submit]{grid-column:1 / -1;width:100%}
  .search .view-choice{grid-column:1 / -1;flex-wrap:wrap;gap:6px}
  .search .view-choice>span{flex:1 1 100%}
  .search .view-choice select{flex:1 1 100%;width:100%;min-width:0}
  .search .check{justify-content:flex-start}
  .search .live-count{grid-column:1 / -1}
  .search select,.search input{text-overflow:ellipsis}
}

/* ================== PENCARIAN HIDUP (LIVE FILTER) SETIAP MENU =========== */
/* Kolom pencarian langsung menyaring daftar yang tampil saat pengguna mengetik
   (tanpa menekan Terapkan). Tombol Terapkan/Tampilkan tetap ada untuk mencari ke
   seluruh data di server. Lihat blok "pencarian hidup" di assets/app.js. */
/* Semua kolom pencarian punya ikon kaca pembesar sendiri + ruang teks yang cukup
   (ikon 14px..31px, teks mulai 44px → jarak 13px, tidak menumpuk). */
.search input[type=search],
.toolbar input[type=search],
.filter-card input[type=search],
input[data-live-filter]{
  background-image:var(--search-icon);
  background-repeat:no-repeat;
  background-position:14px center;
  background-size:17px;
  padding-left:44px;
  padding-right:14px;
}
.filter-card .search input[type=search],
.card-head .search input[type=search]{
  font-size:.95rem;padding:11px 14px 11px 44px;min-height:44px;
}
.filter-card .search input[type=search]{flex:1 1 340px}
.live-count b{color:var(--ink-strong);font-family:var(--mono)}
.is-filtered-out{display:none!important}
tr.live-empty td, p.live-empty{font-size:.8rem}
.saran-kecil{
  display:flex;align-items:center;gap:8px;flex-wrap:wrap;
  margin:0 0 10px;padding:6px 10px;border-radius:var(--radius-sm);
  border:1px dashed var(--nav-active-border);background:var(--nav-active-bg);
  font-size:.74rem;color:var(--ink-2);
}
.saran-kecil strong{color:var(--ink-strong);font-family:var(--mono);font-size:.76rem}
.saran-dot{
  width:7px;height:7px;border-radius:50%;flex:0 0 auto;
  background:linear-gradient(135deg,var(--cyan),#14a38b);
}
.tag-kecil{
  margin-left:6px;font-size:.62rem;letter-spacing:.04em;text-transform:uppercase;
  color:var(--ink-2);border-bottom:1px dotted var(--ink-2);cursor:help;
}
.nowrap{white-space:nowrap}

/* ==================== NOTA PEMBELIAN — TAMPILAN KARTU ==================== */
/* Kartu (detail) untuk menu Pembelian Bahan. Tampilan Tabel ringkas tetap
   memakai desain tabel yang sudah ada (tidak diubah). */
.purchase-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(440px,1fr));gap:22px}
/* Pemilih Rencana Pembelian (langkah 1 alur pembelian): semua pembelian harus
   lewat pengajuan, jadi nota dibuat dari rencana yang sudah disetujui.
   `min(400px,100%)` menjaga kartu tidak meluber di layar HP (≤390px). */
.plan-pick-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(400px,100%),1fr));gap:22px}
.plan-pick-card{gap:14px}
.purchase-card{display:flex;flex-direction:column;gap:16px}
.purchase-head{display:flex;align-items:flex-start;justify-content:space-between;gap:16px}
.purchase-head h2{font-size:1.02rem}
.purchase-hero{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:14px;padding:16px;
  border-radius:var(--radius-sm);border:1px solid var(--line);background:var(--tint-3);
}
.purchase-hero>div span{display:block;font-size:.68rem;text-transform:uppercase;letter-spacing:.07em;color:var(--ink-2)}
.purchase-hero>div b{display:block;font-family:var(--mono);font-size:1rem;margin-top:3px;color:var(--ink-strong)}
.purchase-hero>div small{display:block;font-size:.68rem;color:var(--ink-2);margin-top:2px}
.purchase-items{display:flex;flex-direction:column;gap:8px}
.purchase-items .p-item{
  display:grid;grid-template-columns:minmax(0,1.1fr) minmax(0,1.2fr) auto;gap:10px;align-items:center;
  padding:8px 11px;border:1px solid var(--line);border-radius:var(--radius-sm);
  background:var(--tint-3);font-size:.79rem;
}
.purchase-items .p-item .p-name{min-width:0}
.purchase-items .p-item .p-name small{display:block;font-size:.68rem}
.purchase-items .p-item .p-qty{text-align:right;white-space:nowrap}
.purchase-items .p-item .p-qty small{display:block;font-size:.66rem;font-family:inherit}
.purchase-items .p-item .p-sub{text-align:right;white-space:nowrap;color:var(--ink-strong)}
/* Harga per satuan (mis. "Rp 35.000/kg") = keterangan kecil di bawah subtotal;
   kolom jumlah di sebelahnya hanya memuat "qty + satuan" yang tebal. */
.purchase-items .p-item .p-sub small{display:block;font-size:.66rem;font-family:inherit;font-weight:400;color:var(--ink-3)}
.purchase-photos{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
@media (max-width:760px){
  .purchase-grid{grid-template-columns:1fr}
  .purchase-items .p-item{grid-template-columns:1fr auto;gap:4px}
  .purchase-items .p-item .p-sub{grid-column:2}
}

/* ---- Keterkaitan nota bahan dengan BATCH PRODUKSI & produknya ----
   Kartu kategori "Bahan Baku (Produksi)" menampilkan batch mana yang memakai
   bahan dari nota ini (ditelusuri dari batch_items). */
.usage-block{display:flex;flex-direction:column;gap:6px;margin-top:12px}
.usage-label{font-size:.64rem;letter-spacing:.12em;text-transform:uppercase;color:var(--ink-2);font-weight:700}
.usage-block-none{margin-top:10px}
.usage-block .chip{font-size:.7rem;text-decoration:none}

/* ---------- Kartu mengambang: varian dengan <form> pembungkus ---------- */
/* Dipakai bila seluruh isi kartu adalah form: .sheet-card > form.sheet-form
   > .sheet-body (menggulir) + .sheet-foot (tetap di bawah, DI DALAM kartu).
   Kesalahan lama: .sheet-foot ditulis di luar .sheet-card sehingga tombol
   Simpan melayang di samping kartu (bukan di bawahnya). */
.sheet-form{display:flex;flex-direction:column;flex:1 1 auto;min-height:0}
.sheet-foot .foot-note{flex:1 1 180px;min-width:0}

/* Bagian berjudul di dalam form (memecah isian panjang jadi blok yang jelas) */
.form-section{display:flex;flex-direction:column;gap:12px}
.form-section + .form-section{margin-top:4px;padding-top:16px;border-top:1px solid var(--line)}
.form-section-head{display:flex;align-items:baseline;justify-content:space-between;gap:12px;flex-wrap:wrap}
.form-section-head h3{margin:0;font-size:.82rem;letter-spacing:.02em;color:var(--ink-strong)}
.form-section-head .muted{font-size:.72rem}
.switch-line{
  display:flex;align-items:center;gap:10px;padding:10px 12px;border-radius:var(--radius-sm);
  border:1px solid var(--line);background:var(--tint-3);font-size:.82rem;cursor:pointer;
}
.switch-line span{color:var(--ink)}

/* ============== KETERANGAN BANTUAN (info toggle) ======================= */
/* Teks kecil penjelas di bawah kolom isian / dropdown dan paragraf penjelasan
   panjang bisa disembunyikan lewat tombol "Info" di topbar (preferensi disimpan
   di localStorage 'sentosa-hints' dan diterapkan sebelum CSS dimuat agar tidak
   berkedip). Atribut dipasang di <html> supaya berlaku sebelum <body> ada. */
.btn-hints{gap:8px;min-height:40px;padding:9px 13px}
.btn-hints svg{width:17px;height:17px;fill:currentColor;flex:0 0 17px}
.btn-hints .hints-label{font-size:.76rem;font-weight:600;letter-spacing:.02em}
/* Tombol Info memakai warna aksen saat informasi disembunyikan supaya jelas
   ada yang berubah (dan mudah ditemukan untuk dinyalakan kembali). */
html[data-hints="off"] .btn-hints{border-color:var(--nav-active-border);background:var(--nav-active-bg)}
html[data-hints="off"] .btn-hints .hints-label{text-decoration:line-through}
@media (max-width:520px){ .btn-hints .hints-label{display:none} }

/* Cakupan tombol Info: menyembunyikan teks PENJELAS/PENDUKUNG saja —
   keterangan di bawah kolom isian, subjudul kartu, catatan kaki, label kecil
   statistik, dan badge petunjuk. Nilai utama (angka, isi sel tabel, judul,
   nama kolom) TETAP tampil supaya tidak ada data yang hilang. */
html[data-hints="off"] .info-hint,
html[data-hints="off"] .cell-stack .hint,
html[data-hints="off"] .field > small.muted,
html[data-hints="off"] .sub-head .muted.small,
html[data-hints="off"] .field small,
html[data-hints="off"] .field .hint,
html[data-hints="off"] p.muted.small,
html[data-hints="off"] .card-head .muted,
html[data-hints="off"] .card-head small.muted,
html[data-hints="off"] .form-section-head > .muted,
html[data-hints="off"] .sub-head > .muted,
html[data-hints="off"] .sub-head .muted.small,
html[data-hints="off"] .foot-note,
html[data-hints="off"] .filter-hint,
html[data-hints="off"] .note-line,
html[data-hints="off"] .live-count,
html[data-hints="off"] .badge-soft,
html[data-hints="off"] .money-notice,
html[data-hints="off"] .kpi-foot,
html[data-hints="off"] .mini-stats small,
html[data-hints="off"] .metric-row small,
html[data-hints="off"] .product-hero small,
html[data-hints="off"] .sync-grid > div small,
html[data-hints="off"] caption{
  display:none!important;
}
/* PENGECUALIAN: keterangan yang berisi NILAI/hasil hitung (bukan tulisan
   penjelas) TETAP tampil walau info dimatikan — mis. "1 galon = 19 liter",
   "stok setelah mutasi", atau satuan dari Master Kategori. Elemennya ditandai
   `data-live-hint` oleh markup/JS. */
html[data-hints="off"] [data-live-hint],
html[data-hints="off"] [data-live-hint] *{
  display:revert!important;
}
html[data-hints="off"] .field small[data-live-hint],
html[data-hints="off"] .field [data-live-hint]{display:block!important}

/* ============ DROPDOWN YANG BISA DICARI DENGAN KEYBOARD ==================
   `<select>` asli tetap ada (nilainya yang dikirim ke server) dan disembunyikan
   oleh .cs-native; di atasnya dipasang tombol tampilan + daftar pilihan yang
   bisa diketik untuk menyaring. Daftarnya dirender di <body> (`.cs-pop`) supaya
   tidak terpotong `contain: paint` kartu mengambang.
   ⚠️ Ukuran `.cs-btn` mengikuti aturan yang dulu berlaku untuk `<select>` —
   kalau tidak, dropdown di baris filter akan melar memenuhi lebar. */
.search .cs-btn{flex:0 1 210px;width:auto;min-width:132px}
.filter-card .search .cs-btn{flex:0 0 auto}
.toolbar .cs-btn,.search .cs-btn{max-width:100%}
@media (max-width:900px){ .search .cs-btn{flex:0 1 180px} }
.field .cs-btn{width:100%}
td .cs-btn,th .cs-btn{width:100%}
.plan-row .cs-btn,.recipe-row .cs-btn,.pack-row .cs-btn{width:100%}
.cs-native{
  position:absolute!important;width:1px!important;height:1px!important;padding:0!important;margin:0!important;
  border:0!important;opacity:0!important;clip-path:inset(50%)!important;pointer-events:none!important;
}
.cs-btn{
  display:flex;align-items:center;justify-content:space-between;gap:8px;width:100%;
  padding:9px 30px 9px 11px;border-radius:var(--radius-sm);border:1px solid var(--input-border,var(--line-strong));
  background:var(--input-bg);color:var(--ink);font:inherit;font-size:.82rem;text-align:left;cursor:pointer;
  position:relative;min-height:38px;
}
.cs-btn:hover{border-color:var(--focus-border)}
.cs-btn:focus-visible{outline:2px solid var(--focus-border);outline-offset:1px}
.cs-btn .cs-label{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.cs-btn.is-empty .cs-label{color:var(--ink-3)}
.cs-btn .cs-caret{
  position:absolute;right:9px;top:50%;transform:translateY(-50%);
  width:16px;height:16px;fill:var(--select-caret,currentColor);opacity:.85;flex:0 0 16px;
}
.cs-pop{
  position:fixed;z-index:120;background:var(--pop-bg);border:1px solid var(--line-strong);
  border-radius:var(--radius-sm);box-shadow:0 24px 60px -24px rgba(0,0,0,.85);overflow:hidden;
}
.cs-pop-search{padding:8px;border-bottom:1px solid var(--line)}
.cs-pop-search input{
  width:100%;padding:9px 11px;font-size:.84rem;border-radius:var(--radius-sm);
  border:1px solid var(--line-strong);background:var(--input-bg);color:var(--ink);
}
.cs-list{list-style:none;margin:0;padding:6px;overflow-y:auto;overscroll-behavior:contain;max-height:320px}
.cs-opt{
  display:flex;align-items:center;justify-content:space-between;gap:10px;
  padding:9px 11px;border-radius:var(--radius-sm);font-size:.82rem;cursor:pointer;
}
.cs-opt.is-active{background:var(--tint-hover)}
.cs-opt.is-selected{background:var(--nav-active-bg);color:var(--ink-strong);font-weight:600}
.cs-opt.is-selected::after{content:'✓';font-size:.8rem;opacity:.9}
.cs-group{
  padding:8px 11px 4px;font-size:.64rem;letter-spacing:.12em;text-transform:uppercase;
  color:var(--ink-3);font-weight:700;
}
.cs-empty{padding:12px;font-size:.78rem;color:var(--ink-2);text-align:center}
/* Di dalam baris filter, tombol cari harus sejajar dengan kontrol lain */
.search .cs-wrap,.toolbar .cs-wrap{min-width:0}
.filter-card .search .cs-btn{min-height:38px}
@media (max-width:640px){
  .cs-btn{min-height:44px;font-size:16px}
  .cs-pop-search input{font-size:16px}
}

/* ============ TOMBOL PEMBUKA KARTU PENCARIAN / FILTER (semua modul) =======
   Kartu filter disembunyikan default supaya tampilan ringkas; tombol ini
   membukanya. Dibuat oleh assets/app.js, jadi semua modul seragam. */
/* Jarak tombol [Pencarian] DIJAGA (dulu `margin-bottom:-8px` membuat tombol
   menempel/terlihat bertumpuk dengan tombol di atasnya, terutama pada Master
   Kategori yang kepala kartunya juga punya tombol di kanan). Sekarang jaraknya
   eksplisit dan diberi garis pemisah halus bila berada DI DALAM kartu. */
.search-toggle-bar{display:flex;justify-content:flex-end;margin:0}
/* Di dalam kartu: beri jarak dari kepala kartu + garis pemisah supaya tidak
   berdesakan dengan tombol "+ …" yang juga rata kanan. */
.lab-card > .search-toggle-bar{margin:12px 0 14px;padding-top:12px;border-top:1px dashed var(--line)}
/* Sebagai anak .content (flex dengan gap): jarak sudah diatur gap flex. */
.content > .search-toggle-bar{margin:0}
.btn-search-toggle{display:inline-flex;align-items:center;gap:8px}
.btn-search-toggle svg{width:15px;height:15px;fill:currentColor;opacity:.9}
.btn-search-toggle.is-open{border-color:var(--nav-active-border);background:var(--nav-active-bg);color:var(--ink-strong)}
/* Tombol menandai ada filter yang sedang AKTIF (angka di kanan) — kartunya sendiri
   tetap tertutup sampai pengguna menekannya. */
.btn-search-toggle.has-filter{border-color:var(--focus-border)}
.btn-search-toggle .count-chip{margin-left:2px}
.filter-card.is-collapsed,.toolbar.is-collapsed{display:none!important}
@media (max-width:640px){
  .search-toggle-bar{justify-content:stretch}
  .lab-card > .search-toggle-bar{margin:10px 0 12px}
  .btn-search-toggle{width:100%;justify-content:center}
}

/* ======================= KARTU SUPPLIER (master) ======================== */
.supplier-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(420px,1fr));gap:22px}
.supplier-card{display:flex;flex-direction:column;gap:16px}
.supplier-card.is-off{opacity:.72}
.supplier-head{display:flex;align-items:flex-start;justify-content:space-between;gap:16px}
.supplier-head h2{font-size:1.02rem}
.supplier-hero{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:14px;padding:16px;
  border-radius:var(--radius-sm);border:1px solid var(--line);background:var(--tint-3);
}
.supplier-hero>div span{display:block;font-size:.68rem;text-transform:uppercase;letter-spacing:.07em;color:var(--ink-2)}
.supplier-hero>div b{display:block;font-family:var(--mono);font-size:1rem;margin-top:3px;color:var(--ink-strong)}
.supplier-hero>div small{display:block;font-size:.68rem;color:var(--ink-2);margin-top:2px;overflow-wrap:anywhere}
@media (max-width:760px){ .supplier-grid{grid-template-columns:1fr} }

/* Kontrol isian + tombol sejajar (mis. pilih supplier + "+ Supplier Baru") */
.input-with-btn{display:flex;gap:8px;align-items:stretch;flex-wrap:wrap}
.input-with-btn > select,.input-with-btn > input{flex:1 1 200px;min-width:0}
.input-with-btn > .btn{flex:0 0 auto;white-space:nowrap}

/* ==========================================================================
   RESPONSIVE & MOBILE  (ditaruh paling akhir agar menimpa semua aturan di atas)
   Sasaran: seluruh halaman nyaman dipakai di HP (360–430px), tablet, & desktop.
   Prinsip:
     - tidak ada kontrol yang lebih kecil dari target sentuh (≥36–40px),
     - font input ≥16px di HP agar iOS tidak auto-zoom,
     - grid/tabel melipat ke satu-dua kolom, tabel lebar menggulir di dalam kartu,
     - tidak ada elemen yang menonjol keluar layar (overflow horizontal = 0).
   ========================================================================== */

/* ---------- Pengaman umum ---------- */
img,svg,video,canvas{max-width:100%}
.content,.main,.lab-card,.card-head,.toolbar,.search{min-width:0}
td,th,.mv-main,.p-name,.bcode,.product-code,strong,small{overflow-wrap:anywhere}
.card-head h2{overflow-wrap:anywhere}

/* ---------- Mini-statistik (mis. Mutasi Stok) ---------- */
/* Dulu flex + gap 26px membuat 5 kotak berdesakan (57px) di HP. Sekarang grid
   yang mengisi lebar maksimal dan melipat otomatis. */
.mini-stats{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(164px,1fr));
  gap:12px;margin-bottom:16px;padding:14px;
  background:var(--tint-2);border:1px solid var(--line);border-radius:14px;
}
.mini-stats>div{
  display:flex;flex-direction:column;gap:3px;min-width:0;
  padding:11px 13px;border:1px solid var(--line);border-radius:var(--radius-sm);background:var(--tint-3);
}
.mini-stats>div>span{font-size:.66rem;letter-spacing:.07em;text-transform:uppercase;color:var(--ink-2)}
.mini-stats strong{display:block;font-size:1.14rem;line-height:1.25;font-family:var(--mono);color:var(--ink-strong)}
.mini-stats .muted.small{font-size:.68rem}

/* ---------- Login ---------- */
.login-body{
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:0;min-height:100dvh;padding:92px 20px 48px;
}
.login-wrap{position:relative;z-index:2;display:flex;align-items:center;justify-content:center;width:100%}
.login-card{position:relative;width:min(420px,100%);padding:24px}

/* ---------- Tablet & HP ---------- */
@media (max-width:900px){
  .content{gap:18px;padding:18px 16px calc(48px + env(safe-area-inset-bottom,0px));max-width:100%}
  /* Jarak kartu KPI ke isi di bawahnya dijaga lega juga di tablet/HP. */
  .content > .kpi-grid{margin-bottom:14px}
  /* Navigasi bawah (HP) — lihat markup di includes/layout.php */
  .bottom-nav{display:none}

  /* ---------- TOPBAR DI HP ----------
     Baris 1 (`topbar-main`) MENEMPEL di atas: tombol menu + judul + ikon tema/Info.
     Baris 2 (`.page-actions`) berisi tombol aksi halaman dan ikut naik saat digulir,
     sehingga kepala layar tetap ringkas dan tidak ada tombol yang bertumpuk.
     ⚠️ `display:contents` pada `.topbar` PENTING: elemen `position:sticky` hanya
     menempel di dalam kotak INDUKNYA. Selama `.topbar` masih punya kotak sendiri
     (tingginya hanya setinggi dua baris), `topbar-main` ikut terbuang begitu halaman
     digulir melewatinya (bug nyata: baris judul hilang saat menggulir). Dengan
     `display:contents` kotak itu dihilangkan, sehingga induknya menjadi `.main`
     (setinggi seluruh halaman) dan baris judul benar-benar menempel di atas.
     Baris 2 tetap tidak menempel karena tidak diberi `position:sticky`. */
  .topbar{
    display:contents;
  }
  .topbar-main{
    position:sticky;top:0;z-index:6;display:flex;align-items:center;gap:8px;
    padding:9px 12px;background:var(--topbar-bg);border-bottom:1px solid var(--line);
  }
  .topbar-title{flex:1 1 auto;min-width:0}
  .topbar-title h1{font-size:1.02rem}
  .clock{display:none}
  .topbar-actions{flex:0 0 auto;flex-wrap:nowrap;gap:6px}
  .topbar-actions .btn{padding:9px;min-height:40px}
  .btn-theme .theme-label,.btn-hints .hints-label{display:none}
  .icon-btn{min-height:40px;min-width:40px}
  .page-actions{
    display:flex;gap:8px;flex-wrap:nowrap;align-items:center;
    padding:10px 12px 2px;overflow-x:auto;overscroll-behavior-x:contain;
    -webkit-overflow-scrolling:touch;
  }
  .page-actions::-webkit-scrollbar{display:none}
  .page-actions > *{flex:0 0 auto}
  .page-actions .btn{min-height:40px}

  /* ---------- NAVIGASI BAWAH (HP) ----------
     Aplikasi ini paling sering dipakai dari HP: bar bawah memberi akses satu-tap
     ke menu tersering tanpa membuka laci menu. */
  .bottom-nav{
    display:flex;position:fixed;left:0;right:0;bottom:0;z-index:30;
    background:var(--sidebar-bg);border-top:1px solid var(--line);
    padding:6px 4px calc(6px + env(safe-area-inset-bottom,0px));
    box-shadow:0 -12px 32px -20px rgba(0,0,0,.9);
  }
  .bnav-item{
    position:relative;flex:1 1 0;min-width:0;display:flex;flex-direction:column;align-items:center;gap:3px;
    padding:7px 4px;border-radius:var(--radius-sm);border:0;background:none;cursor:pointer;
    color:var(--ink-2);font:inherit;font-size:.62rem;letter-spacing:.02em;text-decoration:none;
    transition:color .15s,background .15s;
  }
  .bnav-item svg{width:21px;height:21px;fill:currentColor;opacity:.92}
  .bnav-item span{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .bnav-item.is-active{color:var(--ink-strong);background:var(--nav-active-bg);font-weight:700}
  .bnav-item.is-active svg{opacity:1;fill:var(--cyan)}
  .bnav-badge{
    position:absolute;top:3px;right:12%;margin:0;font-size:.6rem;padding:1px 5px;
  }

  /* ---------- POLESAN TAMPILAN HP ----------
     Aplikasi ini paling sering dibuka dari HP, jadi tampilan kecil dibuat lebih
     lembut & mudah dibaca: sudut lebih membulat, garis lebih tipis, angka KPI
     lebih besar, dan sela antar-kartu lega. */
  .lab-card{border-radius:16px;padding:15px 14px}
  .content{gap:14px}
  .content > .kpi-grid{margin-bottom:16px}
  .card-head{gap:10px}
  .card-head h2{font-size:.96rem}
  .kpi-grid,.kpi-grid.compact{grid-template-columns:repeat(2,minmax(0,1fr))!important;gap:10px!important}
  .kpi-grid .kpi,.lab-card.kpi{padding:13px 13px;border-radius:14px}
  .kpi-value{font-size:1.24rem;line-height:1.2}
  .kpi-label{font-size:.66rem}
  .kpi-foot{font-size:.66rem}
  .metric-row,.metric-row.wide,.product-hero,.purchase-hero,.supplier-hero,.preview-box,.totals-grid{
    border-radius:14px;gap:10px;
  }
  .metric-row>div,.purchase-hero>div,.preview-box>div b{font-size:.95rem}
  .toolbar,.filter-card,.mini-stats{border-radius:14px}
  .btn{border-radius:12px}
  .chip{border-radius:14px;padding:6px 12px}
  .tab-bar{gap:6px}
  .tab{border-radius:12px}
  .table-wrap{border-radius:12px}
  /* kepala kartu mengambang: judul lebih lega, subjudul tidak berdesakan */
  .sheet-head{padding:13px 14px;gap:10px}
  .sheet-head h2{font-size:.98rem}
  .sheet-head .row-actions{gap:6px}
  /* input: tinggi nyaman disentuh & font 16px (tidak memicu zoom iOS) */
  .cs-btn,.field input,.field select,.field textarea{font-size:16px}
  /* pilihan tampilan (Kartu/Tabel) di kartu filter: penuh barisnya sendiri */
  .filter-card .view-choice{width:100%;justify-content:space-between}
  .filter-card .view-choice select,.filter-card .view-choice .cs-btn{flex:1 1 auto}

  /* ruang bawah supaya isi tidak tertutup bar navigasi */
  .content{padding-bottom:calc(84px + env(safe-area-inset-bottom,0px))!important}

  /* menu samping: nyaman disentuh + latar gelap untuk menutup */
  .sidebar{padding:18px 14px;overflow-y:auto}
  .nav-link{padding:12px 14px;font-size:.92rem}
  .sidebar-scrim{
    display:block;position:fixed;inset:0;background:rgba(4,8,14,.5);
    z-index:35;opacity:0;pointer-events:none;transition:opacity .2s;
  }
  .sidebar-scrim.is-open{opacity:1;pointer-events:auto}
  html[data-theme="light"] .sidebar-scrim{background:rgba(28,40,70,.32)}

  /* kartu mengambang: menempel bawah, tidak melebihi layar */
  .sheet-backdrop{padding:10px;align-items:flex-end}
  .sheet-card,.sheet-card.narrow,.sheet-card.wide{width:100%;max-height:calc(100dvh - 20px);border-radius:var(--radius) var(--radius) 0 0}
  .sheet-head{padding:14px 16px}
  .sheet-body{padding:16px 14px;gap:14px}
  .sheet-foot{padding:12px 14px;gap:8px}
  .sheet-foot .btn{flex:0 0 auto}

  /* halaman login di tablet & HP: strip di atas jadi baris statis (bukan fixed)
     supaya tidak menumpuk dengan kartu login */
  .banner-strip{
    position:static;width:100%;margin:0 0 16px;padding:10px 12px;gap:16px;
    justify-content:flex-start;flex-wrap:nowrap;overflow-x:auto;white-space:nowrap;
    font-size:.66rem;letter-spacing:.06em;border-radius:var(--radius-sm);
    -webkit-overflow-scrolling:touch;pointer-events:auto;
  }
  .banner-strip::-webkit-scrollbar{display:none}
  .strip-item{flex:0 0 auto}
  .login-body{justify-content:flex-start;padding:18px 16px calc(32px + env(safe-area-inset-bottom,0px))}

  /* grid daftar melipat */
  .product-grid,.batch-grid,.supplier-grid,.purchase-grid,.plan-pick-grid,.recipe-list,.role-cards,.perm-list{grid-template-columns:1fr!important;gap:16px}
  .kpi-grid,.kpi-grid.compact{grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:12px}
  .metric-row,.metric-row.wide,.product-hero,.purchase-hero,.supplier-hero,.preview-box,.totals-grid{
    grid-template-columns:repeat(auto-fit,minmax(132px,1fr));gap:12px;
  }
  .sync-grid{grid-template-columns:repeat(auto-fit,minmax(140px,1fr))}
  .panel-grid,.grid-2{grid-template-columns:1fr}
  .form-section .field-grid,.field-grid{grid-template-columns:repeat(auto-fit,minmax(210px,1fr))}
  .table-wrap{-webkit-overflow-scrolling:touch}
  .purchase-items .p-item,.move-item{grid-template-columns:1fr auto;gap:6px}
  .purchase-items .p-item .p-sub,.move-item .mv-time{grid-column:1 / -1}
}

/* ---------- HP ---------- */
@media (max-width:640px){
  /* target sentuh & tombol */
  .btn{min-height:42px;padding:11px 15px;font-size:.86rem}
  .btn-sm{min-height:38px;padding:9px 13px}
  .row-actions{display:flex;flex-wrap:wrap;gap:8px;width:100%}
  .row-actions .btn{flex:1 1 auto}
  .card-foot{flex-direction:column;align-items:stretch;gap:10px}
  .card-foot .row-actions{width:100%}
  .form-actions{display:flex;flex-direction:column;gap:10px}
  .form-actions .btn{width:100%}
  .card-head{flex-direction:column;align-items:stretch;gap:10px}
  .card-head .btn{width:auto}
  .tab-bar{gap:6px}
  .tab{min-height:44px;display:inline-flex;align-items:center;flex:1 1 auto;justify-content:center;padding:10px 12px;font-size:.8rem}
  .quick-range{margin-left:0}
  .chip{min-height:34px;display:inline-flex;align-items:center}

  /* hindari auto-zoom iOS: font kontrol ≥16px */
  input,select,textarea{font-size:16px!important}
  .num-stepper button{width:26px;height:20px}

  /* jarak & ukuran teks */
  .content{padding:14px 12px calc(56px + env(safe-area-inset-bottom,0px));gap:16px}
  /* blok ini ditaruh PALING AKHIR sehingga menang — jarak kartu KPI ke isi di
     bawahnya harus tetap lega di HP (permintaan pemilik: jangan menempel). */
  .content > .kpi-grid{margin-bottom:16px}
  .lab-card{padding:16px 14px}
  .kpi-grid,.kpi-grid.compact{grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}
  .kpi{padding:14px}
  .kpi-value{font-size:1.12rem}
  .mini-stats{grid-template-columns:repeat(2,minmax(0,1fr));gap:10px;padding:12px}
  .mini-stats strong{font-size:.98rem}
  .supplier-card,.purchase-card,.product-card,.batch-card{gap:14px}

  /* tabel: tetap menggulir di dalam kartu, teks lebih rapat */
  table.data{font-size:.8rem;min-width:560px}
  table.data.compact{min-width:480px;font-size:.78rem}
  table.data thead th{padding:9px 10px}
  table.data td{padding:9px 10px}
  .table-wrap{border-radius:var(--radius-sm)}

  /* halaman login (HP): kartu penuh lebar, kontrol besar & nyaman disentuh */
  .login-body{padding:14px 12px calc(28px + env(safe-area-inset-bottom,0px))}
  .banner-strip{font-size:.62rem}
  .login-wrap{flex:1 1 auto;align-items:flex-start}
  .login-card{width:100%;padding:20px 16px}
  .login-card h2{font-size:1.12rem}
  .login-card .brand-lg .brand-mark{width:44px;height:44px}
  .login-card .btn[type=submit]{min-height:48px;font-size:.95rem}
  .login-card-top{margin-bottom:8px}
  .login-help{font-size:.78rem}

  /* kontrol form penuh lebar */
  .field.inline{flex-direction:column;align-items:stretch}
  .input-with-btn{flex-direction:column;align-items:stretch}
  .input-with-btn>.btn{width:100%}
  .search .view-choice{width:100%}
  .metric-row,.product-hero,.purchase-hero,.supplier-hero,.preview-box{grid-template-columns:repeat(2,minmax(0,1fr))}
  .panel-grid,.grid-2,.recipe-table{grid-template-columns:1fr}
  .log-item{grid-template-columns:1fr;gap:4px}
  .move-item .mv-qty{text-align:left}
  .stack{gap:12px}
}

/* ---------- HP sangat kecil ---------- */
@media (max-width:380px){
  .kpi-grid,.kpi-grid.compact,.mini-stats{grid-template-columns:1fr}
  .metric-row,.product-hero,.purchase-hero,.supplier-hero,.preview-box{grid-template-columns:1fr}
  .btn-hints .hints-label,.btn-theme .theme-label{display:none}
}
@media (max-width:400px){
  /* WAJIB minmax(0,1fr): `1fr` = minmax(auto,1fr) sehingga kolom ikut melebar
     mengikuti min-content anaknya (dropdown dengan pilihan panjang). */
  .search{grid-template-columns:minmax(0,1fr)}
}

/* ---------- Pengaman lebar: grafik & elemen bergulir ---------- */
.bar-chart{max-width:100%;overflow:hidden}
.bar-col{min-width:0}
.bar-x{font-size:.6rem;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}
.role-cards,.batch-list,.purchase-items,.move-list,.log-list{min-width:0}
.log-body,.mv-main{min-width:0}
@media (max-width:640px){
  .bar-chart{height:140px;gap:5px}
  .bar-x{font-size:.54rem}
  .chart-axis{font-size:.64rem}
}

/* Login di tablet ke atas: kartu kembali ke tengah layar (di HP dibuat rata atas
   supaya papan tombol tidak menutupi kolom isian). */
@media (min-width:701px){
  .login-body{justify-content:center}
}

/* ============ KARTU FILTER MANDIRI (mis. Mutasi Stok) ==================== */
/* Berdiri sendiri di paling atas halaman: judul kecil + kolom pencarian besar,
   terpisah dari kartu daftar di bawahnya. */
.filter-card .filter-head{
  display:flex;align-items:baseline;justify-content:space-between;gap:12px;flex-wrap:wrap;
  margin-bottom:12px;
}
.filter-card .filter-head .filter-title{
  font-size:.82rem;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:var(--ink-strong);
}
.filter-card .filter-head .muted{font-size:.74rem}
@media (max-width:640px){
  .filter-card .filter-head{margin-bottom:10px}
  .filter-card .filter-head .filter-title{font-size:.78rem}
}

/* ============ NOMOR BATCH YANG BISA DIKLIK (kartu Formula) ============== */
.batch-refs{
  display:flex;flex-direction:column;gap:8px;padding:12px 14px;
  border:1px solid var(--line);border-radius:var(--radius-sm);background:var(--tint-3);
}
.batch-refs-label{font-size:.72rem;letter-spacing:.04em;text-transform:uppercase;color:var(--ink-2);font-weight:600}
.batch-refs-list{display:flex;flex-wrap:wrap;gap:8px}
.batch-ref{
  display:inline-flex;align-items:center;gap:8px;padding:7px 11px;border-radius:20px;
  border:1px solid var(--line-strong);background:var(--panel-2);text-decoration:none;transition:.15s;
  min-height:34px;
}
.batch-ref:hover{border-color:var(--focus-border);transform:translateY(-1px)}
.batch-ref-code{font-family:var(--mono);font-size:.79rem;font-weight:700;color:var(--code-ink)}
.batch-ref-meta{font-size:.68rem;color:var(--ink-2);font-family:var(--mono)}
.batch-ref .pill{font-size:.62rem;padding:2px 8px}
@media (max-width:640px){
  .batch-ref{min-height:38px;padding:8px 12px}
  .batch-refs-label{font-size:.7rem}
}

/* ==================== RENCANA PEMBELIAN (modul baru) ==================== */
.plan-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(440px,1fr));gap:22px}
.plan-card{display:flex;flex-direction:column;gap:16px}
.plan-card.is-off{opacity:.72}
.plan-head{display:flex;align-items:flex-start;justify-content:space-between;gap:16px}
.plan-head h2{font-size:1.02rem}
.plan-hero{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:14px;padding:16px;
  border-radius:var(--radius-sm);border:1px solid var(--line);background:var(--tint-3);
}
.plan-hero>div span{display:block;font-size:.68rem;text-transform:uppercase;letter-spacing:.07em;color:var(--ink-2)}
.plan-hero>div b{display:block;font-family:var(--mono);font-size:1rem;margin-top:3px;color:var(--ink-strong)}
.plan-hero>div small{display:block;font-size:.68rem;color:var(--ink-2);margin-top:2px;overflow-wrap:anywhere}

/* langkah alur pengajuan → persetujuan → nota */
.plan-steps{display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));gap:12px}
.plan-step{
  display:flex;gap:11px;align-items:flex-start;padding:12px 14px;border-radius:var(--radius-sm);
  border:1px solid var(--line);background:var(--tint-3);
}
.plan-step-num{
  width:26px;height:26px;flex:0 0 26px;border-radius:50%;display:grid;place-items:center;
  font-family:var(--mono);font-weight:700;font-size:.8rem;
  background:var(--panel-2);border:1px solid var(--line-strong);color:var(--ink-2);
}
.plan-step strong{display:block;font-size:.84rem;color:var(--ink-strong)}
.plan-step small{display:block;font-size:.7rem;color:var(--ink-2);margin-top:2px;overflow-wrap:anywhere}
.plan-step.is-active{border-color:var(--nav-active-border);background:var(--nav-active-bg)}
.plan-step.is-active .plan-step-num{background:linear-gradient(135deg,var(--cyan),#14a38b);color:#04121c;border-color:transparent}
.plan-step.is-done{border-color:var(--ok-bd);background:var(--ok-bg)}
.plan-step.is-done .plan-step-num{background:var(--ok-bg);border-color:var(--ok-bd);color:var(--ok-fg)}

/* tabel baris rencana di kartu penginputan */
.plan-table{table-layout:fixed;min-width:0}
.plan-table thead th{font-size:.66rem;letter-spacing:.05em;padding:10px 8px;vertical-align:bottom}
.plan-table td{padding:9px 8px;vertical-align:top}
.plan-table .col-bahan{width:20%}
.plan-table .col-qty{width:9%}
.plan-table .col-unit{width:9%}
.plan-table .col-factor{width:9%}
.plan-table .col-sup{width:15%}
.plan-table .col-price{width:12%}
.plan-table .col-hint{width:14%}
.plan-table .col-note{width:9%}
.plan-table .col-act{width:4%}
.plan-table input,.plan-table select{width:100%;padding:8px 9px;font-size:.82rem;min-width:0}
.price-hints{display:flex;flex-direction:column;gap:5px;margin-bottom:6px}
.price-hints .btn{padding:6px 9px;font-size:.72rem;justify-content:flex-start;white-space:normal;text-align:left;line-height:1.25}
.price-hints .hint-line{font-size:.68rem;color:var(--ink-2);overflow-wrap:anywhere}
.price-hints .hint-line.is-best{color:var(--ok-fg)}
.price-hints .hint-line.is-warn{color:var(--warn-fg)}
.plan-table .qty-hint,.plan-table .stock-hint{display:block;font-size:.66rem;color:var(--ink-2);margin-top:4px}
.approval-card{border-color:var(--nav-active-border)}

/* lencana jumlah tugas approve di menu samping */
.nav-badge{
  margin-left:auto;min-width:20px;height:20px;padding:0 6px;border-radius:20px;
  display:inline-grid;place-items:center;font-size:.68rem;font-weight:700;font-family:var(--mono);
  background:linear-gradient(135deg,var(--warn-fg),#F59E0B);color:#2a1c00;
}
.nav-link.is-active .nav-badge{box-shadow:0 0 0 2px var(--nav-active-bg)}

@media (max-width:900px){
  .plan-table{min-width:760px}
  .plan-steps{grid-template-columns:1fr}
}
@media (max-width:640px){
  .plan-grid{grid-template-columns:1fr;gap:16px}
  .plan-hero{grid-template-columns:repeat(2,minmax(0,1fr))}
  .price-hints .btn{min-height:38px}
}

/* ============================== PAGER DAFTAR ============================ */
.pager{
  display:flex;flex-wrap:wrap;gap:12px;align-items:center;justify-content:space-between;
  margin-top:14px;padding:12px 14px;border:1px solid var(--line);border-radius:var(--radius-sm);background:var(--tint-3);
}
.pager-actions,.pager-per{display:flex;gap:6px;align-items:center;flex-wrap:wrap}
.pager .btn-sm{min-height:34px}
.pager .btn.is-disabled{opacity:.45;pointer-events:none}
@media (max-width:640px){
  .pager{flex-direction:column;align-items:stretch;gap:10px}
  .pager-actions,.pager-per{justify-content:center}
  .pager .btn-sm{min-height:40px}
}

/* ====================== JURNAL (pergerakan uang) ======================== */
.cat-bar{
  display:block;height:9px;border-radius:20px;min-width:3px;
  background:linear-gradient(90deg,var(--cyan),#14a38b);
}

/* ---------- Kartu mengambang: ringan saat digulir (kartu panjang) -------- */
/* Blok besar di dalam kartu yang SEDANG TIDAK TERLIHAT tidak dirender sampai
   mendekat. Diukur pada kartu nota: 30,7 ms/frame (11 frame jatuh) → lihat
   catatan pengukuran di AGENTS.md.
   ⚠️ PENTING: `content-visibility:auto` membawa `contain: paint` SECARA IMPLISIT,
   sehingga setiap kartu MEMOTONG isi yang keluar dari kotaknya (popup/menu absolut
   jadi tidak terlihat & tidak bisa diklik). Karena itu setiap kartu yang sedang
   menampilkan popup di-EXCLUDE lewat `:has()` di bawah — jangan dihapus, dan jangan
   menaruh popup baru di dalam kartu tanpa menambah pengecualiannya di sini. */
.sheet-body .lab-card,
.sheet-body .table-wrap,
.sheet-body .sub-head,
.sheet-body .totals-grid{
  content-visibility:auto;contain-intrinsic-size:auto 300px;
}
/* Kartu/wadah yang sedang menampilkan popup (menu absolut / <details> terbuka)
   DIKECUALIKAN dari optimasi di atas, kalau tidak popup-nya terpotong oleh
   `contain:paint` bawaan `content-visibility:auto` (bug nyata di banyak modul). */
.sheet-body .lab-card:has(.attach-menu.is-open),
.sheet-body .lab-card:has(details[open]),
.sheet-body .table-wrap:has(details[open]){
  content-visibility:visible;
}
/* Bagian kartu yang sedang tidak terlihat tidak dirender sampai mendekat,
   sehingga gulir pada kartu nota/koreksi nota tetap mulus walau isinya banyak. */
.sheet-body > .table-wrap,
.sheet-body > .totals-grid,
.sheet-body > .preview-row,
.sheet-body .photo-attach,
.sheet-body .plan-table,
.sheet-body > .field-grid,
.sheet-body .form-section{
  content-visibility:auto;contain-intrinsic-size:auto 240px;
}

/* ============ SARAN HARGA PADA RENCANA PEMBELIAN (rancang ulang) ========= */
/* Kolom saran dibuat lebih lega + tampil sebagai kartu kecil supaya informasi
   "harga terakhir" dan "harga termurah" mudah dibaca dan tombolnya nyaman. */
.plan-table .col-hint{width:20%}
.plan-table .col-bahan{width:18%}
.plan-table .col-price{width:12%}
.plan-table .col-qty{width:8%}
.plan-table .col-unit{width:8%}
.plan-table .col-factor{width:8%}
.plan-table .col-sup{width:14%}
.plan-table .col-note{width:8%}
.plan-table .col-act{width:4%}
.price-hints{
  display:flex;flex-direction:column;gap:8px;margin-bottom:0;min-width:0;
}
.price-hints .price-item{
  display:flex;flex-direction:column;gap:6px;padding:9px 10px;border-radius:var(--radius-sm);
  border:1px solid var(--line);background:var(--tint-3);min-width:0;
}
.price-hints .price-item.is-best{border-color:var(--ok-bd);background:var(--ok-bg)}
.price-hints .price-item.is-last{border-color:var(--nav-active-border);background:var(--nav-active-bg)}
.price-hints .price-label{
  font-size:.64rem;text-transform:uppercase;letter-spacing:.06em;color:var(--ink-2);font-weight:600;
}
.price-hints .price-value{
  font-family:var(--mono);font-size:.86rem;font-weight:700;color:var(--ink-strong);overflow-wrap:anywhere;
}
.price-hints .price-meta{font-size:.68rem;color:var(--ink-2);overflow-wrap:anywhere;line-height:1.3}
.price-hints .price-item .btn{
  width:100%;justify-content:center;min-height:32px;padding:6px 10px;font-size:.72rem;
}
.price-hints .hint-line{font-size:.68rem;color:var(--ink-2);overflow-wrap:anywhere}
.price-hints .hint-line.is-warn{color:var(--warn-fg)}
.price-hints .hint-empty{font-size:.7rem;color:var(--ink-2)}
@media (max-width:900px){
  .plan-table{min-width:900px}
  .price-hints .price-item{padding:10px}
  .price-hints .price-item .btn{min-height:38px}
}

/* --------- Bukti transfer pada nota --------- */
.pay-proof-box{margin-top:4px;padding:14px;border:1px solid var(--line);border-radius:var(--radius-sm);background:var(--tint-3)}
.pay-proof-box.is-hidden{display:none}
.pay-proof-view{display:flex;flex-direction:column;gap:8px;margin:12px 0;padding:12px 14px;
  border:1px solid var(--ok-bd);border-radius:var(--radius-sm);background:var(--ok-bg)}
/* Kartu Bukti Transfer sekarang memakai tampilan kartu yang sama dengan lampiran
   nota (.lab-card) dan berdiri sejajar dengannya — lihat .grid-2 pada kartu nota. */
.pay-proof-card[data-pay-proof-box] .attach-widget{margin-top:12px}
/* Kartu bukti transfer tetap tampil walau cara bayar tunai — hanya diredupkan
   sebagai penanda bahwa lampirannya opsional (bukan disembunyikan). */
.pay-proof-card.is-off{opacity:.78}
.pay-proof-card.is-off:hover{opacity:1}

/* ====== KONFIRMASI PEMBAYARAN: SATU TOMBOL BESAR (nota pembelian) ======= */
/* Dulu kotak centang kecil "Sudah dibayar lunas". Sekarang satu tombol sebesar
   kartu berisi sakelar + penjelasan supaya tim pembelian lekas paham statusnya.
   Input aslinya tetap <input type=checkbox name="paid"> (berfungsi tanpa JS). */
.paid-switch{
  position:relative;display:flex;align-items:center;gap:14px;width:100%;max-width:560px;
  padding:14px 18px;border-radius:var(--radius-sm);border:1px solid var(--line-strong);
  background:var(--tint-3);cursor:pointer;min-height:60px;
  transition:border-color .15s,background .15s;
}
.paid-switch input{position:absolute;width:1px;height:1px;opacity:0;margin:0}
.paid-switch .ps-knob{
  position:relative;flex:0 0 48px;width:48px;height:27px;border-radius:999px;
  background:var(--panel-2);border:1px solid var(--line-strong);transition:background .16s,border-color .16s;
}
.paid-switch .ps-knob::after{
  content:'';position:absolute;top:2px;left:2px;width:21px;height:21px;border-radius:50%;
  background:var(--ink-2);transition:transform .18s,background .18s;
}
.paid-switch .ps-text{display:flex;flex-direction:column;gap:3px;min-width:0}
.paid-switch .ps-text strong{font-size:1rem;color:var(--ink-strong)}
.paid-switch .ps-toggle{
  margin-left:auto;flex:0 0 auto;font-size:.66rem;color:var(--ink-3);
  text-transform:uppercase;letter-spacing:.07em;
}
.paid-switch:hover{border-color:var(--focus-border)}
.paid-switch:focus-within{outline:2px solid var(--focus-border);outline-offset:2px}
.paid-switch:has(input:checked),
.paid-switch.is-paid{border-color:var(--ok-bd);background:var(--ok-bg)}
.paid-switch:has(input:checked) .ps-knob,
.paid-switch.is-paid .ps-knob{background:var(--ok-bg);border-color:var(--ok-bd)}
.paid-switch:has(input:checked) .ps-knob::after,
.paid-switch.is-paid .ps-knob::after{transform:translateX(21px);background:var(--ok-fg)}
.paid-switch:has(input:checked) .ps-text strong,
.paid-switch.is-paid .ps-text strong{color:var(--ok-fg)}
@media (max-width:640px){
  .paid-switch{padding:13px 14px;gap:12px}
  .paid-switch .ps-toggle{display:none}
}

/* ============ SPINBUTTON −/+ : JARAK AMAN DI SELURUH MODUL ============== */
/* Masalah nyata: pada beberapa modul, aturan `.search input:not([type=checkbox])…`
   (spesifisitas 0,3,1) menimpa `padding-right:30px` milik `.num-wrap>input` (0,1,1)
   sehingga tombol −/+ MENIMPA angka yang sedang diketik (terukur: tombol keluar
   14px dari kotak isian pada kartu "Atur Harga"). Aturan berikut memakai
   spesifisitas cukup + diletakkan paling akhir file agar selalu menang. */
/* Di dalam baris label (flex) pembungkus harus MENGIKUTI lebar input, kalau tidak
   tombol −/+ meleset ke kanan kotak isian (kasus "Atur Harga": 13,5px keluar). */
.field.inline .num-wrap,
.input-with-btn .num-wrap,
.search .num-wrap{width:auto;display:inline-flex;flex-direction:column;min-width:0}
.num-wrap{position:relative}
.num-wrap>input[type=number],
.num-wrap>input[type=text],
.num-wrap>input,
.search .num-wrap>input[type=number],
.search .num-wrap>input,
.filter-card .num-wrap>input,
.field .num-wrap>input[type=number],
.field.grid .num-wrap>input,
.field.inline .num-wrap>input[type=number]{
  padding-right:38px!important;
}
.num-stepper{right:6px;gap:3px}
.num-stepper button{width:22px;height:16px}
/* kotak isian angka yang sempit (di dalam tabel) tetap punya ruang teks:
   min-width 76px ⇒ sisa ruang teks ≥ 38px walau tombol di sisi kanan */
.num-wrap>input.qty-pick,
.num-wrap>input.factor-pick,
.num-wrap>input.price-pick,
.num-wrap>input.qty-input,
.num-wrap>input.pack-qty,
.num-wrap>input.tot-input{min-width:76px}
@media (max-width:900px){
  .num-wrap>input[type=number],.num-wrap>input{padding-right:42px!important}
  .num-stepper button{width:26px;height:19px}
}

/* ============ LEBAR KOLOM TABEL PROPORSIONAL (GLOBAL) ===================
   Permintaan pemilik: lebar kolom mengikuti kebutuhan isi. Kelas `.col-num`
   (uang/angka), `.col-date`, dan `.col-act` dipasang otomatis oleh
   assets/app.js ke SEMUA `table.data`; kolom tersebut hanya mengambil lebar
   minimum yang dibutuhkan, sehingga kolom teks (nama/keterangan) mendapat
   sisa ruang yang wajar. Di layar kecil tabel berubah menjadi kartu
   bertingkat, jadi aturan ini tidak mengganggu tampilan HP. */
table.data{table-layout:auto}
table.data thead th{vertical-align:bottom}
table.data td{overflow-wrap:break-word}
table.data th.col-num,table.data td.col-num{
  width:1%;white-space:nowrap;text-align:right;font-variant-numeric:tabular-nums;
}
table.data th.col-date,table.data td.col-date{width:1%;white-space:nowrap}
table.data th.col-act,table.data td.col-act{width:1%;white-space:nowrap;text-align:right}
table.data td.col-act .btn,table.data td.col-act form{flex:0 0 auto}
/* ⚠️ PENTING: `<select class="cs-native">` (dropdown pencarian yang disembunyikan,
   `position:absolute`) memakai containing block elemen berposisi TERDEKAT. Tanpa
   posisi di sini, containing block-nya menjadi `.content`/body sehingga elemen itu
   LOLOS dari klip `.table-wrap` dan menambah lebar halaman (bug nyata: overflow
   11px di halaman Harga pada 1024px setelah kolom tabel dibuat lebih lebar).
   Dengan `position:relative`, semua isi tabel — termasuk elemen absolut — tetap
   terkurung di dalam wadah gulirnya. */
.table-wrap{position:relative}
@media (max-width:900px){
  /* Di mode kartu bertingkat semua aturan lebar di atas tidak berlaku. */
  table.data th.col-num,table.data td.col-num,
  table.data th.col-date,table.data td.col-date,
  table.data th.col-act,table.data td.col-act{width:auto;white-space:normal;text-align:left}
}

/* ======================== TOMBOL KEMBALI (BACK) ========================= */
.btn-back{display:inline-flex;align-items:center;gap:6px}
.btn-back svg{width:15px;height:15px;fill:currentColor;flex:0 0 15px}
.card-head .btn-back{flex:0 0 auto}
@media (max-width:640px){
  .btn-back{min-height:42px;width:100%;justify-content:center}
}

/* ===================== INPUT RUPIAH (data-money) ======================== */
/* Nilai nominal ditampilkan dengan pemisah ribuan ("26.000") sehingga wajib
   berupa <input type=text> + inputmode numeric. Tampilannya disamakan dengan
   kolom angka lain: rata kanan, huruf monospace, dan tabular agar rapi. */
input[data-money]{
  text-align:right;font-family:var(--mono);font-variant-numeric:tabular-nums;
}
input[data-money]::placeholder{font-family:inherit}
table.data input[data-money]{min-width:96px}
.num-wrap>input[data-money]{padding-right:10px!important}

/* ---- PREFIX "Rp" STATIS DI DALAM KOLOM NOMINAL (komponen global) --------
   Dibuat assets/app.js untuk SETIAP input [data-money]. Prefix menempel di
   dalam kotak input, tidak ikut terkirim (span dekoratif, tanpa name), dan
   tidak mengubah nilai/perhitungan apa pun. */
.money-wrap{position:relative;display:block;width:100%;min-width:0}
/* `.field>span` dipakai untuk label kolom — jangan sampai gaya itu menimpa
   pembungkus input ini (warna/bobot/huruf). */
.field>span.money-wrap,
.field>span.money-prefix{color:inherit;font-weight:400;letter-spacing:0}
.money-wrap>input[data-money]{
  width:100%;padding-left:38px!important;
}
.money-prefix{
  position:absolute;left:11px;top:50%;transform:translateY(-50%);
  font-family:var(--mono);font-size:.8em;font-weight:700;line-height:1;
  letter-spacing:.02em;color:var(--ink-2);pointer-events:none;user-select:none;z-index:1;
}
table.data .money-wrap{min-width:96px}
@media (max-width:640px){
  .money-wrap>input[data-money]{padding-left:40px!important}
}

/* ============ RENCANA PEMBELIAN: jarak & penekanan isi =================== */
/* Kartu perkembangan (Pengajuan → Persetujuan → Nota) perlu ruang lebih dari
   baris berikutnya supaya tidak terlihat menempel. */
.plan-steps{margin:2px 0 20px}
/* Catatan pengajuan ditegaskan (kartu tersendiri + tulisan hitam pekat) karena
   inilah alasan pengajuan yang paling sering dibaca penyetuju. */
.note-highlight{
  margin:6px 0 18px;padding:14px 16px;border-radius:var(--radius-sm);
  border:1px solid var(--nav-active-border);background:var(--nav-active-bg);
  border-left:4px solid var(--cyan);
}
.note-highlight .nh-label{
  display:block;font-size:.68rem;text-transform:uppercase;letter-spacing:.08em;
  color:var(--ink-2);margin-bottom:4px;
}
.note-highlight .nh-body{margin:0;font-size:.94rem;line-height:1.5;overflow-wrap:anywhere}
/* Kartu daftar rencana: daftar bahan ringkas + catatan pengajuan. */
.plan-materials{display:flex;flex-direction:column;gap:8px;padding:12px 14px;
  border:1px solid var(--line);border-radius:var(--radius-sm);background:var(--tint-3)}
.plan-materials .pm-label{font-size:.68rem;text-transform:uppercase;letter-spacing:.07em;color:var(--ink-2)}
.plan-note-line{margin:0;font-size:.88rem;line-height:1.5;overflow-wrap:anywhere}
.plan-note-line>span{font-weight:600}
@media (max-width:640px){
  .plan-steps{margin:2px 0 16px}
  .note-highlight{padding:13px 14px}
}

/* Nomor RP pada kartu Rencana Pembelian berada di dalam kartu mengambang
   (.sheet-card), bukan .lab-card — jadi perlu ikut aturan --code-ink
   (hitam pekat di tema terang, putih di tema gelap) seperti kode lain. */
.sheet-card .code-ink,
.sheet-card h2.mono,
.sheet-card input.code-ink{color:var(--code-ink)}

/* ================= PENYESUAIAN BATCH (pengajuan + persetujuan) ============ */
/* Form pengajuan disembunyikan di dalam <details> supaya kartu penyesuaian tetap
   ringkas: yang terlihat lebih dulu adalah status pengajuan & keputusan atasan. */
.adj-form-wrap>summary{list-style:none;display:inline-flex;align-items:center;gap:8px;cursor:pointer}
.adj-form-wrap>summary::-webkit-details-marker{display:none}
.adj-form-wrap[open]>summary{margin-bottom:6px}

/* ==========================================================================
   PANAH COMBOBOX (select) TIDAK BOLEH MENABRAK TEKS / PLACEHOLDER
   --------------------------------------------------------------------------
   Panah digambar sendiri (background-position:right 10px, lebar 16px) sehingga
   butuh ruang kanan minimal ~30px. Beberapa aturan lama menimpa padding-right
   combobox menjadi 9–10px (.search select, .plan-table select, .recipe-row select,
   .pack-row select, .plan-table input+select) sehingga teks/placeholder berjalan
   DI BAWAH panah — inilah keluhan "panah ke bawah menabrak placeholder".
   Blok ini diletakkan paling akhir + cukup spesifik supaya selalu menang.
   ========================================================================== */
select,
.search select,
.filter-card select,
.field select,
table.data select,
table.data select.unit-input,
table.data select.mat-select,
.plan-table select,
.plan-table select.unit-pick,
.plan-table select.sup-pick,
.recipe-row select,
.recipe-table select.unit-input,
.recipe-table select.mat-select,
.pack-row select,
.pop-body select,
.unit-pick,
.sup-pick,
.mat-pick,
.unit-input,
.mat-select{
  padding-right:32px!important;
  text-overflow:ellipsis;
}
/* Di layar sempit panah sedikit didekatkan tepi supaya ruang teks tetap lega. */
@media (max-width:640px){
  select,.search select,.filter-card select,.field select,
  .plan-table select,.recipe-row select,.pack-row select,.pop-body select{
    padding-right:30px!important;
  }
  /* Combobox di baris pencarian diberi lebar minimum yang cukup untuk teksnya. */
  .search select{min-width:132px}
}

/* Lencana pada tombol menu (HP): total tugas yang masih menggantung di semua menu
   supaya tetap terlihat walau menu samping sedang tertutup. */
.icon-btn{position:relative}
.icon-badge{position:absolute;top:-4px;right:-6px;margin:0;min-width:18px;height:18px;font-size:.62rem;
  border:2px solid var(--panel);box-shadow:none}

/* ====== FILTER PENCARIAN MUTASI STOK: 1 BARIS DI DESKTOP, RAPI DI HP ====== */
/* ⚠️ SEMUA selektor di blok ini memakai `.filter-card .search.stock-filter` (spesifisitas 0,3,1).
   Dengan `.stock-filter` saja (0,1,0) aturan umum `.filter-card .search{gap:12px}`
   (0,2,1) menang, sehingga `flex-wrap`/`gap` di sini DIABAIKAN dan kontrol turun ke
   baris kedua walau ruang masih cukup — jangan turunkan spesifisitasnya. */
.filter-card .search.stock-filter{display:flex;flex-wrap:wrap;gap:10px;align-items:flex-end;width:100%}
.filter-card .search.stock-filter .sf-q{flex:1 1 240px;min-width:170px}
.filter-card .search.stock-filter .sf-q input[type=search]{width:100%;min-width:0}
.filter-card .search.stock-filter > select{flex:1 1 150px;min-width:120px;width:auto}
.filter-card .search.stock-filter .sf-date{flex:1 1 150px;min-width:126px}
.filter-card .search.stock-filter .sf-date > input{flex:1 1 auto;min-width:0;width:100%}
.filter-card .search.stock-filter .sf-foot{display:flex;gap:8px;align-items:center;flex:0 0 auto;flex-wrap:wrap}
.filter-card .search.stock-filter .live-count{flex:1 1 100%}
/* DESKTOP (≥1180px): paksa SATU baris. `flex-wrap:nowrap` wajib — dengan wrap,
   kontrol terakhir turun ke baris kedua walau ruang sisa masih cukup setelah
   kontrol menyusut. min-width kecil membuat semuanya boleh menyusut, bukan meluber. */
@media (min-width:1180px){
  .filter-card .search.stock-filter{flex-wrap:nowrap;gap:8px}
  .filter-card .search.stock-filter .sf-q{flex:1 1 160px;min-width:110px}
  .filter-card .search.stock-filter > select{flex:0 1 auto;min-width:96px;max-width:190px}
  .filter-card .search.stock-filter .sf-date{flex:0 0 auto;min-width:0}
  .filter-card .search.stock-filter .sf-date > input{width:112px}
}
@media (max-width:640px){
  .filter-card .search.stock-filter > select{flex:1 1 calc(50% - 8px)}
  .filter-card .search.stock-filter .sf-date{flex:1 1 calc(50% - 8px)}
  .filter-card .search.stock-filter .sf-date > span{display:none}   /* label "Periode" cukup sekali */
  .filter-card .search.stock-filter .sf-foot{flex:1 1 100%}
  .filter-card .search.stock-filter .sf-foot .btn{flex:1 1 auto;justify-content:center}
}
@media (max-width:400px){
  .filter-card .search.stock-filter > select,.filter-card .search.stock-filter .sf-date{flex:1 1 100%}
}

/* ============ RENCANA PEMBELIAN: jarak & penekanan isi =================== */
/* Kartu perkembangan (Pengajuan → Persetujuan → Nota) perlu ruang lebih dari
   baris berikutnya supaya tidak terlihat menempel. */
.plan-steps{margin:2px 0 20px}
/* Catatan pengajuan ditegaskan (kartu tersendiri + tulisan hitam pekat) karena
   inilah alasan pengajuan yang paling sering dibaca penyetuju. */
.note-highlight{
  margin:6px 0 18px;padding:14px 16px;border-radius:var(--radius-sm);
  border:1px solid var(--nav-active-border);background:var(--nav-active-bg);
  border-left:4px solid var(--cyan);
}
.note-highlight .nh-label{
  display:block;font-size:.68rem;text-transform:uppercase;letter-spacing:.08em;
  color:var(--ink-2);margin-bottom:4px;
}
.note-highlight .nh-body{margin:0;font-size:.94rem;line-height:1.5;overflow-wrap:anywhere}
/* Kartu daftar rencana: daftar bahan ringkas + catatan pengajuan. */
.plan-materials{display:flex;flex-direction:column;gap:8px;padding:12px 14px;
  border:1px solid var(--line);border-radius:var(--radius-sm);background:var(--tint-3)}
.plan-materials .pm-label{font-size:.68rem;text-transform:uppercase;letter-spacing:.07em;color:var(--ink-2)}
.plan-note-line{margin:0;font-size:.88rem;line-height:1.5;overflow-wrap:anywhere}
.plan-note-line>span{font-weight:600}
@media (max-width:640px){
  .plan-steps{margin:2px 0 16px}
  .note-highlight{padding:13px 14px}
}

/* Nomor RP pada kartu Rencana Pembelian berada di dalam kartu mengambang
   (.sheet-card), bukan .lab-card — jadi perlu ikut aturan --code-ink
   (hitam pekat di tema terang, putih di tema gelap) seperti kode lain. */
.sheet-card .code-ink,
.sheet-card h2.mono,
.sheet-card input.code-ink{color:var(--code-ink)}

/* ================= PENYESUAIAN BATCH (pengajuan + persetujuan) ============ */
/* Form pengajuan disembunyikan di dalam <details> supaya kartu penyesuaian tetap
   ringkas: yang terlihat lebih dulu adalah status pengajuan & keputusan atasan. */
.adj-form-wrap>summary{list-style:none;display:inline-flex;align-items:center;gap:8px;cursor:pointer}
.adj-form-wrap>summary::-webkit-details-marker{display:none}
.adj-form-wrap[open]>summary{margin-bottom:6px}

/* ==========================================================================
   PANAH COMBOBOX (select) TIDAK BOLEH MENABRAK TEKS / PLACEHOLDER
   --------------------------------------------------------------------------
   Panah digambar sendiri (background-position:right 10px, lebar 16px) sehingga
   butuh ruang kanan minimal ~30px. Beberapa aturan lama menimpa padding-right
   combobox menjadi 9–10px (.search select, .plan-table select, .recipe-row select,
   .pack-row select, .plan-table input+select) sehingga teks/placeholder berjalan
   DI BAWAH panah — inilah keluhan "panah ke bawah menabrak placeholder".
   Blok ini diletakkan paling akhir + cukup spesifik supaya selalu menang.
   ========================================================================== */
select,
.search select,
.filter-card select,
.field select,
table.data select,
table.data select.unit-input,
table.data select.mat-select,
.plan-table select,
.plan-table select.unit-pick,
.plan-table select.sup-pick,
.recipe-row select,
.recipe-table select.unit-input,
.recipe-table select.mat-select,
.pack-row select,
.pop-body select,
.unit-pick,
.sup-pick,
.mat-pick,
.unit-input,
.mat-select{
  padding-right:32px!important;
  text-overflow:ellipsis;
}
/* Di layar sempit panah sedikit didekatkan tepi supaya ruang teks tetap lega. */
@media (max-width:640px){
  select,.search select,.filter-card select,.field select,
  .plan-table select,.recipe-row select,.pack-row select,.pop-body select{
    padding-right:30px!important;
  }
  /* Combobox di baris pencarian diberi lebar minimum yang cukup untuk teksnya. */
  .search select{min-width:132px}
}

/* Lencana pada tombol menu (HP): total tugas yang masih menggantung di semua menu
   supaya tetap terlihat walau menu samping sedang tertutup. */
.icon-btn{position:relative}
.icon-badge{position:absolute;top:-4px;right:-6px;margin:0;min-width:18px;height:18px;font-size:.62rem;
  border:2px solid var(--panel);box-shadow:none}

/* ====== FILTER PENCARIAN MUTASI STOK: 1 BARIS DI DESKTOP, RAPI DI HP ====== */
/* Desktop (≥1180px): SATU baris — `flex-wrap:nowrap` supaya semua kontrol benar-benar
   berada di satu garis (jika hanya mengandalkan wrap, kontrol terakhir akan turun ke
   baris berikutnya walau ruang masih cukup setelah menyusut). Setiap kontrol punya
   `min-width` kecil sehingga boleh menyusut tanpa meluber.
   Di bawah itu: membungkus otomatis menjadi 2 kolom yang proporsional. */
.stock-filter{display:flex;flex-wrap:wrap;gap:10px;align-items:flex-end;width:100%}
.stock-filter .sf-q{flex:1 1 240px;min-width:170px}
.stock-filter .sf-q input[type=search]{width:100%;min-width:0}
.stock-filter > select{flex:1 1 150px;min-width:120px;width:auto}
.stock-filter .sf-date{flex:1 1 150px;min-width:126px}
.stock-filter .sf-date > input{flex:1 1 auto;min-width:0;width:100%}
.stock-filter .sf-foot{display:flex;gap:8px;align-items:center;flex:0 0 auto;flex-wrap:wrap}
.stock-filter .live-count{flex:1 1 100%}
@media (min-width:1180px){
  .stock-filter{flex-wrap:nowrap;gap:8px}
  .stock-filter .sf-q{flex:1 1 160px;min-width:110px}
  .stock-filter > select{flex:0 1 auto;min-width:96px;max-width:190px}
  .stock-filter .sf-date{flex:0 0 auto;min-width:0}
  .stock-filter .sf-date > input{width:112px}
}
@media (max-width:640px){
  .stock-filter > select{flex:1 1 calc(50% - 8px)}
  .stock-filter .sf-date{flex:1 1 calc(50% - 8px)}
  .stock-filter .sf-date > span{display:none}   /* label periode cukup sekali */
  .stock-filter .sf-foot{flex:1 1 100%}
  .stock-filter .sf-foot .btn{flex:1 1 auto;justify-content:center}
}
@media (max-width:400px){
  .stock-filter > select,.stock-filter .sf-date{flex:1 1 100%}
}

/* ============ RENCANA PEMBELIAN: jarak & penekanan isi =================== */
/* Kartu perkembangan (Pengajuan → Persetujuan → Nota) perlu ruang lebih dari
   baris berikutnya supaya tidak terlihat menempel. */
.plan-steps{margin:2px 0 20px}
/* Catatan pengajuan ditegaskan (kartu tersendiri + tulisan hitam pekat) karena
   inilah alasan pengajuan yang paling sering dibaca penyetuju. */
.note-highlight{
  margin:6px 0 18px;padding:14px 16px;border-radius:var(--radius-sm);
  border:1px solid var(--nav-active-border);background:var(--nav-active-bg);
  border-left:4px solid var(--cyan);
}
.note-highlight .nh-label{
  display:block;font-size:.68rem;text-transform:uppercase;letter-spacing:.08em;
  color:var(--ink-2);margin-bottom:4px;
}
.note-highlight .nh-body{margin:0;font-size:.94rem;line-height:1.5;overflow-wrap:anywhere}
/* Kartu daftar rencana: daftar bahan ringkas + catatan pengajuan. */
.plan-materials{display:flex;flex-direction:column;gap:8px;padding:12px 14px;
  border:1px solid var(--line);border-radius:var(--radius-sm);background:var(--tint-3)}
.plan-materials .pm-label{font-size:.68rem;text-transform:uppercase;letter-spacing:.07em;color:var(--ink-2)}
.plan-note-line{margin:0;font-size:.88rem;line-height:1.5;overflow-wrap:anywhere}
.plan-note-line>span{font-weight:600}
@media (max-width:640px){
  .plan-steps{margin:2px 0 16px}
  .note-highlight{padding:13px 14px}
}

/* Nomor RP pada kartu Rencana Pembelian berada di dalam kartu mengambang
   (.sheet-card), bukan .lab-card — jadi perlu ikut aturan --code-ink
   (hitam pekat di tema terang, putih di tema gelap) seperti kode lain. */
.sheet-card .code-ink,
.sheet-card h2.mono,
.sheet-card input.code-ink{color:var(--code-ink)}

/* ================= PENYESUAIAN BATCH (pengajuan + persetujuan) ============ */
/* Form pengajuan disembunyikan di dalam <details> supaya kartu penyesuaian tetap
   ringkas: yang terlihat lebih dulu adalah status pengajuan & keputusan atasan. */
.adj-form-wrap>summary{list-style:none;display:inline-flex;align-items:center;gap:8px;cursor:pointer}
.adj-form-wrap>summary::-webkit-details-marker{display:none}
.adj-form-wrap[open]>summary{margin-bottom:6px}

/* ==========================================================================
   PANAH COMBOBOX (select) TIDAK BOLEH MENABRAK TEKS / PLACEHOLDER
   --------------------------------------------------------------------------
   Panah digambar sendiri (background-position:right 10px, lebar 16px) sehingga
   butuh ruang kanan minimal ~30px. Beberapa aturan lama menimpa padding-right
   combobox menjadi 9–10px (.search select, .plan-table select, .recipe-row select,
   .pack-row select, .plan-table input+select) sehingga teks/placeholder berjalan
   DI BAWAH panah — inilah keluhan "panah ke bawah menabrak placeholder".
   Blok ini diletakkan paling akhir + cukup spesifik supaya selalu menang.
   ========================================================================== */
select,
.search select,
.filter-card select,
.field select,
table.data select,
table.data select.unit-input,
table.data select.mat-select,
.plan-table select,
.plan-table select.unit-pick,
.plan-table select.sup-pick,
.recipe-row select,
.recipe-table select.unit-input,
.recipe-table select.mat-select,
.pack-row select,
.pop-body select,
.unit-pick,
.sup-pick,
.mat-pick,
.unit-input,
.mat-select{
  padding-right:32px!important;
  text-overflow:ellipsis;
}
/* Di layar sempit panah sedikit didekatkan tepi supaya ruang teks tetap lega. */
@media (max-width:640px){
  select,.search select,.filter-card select,.field select,
  .plan-table select,.recipe-row select,.pack-row select,.pop-body select{
    padding-right:30px!important;
  }
  /* Combobox di baris pencarian diberi lebar minimum yang cukup untuk teksnya. */
  .search select{min-width:132px}
}

/* Lencana pada tombol menu (HP): total tugas yang masih menggantung di semua menu
   supaya tetap terlihat walau menu samping sedang tertutup. */
.icon-btn{position:relative}
.icon-badge{position:absolute;top:-4px;right:-6px;margin:0;min-width:18px;height:18px;font-size:.62rem;
  border:2px solid var(--panel);box-shadow:none}

/* ====== FILTER PENCARIAN MUTASI STOK (1 baris di desktop, membungkus di HP) ===== */
/* Satu baris flex: kolom pencarian tumbuh mengisi sisa ruang, dropdown & tanggal
   punya lebar proporsional, tombol di ujung. Semua memakai `min-width:0` supaya bisa
   menyusut (tanpa itu kontrol saling menumpuk / meluber di layar sempit). */
.stock-filter{display:flex;flex-wrap:wrap;gap:10px;align-items:flex-end;width:100%}
.stock-filter .sf-q{flex:1 1 240px;min-width:180px}
.stock-filter .sf-q input[type=search]{width:100%;min-width:0}
.stock-filter > select{flex:0 1 170px;min-width:132px;width:auto}
.stock-filter .sf-date{flex:0 1 150px;min-width:126px}
.stock-filter .sf-date > input{flex:1 1 auto;min-width:0;width:100%}
.stock-filter .sf-foot{display:flex;gap:8px;align-items:center;flex:0 0 auto;flex-wrap:wrap}
.stock-filter .live-count{flex:1 1 100%}
/* Tablet & HP: dropdown berbagi baris 2 kolom, pencarian & tombol selebar kartu. */
@media (max-width:1024px){
  .stock-filter .sf-q{flex:1 1 100%}
  .stock-filter > select{flex:1 1 calc(33.333% - 8px);min-width:120px}
  .stock-filter .sf-date{flex:1 1 calc(33.333% - 8px)}
}
@media (max-width:640px){
  .stock-filter > select{flex:1 1 calc(50% - 8px)}
  .stock-filter .sf-date{flex:1 1 calc(50% - 8px)}
  .stock-filter .sf-date > span{display:none}   /* label periode cukup sekali */
  .stock-filter .sf-foot{flex:1 1 100%}
  .stock-filter .sf-foot .btn{flex:1 1 auto;justify-content:center}
}
@media (max-width:400px){
  .stock-filter > select,.stock-filter .sf-date{flex:1 1 100%}
}

/* ============ RENCANA PEMBELIAN: jarak & penekanan isi =================== */
/* Kartu perkembangan (Pengajuan → Persetujuan → Nota) perlu ruang lebih dari
   baris berikutnya supaya tidak terlihat menempel. */
.plan-steps{margin:2px 0 20px}
/* Catatan pengajuan ditegaskan (kartu tersendiri + tulisan hitam pekat) karena
   inilah alasan pengajuan yang paling sering dibaca penyetuju. */
.note-highlight{
  margin:6px 0 18px;padding:14px 16px;border-radius:var(--radius-sm);
  border:1px solid var(--nav-active-border);background:var(--nav-active-bg);
  border-left:4px solid var(--cyan);
}
.note-highlight .nh-label{
  display:block;font-size:.68rem;text-transform:uppercase;letter-spacing:.08em;
  color:var(--ink-2);margin-bottom:4px;
}
.note-highlight .nh-body{margin:0;font-size:.94rem;line-height:1.5;overflow-wrap:anywhere}
/* Kartu daftar rencana: daftar bahan ringkas + catatan pengajuan. */
.plan-materials{display:flex;flex-direction:column;gap:8px;padding:12px 14px;
  border:1px solid var(--line);border-radius:var(--radius-sm);background:var(--tint-3)}
.plan-materials .pm-label{font-size:.68rem;text-transform:uppercase;letter-spacing:.07em;color:var(--ink-2)}
.plan-note-line{margin:0;font-size:.88rem;line-height:1.5;overflow-wrap:anywhere}
.plan-note-line>span{font-weight:600}
@media (max-width:640px){
  .plan-steps{margin:2px 0 16px}
  .note-highlight{padding:13px 14px}
}

/* Nomor RP pada kartu Rencana Pembelian berada di dalam kartu mengambang
   (.sheet-card), bukan .lab-card — jadi perlu ikut aturan --code-ink
   (hitam pekat di tema terang, putih di tema gelap) seperti kode lain. */
.sheet-card .code-ink,
.sheet-card h2.mono,
.sheet-card input.code-ink{color:var(--code-ink)}

/* ================= PENYESUAIAN BATCH (pengajuan + persetujuan) ============ */
/* Form pengajuan disembunyikan di dalam <details> supaya kartu penyesuaian tetap
   ringkas: yang terlihat lebih dulu adalah status pengajuan & keputusan atasan. */
.adj-form-wrap>summary{list-style:none;display:inline-flex;align-items:center;gap:8px;cursor:pointer}
.adj-form-wrap>summary::-webkit-details-marker{display:none}
.adj-form-wrap[open]>summary{margin-bottom:6px}

/* ==========================================================================
   PANAH COMBOBOX (select) TIDAK BOLEH MENABRAK TEKS / PLACEHOLDER
   --------------------------------------------------------------------------
   Panah digambar sendiri (background-position:right 10px, lebar 16px) sehingga
   butuh ruang kanan minimal ~30px. Beberapa aturan lama menimpa padding-right
   combobox menjadi 9–10px (.search select, .plan-table select, .recipe-row select,
   .pack-row select, .plan-table input+select) sehingga teks/placeholder berjalan
   DI BAWAH panah — inilah keluhan "panah ke bawah menabrak placeholder".
   Blok ini diletakkan paling akhir + cukup spesifik supaya selalu menang.
   ========================================================================== */
select,
.search select,
.filter-card select,
.field select,
table.data select,
table.data select.unit-input,
table.data select.mat-select,
.plan-table select,
.plan-table select.unit-pick,
.plan-table select.sup-pick,
.recipe-row select,
.recipe-table select.unit-input,
.recipe-table select.mat-select,
.pack-row select,
.pop-body select,
.unit-pick,
.sup-pick,
.mat-pick,
.unit-input,
.mat-select{
  padding-right:32px!important;
  text-overflow:ellipsis;
}
/* Di layar sempit panah sedikit didekatkan tepi supaya ruang teks tetap lega. */
@media (max-width:640px){
  select,.search select,.filter-card select,.field select,
  .plan-table select,.recipe-row select,.pack-row select,.pop-body select{
    padding-right:30px!important;
  }
  /* Combobox di baris pencarian diberi lebar minimum yang cukup untuk teksnya. */
  .search select{min-width:132px}
}

/* Lencana pada tombol menu (HP): total tugas yang masih menggantung di semua menu
   supaya tetap terlihat walau menu samping sedang tertutup. */
.icon-btn{position:relative}
.icon-badge{position:absolute;top:-4px;right:-6px;margin:0;min-width:18px;height:18px;font-size:.62rem;
  border:2px solid var(--panel);box-shadow:none}


/* Tombol aksi "positif" (mis. Tandai Lunas) — hijau lembut, tetap ikut tema. */
.btn-ok{border-color:var(--ok-bd);background:var(--ok-bg);color:var(--ok-fg)}
.btn-ok:hover{background:var(--ok-bg);border-color:var(--ok-fg)}

/* ============ TABEL BAHAN BAKU: SEL STOK BERTINGKAT + ARAH MUTASI ========== */
/* Satuan besar di baris atas, satuan terkecil DI BAWAHNYA, dengan tanda +/− dan
   warna hijau (bertambah) / merah (berkurang) sesuai mutasi terakhir. */
/* Kolom Stok daftar bahan: angka = stok APA ADANYA (tanpa tanda +/−) dan
   warnanya menunjukkan TINGKAT stok (permintaan pemilik):
     .is-ok   = hijau  → stok aman
     .is-near = kuning → mendekati stok minimum (≤ 125% minimum)
     .is-low  = merah  → pada / di bawah stok minimum
   Kelas .is-up/.is-down (arah mutasi) SUDAH TIDAK DIPAKAI di sini. */
.stock-cell{display:inline-flex;flex-direction:column;align-items:flex-end;gap:1px;line-height:1.25}
.stock-cell .stock-main{white-space:nowrap}
.stock-cell .stock-sub{font-size:.68rem;white-space:nowrap;opacity:.85}
.stock-cell.is-ok .stock-main,
.stock-cell.is-ok .stock-sub{color:var(--green)}
.stock-cell.is-near .stock-main,
.stock-cell.is-near .stock-sub{color:var(--amber)}
.stock-cell.is-low .stock-main,
.stock-cell.is-low .stock-sub{color:var(--red)}
.stock-cell.is-low .stock-main,.stock-cell.is-near .stock-main{font-weight:700}
/* Di layar sempit sel stok tetap terbaca (angka tidak terpotong). */
@media (max-width:640px){
  .stock-cell{align-items:flex-start}
}

/* ====== KOLOM ANGKA TANPA TOMBOL −/+ (mis. Jumlah & Isi/Satuan rencana) ====== */
/* Stepper buatan kita tidak dipasang (data-no-stepper), tetapi spinbutton ASLI
   browser juga harus disembunyikan — kalau tidak, panah −/+ bawaan tetap muncul
   saat kolom difokus dan justru itulah yang ingin dihilangkan pemilik.
   Nilai tetap bisa diubah lewat scroll mouse (assets/app.js · data-wheel-edit). */
input[type=number][data-no-stepper="1"]{
  -webkit-appearance:textfield;appearance:textfield;
  padding-right:10px!important;
}
input[type=number][data-no-stepper="1"]::-webkit-outer-spin-button,
input[type=number][data-no-stepper="1"]::-webkit-inner-spin-button{
  -webkit-appearance:none;appearance:none;margin:0;width:0;height:0;
}
input[type=number][data-no-stepper="1"]{-moz-appearance:textfield}

/* =============== PEMBAYARAN: blok bukti transfer yang ditandai ============= */
/* Saat jenis pembayaran non-tunai dan bukti belum dilampirkan, blok unggah
   ditandai (garis peringatan) supaya tidak ada pembayaran tanpa bukti. */
.field.is-warn > span:first-child{color:var(--warn-fg)}
.field.is-warn{border-left:3px solid var(--warn-bd);padding-left:12px;border-radius:var(--radius-sm)}
.badge-ok{background:var(--ok-bg);color:var(--ok-fg);border:1px solid var(--ok-bd)}
.chip.is-warn{border-color:var(--warn-bd);background:var(--warn-bg);color:var(--warn-fg)}

/* ============ MUTASI PRODUK: pilih tujuan penjualan / internal ============= */
/* Dua pilihan besar (radio) supaya jelas barang keluar itu DIJUAL (jadi piutang)
   atau dipakai internal (bukan penjualan). */
.movetype-choice{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:12px}
.movetype-opt{
  display:flex;gap:10px;align-items:flex-start;padding:12px 14px;border-radius:var(--radius-sm);
  border:1px solid var(--line);background:var(--tint-3);cursor:pointer;
}
.movetype-opt input{margin-top:3px}
.movetype-opt strong{display:block;font-size:.85rem;color:var(--ink-strong)}
.movetype-opt small{display:block;font-size:.72rem;color:var(--ink-2);margin-top:2px}
.movetype-opt.is-active{border-color:var(--nav-active-border);background:var(--nav-active-bg)}

/* Status pembayaran pada kartu nota (read-only + tautan ke Pembayaran Hutang). */
.pay-status-box{
  display:flex;align-items:center;gap:14px;padding:13px 16px;border-radius:var(--radius-sm);
  border:1px solid var(--line-strong);background:var(--tint-3);min-height:58px;
}
.pay-status-box .ps-knob{
  position:relative;flex:0 0 44px;width:44px;height:25px;border-radius:999px;
  background:var(--panel-2);border:1px solid var(--line-strong);
}
.pay-status-box .ps-knob::after{
  content:'';position:absolute;top:2px;left:2px;width:19px;height:19px;border-radius:50%;background:var(--ink-2);
}
.pay-status-box .ps-text{display:flex;flex-direction:column;gap:3px;min-width:0}
.pay-status-box .ps-text strong{font-size:.95rem;color:var(--ink-strong)}
.pay-status-box .btn{margin-left:auto;flex:0 0 auto}
.pay-status-box.is-paid{border-color:var(--ok-bd);background:var(--ok-bg)}
.pay-status-box.is-paid .ps-knob{background:var(--ok-bg);border-color:var(--ok-bd)}
.pay-status-box.is-paid .ps-knob::after{transform:translateX(19px);background:var(--ok-fg)}
.pay-status-box.is-paid .ps-text strong{color:var(--ok-fg)}
/* SAKELAR status pembayaran kartu nota: kotaknya sendiri bisa ditekan (label +
   input tersembunyi) sehingga "Status pembayaran" benar-benar BERFUNGSI saat data
   nota diisi — bukan kotak baca-saja lagi. Kotak yang sudah lunas tetap tampil
   hijau seperti sebelumnya (kelas .is-paid), dan sakelar yang sedang menyala
   memakai kelas yang sama lewat :has(input:checked). */
label.pay-status-box{cursor:pointer}
.pay-status-box input[type=checkbox]{position:absolute;width:1px;height:1px;opacity:0;margin:0}
label.pay-status-box:hover{border-color:var(--focus-border)}
.pay-status-box:has(input:checked){border-color:var(--ok-bd);background:var(--ok-bg)}
.pay-status-box:has(input:checked) .ps-knob{background:var(--ok-bg);border-color:var(--ok-bd)}
.pay-status-box:has(input:checked) .ps-knob::after{transform:translateX(19px);background:var(--ok-fg)}
.pay-status-box:has(input:checked) .ps-text strong{color:var(--ok-fg)}
@media (max-width:640px){
  .pay-status-box{flex-wrap:wrap}
  .pay-status-box .btn{margin-left:0;width:100%;justify-content:center}
}

/* ════════════════════════════════════════════════════════════════════════
   GLOBAL HP: TABEL TIDAK PERNAH PERLU DIGESER KE SAMPING
   Permintaan pemilik: aplikasi dipakai di HP kecil & potret. Setiap tabel data
   disusun ulang menjadi KARTU BERTINGKAT — setiap sel diberi label kolomnya
   lewat atribut `data-label` (dipasang otomatis oleh assets/app.js dari <thead>),
   jadi tidak ada satu pun informasi yang hilang walau layar sempit.
   Tabel yang memang sudah punya tata letak HP sendiri dikecualikan
   (`.cost-table`, atau apa pun ber-atribut `data-no-stack`).
   ════════════════════════════════════════════════════════════════════════ */
@media (max-width:900px){
  table.data[data-stack]{
    display:block;width:100%;min-width:0!important;
    border-collapse:separate;border-spacing:0;font-size:.84rem;
  }
  table.data[data-stack] thead{display:none}
  table.data[data-stack] tbody,
  table.data[data-stack] tfoot{display:block;width:auto}
  table.data[data-stack] tbody tr{
    display:block;width:auto;margin:0 0 10px;padding:11px 12px;
    border:1px solid var(--line);border-radius:var(--radius-sm);background:var(--tint-3);
  }
  table.data[data-stack] tbody tr:last-child{margin-bottom:0}
  table.data[data-stack] tbody tr:hover{background:var(--tint-3)}
  table.data[data-stack] td,
  table.data[data-stack] tbody th{
    display:grid;grid-template-columns:minmax(0,100px) minmax(0,1fr);
    gap:3px 10px;align-items:start;width:auto;padding:5px 0;border:0;
    border-bottom:1px dashed var(--row-border);text-align:left!important;
  }
  table.data[data-stack] tr > *:last-child{border-bottom:0}
  table.data[data-stack] td::before{
    content:attr(data-label);font-size:.65rem;font-weight:700;letter-spacing:.05em;
    text-transform:uppercase;color:var(--ink-2);padding-top:2px;overflow-wrap:anywhere;
  }
  table.data[data-stack] td:not([data-label])::before{content:none}
  table.data[data-stack] td.stack-full{display:block}
  table.data[data-stack] td > *{min-width:0}
  table.data[data-stack] td .cell-stack{width:100%}
  table.data[data-stack] td input,
  table.data[data-stack] td select,
  table.data[data-stack] td textarea{width:100%;max-width:none}
  table.data[data-stack] td.ta-c .btn{width:100%}
  table.data[data-stack] tfoot tr{display:block;width:auto}
  table.data[data-stack] tfoot th{
    display:flex;align-items:baseline;justify-content:space-between;gap:10px;
    width:auto;padding:7px 2px;border:0;
  }
  /* di dalam kartu mengambang jaraknya dirapatkan (ruang lebih sempit) */
  .sheet-body table.data[data-stack] tbody tr{padding:9px 10px;margin-bottom:8px}

  /* Tabel label–nilai (tanpa <thead>, mis. halaman Pengaturan): satu baris rapi. */
  table.data[data-stack="plain"] tbody tr{
    display:flex;align-items:baseline;justify-content:space-between;gap:14px;flex-wrap:wrap;
  }
  table.data[data-stack="plain"] td,
  table.data[data-stack="plain"] tbody th{
    display:block;width:auto;border:0;padding:2px 0;text-align:right!important;
  }
  table.data[data-stack="plain"] td:first-child,
  table.data[data-stack="plain"] tbody th{text-align:left!important}

  /* Tabel tanpa judul kolom & kolomnya banyak: cukup ditumpuk tanpa label. */
  table.data[data-stack="bare"] td,
  table.data[data-stack="bare"] tbody th{display:block;width:auto;text-align:left!important}
}

/* ════════════════════════════════════════════════════════════════════════
   MUTASI STOK: SEMUA TEKS DITEGASKAN
   Permintaan pemilik: seluruh tulisan pada menu Mutasi Stok harus tegas
   (waktu, asal baris, keterangan, nilai, rujukan) — bukan abu-abu pucat.
   ════════════════════════════════════════════════════════════════════════ */
.smv-card .smv-head .smv-time,
.smv-card .smv-head .smv-src{color:var(--ink);font-weight:600}
.smv-card .smv-item strong{font-weight:700;color:var(--head-ink)}
.smv-card .smv-item small{color:var(--ink);font-weight:500}
.smv-card .smv-item .smv-note{color:var(--ink);font-weight:600}
.smv-card .smv-qty{font-weight:700;color:var(--head-ink)}
.smv-card .smv-qty .smv-unit{color:var(--ink);font-weight:600}
.smv-card .smv-qty small{color:var(--ink);font-weight:600}
.smv-card .smv-meta{color:var(--ink);font-weight:600}
.smv-card .smv-meta strong{font-weight:700}
.smv-card .smv-locked{color:var(--ink-2);font-weight:600}
.smv-card .smv-foot .badge{font-weight:700}
.stock-move-list + .pager,
.stock-move-list ~ p.muted{font-weight:600}

/* ════════════════════════════════════════════════════════════════════════
   KARTU KEPUTUSAN PERSETUJUAN: JARAK ANTAR FORM
   Dulu tombol [Setujui Rencana] menempel dengan form penolakan di bawahnya.
   ════════════════════════════════════════════════════════════════════════ */
.approval-card{display:flex;flex-direction:column;gap:20px}
.approval-card > .card-head{margin-bottom:0}

/* ════════════════════════════════════════════════════════════════════════
   RENCANA PEMBELIAN — KARTU DAFTAR (rancang ulang minimalis)
   Yang ditampilkan: nama supplier, total bahan, satuan, dan total rupiah.
   ════════════════════════════════════════════════════════════════════════ */
.plan-card .plan-hero{grid-template-columns:repeat(auto-fit,minmax(132px,1fr));gap:12px;padding:14px}
.plan-card .plan-hero > div b{font-size:.95rem}
.plan-hero .ph-supplier{
  font-family:inherit!important;font-size:.86rem!important;line-height:1.3;
  overflow-wrap:anywhere;
}
.plan-card .plan-materials{padding:10px 12px}
.plan-card .plan-materials .chip-row{gap:6px}
@media (max-width:640px){
  .plan-card .plan-hero{grid-template-columns:repeat(2,minmax(0,1fr));gap:10px;padding:12px}
  .plan-card .plan-hero > div b{font-size:.9rem}
}

/* ════════════════════════════════════════════════════════════════════════
   PEMILIH RENCANA PEMBELIAN (kartu "Buat Nota dari Rencana Pembelian")
   Permintaan pemilik: pada baris daftar harus langsung terlihat NAMA BARANG,
   JUMLAH, dan NOMINAL-nya — tanpa harus membuka apa pun.
   ════════════════════════════════════════════════════════════════════════ */
.plan-pick-card .pick-items{
  margin:0;font-size:.79rem;font-weight:600;color:var(--ink);line-height:1.45;
  padding:10px 12px;border-radius:var(--radius-sm);
  border:1px dashed var(--line-strong);background:var(--tint-3);
}
.move-item .mv-items{color:var(--ink)!important;font-weight:600}
.move-item .mv-qty strong{display:block;font-weight:700;color:var(--head-ink);margin-bottom:2px}
.move-item .mv-qty .btn{margin-top:6px}
@media (max-width:640px){
  /* di HP tombol [Buka] jadi selebar kartu supaya mudah ditekan */
  .move-item .mv-qty{width:100%;text-align:left}
  .move-item .mv-qty .btn{width:100%;justify-content:center}
}

/* ════════════════════════════════════════════════════════════════════════
   GLOBAL: SEMUA TEKS DI DALAM KARTU PEKAT (tidak abu-abu)
   Permintaan pemilik: "semua hurufnya tidak hitam pekat, jadikan warna pekat
   tidak abu-abu pada semua modul".
   Dua langkah:
     1. Token warna dipertegas (tema gelap dibuat lebih terang, tema terang
        dibuat lebih hitam) — otomatis berlaku ke SELURUH komponen yang memakai
        --ink / --ink-2 / --ink-3 (110 tempat), bukan hanya kartu.
     2. Di dalam kartu/panel, warna dasar teks memakai --ink-strong sehingga
        tulisan biasa benar-benar pekat; teks sekunder (.muted) tetap punya
        tingkatan sendiri dengan warna yang sudah dipertegas di langkah 1.
   ⚠️ Ditulis di PALING AKHIR berkas supaya menang dari blok :root /
   html[data-theme] yang ada di atas (spesifisitas sama → yang belakangan menang).
   ════════════════════════════════════════════════════════════════════════ */
:root{
  --ink:#EEF5FF;
  --ink-2:#CAD8EA;
  --ink-3:#A9BAD0;
  --ink-strong:#FFFFFF;
  /* ikon/panah kontrol ikut lebih terang agar seragam dengan teks pekat */
  --select-caret:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23CAD8EA' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  --search-icon:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23CAD8EA' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='m20 20-3.6-3.6'/%3E%3C/svg%3E");
}
html[data-theme="light"]{
  --ink:#0C1630;
  --ink-2:#333E58;
  --ink-3:#414D69;
  --ink-strong:#04081A;
  --select-caret:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23333E58' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  --search-icon:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23333E58' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='m20 20-3.6-3.6'/%3E%3C/svg%3E");
}
/* Warna dasar teks di dalam kartu & panel = paling pekat. */
.lab-card,
.sheet-card,
.modal-card,
.pop-body,
.kpi,
.preview-box,
.mini-stats,
.metric-row,
.plan-hero,
.batch-list,
.timeline,
.log-list,
.role-cards{
  color:var(--ink-strong);
}
/* Label/penjelas kecil tetap punya tingkatan, tapi sudah jauh lebih pekat. */
.lab-card .muted,
.lab-card .muted.small,
.lab-card small,
.lab-card .small,
.sheet-card .muted,
.sheet-card small,
.modal-card .muted,
.modal-card small{
  font-weight:500;
}
.lab-card .muted,
.sheet-card .muted,
.modal-card .muted{color:var(--ink-2)}
/* Judul kolom tabel = teks tegas, bukan abu pudar. */
table.data thead th{color:var(--ink-2);font-weight:700}
table.data tfoot th{color:var(--ink-strong);font-weight:700}
/* Kode (mono) selalu pekat di dalam kartu. */
.lab-card .mono,
.sheet-card .mono{font-weight:600}
/* Chip, pill, badge, tab: teksnya ditegaskan supaya tidak terlihat abu. */
.chip,.pill,.badge,.tab,.kpi-label,.kpi-foot{font-weight:650}
.chip,.badge-soft,.pill-soft{color:var(--ink)}
.tab{color:var(--ink-2)}
.kpi-label,.kpi-foot,.metric-row span,.plan-hero>div span{color:var(--ink-2);font-weight:700}

/* ════════════════════════════════════════════════════════════════════════
   MUTASI STOK: NOMOR (ID) SETIAP MUTASI
   Setiap kartu mutasi punya nomor sendiri yang mudah disebut saat penelusuran
   ("mutasi #138"). Ditampilkan di kepala kartu dan di baris meta.
   ════════════════════════════════════════════════════════════════════════ */
.smv-card .smv-id{
  font-family:var(--mono);font-size:.72rem;font-weight:700;letter-spacing:.02em;
  padding:3px 9px;border-radius:20px;border:1px solid var(--line-strong);
  background:var(--chip-bg);color:var(--code-ink);white-space:nowrap;
}
.smv-card .smv-meta .mono{color:var(--code-ink)}

/* ════════════════════════════════════════════════════════════════════════
   KEPALA HALAMAN YANG MENEMPEL HARUS PUNYA LATAR PEKAT
   `--topbar-bg` adalah gradien setengah transparan (agar menyatu dengan latar
   bergradien halaman). Begitu kepala benar-benar menempel di atas, isi halaman
   yang lewat di bawahnya akan tampak menembus tulisan judul. Diberi warna dasar
   pekat di bawah gradiennya.
   ════════════════════════════════════════════════════════════════════════ */
.topbar,.topbar-main{
  background-color:var(--bg-2);
  background-image:var(--topbar-bg);
}

/* ════════════════════════════════════════════════════════════════════════
   TUJUAN PENGADAAN pada kartu Detail Pembelian (Rencana Pembelian)
   Permintaan pemilik: alasan pengajuan harus terbaca di kartu Detail Pembelian,
   sebelum daftar bahannya — bukan hanya terselip di judul kartu.
   ════════════════════════════════════════════════════════════════════════ */
.purpose-strip{
  display:flex;flex-wrap:wrap;align-items:baseline;gap:6px 14px;
  margin:0 0 12px;padding:11px 14px;border-radius:var(--radius-sm);
  border:1px solid var(--line-strong);background:var(--tint-3);
  border-left:3px solid var(--cyan);
}
.purpose-strip .pp-label{
  font-size:.66rem;letter-spacing:.06em;text-transform:uppercase;
  color:var(--ink-2);font-weight:700;white-space:nowrap;
}
.purpose-strip .pp-body{display:flex;flex-wrap:wrap;align-items:baseline;gap:4px 10px;min-width:0;flex:1 1 auto}
.purpose-strip .pp-name{font-size:.92rem;font-weight:700;color:var(--code-ink);overflow-wrap:anywhere}
.purpose-strip .pp-hint{font-size:.76rem;color:var(--ink-2);font-weight:600;overflow-wrap:anywhere}
.purpose-strip .chip{font-size:.68rem}
@media (max-width:640px){
  .purpose-strip{padding:10px 12px;gap:4px 10px}
  .purpose-strip .pp-label{font-size:.64rem;width:100%}
  .purpose-strip .pp-name{font-size:.88rem}
}

/* ════════════════════════════════════════════════════════════════════════
   DETAIL NOTA PEMBELIAN: LAMPIRAN NOTA + BUKTI PEMBAYARAN BERDAMPINGAN
   (permintaan pemilik — Bukti Pembayaran dipindah dari kartu utama ke bagian
   bawah, sejajar dengan Lampiran Nota, dan KEDUA kartu memakai SATU desain
   yang sama: kepala (chip kode + pill jenis) → grid fakta bisnis → strip
   thumbnail yang bisa diklik untuk pratinjau.)
   ════════════════════════════════════════════════════════════════════════ */
/* Kedua kartu WAJIB sama tinggi: grid-nya di-stretch dan tiap kartu dibuat
   flex kolom, sehingga kartu yang isinya lebih sedikit tetap SEPANJANG
   pasangannya (bukan lebih pendek). */
/* Dua kolom sejak tablet (360px terlalu lebar → di 768px kartu jadi menumpuk);
   di ≤640px tetap ditumpuk sesuai aturan HP di bawah. */
.detail-attach{align-items:stretch;grid-template-columns:repeat(auto-fit,minmax(320px,1fr))}
.detail-attach > .lab-card{min-width:0;display:flex;flex-direction:column}
/* Catatan kaki kartu didorong ke dasar kartu → garis bawah kedua kartu rata. */
.detail-attach > .lab-card > .attach-hint{margin-top:auto;padding-top:12px}
.detail-attach > .lab-card > .empty,
.detail-attach > .lab-card > .alert{margin:auto 0}
/* Daftar berkas: satu blok per berkas/pembayaran (dipakai KEDUA kartu). */
.attach-list{display:flex;flex-direction:column;gap:12px;margin-bottom:14px}
.attach-item{
  display:flex;flex-direction:column;gap:10px;padding:12px 14px;
  border:1px solid var(--line);border-radius:var(--radius-sm);background:var(--tint-3);
}
.attach-head{display:flex;flex-wrap:wrap;align-items:center;gap:8px}
.attach-head .attach-code{
  font-family:var(--mono);font-size:.82rem;font-weight:700;color:var(--code-ink);
  padding:3px 9px;border-radius:20px;border:1px solid var(--line-strong);background:var(--chip-bg);
}
.attach-head .pill{margin-left:0}
.attach-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(110px,1fr));gap:10px}
.attach-grid > div{display:flex;flex-direction:column;gap:2px;min-width:0}
.attach-grid span{
  font-size:.63rem;letter-spacing:.05em;text-transform:uppercase;font-weight:700;color:var(--ink-2);
}
.attach-grid strong{font-size:.82rem;color:var(--ink-strong);overflow-wrap:anywhere}
.attach-grid small{font-size:.68rem;color:var(--ink-2)}
.attach-item .photo-strip{margin-bottom:0}
@media (max-width:640px){
  /* di HP dua kartu itu ditumpuk (Lampiran Nota dulu, lalu Bukti Pembayaran) */
  .detail-attach{grid-template-columns:1fr;gap:16px}
  .attach-grid{grid-template-columns:repeat(2,minmax(0,1fr))}
  .attach-item .photo-strip{gap:10px}
}

/* ════════════════════════════════════════════════════════════════════════
   ⚠️ KILAU KARTU (.lab-card::before) TIDAK BOLEH MENUTUPI TEKS  — GLOBAL
   ════════════════════════════════════════════════════════════════════════
   BUG NYATA yang dilaporkan pemilik: di TEMA TERANG, tulisan di bagian ATAS
   kartu tampak ABU-ABU (tenggelam) sedangkan tulisan di bagian bawah hitam
   pekat — makin ke bawah makin tegas, dan makin banyak kartu bersarang makin
   kelabu. Penyebabnya: `.lab-card::before` (lapisan kilau `--sheen`) adalah
   elemen BERPOSISI, sehingga menurut urutan pelukisan CSS ia dilukis di ATAS
   teks yang mengalir normal di dalam kartu. Di tema terang kilaunya
   `rgba(255,255,255,.55)` — cukup pekat untuk menjadikan teks hitam (0,0,0)
   tampil ~(136,136,136) di layar (terukur dari tangkapan layar), dan karena
   gradiennya meredup ke bawah, teks semakin ke bawah tampak makin hitam.
   Setiap `.lab-card` bersarang menambah satu lapisan kilau lagi → makin kelabu.

   Perbaikan: kartu diberi konteks tumpukan sendiri (`isolation:isolate`) dan
   kilau diturunkan ke `z-index:-1`, sehingga urutannya menjadi
   latar kartu → kilau → TEKS. Tampilan "kaca" tetap sama, tetapi teks selalu
   memakai warnanya sendiri (hitam pekat di tema terang) di KEDUA tema.
   ⚠️ Jangan mengembalikan `::before` tanpa `z-index:-1`, dan jangan menghapus
   `isolation:isolate` — tanpa itu `z-index:-1` bisa jatuh ke belakang latar
   halaman sehingga kilaunya hilang (bukan sekadar salah urutan). */
.lab-card{isolation:isolate}
.lab-card::before{z-index:-1}



/* ════════════════════════════════════════════════════════════════════════
   MUTASI STOK — arah stok pada angka kanan kartu (+hijau / −merah)
   ⚠️ BUG NYATA: aturan `.smv-card .smv-qty{color:var(--head-ink)}` (yang dibuat
   saat teks ditegaskan) MENIMPA `.pos`/`.neg` karena spesifisitasnya lebih
   tinggi, sehingga angka "−5 Liter" TIDAK pernah merah walau stok berkurang.
   Aturan di bawah menang (0,3,0) dan mengembalikan warna arah stok.
   ════════════════════════════════════════════════════════════════════════ */
.smv-card .smv-qty.pos,
.smv-card .smv-qty.pos .smv-unit,
.smv-card .smv-qty.pos small{color:var(--green)}
.smv-card .smv-qty.neg,
.smv-card .smv-qty.neg .smv-unit,
.smv-card .smv-qty.neg small{color:var(--red)}

/* ════════════════════════════════════════════════════════════════════════
   NOMOR RUJUKAN YANG BISA DIKLIK (semua kartu mutasi)
   Berupa chip kecil berikon dokumen — ukurannya tetap sejalan dengan teks
   sekitarnya (proposional), bukan tombol besar.
   ════════════════════════════════════════════════════════════════════════ */
.ref-chip{
  display:inline-flex;align-items:center;gap:5px;padding:2px 8px 2px 6px;
  margin-left:2px;border-radius:20px;border:1px solid var(--line-strong);
  background:var(--chip-bg);cursor:pointer;font:inherit;font-size:.72rem;
  line-height:1.5;transition:border-color .15s,background .15s;vertical-align:baseline;
}
.ref-chip:hover{border-color:var(--focus-border);background:var(--tint-hover)}
.ref-chip .ref-ico{display:inline-flex;flex:0 0 auto}
.ref-chip .ref-ico svg{width:12px;height:12px;fill:var(--cyan)}
.ref-chip .ref-code{font-weight:700;color:var(--code-ink)}
.smv-ref{display:inline-flex;align-items:center;gap:4px;flex-wrap:wrap}

/* ════════════════════════════════════════════════════════════════════════
   KARTU PRATINJAU LAMPIRAN — panel data bisnis
   Sisi kanan modal menampung daftar fakta (label + nilai) dan tombol menuju
   dokumen induknya. Wajib bisa menggulir sendiri di HP.
   ════════════════════════════════════════════════════════════════════════ */
.modal-side{display:flex;flex-direction:column;gap:12px;min-width:0}
.modal-side .btn-block{width:100%;justify-content:center}
.ref-card{max-width:520px}
.ref-card .modal-meta{max-height:60vh;overflow-y:auto}
@media (max-width:760px){
  .modal-side{gap:10px}
  .ref-card .modal-meta{max-height:52vh}
}

/* ════════════════════════════════════════════════════════════════════════
   TABEL BIAYA TAMBAHAN BATCH: JANGAN MEMAKSA LEBAR 480px DI HP
   ⚠️ BUG NYATA (ketemu saat menguji ulang): blok HP di tengah berkas menulis
   `table.data.compact{min-width:480px}`. Karena spesifisitasnya SAMA (0,2,0)
   dengan `table.data.cost-table{min-width:0}` dan letaknya LEBIH BAWAH, aturan
   itu menang sehingga tata letak HP milik tabel biaya (yang sudah menumpuk per
   baris) tetap dipaksa selebar 480px → kartu harus digeser ke samping pada
   batch yang punya rincian biaya. Aturan di bawah (paling akhir berkas) menang.
   ════════════════════════════════════════════════════════════════════════ */
@media (max-width:760px){
  table.data.compact.cost-table{min-width:0!important;width:100%}
  table.data.compact.cost-table tfoot th{min-width:0}
}

/* ════════════════════════════════════════════════════════════════════════
   MUTASI STOK — baris "Diinput Oleh" berdiri SENDIRI di bawah rujukan
   (permintaan pemilik: jangan berdampingan dengan nomor rujukan). Diberi
   garis pemisah halus supaya jelas ini baris terpisah, bukan bagian rujukan.
   ════════════════════════════════════════════════════════════════════════ */
.smv-card .smv-meta-who{
  margin-top:-2px;padding-top:6px;border-top:1px dashed var(--row-border);
}
.smv-card .smv-meta-who span{color:var(--ink-2)}
.smv-card .smv-meta-who strong{color:var(--ink-strong);font-weight:700}

/* ════════════════════════════════════════════════════════════════════════
   KARTU "CATAT MUTASI PRODUK JADI" — BARIS PRODUK (multi-produk)
   Satu baris = satu kartu kecil berisi produk, jumlah, satuan, isi/satuan,
   dan pratinjau stok. Dirancang untuk HP: kolom melipat 2-2, tinggi nyaman
   disentuh, dan informasi penting (stok → setelah) selalu terlihat.
   ════════════════════════════════════════════════════════════════════════ */
.mut-rows{display:flex;flex-direction:column;gap:14px}
.mut-row{
  display:flex;flex-direction:column;gap:10px;padding:12px 14px;
  border:1px solid var(--line-strong);border-radius:var(--radius-sm);
  background:var(--tint-3);
}
.mut-row-head{display:flex;align-items:center;gap:10px}
.mut-row-no{
  flex:1 1 auto;min-width:0;font-size:.78rem;font-weight:700;color:var(--ink-strong);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.mut-row-del{
  flex:0 0 auto;width:28px;height:28px;border-radius:50%;cursor:pointer;
  border:1px solid var(--err-bd);background:var(--err-bg);color:var(--err-fg);
  font-size:1rem;line-height:1;display:grid;place-items:center;padding:0;
}
.mut-row-del:hover{background:var(--err-bg-hover)}
.mut-row-grid{margin:0}
.mut-row .field>span{font-size:.72rem}
.mut-row-preview{
  display:flex;align-items:baseline;gap:8px;flex-wrap:wrap;
  padding:8px 10px;border-radius:var(--radius-sm);background:var(--tint-2);
  border:1px dashed var(--line);
}
.mut-row-preview span{font-size:.68rem;letter-spacing:.04em;text-transform:uppercase;color:var(--ink-2);font-weight:700}
.mut-row-preview strong{font-size:.86rem;color:var(--ink-strong);font-weight:700}
.mut-row-preview strong.neg.is-warn{color:var(--red)}
.mut-row-preview em{font-size:.72rem;color:var(--ink-2);font-style:normal}
@media (max-width:640px){
  .mut-row{padding:11px 12px;gap:9px}
  /* Jumlah & Satuan berdampingan, "Isi per satuan" satu baris penuh. */
  .mut-row-grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}
  .mut-row-grid .field:not(.span-2){min-width:0}
  .mut-row-grid .field:last-child{grid-column:1 / -1}
}

/* ════════════════════════════════════════════════════════════════════════
   KARTU DAFTAR RENCANA PEMBELIAN — DIRANCANG ULANG (permintaan pemilik)
   · .plan-hero tanpa <small> (label + nilai saja, tidak menumpuk)
   · sel pertama = Tujuan Pengadaan (menggantikan "Total Bahan")
   · .plan-materials = DAFTAR BAHAN: nama + total jumlah belanja + satuan
   ════════════════════════════════════════════════════════════════════════ */
.plan-card .plan-hero > div b{line-height:1.35}
.plan-card .plan-head .product-code{
  display:block;margin-top:3px;color:var(--ink-2);font-family:var(--mono);font-size:.74rem;
}
/* Daftar bahan: satu baris per bahan (nama di kiri, jumlah di kanan). */
.pm-list{display:flex;flex-direction:column;gap:0;list-style:none;margin:2px 0 0;padding:0}
.pm-list li{
  display:flex;align-items:baseline;gap:12px;justify-content:space-between;
  padding:6px 0;border-bottom:1px dashed var(--row-border);min-width:0;
}
.pm-list li:last-child{border-bottom:0;padding-bottom:0}
.pm-list li:first-child{padding-top:0}
.pm-list .pm-name{
  min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  font-size:.82rem;color:var(--ink-strong);font-weight:600;
}
.pm-list .pm-qty{flex:0 0 auto;font-size:.82rem;font-weight:700;color:var(--ink-strong);white-space:nowrap}
.pm-list .pm-more{display:block;font-size:.74rem;color:var(--ink-2);padding:6px 0 0;border-bottom:0}
@media (max-width:640px){
  .plan-card .plan-hero{grid-template-columns:repeat(2,minmax(0,1fr));gap:12px}
  .pm-list .pm-name{font-size:.8rem}
}

/* ════════════════════════════════════════════════════════════════════════
   KARTU DAFTAR PEMBELIAN BARANG & JASA (tab Pembelian)
   · tanggal pembelian ditampilkan sebagai teks biasa di bawah nomor nota
   · Tujuan Pengadaan / Supplier / Area-Unit dipindah KE DALAM .purchase-hero
     (bukan lagi chip) — nilai teksnya tidak boleh memakai font mono
   ════════════════════════════════════════════════════════════════════════ */
.purchase-hero > div b.np-strong{
  font-family:inherit;font-size:.9rem;line-height:1.3;overflow-wrap:anywhere;
}
.purchase-card .purchase-head .product-code{
  display:block;margin-top:3px;color:var(--ink-2);font-family:var(--mono);font-size:.74rem;
}

/* ════════════════════════════════════════════════════════════════════════
   BARIS RINCIAN LEBIH LEGA DI HP (tabel detail Barang & Jasa)
   Permintaan pemilik: barisnya jangan terlalu menempel saat tampilan mobile.
   ════════════════════════════════════════════════════════════════════════ */
@media (max-width:900px){
  table.data.np-detail-table tbody tr{padding:14px 14px;margin-bottom:14px}
  table.data.np-detail-table tbody td{padding:7px 0}
  table.data.np-detail-table tbody td::before{padding-top:1px}
  table.data.np-detail-table tbody td:last-child{border-bottom:0}
}
@media (max-width:640px){
  table.data.np-detail-table tbody tr{padding:15px 14px;margin-bottom:16px}
  table.data.np-detail-table tbody td{padding:8px 0}
}

/* ════════════════════════════════════════════════════════════════════════
   KARTU NOTA BARANG & JASA — JARAK TOMBOL / RINCIAN & PENEGASAN TOTAL
   Permintaan pemilik:
     · jarak antar baris SUBTOTAL ITEM / DISKON / PAJAK / TOTAL diperbesar,
     · bagian TOTAL dibuat lebih menonjol (lebih besar & lebar penuh),
     · kartu STATUS PEMBAYARAN dan kedua kartu LAMPIRAN tidak lagi menempel.
   ════════════════════════════════════════════════════════════════════════ */
/* ⚠️ BUG NYATA (ditemukan saat memperbaiki jarak): `.totals-grid` HANYA mengatur
   `grid-template-columns` tanpa `display:grid`, sehingga keempat kartu
   (Subtotal item / Diskon / Pajak-ongkos / Total) selama ini DITUMPUK selebar
   penuh tanpa jarak yang benar. `display:grid` wajib ada — jangan dihapus. */
/* Kolom eksplisit (bukan auto-fit): kartu Total memakai `grid-column:1/-1`,
   sehingga kalau grid-nya auto-fit akan meninggalkan kolom kosong di baris
   pertama dan kartu kecil jadi sempit. Tiga kartu pertama dibagi rata. */
#form-nonproduksi .totals-grid{
  display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:14px;margin-top:20px;
}
/* POLESAN UMUM: semua `.totals-grid` (dipakai juga modul lain) ikut diperbaiki. */
.totals-grid{display:grid}
#form-nonproduksi .total-card{padding:14px 16px}
#form-nonproduksi .total-card span{font-size:.68rem}
#form-nonproduksi .total-card b,
#form-nonproduksi .total-card strong{font-size:1.05rem}
/* TOTAL: satu baris penuh + angka paling besar supaya langsung jadi perhatian. */
#form-nonproduksi .total-card.is-total{
  grid-column:1 / -1;padding:18px 20px;margin-top:4px;
  border-color:var(--focus-border);background:var(--preview-bg);
}
#form-nonproduksi .total-card.is-total b,
#form-nonproduksi .total-card.is-total strong{font-size:1.6rem;line-height:1.2}
@media (max-width:900px){
  #form-nonproduksi .totals-grid{grid-template-columns:repeat(3,minmax(0,1fr));gap:12px}
}
@media (max-width:640px){
  #form-nonproduksi .totals-grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:12px}
  #form-nonproduksi .total-card.is-total{padding:16px}
  #form-nonproduksi .total-card.is-total b,
  #form-nonproduksi .total-card.is-total strong{font-size:1.38rem}
}
/* Kartu-kartu di dalam form diberi jarak lega (tidak menempel satu sama lain). */
#form-nonproduksi > .lab-card + .lab-card{margin-top:18px}
/* Kartu Bukti Pembayaran: diredupkan saat tunai (bukti opsional), sama seperti
   kartu bukti transfer pada nota pembelian bahan. */
[data-np-proof-card].is-off{opacity:.78}
[data-np-proof-card].is-off:hover{opacity:1}

/* ═══ PRATINJAU LAMPIRAN NON-GAMBAR (PDF / dokumen) DI KARTU LAMPIRAN ═══
   RIWAYAT BUG: kartu pratinjau lampiran dulu SELALU memakai <img>, sehingga
   lampiran PDF yang berhasil diunggah selalu berakhir sebagai "Gambar tidak
   bisa ditampilkan" (laporan pemilik: "upload file pdf status ter upload, tapi
   tidak bisa View"). Sekarang: PDF dirender penampil PDF bawaan browser di dalam
   <iframe>, sedangkan berkas lain (docx/xlsx/zip/…) tampil sebagai kartu berkas
   dengan tombol Buka di tab baru / Unduh. */
.doc-frame{width:100%;height:58vh;min-height:320px;border:1px solid var(--line-strong);
  border-radius:var(--radius-sm);background:#fff}
.modal-figure .doc-thumb.big{width:100%;display:flex;flex-direction:column;gap:8px;
  text-align:center;padding:24px;line-height:1.5}
.modal-figure .doc-thumb.big strong{font-size:.95rem;letter-spacing:.08em;color:var(--code-ink)}
.modal-figure .doc-thumb.big span{font-size:.8rem;color:var(--ink-2)}
@media (max-width:760px){
  .doc-frame{height:44vh;min-height:240px}
}

/* Kartu pesanan online: baris ubah status pengiriman. */
.online-ship{margin-top:12px;padding-top:12px;border-top:1px dashed var(--line-strong)}
.online-ship .search{display:flex;flex-wrap:wrap;gap:8px}
.online-ship .search input[type=text],
.online-ship .search select{flex:1 1 130px;min-width:0}
/* Tombol "Lihat berkas" PDF (pop-up lampiran) & label QR produk. */
.pill-penjualan{border-color:var(--ok-bd);background:var(--ok-bg);color:var(--ok-fg)}
/* Utilitas: label yang hanya dibaca pembaca layar (dipakai baris keranjang kasir). */
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip-path:inset(50%);white-space:nowrap;border:0}
.lab-card.is-off{opacity:.72}

/* ═══════════════════════════════════════════════════════════════════════════
   KASIR (POS) SATU LAYAR — rancang ulang halaman Kasir.
   Halaman TIDAK menggulir: kolom kiri (pindai + katalog + riwayat) dan kolom
   kanan (keranjang) masing-masing menggulir DI DALAM kartunya sendiri.
   Di HP keranjang & panel berupa lapisan melayang yang dibuka tombol khusus.
   ═══════════════════════════════════════════════════════════════════════════ */
body.kasir-full .shell{height:100dvh;overflow:hidden}
body.kasir-full .sidebar{overflow-y:auto}
body.kasir-full .main{min-height:0}
body.kasir-full .content{gap:0;padding:12px 16px 16px;max-width:1600px;flex:1 1 auto;min-height:0;
  height:auto;overflow:hidden}
body.kasir-full .content > .alert{flex:0 0 auto}
.pos-wrap{flex:1 1 auto;min-height:0;position:relative}
.pos-form{display:grid;grid-template-columns:minmax(0,1fr) 384px;gap:18px;height:100%;min-height:0}

/* ---------- KOLOM KIRI: pindai + katalog + riwayat (menggulir sendiri) ---- */
.pos-left{display:flex;flex-direction:column;gap:14px;min-height:0;min-width:0}
.pos-scan-card{flex:0 0 auto;padding:14px 16px}
.pos-scan-card .kasir-scan-bar{align-items:center}
.pos-scan-card .kasir-scan-input{height:46px}
.kasir-scan-btn{flex:0 0 auto;display:inline-flex;align-items:center;gap:7px;height:46px;
  padding:0 14px;font-size:.82rem}
.kasir-scan-btn svg{width:18px;height:18px;fill:currentColor}
.kasir-scan-btn.is-active{border-color:var(--ok-bd);color:var(--ok-fg);background:var(--ok-bg)}
.pos-scan-card .kasir-camera{margin-top:12px}
.pos-scan-card .kasir-camera video{max-height:34vh}

.pos-catalog-card{flex:1 1 auto;min-height:0;display:flex;flex-direction:column;padding:12px 14px;
  border:1px solid var(--line);border-radius:var(--radius);background:var(--panel);
  box-shadow:var(--shadow);position:relative;isolation:isolate}
.pos-catalog-card::before{content:'';position:absolute;inset:0;border-radius:inherit;
  background:var(--sheen);z-index:-1;pointer-events:none}
.pos-catalog-head{display:flex;align-items:center;justify-content:space-between;gap:12px;
  flex:0 0 auto;padding:2px 2px 10px}
.pos-catalog-title{font-weight:700;color:var(--head-ink);font-size:.92rem}
.count-chip.has-q{border-color:var(--focus-border);color:var(--ink)}
.kasir-catalog{flex:1 1 auto;min-height:0;overflow-y:auto;overscroll-behavior:contain;
  display:grid;grid-template-columns:repeat(auto-fill,minmax(190px,1fr));gap:10px;
  align-content:start;padding:2px}
.kasir-catalog .empty{grid-column:1/-1;margin:8px 2px}
.pos-catalog-empty{margin:10px 2px 2px;color:var(--ink-2);font-size:.85rem}
.kasir-cat-item{display:flex;flex-direction:column;gap:4px;text-align:left;cursor:pointer;
  border:1px solid var(--line);border-radius:var(--radius-sm);background:var(--tint-3);
  padding:10px 12px;color:var(--ink);font:inherit;min-height:74px}
.kasir-cat-item:hover{border-color:var(--focus-border);background:var(--tint-hover)}
.kasir-cat-item:active{transform:translateY(1px)}
.kasir-cat-item strong{font-size:.85rem;line-height:1.25;color:var(--ink-strong);
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.kasir-cat-code{font-size:.68rem;color:var(--ink-3)}
.kasir-cat-meta{display:flex;align-items:baseline;justify-content:space-between;gap:8px;margin-top:auto}
.kasir-cat-price{font-size:.82rem;font-weight:700;color:var(--cyan)}
.kasir-cat-stock{font-size:.68rem;color:var(--ink-2)}
.kasir-cat-item[data-stock="0"] .kasir-cat-stock{color:var(--err-fg);font-weight:600}
.kasir-catalog.is-filtered{grid-template-columns:repeat(auto-fill,minmax(240px,1fr))}
.kasir-catalog.is-filtered .kasir-cat-item{min-height:0}

.pos-recent-card{flex:0 0 auto;max-height:26vh;display:flex;flex-direction:column;
  border:1px solid var(--line);border-radius:var(--radius);background:var(--panel);
  box-shadow:var(--shadow);padding:10px 14px;position:relative;isolation:isolate}
.pos-recent-card::before{content:'';position:absolute;inset:0;border-radius:inherit;
  background:var(--sheen);z-index:-1;pointer-events:none}
.pos-recent-head{display:flex;align-items:center;justify-content:space-between;gap:10px;
  font-weight:700;color:var(--head-ink);font-size:.88rem;padding-bottom:6px;flex:0 0 auto}
.kasir-recent{overflow-y:auto;overscroll-behavior:contain;display:flex;flex-direction:column;gap:6px}
.kasir-recent-item{display:grid;grid-template-columns:auto minmax(0,1fr) auto auto auto;gap:10px;
  align-items:center;border:1px solid var(--row-border);border-radius:var(--radius-sm);
  padding:7px 10px;background:var(--tint-3);font-size:.8rem}

/* ---------- KOLOM KANAN (desktop): keranjang selalu tampil ---------------- */
.pos-right{display:flex;flex-direction:column;min-height:0;min-width:0}
.pos-cart-card{flex:1 1 auto;min-height:0;display:flex;flex-direction:column;gap:10px;
  border:1px solid var(--line-strong);border-radius:var(--radius);background:var(--panel);
  box-shadow:var(--shadow);padding:14px;position:relative;isolation:isolate}
.pos-cart-card::before{content:'';position:absolute;inset:0;border-radius:inherit;
  background:var(--sheen);z-index:-1;pointer-events:none}
.pos-cart-head{display:flex;align-items:center;justify-content:space-between;gap:10px}
.pos-cart-title{display:inline-flex;align-items:center;gap:8px;font-weight:700;color:var(--head-ink);
  font-size:.95rem}
.pos-cart-title svg{width:19px;height:19px;fill:var(--cyan)}
.pos-cart-count{flex:0 0 auto;align-self:flex-start}
/* Tombol tutup keranjang: hanya berguna di HP (di desktop keranjang selalu tampil). */
.pos-cart-close{display:none}
.pos-cart-card .kasir-lines{flex:1 1 auto;min-height:0;overflow-y:auto;overscroll-behavior:contain;
  padding-right:2px;margin-top:2px}
.pos-cart-card .kasir-total{flex:0 0 auto;margin-top:2px;padding-top:10px;
  border-top:1px dashed var(--line-strong)}
.pos-cart-buttons{flex:0 0 auto;display:flex;flex-direction:column;gap:8px}
.pos-cart-buttons .btn{min-height:46px;justify-content:center}

/* ---------- PANEL Pelanggan & Pembayaran ---------------------------------- */
/* Desktop: kartu biasa di bawah kolom kanan (area .pos-panels menggulir bila
   sempit). HP: lapisan melayang dari bawah, dibuka tombol ikon kiri bawah. */
.pos-panels{display:contents}
/* Lapisan redup: menandai panel sebagai modal + bisa diklik untuk menutup. */
.pos-scrim{position:absolute;inset:0;z-index:40;display:none;background:rgba(4,8,14,.5);
  border-radius:var(--radius)}
.pos-scrim.is-open{display:block}
html[data-theme="light"] .pos-scrim{background:rgba(28,40,70,.32)}
/* Panel = KARTU DIALOG (bukan menumpuk isi kartu keranjang) supaya tidak ada
   tombol yang tertutup; ditutup lewat "Selesai ✕", klik latar, atau Esc. */
.pos-panel{position:absolute;z-index:50;top:50%;left:50%;transform:translate(-50%,-50%);
  width:min(480px,94%);max-height:min(88%,680px);display:none;flex-direction:column;
  border:1px solid var(--line-strong);border-radius:var(--radius);background:var(--pop-bg);
  box-shadow:var(--shadow)}
.pos-panel.is-open{display:flex}
.pos-panel-head{display:flex;align-items:center;gap:10px;padding:12px 14px;
  border-bottom:1px solid var(--line);flex:0 0 auto}
.pos-panel-title{font-weight:700;color:var(--head-ink);flex:1 1 auto}
.pos-panel-body{flex:1 1 auto;min-height:0;overflow-y:auto;overscroll-behavior:contain;padding:14px}
.pos-panel .preview-box{margin-top:14px;grid-template-columns:repeat(2,minmax(0,1fr))}

/* ---------- Tombol melayang POS (khusus HP) ------------------------------
   Di desktop tombol Pelanggan / Diskon & Bayar tersedia di dalam kartu
   keranjang (`.pos-cart-tools`) sehingga tidak menutupi kartu lain. */
.pos-fabs{position:absolute;left:0;bottom:0;display:none;gap:10px;z-index:45}
/* Deret tombol pembuka panel di dalam kartu keranjang (desktop). */
.pos-cart-tools{display:none;gap:8px}
.pos-cart-tools .btn{flex:1 1 0;justify-content:center;display:inline-flex;align-items:center;gap:7px}
.pos-cart-tools svg{width:16px;height:16px;fill:currentColor}
.pos-fab{width:52px;height:52px;border-radius:50%;border:1px solid var(--line-strong);
  background:var(--panel);box-shadow:var(--shadow);cursor:pointer;display:grid;place-items:center;
  position:relative;color:var(--ink)}
.pos-fab svg{width:22px;height:22px;fill:var(--ink-2)}
.pos-fab:active{transform:translateY(1px)}
.pos-fab-cart{background:var(--primary-grad);border-color:transparent}
.pos-fab-cart svg{fill:#f3fdf9}
.pos-fab-badge{position:absolute;top:-4px;right:-4px;min-width:20px;height:20px;border-radius:999px;
  background:var(--amber);color:#1F1B3A;font-size:.68rem;font-weight:800;display:grid;place-items:center;
  padding:0 5px}
.pos-fab-badge:empty{display:none}
.pos-fab.has-items{box-shadow:0 0 0 3px rgba(251,191,36,.25), var(--shadow)}

/* ---------- Baris keranjang (dipakai desktop & sheet HP) ------------------ */
.kasir-line{border:1px solid var(--line);border-radius:var(--radius-sm);background:var(--tint-3);
  padding:10px}
.kasir-line.is-filled{border-color:var(--focus-border);background:var(--preview-bg)}
.kasir-line-main{display:grid;grid-template-columns:minmax(0,1fr) auto auto auto;gap:10px;align-items:center}
.kasir-line-main .field{margin:0}
.kasir-line-qty{display:flex;align-items:center;gap:4px}
.kasir-line-qty input{width:64px;text-align:center;height:40px}
.kasir-line-qty .btn{width:36px;height:40px;padding:0;justify-content:center;font-size:1.05rem;flex:0 0 auto}
.kasir-line-unit{min-width:34px;font-size:.75rem;color:var(--ink-2)}
.kasir-line-sub{font-weight:700;white-space:nowrap;min-width:86px;text-align:right}
.kasir-line-extra{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:8px;margin-top:8px}
.kasir-line-extra .field{margin:0}
.kasir-line-extra .field.inline{flex-direction:column;align-items:stretch;gap:3px}
.kasir-line-extra .field>span{font-size:.68rem;text-transform:uppercase;letter-spacing:.05em;color:var(--ink-2)}

/* ============================== MOBILE (≤980px) =========================== */
@media (max-width:980px){
  /* Tinggi mengikuti sisa layar: topbar HP 2 baris + bar navigasi bawah. */
  body.kasir-full .content{padding:10px 12px 10px!important;min-height:0;flex:1 1 auto}
  .pos-form{grid-template-columns:1fr;gap:12px;position:relative;height:100%}
  .pos-left{gap:10px}

  /* Keranjang = SHEET dari bawah; dibuka tombol keranjang melayang. */
  .pos-right{position:static}
  .pos-cart-card{position:fixed;left:0;right:0;bottom:0;top:auto;z-index:70;
    max-height:calc(100dvh - 130px);border-radius:18px 18px 0 0;transform:translateY(105%);
    transition:transform .22s ease;box-shadow:0 -18px 40px -18px rgba(0,0,0,.85);gap:8px;padding:12px 14px;
    padding-bottom:calc(12px + env(safe-area-inset-bottom,0px))}
  .pos-cart-card.is-open{transform:translateY(0)}
  .pos-cart-card::after{content:'';position:absolute;top:6px;left:50%;transform:translateX(-50%);
    width:44px;height:4px;border-radius:999px;background:var(--line-strong)}
  .pos-cart-head{padding-top:6px}
  .pos-cart-count{display:none}
  .pos-cart-close{display:inline-flex}

  /* Panel = lapisan penuh dari bawah (di atas keranjang) + lapisan redup penuh. */
  .pos-panels{display:contents}
  .pos-scrim{position:fixed;inset:0;z-index:55;border-radius:0;background:rgba(4,8,14,.55)}
  .pos-panel{position:fixed;inset:auto 0 0 0;top:auto;left:0;width:100%;
    max-height:calc(100dvh - 120px);border-radius:18px 18px 0 0;z-index:60;
    transform:translateY(105%);display:flex;transition:transform .22s ease;background:var(--pop-bg)}
  .pos-panel.is-open{transform:translateY(0)}
  .pos-panel .preview-box{grid-template-columns:repeat(2,minmax(0,1fr))}

  /* Tombol keranjang melayang di kanan bawah; ikon pelanggan & bayar di kirinya.
     ⚠️ z-index WAJIB di atas `.bottom-nav` (30) dan dinaikkan di atas bar itu —
     kalau tidak, tautan navigasi bawah mencegat ketukan (bug nyata yang tertangkap
     uji hit-test: tombol terlihat tapi tidak bisa ditekan). */
  .pos-fabs{display:flex;right:14px;left:auto;align-items:center;gap:10px;z-index:45;
    bottom:calc(74px + env(safe-area-inset-bottom,0px))}
  .pos-fab{width:50px;height:50px}
  .pos-fab-cart{width:58px;height:58px}

  /* Katalog: hasil pencarian melapang penuh agar stok & harga terbaca. */
  .kasir-catalog{grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:8px}
  .kasir-cat-item{padding:9px 10px;min-height:70px}
  .kasir-catalog.is-filtered{grid-template-columns:1fr}
  .kasir-catalog.is-filtered .kasir-cat-item{flex-direction:row;align-items:center;gap:10px}
  .kasir-catalog.is-filtered .kasir-cat-item strong{flex:1 1 auto;-webkit-line-clamp:2}
  .kasir-catalog.is-filtered .kasir-cat-code{display:none}
  .kasir-catalog.is-filtered .kasir-cat-meta{margin-top:0;flex-direction:column;align-items:flex-end;gap:2px}

  /* Baris keranjang menyusun ulang agar tidak sempit di layar 320–430px. */
  .kasir-line-main{grid-template-columns:1fr auto;gap:8px}
  .kasir-line-main .kasir-line-product{grid-column:1 / -1}
  .kasir-line-sub{grid-column:1;text-align:left;min-width:0}
  /* Ruang bebas agar tombol melayang tidak menutupi isi yang paling bawah. */
  .kasir-catalog{padding-bottom:72px}
  .kasir-recent{padding-bottom:72px}
  .kasir-recent-item{grid-template-columns:1fr auto;gap:4px 8px;font-size:.76rem}
  .kasir-recent-item .row-actions{grid-column:1 / -1;justify-content:flex-start}
  .pos-recent-card{max-height:30vh}
  .pos-scan-card .kasir-camera video{max-height:30vh}
}

/* Desktop: tombol pembuka panel ada di kartu keranjang (FAB disembunyikan). */
@media (min-width:981px){
  .pos-cart-tools{display:flex}
}

/* Layar sedang: katalog hasil filter tetap 2 kolom agar tidak terlalu lapang. */
@media (max-width:1240px) and (min-width:981px){
  .pos-form{grid-template-columns:minmax(0,1fr) 350px}
  .kasir-catalog{grid-template-columns:repeat(auto-fill,minmax(170px,1fr))}
}

/* Layar pendek (laptop kecil): riwayat dipipihkan supaya katalog tetap lega. */
@media (max-height:760px) and (min-width:981px){
  .pos-recent-card{max-height:20vh}
  .pos-scan-card .kasir-camera video{max-height:26vh}
}


/* ==========================================================================
   KLINIK SENTOSA — TEMA MEDIS (putih + HIJAU) + KOMPONEN KHUSUS KLINIK
   ==========================================================================
   Blok ini diletakkan PALING AKHIR berkas supaya menang atas aturan sebelumnya
   (spesifisitas sama → yang belakangan menang).

   1) TEMA MEDIS sebagai tema DEFAULT & tema terang: palet putih bersih dengan
      aksen teal (#0b6a5c) + biru (#0f8a73). Tema gelap tetap tersedia lewat
      tombol tema (memakai token gelap di awal berkas).
      ⚠️ Selector `html:not([data-theme])` dipakai supaya aplikasi tampil terang
      walaupun JavaScript mati (tanpa atribut data-theme).
   2) Komponen yang hanya dipakai modul klinik: langkah persetujuan, baris grafik,
      kartu pemilih rencana, strip tujuan pengadaan, form inline di dalam tabel,
      dan tabel yang bisa digeser mendatar di HP.
   ========================================================================== */

html:not([data-theme]),
html[data-theme="light"]{
  --bg:#F2F7FB;
  --bg-2:#E6EFF7;
  --panel:rgba(255,255,255,.97);
  --panel-2:rgba(255,255,255,.72);
  --line:rgba(15,23,42,.10);
  --line-strong:rgba(15,23,42,.16);
  --ink:#0F172A;
  --ink-2:#334155;
  --ink-3:#41506B;
  --ink-strong:#060D1A;
  --head-ink:#000000;
  --code-ink:#000000;
  --cyan:#0b6a5c;
  --violet:#0f8a73;
  --green:#047857;
  --amber:#B45309;
  --red:#B91C1C;
  --radius:14px;
  --radius-sm:10px;
  --shadow:0 16px 34px -26px rgba(15,23,42,.45);
  --body-bg:
    radial-gradient(880px 520px at 4% -12%, rgba(11,106,92,.14), transparent 62%),
    radial-gradient(820px 520px at 100% -6%, rgba(15,138,115,.12), transparent 60%),
    radial-gradient(700px 620px at 50% 118%, rgba(13,148,136,.10), transparent 64%),
    linear-gradient(180deg,var(--bg) 0%, var(--bg-2) 100%);
  --sidebar-bg:linear-gradient(180deg,rgba(255,255,255,.97),rgba(240,247,253,.95));
  --topbar-bg:linear-gradient(180deg,rgba(255,255,255,.97),rgba(255,255,255,.80));
  --strip-bg:rgba(255,255,255,.86);
  --grid-c:rgba(15,23,42,.05);
  --sheen:linear-gradient(160deg,rgba(255,255,255,.6),transparent 45%);
  --pop-bg:rgba(255,255,255,.99);
  --input-bg:rgba(255,255,255,.95);
  --tint:rgba(15,23,42,.045);
  --tint-2:rgba(15,23,42,.03);
  --tint-3:rgba(15,23,42,.025);
  --tint-hover:rgba(15,23,42,.05);
  --th-bg:rgba(11,106,92,.07);
  --foot-bg:rgba(11,106,92,.06);
  --row-border:rgba(15,23,42,.08);
  --track:rgba(15,23,42,.09);
  --chip-bg:rgba(15,23,42,.04);
  --warn-row:rgba(245,158,11,.10);
  --nav-active-bg:linear-gradient(100deg,rgba(11,106,92,.14),rgba(15,138,115,.10));
  --nav-active-border:rgba(11,106,92,.32);
  --tab-active-bg:linear-gradient(180deg,rgba(11,106,92,.14),rgba(11,106,92,.03));
  --brand-bg:linear-gradient(140deg,#0b6a5c,#0f8a73);
  --brand-border:transparent;
  --brand-fg:#FFFFFF;
  --brand-accent:#e2f7f0;
  --brand-shadow:0 12px 24px -14px rgba(11,106,92,.8);
  --avatar-bg:linear-gradient(140deg,rgba(11,106,92,.18),rgba(15,138,115,.16));
  --avatar-border:rgba(11,106,92,.28);
  --avatar-fg:#083c33;
  --btn-bg:rgba(15,23,42,.045);
  --btn-bg-hover:rgba(15,23,42,.09);
  --btn-border-hover:rgba(15,23,42,.22);
  --primary-grad:linear-gradient(100deg,#0b6a5c,#0f8a73);
  --primary-shadow:0 12px 26px -16px rgba(11,106,92,.85);
  --focus-border:rgba(11,106,92,.55);
  --focus-ring:rgba(11,106,92,.16);
  --input-hover:rgba(15,23,42,.28);
  --select-caret:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23334155' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  --search-icon:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23334155' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='m20 20-3.6-3.6'/%3E%3C/svg%3E");
  color-scheme:light;
  --preview-bg:rgba(11,106,92,.07);
  --preview-bd:rgba(11,106,92,.22);
  --bar-fill:linear-gradient(180deg,#0b6a5c,#0f8a73);
  --bar-shadow:0 0 14px -5px rgba(11,106,92,.5);
  --ok-bg:rgba(4,120,87,.12); --ok-fg:#04543C; --ok-bd:rgba(4,120,87,.28);
  --warn-bg:rgba(180,83,9,.13); --warn-fg:#7C3A00; --warn-bd:rgba(180,83,9,.3);
  --err-bg:rgba(185,28,28,.11); --err-fg:#8B1A1A; --err-bd:rgba(185,28,28,.28);
  --info-bg:rgba(15,138,115,.11); --info-fg:#0b4f42; --info-bd:rgba(15,138,115,.28);
  --note-border:rgba(11,106,92,.45);
}
/* Judul & kode tetap hitam pekat di tema terang. */
html:not([data-theme]) .lab-card,html[data-theme="light"] .lab-card{isolation:isolate}
html:not([data-theme]) .lab-card::before,html[data-theme="light"] .lab-card::before{z-index:-1}

/* ---------- Langkah persetujuan (spans di dalam .plan-steps) ---------- */
.plan-steps > span,
.plan-steps > .plan-step{
  display:flex;align-items:center;gap:8px;padding:11px 14px;font-size:.85rem;font-weight:600;
  border:1px solid var(--line-strong);border-radius:var(--radius-sm);background:var(--tint-3);
}
.plan-steps > .is-done{border-color:var(--ok-bd);background:var(--ok-bg);color:var(--ok-fg)}
.plan-steps > .is-done::before{content:"✓";font-weight:800}

/* ---------- Strip Tujuan Pengadaan (kartu detail rencana) ---------- */
.purpose-strip{
  display:flex;flex-wrap:wrap;align-items:center;gap:10px;
  margin:14px 0 18px;padding:12px 14px;border-radius:var(--radius-sm);
  background:var(--preview-bg);border:1px solid var(--preview-bd);border-left:4px solid var(--cyan);
}
.purpose-strip .pp-label{
  font-size:.7rem;text-transform:uppercase;letter-spacing:.12em;color:var(--ink-2);font-weight:700;
}
.purpose-strip .pp-name{font-weight:800;color:var(--code-ink)}
.purpose-strip .pp-hint{font-size:.8rem;color:var(--ink-2)}

/* ---------- Grafik batang sederhana (jurnal & laporan) ---------- */
.bar-list{display:grid;gap:10px}
.bar-row{display:grid;grid-template-columns:74px minmax(0,1fr) auto;align-items:center;gap:12px}
.bar-row .bar-label{font-size:.8rem;color:var(--ink-2);font-weight:600}
.bar-track{display:block;height:11px;border-radius:20px;background:var(--track);overflow:hidden}
.bar-fill{display:block;height:100%;border-radius:20px;background:linear-gradient(90deg,var(--cyan),#0f8a73)}
.bar-row .bar-value{font-size:.82rem;font-weight:700;white-space:nowrap}
@media (max-width:640px){
  .bar-row{grid-template-columns:56px minmax(0,1fr);row-gap:2px}
  .bar-row .bar-value{grid-column:2;text-align:right}
}

/* ---------- Kartu pemilih Rencana Pembelian (Buat Nota) ---------- */
.plan-pick-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(320px,1fr));gap:20px;margin-top:8px}
.plan-pick-card{display:flex;flex-direction:column;gap:14px}
.pick-items{display:flex;flex-wrap:wrap;gap:8px}
.pick-items .chip{font-size:.76rem}

/* ---------- Baris item pada kartu daftar (3 kolom) ---------- */
.purchase-items .p-item{display:grid;grid-template-columns:minmax(0,1fr) auto auto;gap:10px;align-items:center}
.purchase-items .p-item .p-qty{font-weight:700;color:var(--ink-2);white-space:nowrap}
.purchase-items .p-item .p-sub{text-align:right;font-weight:700;white-space:nowrap}
.purchase-items .p-item .p-sub small{display:block;font-weight:500;color:var(--ink-2);font-size:.74rem}

/* ---------- Kaki tabel (tombol tambah baris + total) ---------- */
.table-foot{
  display:flex;flex-wrap:wrap;align-items:center;gap:12px;margin-top:12px;padding-top:12px;
  border-top:1px dashed var(--line-strong);
}
.total-chip{
  margin-left:auto;padding:8px 14px;border-radius:999px;background:var(--preview-bg);
  border:1px solid var(--preview-bd);font-size:.86rem;
}
.total-chip strong{font-weight:800}

/* ---------- Form/inline aksi di dalam tabel & baris ---------- */
.inline-form{display:inline-flex;align-items:center;gap:8px;margin:0;flex-wrap:wrap}
.inline-form.stack{display:flex}
.row-actions{gap:8px}
.head-chips{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.scroll-x{overflow-x:auto;-webkit-overflow-scrolling:touch;padding-bottom:2px}
.table-wrap{max-width:100%}

/* ---------- Matriks izin (halaman Role / Peran) ---------- */
.perm-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:12px}
.perm-item span{display:flex;flex-direction:column;gap:2px;min-width:0}
.perm-item small{font-size:.72rem;line-height:1.35}

/* ---------- Rangkaian nomor antrean pada kartu ---------------------------------- */
.mv-no{
  display:inline-flex;align-items:center;justify-content:center;min-width:52px;padding:4px 8px;
  border-radius:10px;background:var(--brand-bg);color:#fff;font-weight:800;font-family:var(--mono);
  font-size:.9rem;
}

/* ---------- Form pada kartu mengambang: susun rapat ---------- */
.sheet-body .form-section + .form-section{margin-top:18px}
.sheet-body .card-foot{margin-top:14px}

/* ---------- Formulir tidak melebar di desktop (kartu klinik) ---------- */
.stack > .lab-card + .lab-card{margin-top:18px}
.preview-box + .field-grid,
.field-grid + .preview-box{margin-top:16px}


/* ==========================================================================
   KLINIK SENTOSA — BRAND HIJAU (global) + HALAMAN MASUK DUA PANEL
   ==========================================================================
   Blok ini diletakkan PALING AKHIR berkas sehingga menang atas aturan di atas.

   1) TOKEN BRAND HIJAU (mengikuti warna brand klinik) untuk SEMUA tema:
      `--brand`, `--brand-dark`, `--brand-light`, gradien tombol utama, dan
      warna aksen (`--cyan`/`--violet` dipakai sebagai aksen di seluruh aplikasi
      sehingga keduanya diarahkan ke keluarga hijau).
   2) TATA LETAK HALAMAN MASUK: panel brand (kiri, hijau) + panel formulir
      (kanan). Di layar kecil panel brand menjadi kepala ringkas.
   ========================================================================== */

:root,
html[data-theme="dark"]{
  --brand:#0E7C6B;
  --brand-dark:#0B6A5C;
  --brand-light:#2DD4A7;
  --brand-soft:rgba(45,212,167,.16);
  --cyan:#2DD4A7;              /* aksen utama (tema gelap) */
  --violet:#14A38B;            /* aksen kedua — tetap keluarga hijau */
  --green:#34D399;
  --primary-grad:linear-gradient(100deg,#0B6A5C,#0E7C6B);
  --primary-shadow:0 12px 28px -14px rgba(45,212,167,.7);
  --focus-border:rgba(45,212,167,.62);
  --focus-ring:rgba(45,212,167,.18);
  --nav-active-bg:linear-gradient(100deg,rgba(45,212,167,.16),rgba(20,163,139,.14));
  --nav-active-border:rgba(45,212,167,.32);
  --tab-active-bg:linear-gradient(180deg,rgba(45,212,167,.16),rgba(45,212,167,.04));
  --brand-bg:linear-gradient(140deg,#0E7C6B,#2DD4A7);
  --brand-border:rgba(45,212,167,.35);
  --brand-shadow:0 0 22px -6px rgba(45,212,167,.45), inset 0 0 14px -6px rgba(255,255,255,.35);
  --avatar-bg:linear-gradient(140deg,rgba(45,212,167,.30),rgba(20,163,139,.35));
  --avatar-border:rgba(150,214,197,.25);
  --stepnum-bg:linear-gradient(140deg,rgba(45,212,167,.25),rgba(20,163,139,.30));
  --stepnum-bd:rgba(45,212,167,.35);
  --bar-fill:linear-gradient(180deg,rgba(45,212,167,.95),rgba(20,163,139,.55));
  --bar-shadow:0 0 16px -4px rgba(45,212,167,.6);
  --note-border:rgba(45,212,167,.42);
}
html:not([data-theme]),
html[data-theme="light"]{
  --brand:#0E7C6B;
  --brand-dark:#0B6A5C;
  --brand-light:#14A38B;
  --brand-soft:rgba(14,124,107,.10);
  --primary-grad:linear-gradient(100deg,#0B6A5C,#0E7C6B);
  --primary-shadow:0 12px 26px -16px rgba(11,106,92,.85);
  --brand-bg:linear-gradient(140deg,#0E7C6B,#14A38B);
  --bar-fill:linear-gradient(90deg,#0E7C6B,#14A38B);
}
/* Logo silang medis di kotak brand. */
.brand-mark svg{width:52%;height:52%;fill:var(--brand-accent)}

/* ---------- HALAMAN MASUK: DUA PANEL ---------- */
.login-body{display:block;min-height:100dvh;padding:0}
.login-split{
  position:relative;z-index:2;display:grid;grid-template-columns:minmax(320px,42%) 1fr;
  min-height:100dvh;width:100%;
}
/* Panel brand (kiri) — hijau brand, tidak ikut berubah pada tema gelap. */
.login-brand{
  position:relative;display:flex;flex-direction:column;gap:28px;
  padding:34px 38px 30px;color:#EAFBF6;overflow:hidden;
  background:linear-gradient(160deg,var(--brand) 0%,var(--brand-dark) 100%);
}
.login-brand::before{
  content:"";position:absolute;width:420px;height:420px;right:-150px;bottom:-170px;border-radius:50%;
  background:radial-gradient(circle,rgba(255,255,255,.10),transparent 68%);pointer-events:none;
}
.login-brand::after{
  /* Hiasan diletakkan di bawah-kanan (JAUH dari teks brand) supaya kontras teks tetap tinggi. */
  content:"";position:absolute;width:300px;height:300px;left:-120px;bottom:-140px;border-radius:50%;
  background:radial-gradient(circle,rgba(255,255,255,.09),transparent 70%);pointer-events:none;
}
.lb-top{display:flex;align-items:center;gap:12px;position:relative;z-index:1}
.lb-mark{
  width:44px;height:44px;flex:0 0 44px;border-radius:13px;display:grid;place-items:center;
  background:rgba(255,255,255,.96);color:var(--brand);box-shadow:0 10px 22px -14px rgba(0,0,0,.6);
}
.lb-mark svg{width:24px;height:24px;fill:currentColor}
.lb-name strong{display:block;font-size:1.06rem;font-weight:800;letter-spacing:.01em}
.lb-name small{
  display:block;font-size:.62rem;letter-spacing:.16em;text-transform:uppercase;
  color:rgba(255,255,255,.94);font-weight:600;margin-top:2px;
}
.lb-mid{margin-top:auto;margin-bottom:auto;position:relative;z-index:1;max-width:520px}
.login-brand h1{
  font-size:clamp(1.35rem,2.4vw,1.95rem);line-height:1.22;margin:0 0 14px;
  color:#FFFFFF;letter-spacing:-.01em;
}
.lb-desc{margin:0 0 26px;color:rgba(255,255,255,.90);font-size:.92rem;line-height:1.6;max-width:460px}
.lb-features{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:16px}
.lb-features li{display:flex;gap:12px;align-items:flex-start}
.lbf-ico{
  width:36px;height:36px;flex:0 0 36px;border-radius:11px;display:grid;place-items:center;
  background:rgba(255,255,255,.14);border:1px solid rgba(255,255,255,.20);
}
.lbf-ico svg{width:19px;height:19px;fill:#FFFFFF}
.lb-features strong{display:block;font-size:.88rem;color:#FFFFFF;margin-bottom:2px}
.lb-features small{display:block;font-size:.78rem;line-height:1.5;color:rgba(255,255,255,.90);max-width:420px}
.lb-foot{
  position:relative;z-index:1;font-size:.74rem;color:rgba(255,255,255,.92);
  border-top:1px solid rgba(255,255,255,.16);padding-top:14px;
}
.lb-foot .lb-tag{opacity:.85}

/* Panel formulir (kanan). */
.login-panel{
  position:relative;display:flex;flex-direction:column;justify-content:center;align-items:center;
  padding:34px clamp(20px,5vw,64px) 40px;
}
.lp-top{position:absolute;top:22px;right:clamp(20px,5vw,64px)}
.lp-box{width:min(420px,100%)}
.lp-head{margin-bottom:20px}
.lp-head h2{font-size:1.5rem;margin:0 0 6px;letter-spacing:-.01em}
.lp-head .muted{margin:0;font-size:.88rem}
.auth-form{gap:16px}
.auth-field{display:flex;flex-direction:column;gap:7px}
.af-label{font-size:.78rem;font-weight:700;letter-spacing:.02em;color:var(--ink-2)}
.af-input{position:relative;display:flex;align-items:center}
.af-input .af-ico{
  position:absolute;left:14px;width:18px;height:18px;fill:var(--ink-3);pointer-events:none;
}
.af-input input{
  width:100%;height:48px;padding:0 46px 0 44px;border-radius:12px;
  border:1px solid var(--line-strong);background:var(--input-bg);color:var(--ink);
  font-size:.95rem;font-family:inherit;
}
.af-input input::placeholder{color:var(--ink-3)}
.af-input input:focus{
  outline:none;border-color:var(--focus-border);box-shadow:0 0 0 3px var(--focus-ring);
}
.af-eye{
  position:absolute;right:8px;width:34px;height:34px;border-radius:9px;display:grid;place-items:center;
  border:0;background:transparent;color:var(--ink-3);cursor:pointer;
}
.af-eye:hover{background:var(--btn-bg-hover);color:var(--ink)}
.af-eye svg{width:18px;height:18px;fill:currentColor}
.af-eye .ico-eye-off{display:none}
.af-eye.is-on .ico-eye{display:none}
.af-eye.is-on .ico-eye-off{display:block}
.btn-login{min-height:48px;font-size:.95rem;font-weight:700;border-radius:12px}
.login-help{margin:14px 0 0}

/* ---------- Halaman masuk di layar kecil: panel brand jadi kepala ringkas ---------- */
@media (max-width:900px){
  /* Baris pertama setinggi isinya, baris formulir mengambil SISA tinggi layar
     (tanpa ini panel brand ikut melar memenuhi layar). */
  .login-split{grid-template-columns:1fr;grid-template-rows:auto 1fr;min-height:100dvh}
  .login-brand{gap:0;padding:18px 20px;flex-direction:row;align-items:center;justify-content:space-between}
  .login-brand::after{display:none}
  .lb-mid{display:none}
  .lb-foot{display:none}
  .lb-mark{width:38px;height:38px;flex-basis:38px;border-radius:11px}
  .lb-mark svg{width:21px;height:21px}
  .lb-name strong{font-size:.98rem}
  .login-panel{flex:1 1 auto;justify-content:flex-start;padding:22px 18px calc(30px + env(safe-area-inset-bottom,0px))}
  .lp-top{position:static;display:flex;justify-content:flex-end;margin-bottom:14px}
  .lp-head h2{font-size:1.24rem}
  .af-input input{height:50px;font-size:16px}   /* 16px = iOS tidak auto-zoom */
  .btn-login{min-height:50px}
}
@media (max-width:380px){
  .login-panel{padding:18px 14px calc(26px + env(safe-area-inset-bottom,0px))}
}


/* ==========================================================================
   SIDEBAR AKORDEON (grup menu buka/tutup)
   ==========================================================================
   Grup menu dirender sebagai <button class="nav-group"> + <div class="nav-items">.
   Default TERTUTUP & hanya satu grup terbuka (lihat assets/app.js + skrip kecil
   di includes/layout.php yang memulihkan grup terakhir sebelum halaman digambar). */
/* Ukuran huruf judul grup = ukuran huruf menu (font-size disamakan).
   Padding horizontal grup dibuat LEBIH RAPAT daripada menu (lihat `.nav-items .nav-link`
   yang menjorok ke kanan) supaya judul grup panjang seperti "Rekam Medis Elektronik"
   tetap muat DALAM SATU BARIS dan menu terlihat sebagai isi (bertingkat) di bawahnya.
   ⚠️ Ruang untuk label = lebar wadah − (padding 2×) − ikon 17 − gap 2× − caret.
   Karena itu lencana grup TIDAK ikut berbaris di sini (lihat aturan lencana di bawah). */
.nav-group{
  position:relative;
  display:flex;align-items:center;gap:9px;width:100%;min-width:0;
  background:transparent;border:0;cursor:pointer;text-align:left;font-family:inherit;
  font-size:.87rem;font-weight:600;letter-spacing:0;text-transform:none;color:var(--ink-2);
  margin:12px 0 4px;padding:6px 8px;border-radius:var(--radius-sm);
}
.nav-group:hover{color:var(--ink);background:var(--tint-hover)}
.nav-group.is-active{color:var(--ink-strong)}
/* Ikon kategori: satu gaya dengan ikon menu (SVG 24×24, fill currentColor). */
.nav-group-ico{flex:0 0 17px;width:17px;height:17px;display:grid;place-items:center;color:var(--ink-3)}
.nav-group-ico svg{width:17px;height:17px;fill:currentColor;display:block}
.nav-group:hover .nav-group-ico{color:var(--ink-2)}
.nav-group.is-active .nav-group-ico{color:var(--brand)}
.nav-group-label{flex:1 1 auto;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* LENCANA GRUP = lencana kecil di pojok kanan-atas IKON grup (bukan di baris label).
   Dulu lencana ikut berbaris setelah label sehingga memakan ~30px: judul grup yang
   panjang ("Rekam Medis Elektronik") terpotong menjadi "Rekam Medis Elektro…".
   Jumlahnya tetap terbaca, rinciannya ada di `title` (tooltip) — lihat layout.php. */
.nav-group .nav-group-badge{
  /* menempel di pojok kanan-atas IKON (ikon ada di 8..25px dari tepi tombol),
     ujung kanan lencana (±30px) tetap di kiri awal label (±34px) agar TIDAK
     menabrak tulisan judul. `top:0` membuatnya tidak keluar dari kotak tombol. */
  position:absolute;left:14px;top:0;margin:0;
  min-width:16px;height:16px;padding:0 3px;font-size:.62rem;
  box-shadow:0 0 0 2px var(--pop-bg);
}
.nav-group.nav-group .nav-caret{width:12px;height:12px;fill:var(--ink-3);transition:transform .16s;flex:0 0 12px}
.nav-group:hover .nav-caret,.nav-group.is-active .nav-caret{fill:currentColor}
.nav-group[aria-expanded="true"] .nav-caret{transform:rotate(180deg)}
.nav-items{display:flex;flex-direction:column;gap:3px;padding:2px 0 4px}
/* Menu di dalam grup MENJOROK ke kanan dari tombol grupnya (permintaan pemilik:
   "beri jarak ke kanan sedikit, jangan sejajar dengan tombol Nav. Group") sehingga
   kepala grup vs isinya langsung terlihat berbeda tanpa perlu garis pemisah.
   Aturan ini sengaja spesifik (`.nav-items .nav-link`) supaya menu mandiri
   (Dashboard · Investor) yang berdiri sendiri TETAP sejajar dengan kepala grup. */
.nav-items .nav-link{padding-left:24px;padding-right:10px}
.nav-items[hidden]{display:none}


/* ==========================================================================
   BARCODE — kolom input + tombol pindai + panel kamera
   ========================================================================== */
.bc-wrap{display:flex;align-items:center;gap:8px}
.bc-wrap input{flex:1 1 auto}
.bc-btn{
  flex:0 0 auto;width:34px;height:34px;border-radius:9px;display:grid;place-items:center;
  border:1px solid var(--line-strong);background:var(--btn-bg);color:var(--ink-2);cursor:pointer;
}
.bc-btn:hover{background:var(--btn-bg-hover);color:var(--ink)}
.bc-btn.is-on{background:var(--primary-grad);border-color:transparent;color:#fff}
.bc-btn svg{width:17px;height:17px;fill:currentColor}
.bc-status{display:block;margin-top:4px}
.bc-status.neg{color:var(--red)}
.bc-status.pos{color:var(--green)}
.bc-panel{
  margin-top:8px;border:1px solid var(--line-strong);border-radius:var(--radius-sm);
  overflow:hidden;background:var(--input-bg);
}
.bc-panel video{display:block;width:100%;max-height:240px;background:#000}
.bc-panel-foot{display:flex;align-items:center;gap:10px;justify-content:space-between;padding:8px 10px}
@media (max-width:640px){
  .bc-btn{width:40px;height:40px}
}

/* ---------- Nav group di HP: ukuran huruf & tinggi sentuh = menu ---------- */
/* Ditaruh setelah blok akordeon karena spesifisitasnya sama (0,1,0) —
   tanpa ini aturan desktop di atasnya akan menang meski di dalam media query. */
@media (max-width:900px){
  .nav-group{
    font-size:.92rem;            /* = .nav-link di HP */
    padding:10px 8px;
    margin:10px 0 2px;
    min-height:44px;             /* target sentuh nyaman, sejajar menu 48px */
  }
  .nav-group-ico,.nav-group-ico svg{width:18px;height:18px;flex-basis:18px}
  .nav-group-label{font-size:.92rem}
  .nav-group .nav-group-badge{left:15px;top:1px}
  .nav-items .nav-link{padding-left:27px}
}

/* ════════════════════════════════════════════════════════════════════════
   MENU MANDIRI DI ATAS AKORDEON (Dashboard · Investor)
   Permintaan pemilik: Dashboard keluar dari grup "Operasional" dan berdiri
   sendiri di paling atas; di bawahnya Investor. Keduanya bukan bagian dari
   operasional harian, jadi TIDAK ikut dibuka-tutup (akordeon) — cukup diberi
   pemisah tipis dari grup pertama di bawahnya.
   ════════════════════════════════════════════════════════════════════════ */
/* Menu mandiri = saudara kepala grup: ikonnya dibuat sejajar PERSIS dengan ikon
   kepala grup (padding 7px + border 1px = 8px, sama dengan padding grup) dan
   jaraknya 9px supaya LABEL-nya juga sejajar. */
.nav-link-top{font-weight:600;padding-left:7px;gap:9px}
.nav-link-top + .nav-link-top{margin-top:2px}
.nav-link-top:last-of-type{margin-bottom:8px}
.nav-link-top.is-active{box-shadow:inset 3px 0 0 var(--brand)}

/* ════════════════════════════════════════════════════════════════════════
   MODUL RAK — baris "atur isi rak" (satu form per rak di dalam kartu)
   ════════════════════════════════════════════════════════════════════════ */
.row-inline{
  display:flex;align-items:center;gap:10px;flex-wrap:wrap;
  padding:8px 0;border-bottom:1px dashed var(--row-border);
}
.row-inline:last-of-type{border-bottom:0}
.row-inline-main{flex:1 1 220px;min-width:0;display:flex;flex-direction:column;gap:1px}
.row-inline-main strong{font-size:.86rem;color:var(--ink-strong)}
.row-inline input[type=number]{width:110px;text-align:right;flex:0 0 auto}
.row-inline .btn{flex:0 0 auto}
@media (max-width:640px){
  .row-inline{gap:8px}
  .row-inline-main{flex:1 1 100%}
  .row-inline input[type=number]{flex:1 1 auto;width:auto}
}

/* ════════════════════════════════════════════════════════════════════════
   MENU INVESTOR — batang tren bulanan, sparkline harian, bar sumber laba
   ════════════════════════════════════════════════════════════════════════ */
/* .cat-bar dipakai sebagai TRACK; elemen <i> di dalamnya yang menjadi isian. */
.cat-bar{display:block;height:9px;border-radius:20px;background:var(--tint-3);overflow:hidden;min-width:3px;margin-top:4px}
.cat-bar i{display:block;height:100%;border-radius:20px;background:linear-gradient(90deg,var(--cyan),var(--brand-light,#14a38b))}
.mini-stats > div{min-width:0}

.month-bars{display:flex;flex-direction:column;gap:6px;margin-top:4px}
.month-row{display:grid;grid-template-columns:56px minmax(0,1fr) 104px;gap:10px;align-items:center}
.month-row .mb-label{font-family:var(--mono);font-size:.7rem;color:var(--ink-2)}
.month-row .mb-value{font-size:.72rem;text-align:right;color:var(--ink-strong)}
.mb-track{position:relative;display:flex;flex-direction:column;gap:2px;justify-content:center;min-width:0}
.mb-track i{display:block;height:7px;border-radius:20px;min-width:2px}
.mb-track .mb-omset{background:linear-gradient(90deg,var(--cyan),var(--brand,#0E7C6B))}
.mb-track .mb-margin{background:var(--tint-4,rgba(255,255,255,.16));height:5px}

.spark-row{display:flex;align-items:flex-end;gap:4px;height:120px;margin-top:6px;overflow-x:auto;padding-bottom:2px}
.spark-cell{flex:1 0 16px;min-width:16px;display:flex;flex-direction:column;justify-content:flex-end;align-items:center;gap:3px;height:100%}
.spark-cell i{width:100%;max-width:18px;display:block;border-radius:4px 4px 2px 2px;
  background:linear-gradient(180deg,var(--cyan),var(--brand,#0E7C6B));min-height:3px}
.spark-cell span{font-family:var(--mono);font-size:.58rem;color:var(--ink-3)}

@media (max-width:640px){
  .month-row{grid-template-columns:46px minmax(0,1fr) 84px;gap:7px}
  .month-row .mb-value{font-size:.66rem}
  .spark-row{height:96px}
}

/* ════════════════════════════════════════════════════════════════════════
   PERMINTAAN BARANG (PB) — kartu daftar, progres penerimaan, SLA, penelusuran
   Semua memakai variabel tema (gelap/terang) & tanpa backdrop-filter.
   ════════════════════════════════════════════════════════════════════════ */
.pb-grid{display:grid;gap:18px;grid-template-columns:repeat(auto-fill,minmax(340px,1fr))}
@media (max-width:760px){ .pb-grid{grid-template-columns:1fr;gap:14px} }
.pb-card{display:flex;flex-direction:column;gap:10px;contain:layout paint}
.pb-card h2{font-size:1rem;margin:0}
.pb-meta{display:flex;flex-wrap:wrap;gap:6px 16px;font-size:.8rem;color:var(--ink-2)}
.pb-meta b{color:var(--ink);font-weight:600}
.pb-progress{height:8px;border-radius:20px;background:var(--track);overflow:hidden}
.pb-progress i{display:block;height:100%;border-radius:20px;background:linear-gradient(90deg,var(--brand,#0E7C6B),var(--brand-light,#2DD4A7))}
.pb-progress-text{font-size:.72rem;color:var(--ink-2);font-variant-numeric:tabular-nums}
.pb-sla{font-size:.72rem;font-weight:600;color:var(--ink-2)}
.pb-sla.is-late{color:var(--red)}
.pb-attach{margin-top:10px}

/* Penelusuran dokumen PB → RP → Pembelian → Penerimaan */
.trace{display:grid;gap:14px;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));margin:6px 0 4px}
.trace-col{display:flex;flex-direction:column;gap:6px;min-width:0;
  border:1px solid var(--line);border-radius:var(--radius-sm);padding:10px 12px;background:var(--tint-3)}
.trace-title{font-size:.7rem;font-weight:700;letter-spacing:.05em;text-transform:uppercase;color:var(--ink-2)}
.trace-item{display:flex;align-items:center;gap:8px;flex-wrap:wrap;min-width:0;
  padding:5px 0;border-bottom:1px dashed var(--row-border);font-size:.8rem;color:var(--ink)}
.trace-item:last-child{border-bottom:0}
a.trace-item:hover{color:var(--brand)}

/* Tabel detail produk pada kartu PB — tidak boleh memaksa geser di HP */
.pb-table{table-layout:auto}
@media (max-width:640px){
  .pb-card{padding:14px}
  .trace{grid-template-columns:1fr}
}

/* ════════════════════════════════════════════════════════════════════════
   INVESTOR — kartu TREN BULANAN LEBAR (tepat di bawah KPI)
   Permintaan pemilik: kartu lebar & TETAP rapi di ponsel. Nilai tidak boleh
   turun ke baris kedua → `white-space:nowrap` + font mengecil di layar sempit,
   dan batangnya boleh digeser mendatar bila 12 bulan tidak muat.
   ════════════════════════════════════════════════════════════════════════ */
.inv-trend{width:100%}
.inv-trend .month-bars{max-height:none}
.inv-trend .month-row{grid-template-columns:58px minmax(0,1fr) 118px}
.inv-trend .mb-value{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
@media (max-width:900px){
  .inv-trend .month-row{grid-template-columns:52px minmax(0,1fr) 104px;gap:8px}
  .inv-trend .mb-value{font-size:.68rem}
}
@media (max-width:640px){
  .inv-trend{overflow-x:auto}
  .inv-trend .month-bars{min-width:0}
  .inv-trend .month-row{grid-template-columns:46px minmax(90px,1fr) 96px;gap:6px}
  .inv-trend .mb-label{font-size:.66rem;white-space:nowrap}
  .inv-trend .mb-value{font-size:.64rem}
  /* label & nilai kartu KPI tidak boleh membungkus ke baris kedua */
  .kpi-grid .kpi-label,.kpi-grid .kpi-value,.kpi-grid .kpi-foot{overflow-wrap:normal;word-break:normal}
  .kpi-grid .kpi-value{white-space:nowrap}
}

/* Angka & label kartu ringkasan: satu baris (tidak masuk baris ke-2) */
.kpi-grid .kpi-label{display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.kpi-grid .kpi-value{white-space:nowrap}
.month-row .mb-value{font-variant-numeric:tabular-nums}

/* ════════════════════════════════════════════════════════════════════════
   ROLE / PERAN — Kontrol Data & KPI (pindahan dari menu Pengaturan)
   ════════════════════════════════════════════════════════════════════════ */
.kpi-scope-note{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin:2px 0 12px}
.kpi-all-bar{
  display:flex;align-items:center;gap:14px;flex-wrap:wrap;
  padding:10px 12px;margin:4px 0 10px;border:1px solid var(--line-strong);
  border-radius:var(--radius-sm);background:var(--tint-3);
}
.kpi-all-bar .switch-line{margin:0}
.kpi-section .form-section-head{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap}
.kpi-pick-all{margin:0;flex:0 0 auto}
.kpi-pick-all span{font-size:.78rem;font-weight:600}
.kpi-section .perm-grid{grid-template-columns:repeat(auto-fill,minmax(230px,1fr))}
.kpi-section .perm-item{min-width:0}
.kpi-section .perm-item strong{font-weight:600;overflow-wrap:anywhere}
@media (max-width:640px){
  .kpi-section .perm-grid{grid-template-columns:1fr}
  .kpi-pick-all span{font-size:.76rem}
}

/* Tombol "Aktifkan Semua KPI untuk <nama panjang>" tidak boleh melebarkan halaman
   di layar sangat sempit (320px) — teksnya boleh membungkus. */
#kontrol-kpi .inline-form{max-width:100%}
@media (max-width:640px){
  #kontrol-kpi .inline-form .btn{
    white-space:normal;max-width:100%;height:auto;min-height:38px;
    padding:9px 12px;text-align:center;
  }
}

/* ══════════════════════════════════════════════════════════════════════════
   TOGGLE TAMPILAN (Kartu ⇄ Tabel) DI TOPBAR
   Markup & kelasnya sama dengan tombol tema/Info (`.btn.btn-theme`) supaya
   seragam. Label menampilkan tampilan yang sedang dipakai ("Kartu"/"Tabel").
   Bila halaman hanya punya satu bentuk tampilan, tombolnya diredupkan &
   tidak bereaksi (aria-disabled) — bukan disembunyikan.
   ══════════════════════════════════════════════════════════════════════════ */
.btn-theme.view-toggle .view-label{font-size:.76rem;font-weight:600;letter-spacing:.02em}
.btn-theme.view-toggle.is-off{opacity:.5;cursor:not-allowed}
@media (max-width:520px){ .btn-theme.view-toggle .view-label{display:none} }

/* ══════════════════════════════════════════════════════════════════════════
   GLOBAL SEARCH INPUT (SEMUA MENU DAFTAR DATA)
   Satu komponen pencarian yang selalu tampil di atas kartu filter. Mencari
   mencakup seluruh field daftar (nomor dokumen, nama, tanggal, status,
   referensi) dan filter yang sedang aktif ikut dipertahankan.
   ══════════════════════════════════════════════════════════════════════════ */
.global-search{
  display:flex;flex-wrap:wrap;align-items:center;gap:10px;
  margin:0 0 14px;padding:8px 10px;
  border:1px solid var(--line);border-radius:var(--radius);
  background:var(--panel);
}
.gs-field{position:relative;display:block;flex:1 1 260px;min-width:0}
.gs-icon{
  position:absolute;left:14px;top:50%;transform:translateY(-50%);
  width:18px;height:18px;fill:var(--ink-3);pointer-events:none;
}
/* ── SUFFIX KOLOM PENCARIAN ───────────────────────────────────────────────
   `.gs-suffix`  = ikon penanda (mis. labu/flask untuk pencarian ZAT AKTIF),
                   murni dekoratif.
   `.gs-scan`    = TOMBOL pindai barcode (membuka pop-up kamera) — menempel di
                   dalam kotak pencarian, di sisi KANAN.
   Keduanya butuh ruang di kanan input supaya teks tidak tertutup. */
.gs-suffix{
  position:absolute;right:14px;top:50%;transform:translateY(-50%);
  width:18px;height:18px;display:flex;align-items:center;justify-content:center;
  pointer-events:none;
}
.gs-suffix svg{width:18px;height:18px;fill:var(--ink-3)}
.gs-field.has-suffix input[type=search]{padding-right:44px}
.gs-scan{
  position:absolute;right:5px;top:50%;transform:translateY(-50%);
  display:inline-flex;align-items:center;gap:6px;
  height:36px;padding:0 10px;border-radius:9px;
  border:1px solid var(--line-strong);background:var(--tint-3);
  color:var(--ink-2);font-family:inherit;font-size:.76rem;font-weight:650;
  cursor:pointer;white-space:nowrap;
}
.gs-scan:hover{background:var(--panel);color:var(--ink-strong);border-color:var(--brand,#0E7C6B)}
.gs-scan:focus-visible{outline:2px solid var(--brand,#0E7C6B);outline-offset:2px}
.gs-scan svg{width:17px;height:17px;fill:currentColor;flex:0 0 17px}
.gs-field.has-scan input[type=search]{padding-right:150px}
@media (max-width:1180px){
  /* Ruang menyempit → tombol jadi ikon saja (label tetap ada sebagai tooltip). */
  .gs-scan-lbl{display:none}
  .gs-scan{padding:0 8px}
  .gs-field.has-scan input[type=search]{padding-right:58px}
}
.global-search input[type=search]{
  width:100%;min-height:46px;font-size:.95rem;
  padding:11px 14px 11px 44px;
  /* ikon kaca pembesar digambar oleh .gs-icon (SVG) — matikan ikon latar
     bawaan agar tidak muncul dua ikon di kolom yang sama. */
  background-image:none;
}
.global-search .btn{flex:0 0 auto;min-height:44px;padding:0 18px}
.global-search .live-count{flex:1 1 100%;margin:0}
@media (max-width:640px){
  .global-search{padding:8px;gap:8px}
  .gs-field{flex:1 1 100%}
  .global-search .btn{flex:1 1 100%;min-height:44px}
}

/* ══════════════════════════════════════════════════════════════════════════
   ANGKA KARTU RINGKASAN (KPI) TIDAK BOLEH MELUBER ATAU TERPOTONG
   `white-space:nowrap` membuat nominal panjang ("Rp 13.124.600") melebihi
   kotak kartu → halaman bergeser ke samping (bug nyata: Laporan pada 1440px
   overflow 7px). Dua lapis penjagaan:
   1. ukuran huruf mengikuti LEBAR KARTU (container query 12,4cqi) sehingga
      nominal biasa tetap satu baris dengan huruf tetap besar;
   2. bila nominalnya luar biasa panjang (belasan digit), nilainya TURUN BARIS
      (bukan terpotong / bukan menggeser halaman).
   ══════════════════════════════════════════════════════════════════════════ */
.kpi-grid .kpi{min-width:0;container-type:inline-size}
.kpi-grid .kpi-value{
  font-size:clamp(.95rem, 12.4cqi, 1.6rem);
  line-height:1.16;max-width:100%;
  white-space:normal;overflow-wrap:anywhere;
}
@media (max-width:640px){
  /* Di HP kartu 2 kolom dengan huruf lebih kecil (aturan lama). */
  .kpi-grid .kpi-value{font-size:clamp(.88rem, 12.4cqi, 1.24rem)}
}
@media (max-width:380px){
  /* 1 kolom di HP sangat kecil supaya nominal panjang tetap utuh.
     `!important` wajib: aturan 2 kolom di blok ≤900px memakai !important. */
  .kpi-grid,.kpi-grid.compact{grid-template-columns:1fr!important}
  .kpi-grid .kpi-value{font-size:clamp(.86rem, 8.4cqi, 1.18rem)}
}

/* ══════════════════════════════════════════════════════════════════════════
   OPTIMASI GLOBAL: SKALA HURUF, LEBAR KONTEN & TABEL
   Permintaan pemilik: huruf isi/label/tabel/input/tombol naik 1–2 px, konten
   memakai hampir seluruh lebar area kerja (tanpa ruang kosong menumpuk di
   kanan), dan tabel nyaman dibaca tanpa memotong informasi.
   ⚠️ Semua perubahan di sini GLOBAL (satu tempat) — warna Sentosa, sidebar,
   struktur, dan logika bisnis tidak disentuh.

   1) SKALA HURUF — root 16px → 17,2px (+7,5%).
      ±360 ukuran huruf di aplikasi ini memakai `rem`, jadi menaikkan root
      menaikkan SEMUA teks secara proporsional (hierarki judul → isi → label
      tetap sama, rasio tidak berubah) tanpa menyunting ratusan aturan.
      Ukuran px (mis. tinggi tombol & padding) TIDAK ikut berubah sehingga
      tata letak & target sentuh tetap seperti semula. */
html{font-size:17.2px}
body{font-size:16px}          /* teks tanpa ukuran eksplisit: 14,5px → 16px */

/* 2) LEBAR KONTEN — hampir seluruh area kerja setelah sidebar.
   Dulu `max-width:1400px` membuat di layar 1920px tersisa ±256px kosong di
   KANAN (konten tidak dipusatkan). Sekarang konten mengisi area kerja dengan
   padding kiri–kanan proporsional (clamp), dan bila layar sangat lebar
   (>1800px) barulah dibatasi & dipusatkan agar baris teks tidak terlalu
   panjang. Padding topbar disamakan supaya judul halaman tetap sejajar. */
/* Sidebar 264 → 272px: huruf judul grup ikut naik, judul terpanjang
   ("Rekam Medis Elektronik") butuh 4px lagi agar tetap SATU BARIS.
   ⚠️ WAJIB dibungkus media query: tanpa itu aturan ini menimpa
   `.shell{grid-template-columns:1fr}` di ≤900px sehingga `.main` hanya
   mendapat kolom 272px (sidebar berada di kolom yang sama) dan SELURUH isi
   halaman di HP menyempit ±118px — bug responsif nyata yang dilaporkan
   pemilik (kartu KPI 115px, teks bertumpuk). */
@media (min-width:901px){
  .shell{grid-template-columns:272px 1fr}
}

.content{
  padding:26px clamp(18px,2.1vw,36px) 48px;
  max-width:1840px;margin-inline:auto;
}
.topbar{padding:16px clamp(18px,2.1vw,36px)}

/* 3) TABEL — teks & jarak sel naik supaya mudah dibaca; lebar kolom tetap
   mengikuti isi (kelas .col-num/.col-date/.col-act dipasang assets/app.js),
   sehingga horizontal scroll hanya muncul bila isinya benar-benar lebar. */
table.data{font-size:.88rem}
table.data.compact{font-size:.86rem}
table.data thead th{font-size:.74rem;letter-spacing:.07em}
table.data td{line-height:1.45}
table.data.compact td,table.data.compact thead th{padding:9px 8px}
/* Kolom AKSI: tombol boleh turun baris (dulu nowrap). Satu sel dengan 3 tombol
   tadinya memakan ±248px dan memaksa tabel bergeser; dengan wrap cukup selebar
   tombol terlebar sehingga tabel muat tanpa scroll. */
table.data td.col-act{white-space:normal}
table.data td.col-act .btn{max-width:100%;margin:2px 0}
/* Lebar minimum tabel DIHAPUS: sebelumnya `min-width:660px/520px` memaksa
   geser horizontal padahal wadahnya (mis. tabel ringkas di dalam kartu
   `.grid-2`) lebih sempit. Dengan min-width:0 tabel menyesuaikan wadah dan
   teks panjang membungkus — tidak ada informasi yang terpotong. */
table.data,table.data.compact{min-width:0}
/* Judul kolom boleh membungkus (dulu nowrap) supaya kolom bisa menyempit
   sebelum memutuskan menggeser tabel. */
table.data thead th{white-space:normal;overflow-wrap:break-word}

/* 4) KOMPONEN ISI — label, KPI, tombol, pill/chip ikut naik sedikit agar
   tetap seimbang dengan teks tabel (tidak ada bagian yang terlihat "kecil"). */
.field{font-size:.83rem}
.kpi-label{font-size:.74rem}
.kpi-foot{font-size:.76rem}
.metric-row span{font-size:.72rem}
.btn{font-size:.85rem}
.btn-sm{font-size:.8rem}
.pill{font-size:.7rem}
.chip{font-size:.76rem}
/* Kartu KPI: minimum sedikit lebih lebar agar nominal & label tidak berdesakan
   setelah huruf naik. */
.kpi-grid.compact{grid-template-columns:repeat(auto-fit,minmax(min(212px,100%),1fr))}

/* 5) RESPONSIF — HP/tablet tetap memakai padding & skala lama (huruf isi 16px,
   kontrol 16px agar iOS tidak auto-zoom); tabel sudah menjadi kartu bertingkat
   di ≤900px sehingga tidak perlu digeser. */
@media (max-width:900px){
  .content{padding:18px 16px 40px;max-width:none}
  .topbar{padding:16px 16px}
}
@media (max-width:640px){
  table.data,table.data.compact{font-size:.86rem}
  .kpi-label{font-size:.72rem}
  .kpi-foot{font-size:.74rem}
}
/* Kolom angka berisi gabungan beberapa bagian ("5 kg · 3 liter") boleh turun
   baris supaya tabel tidak perlu digeser; nominal murni tetap nowrap. */
table.data td.col-num-wrap{white-space:normal}

/* ── Kepala kartu (judul + pill) tidak boleh meluber setelah huruf naik ──
   `.purchase-head` memakai flex tanpa `min-width:0`, sehingga judul panjang
   (mis. nama pasien + poli) mendorong pill keluar kartu dan halaman bergeser
   ke samping (terukur: Pendaftaran pada 1100px meluber 37px). */
.purchase-head > div{min-width:0}
.purchase-head > div:first-child{flex:1 1 auto}
.purchase-head h2,.purchase-head .product-code{overflow-wrap:anywhere}
.purchase-head > .head-chips,.purchase-head > .pill{flex:0 0 auto;max-width:100%}
.head-chips{flex-wrap:wrap}

/* ── Baris ringkas `.move-item` menyesuaikan JUMLAH anaknya ────────────────
   Template lama `118px auto minmax(0,1fr) auto` mengasumsikan 4 anak (kolom
   waktu yang sekarang sudah tidak dipakai). Pada markup nyata (2–3 anak)
   status/angka jatuh ke kolom 1fr yang menyempit sehingga pill meluber keluar
   kartu dan halaman bergeser (terukur: Pendaftaran 1024px meluber 59px).
   Sekarang kolom mengikuti jumlah anak; tanpa anak ketiga (isi + status/angka)
   cukup dua kolom. */
.move-item > *{min-width:0}
.move-item:has(> *:nth-child(3)){grid-template-columns:auto minmax(0,1fr) auto}
.move-item:not(:has(> *:nth-child(3))){grid-template-columns:minmax(0,1fr) auto}
.move-item > .mv-qty,.move-item > .pill,.move-item > .mv-right{justify-self:end}

/* ── Wadah tabel yang SEKALIGUS kartu (`.table-wrap.lab-card`) ─────────────
   Padding kanan wadah gulir dihitung dua kali oleh peramban sehingga muncul
   scrollbar horizontal ±15px padahal tabelnya sudah muat (terukur pada Master
   Kategori/Pengguna/Jurnal/Piutang). Padding kanan dipindahkan ke padding sel
   terakhir supaya jarak visual tetap sama tanpa scrollbar palsu. */
.table-wrap.lab-card{padding-right:0}
.table-wrap.lab-card table.data > tbody > tr > td:last-child,
.table-wrap.lab-card table.data > thead > tr > th:last-child{padding-right:10px}
@media (max-width:900px){
  /* mode kartu bertingkat: jarak kanan tidak perlu lagi */
  .table-wrap.lab-card table.data > tbody > tr > td:last-child,
  .table-wrap.lab-card table.data > thead > tr > th:last-child{padding-right:8px}
}

/* Tombol di KOLOM AKSI tabel dibuat lebih ringkas (bukan lebih kecil dari teks
   isi, hanya padding/tinggi minimum). Ini memangkas lebar kolom aksi sehingga
   tabel muat tanpa digeser DAN baris tidak menjadi tinggi karena tombol
   bertumpuk. Tampilan tombol di luar tabel tidak berubah. */
table.data td.col-act .btn{
  padding:6px 10px;min-height:30px;font-size:.79rem;border-radius:8px;
}
table.data td.col-act form.inline-form{display:inline-flex}

/* ── Label kartu KPI: BOLEH MEMBUNGKUS (tidak terpotong, tidak menimpa angka) ──
   Setelah huruf diperbesar 1–2px, label seperti "Stok di bawah minimum" atau
   "Pemeriksaan periode ini" terpotong ("…") pada kartu 1024px/HP. Label kini
   membungkus sebanyak yang diperlukan.
   ⚠️ JANGAN memakai `-webkit-line-clamp` + `overflow:visible`: teks baris ke-3
   tetap DILUKIS walau kotaknya dipotong sehingga ANGKA di bawahnya tertimpa
   (bug nyata pada tangkapan layar HP yang dilaporkan pemilik: "TAGIHAN BELUM…
   LUNAS" bertumpuk dengan angka 1). Kotak label dibiarkan tumbuh; kartu dalam
   satu baris grid otomatis sama tinggi. */
.kpi-grid .kpi-label{
  white-space:normal;overflow:visible;text-overflow:clip;
  line-height:1.26;display:block;
}

/* ══════════════════════════════════════════════════════════════════════════
   TOMBOL AKSI TABEL → ICON BUTTON SATU BARIS + TOOLTIP
   Markup asli (a.btn / button) tidak diubah; `assets/app.js` mengganti isinya
   dengan ikon dan memindahkan teks tombol ke `data-tip`/`aria-label`.
   Tanpa JavaScript tombol tetap tampil dengan teksnya.
   ══════════════════════════════════════════════════════════════════════════ */
table.data td.col-act, table.data td.row-actions{white-space:nowrap}
.btn.icon-btn{
  position:relative;width:34px;height:34px;min-height:34px;padding:0;
  display:inline-flex;align-items:center;justify-content:center;
  border-radius:9px;margin:0 1px;vertical-align:middle;
}
.btn.icon-btn svg{width:16px;height:16px;fill:currentColor;flex:0 0 16px}
.btn.icon-btn.icon-btn-danger{
  background:var(--err-bg);border-color:var(--err-bd);color:var(--err-fg);
}
.btn.icon-btn.icon-btn-danger:hover{background:var(--err-bg-hover)}
/* ⚠️ `.act-tip` (tooltip tombol aksi) DIHAPUS seluruhnya — permintaan pemilik:
   "hilangkan fitur tooltip on hover pada aplikasi, keseluruhan".
   Jangan menghidupkan kembali tooltip lewat ::after/::before absolut (itu juga
   menambah area gulir `.table-wrap`). */
/* Di layar sentuh tooltip tidak relevan — ukuran tombol tetap nyaman. */
@media (max-width:900px){
  /* Kartu bertingkat: sel AKSI dibuat blok penuh (label di atas, ikon di bawah).
     Tanpa ini dua ikon aksi (34–40px) tidak muat di kolom nilai 72px sehingga
     tabelnya menampilkan scrollbar horizontal (terukur pada Kasir 390px). */
  table.data[data-stack] td.col-act,
  table.data[data-stack] td.row-actions{display:block;white-space:normal}
  table.data[data-stack] td.col-act::before,
  table.data[data-stack] td.row-actions::before{display:block;margin-bottom:5px}
  table.data[data-stack] td.col-act .icon-btn{margin:0 6px 4px 0}
}
@media (max-width:640px){
  .btn.icon-btn{width:40px;height:40px;min-height:40px}
  .btn.icon-btn svg{width:18px;height:18px;flex:0 0 18px}
}

/* ══════════════════════════════════════════════════════════════════════════
   PEMILIH KOLOM TABEL ("Kolom") — dipakai semua tabel daftar
   Bar diletakkan DI LUAR `.table-wrap` supaya panel dropdown tidak terpotong
   `overflow` wadah gulir tabel.
   ══════════════════════════════════════════════════════════════════════════ */
.table-tools{
  position:relative;display:flex;justify-content:flex-end;align-items:center;
  gap:8px;margin:0 0 8px;
}
.btn-cols{
  display:inline-flex;align-items:center;gap:7px;min-height:34px;
  padding:6px 12px;font-size:.8rem;
}
.btn-cols svg{width:15px;height:15px;fill:currentColor;flex:0 0 15px;opacity:.9}
.btn-cols.has-filter{border-color:var(--nav-active-border);background:var(--nav-active-bg)}
.btn-cols .count-chip{
  font-size:.68rem;font-weight:700;padding:1px 6px;border-radius:20px;
  background:var(--nav-active-bg);border:1px solid var(--nav-active-border);color:var(--ink-strong);
}
.cols-panel{
  position:absolute;right:0;top:calc(100% + 6px);z-index:55;
  width:min(290px,86vw);padding:10px;
  background:var(--panel);border:1px solid var(--line-strong);border-radius:var(--radius-sm);
  box-shadow:0 16px 38px rgba(3,14,12,.24);
}
.cols-panel[hidden]{display:none}
.cols-panel-head{display:flex;align-items:baseline;justify-content:space-between;gap:8px;margin-bottom:8px}
.cols-panel-head strong{font-size:.8rem}
.cols-panel-body{display:flex;flex-direction:column;gap:2px;max-height:min(46vh,320px);overflow-y:auto}
.cols-item{
  display:flex;align-items:center;gap:9px;padding:6px 7px;border-radius:8px;
  font-size:.82rem;cursor:pointer;
}
.cols-item:hover{background:var(--tint-hover)}
.cols-item input[type=checkbox]{
  width:17px;height:17px;min-width:17px;padding:0;margin:0;flex:0 0 17px;
}
.cols-item span{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.cols-panel-foot{display:flex;gap:8px;margin-top:9px;padding-top:9px;border-top:1px solid var(--line)}
.cols-panel-foot .btn{flex:1 1 auto;min-height:32px;padding:5px 10px;font-size:.78rem}
/* Kolom yang disembunyikan pengguna */
table.data .col-hidden{display:none!important}
@media (max-width:640px){
  .table-tools{margin-bottom:6px}
  .btn-cols{min-height:38px}
  .cols-panel{width:min(300px,92vw)}
}

/* ══════════════════════════════════════════════════════════════════════════
   DAFTAR HARGA (Master Harga) — dua tabel terkelompok, muat tanpa geser
   ══════════════════════════════════════════════════════════════════════════ */
.price-group-head{
  display:flex;align-items:baseline;gap:10px;flex-wrap:wrap;
  margin:16px 0 8px;
}
.price-group-head:first-child{margin-top:0}
.price-group-head h3{font-size:.94rem;color:var(--head-ink)}
table.data.price-table{min-width:0}
/* padding sel lebih rapat khusus tabel harga (banyak kolom input) */
table.data.price-table td,table.data.price-table thead th{padding:8px 7px}
table.data.price-table .col-item{min-width:168px}
table.data.price-table .col-unit{white-space:nowrap}
table.data.price-table .col-money{min-width:96px}
table.data.price-table .col-pct{min-width:72px}
table.data.price-table .col-mode{min-width:132px}
table.data.price-table input[type=number],
table.data.price-table input[type=text]{
  width:100%;min-width:0;max-width:none;
}
table.data.price-table input[type=number]{text-align:right}
table.data.price-table td .muted.small{display:block;margin-top:2px}
/* Blok "Dasar + tarif": pilihan mode di atas, margin & markup berlabel di bawah.
   Label diletakkan DI ATAS isian (bukan di samping) supaya lebar kolom cukup
   selebar isiannya — tabel muat tanpa geser bahkan di layar 1280px. */
.px-stack{display:flex;flex-direction:column;gap:5px;min-width:0}
.price-table .px-mini{flex-direction:column;align-items:stretch;gap:2px}
.price-table .px-mini > span:first-child{min-width:0;font-size:.66rem;line-height:1.2}
.px-stack select{width:100%;min-width:0;font-size:.8rem;padding-right:28px}
.px-mini{display:flex;align-items:center;gap:6px;min-width:0}
.px-mini > span:first-child{
  font-size:.68rem;color:var(--ink-2);font-weight:600;white-space:nowrap;
  flex:0 0 auto;letter-spacing:.02em;min-width:64px;
}
.px-mini > input{flex:1 1 auto;min-width:0}
/* Di HP tabel menjadi kartu bertingkat: label kolom tampil, input penuh. */
@media (max-width:900px){
  table.data.price-table .col-item,
  table.data.price-table .col-money,
  table.data.price-table .col-pct,
  table.data.price-table .col-mode{min-width:0}
  /* Kartu bertingkat tabel harga: label DI ATAS isian, bukan dua kolom
     (kolom nilai 100px tidak cukup untuk isian nominal → meluber). */
  table.data.price-table[data-stack] td{display:block}
  table.data.price-table[data-stack] td::before{display:block;margin-bottom:3px}
  /* Kartu bertingkat: label di atas, kolom isian penuh di bawahnya. Baris flex
     yang dipaksa berdampingan (label 64px + isian 64px) meluber dari kolom nilai
     kartu (terukur 264px pada wadah 208px), jadi di HP label dibuat sebaris
     penuh lebih dulu. */
  .px-mini{flex-wrap:wrap;gap:4px}
  .px-mini > span:first-child{min-width:0;flex:1 1 100%;white-space:normal}
  .px-mini > .num-wrap,.px-mini > input{flex:1 1 100%;min-width:0}
  .px-stack select{min-width:0}
}
/* Sel hasil di dalam blok bertumpuk (HJO & jenjang) */
.price-table .px-out{display:block;font-family:var(--mono);font-variant-numeric:tabular-nums;text-align:right}
.price-table .px-stack .muted.small{margin-top:0}

/* Kartu bertingkat (≤900px): pill/chip status di dalam sel boleh membungkus.
   Dengan `white-space:nowrap` bawaan, label "Belum Dibayar" (104px) tidak muat di
   kolom nilai yang sempit sehingga SEL MELUBER dan tabel menampilkan scrollbar
   horizontal (terukur: Kasir 390px, sel Status 220px pada 182px). */
@media (max-width:900px){
  table.data[data-stack] td .pill,
  table.data[data-stack] td .chip,
  table.data[data-stack] td .badge{white-space:normal}
  table.data[data-stack] td.grid > .pill{justify-self:start}
}

/* Target sentuh: tombol kecil dibuat ≥36px di layar sempit (sebelumnya tepat
   34px sehingga pembulatan subpiksel membuatnya terukur <34px). */
@media (max-width:900px){
  .btn-sm{min-height:36px}
  .table-tools .btn-cols{min-height:38px}
}

/* ══════════════════════════════════════════════════════════════════════════
   RONDE PERBAIKAN GLOBAL (permintaan pemilik)
   1. HP: `<html>` tidak boleh menyempit — `.shell` kembali 1 kolom (lihat
      perbaikan media query di atas), kartu KPI & navigasi bawah dirapikan.
   2. Tombol aksi (ikon di tabel) WAJIB mengikuti tema: ikon hitam di tema
      terang, putih di tema gelap.
   3. Tabel desktop: isi sel tidak lagi ditumpuk 2 baris (nilai + keterangan
      kecil di bawahnya) — keterangan kecil ikut sebaris. Tampilan HP (kartu
      bertingkat) TIDAK berubah.
   ══════════════════════════════════════════════════════════════════════════ */

/* ---------- 2) TOMBOL AKSI IKON: warna ikut tema ----------
   `.icon-btn{background:var(--tint)}` (spesifisitas sama, ditulis lebih dulu)
   MENIMPA latar `.btn-primary` sehingga tombol aksi utama tampil sebagai kotak
   pucat dengan ikon PUTIH (warna `.btn-primary`) → ikon mata hampir tak terlihat
   di tema terang. Sekarang semua tombol aksi memakai latar netral + warna teks
   tema (`--ink`): hitam di tema terang, putih di tema gelap. */
.icon-btn{color:var(--ink)}
.btn.icon-btn,
.btn.icon-btn.btn-primary,
.btn.icon-btn.btn-ghost{
  background:var(--btn-bg);
  border-color:var(--line-strong);
  color:var(--ink);
  box-shadow:none;
}
.btn.icon-btn:hover,
.btn.icon-btn.btn-primary:hover{background:var(--btn-bg-hover);border-color:var(--btn-border-hover);filter:none}
.btn.icon-btn.icon-btn-danger,
.btn.icon-btn.btn-danger{
  background:var(--err-bg);border-color:var(--err-bd);color:var(--err-fg);
}
.btn.icon-btn.icon-btn-danger:hover{background:var(--err-bg-hover);filter:none}
.btn.icon-btn svg,.icon-btn svg{fill:currentColor}

/* ---------- 3) NAVIGASI BAWAH HP: lencana tidak menimpa label ----------
   `.bnav-item span{overflow:hidden;text-overflow:ellipsis}` juga mengenai
   lencana (span) sehingga angka terpotong; posisinya di atas label membuat
   tulisan menu tampak bertumpuk. Lencana dipindah ke pojok kanan-atas ikon
   dan diberi latar penuh supaya angkanya selalu terbaca. */
@media (max-width:900px){
  .bnav-item{padding-top:6px}
  .bnav-item > span:not(.nav-badge){max-width:100%}
  .bnav-item .bnav-badge{
    top:2px;right:6px;left:auto;bottom:auto;
    max-width:none;overflow:visible;text-overflow:clip;
    line-height:1.1;padding:1px 5px;border-radius:9px;
    background:var(--err-fg);color:#fff;border:0;
    box-shadow:0 0 0 2px var(--sidebar-bg);
    pointer-events:none;z-index:2;
  }
}

/* ---------- 4) KPI di HP: label maksimal 2 baris, angka tidak menempel ---------- */
@media (max-width:900px){
  .kpi-grid .kpi{padding:12px 12px;gap:5px}
  .kpi-grid .kpi-label{line-height:1.24}
  .kpi-grid .kpi-value{line-height:1.2;margin-top:1px}
}

/* ---------- 5) TABEL DESKTOP: satu baris (keterangan kecil sebaris) ----------
   `assets/app.js` menandai sel yang berisi `<br>` + keterangan kecil
   (`small`/`.muted.small`): <br> disembunyikan, keterangan dibuat sebaris dan
   dipisah "·". Hanya berlaku ≥901px; di HP tabel tetap menjadi kartu
   bertingkat sehingga keterangan tetap tampil di bawah nilai. */
@media (min-width:901px){
  table.data td .cell-inline-sub{
    display:inline;margin:0;font-size:inherit;white-space:normal;
  }
  table.data td .cell-inline-sub.cell-inline-tiny{font-size:.76rem}
  /* Sel yang sudah "flat" tidak boleh menambah tinggi baris karena
     elemen blok kecil (mis. `.muted.small` global) — paksa sebaris. */
  table.data td.is-flat small,
  table.data td.is-flat span.small{display:inline!important;margin:0!important}
}

/* Pemisah keterangan yang dipindah sebaris pada tabel desktop (lihat
   `flattenCells()` di assets/app.js). */
table.data td .cell-sep{color:var(--ink-3);white-space:pre}

/* ── PERMINTAAN BARANG: baris "Produk baru" (belum ada di persediaan) ──
   Kolom nama produk muncul DI BAWAH dropdown begitu pengguna memilih
   "➕ Produk baru"; di HP (kartu bertingkat) tetap satu kolom penuh. */
.pb-table .pb-item-cell{min-width:190px}
.pb-table .pb-new-name{margin-top:6px;width:100%;font-size:.82rem}
.pb-table .pb-new-name[hidden]{display:none}
@media (max-width:900px){
  .pb-table .pb-item-cell{min-width:0}
}

/* ══════════════════════════════════════════════════════════════════════════
   KOLOM AKSI TABEL: SEMUA TOMBOL DALAM SATU BARIS & SEJAJAR
   Bug nyata (dilaporkan pemilik): pada tampilan Tabel menu Rencana Pembelian
   & Pembelian, 2–3 tombol aksi TURUN BARIS dan saling menimpa karena kolomnya
   sempit (16–51px) — tombol juga diperas sampai SVG-nya tidak kelihatan.
   Penyebab kedua: `<td class="row-actions">` menjadi `display:flex` sehingga
   tombol menyusut di dalam sel tabel.
   Perbaikan:
   · `<td>` aksi tetap `table-cell` (bukan flex) + `white-space:nowrap`;
   · isi sel dibungkus `.act-row` (dibuat assets/app.js) = flex satu baris,
     `align-items:center` sehingga tombol `<form>`/tautan sejajar sempurna;
   · tombol ikon tidak boleh menyusut (`flex:0 0 auto`, lebar tetap) — ini yang
     membuat SVG selalu tampil utuh.
   ══════════════════════════════════════════════════════════════════════════ */
table.data td.col-act,
table.data td.row-actions{
  display:table-cell;            /* jangan flex — flex pada <td> memeras tombol */
  white-space:nowrap;
  vertical-align:middle;
}
.act-row{
  display:flex;align-items:center;justify-content:center;gap:6px;
  flex-wrap:nowrap;min-width:0;
}
/* Form (tombol submit) & pembungkus lama `.row-actions` tidak lagi memotong baris:
   `display:contents` membuat tombolnya menjadi anak langsung `.act-row` sehingga
   sejajar dengan tautan di sebelahnya (dulu selisih 4–5px). */
.act-row > form,
.act-row > .row-actions{display:contents;margin:0}
.act-row > .btn,
.act-row > form > .btn,
.act-row > .row-actions > .btn,
.act-row > .row-actions > form > .btn{flex:0 0 auto}
.btn.icon-btn{flex:0 0 auto;width:34px;min-width:34px;height:34px}
table.data td.col-act .act-row{justify-content:center}
/* Tanpa JavaScript tetap aman: tombol bertulisan tidak dipaksa satu baris bila
   ruang benar-benar tidak cukup, tetapi tidak lagi saling menimpa. */
table.data td.col-act{min-width:0}
@media (max-width:900px){
  /* Kartu bertingkat HP: tombol aksi boleh membungkus & tidak dijejalkan. */
  table.data[data-stack] td.col-act,
  table.data[data-stack] td.row-actions{display:block}
  table.data[data-stack] td.col-act{width:auto}
  table.data[data-stack] .act-row{flex-wrap:wrap;justify-content:flex-start;gap:8px}
  .btn.icon-btn{width:40px;min-width:40px;height:40px}
}

/* ── Ikon tombol aksi TIDAK BOLEH DIPERAS ──────────────────────────────────
   `table.data td.col-act .btn{padding:6px 10px}` (0,3,1) mengalahkan
   `.btn.icon-btn{padding:0}` (0,2,0) sehingga tombol ikon 34px hanya menyisakan
   ruang isi 14px → SVG menyusut jadi 12px (terlihat "tidak menampilkan svg").
   Aturan di bawah (lebih spesifik + paling akhir) mengembalikan padding 0 dan
   ukuran ikon tetap 16px. */
table.data td.col-act .btn.icon-btn,
table.data td.row-actions .btn.icon-btn,
.act-row .btn.icon-btn{
  padding:0;margin:0;min-height:34px;height:34px;width:34px;min-width:34px;
  border-radius:9px;font-size:0;
}
table.data td.col-act .btn.icon-btn svg,
table.data td.row-actions .btn.icon-btn svg,
.act-row .btn.icon-btn svg{
  width:16px;height:16px;min-width:16px;flex:0 0 16px;
}
@media (max-width:900px){
  table.data td.col-act .btn.icon-btn,
  table.data td.row-actions .btn.icon-btn,
  .act-row .btn.icon-btn{width:40px;min-width:40px;height:40px;min-height:40px;margin:0 6px 4px 0}
  table.data td.col-act .btn.icon-btn svg,
  table.data td.row-actions .btn.icon-btn svg,
  .act-row .btn.icon-btn svg{width:18px;height:18px;min-width:18px;flex:0 0 18px}
}

/* ══════════════════════════════════════════════════════════════════════════
   PILL STATUS & PRIORITAS BERWARNA (bertingkat)
   ⚠️ Kelas `pill-ok` / `pill-err` / `pill-info` dipakai di SELURUH aplikasi
   (ribuan pemanggilan `status_pill()`), tetapi selama ini BELUM punya aturan
   CSS sehingga pill tampil transparan/tanpa warna. Sekarang semuanya berwarna
   sesuai tingkatannya:
     pill-ok    hijau  → selesai / disetujui / lunas
     pill-warn  kuning → menunggu / revisi / prioritas tinggi
     pill-err   merah  → ditolak / batal / darurat / lewat SLA
     pill-info  biru   → tahap proses (dalam rencana, dalam pembelian, info)
     pill-off   abu    → draft / nonaktif
   ══════════════════════════════════════════════════════════════════════════ */
.pill-ok{background:var(--ok-bg);color:var(--ok-fg);border-color:var(--ok-bd);margin-left:6px}
.pill-err{background:var(--err-bg);color:var(--err-fg);border-color:var(--err-bd);margin-left:6px}
.pill-info{background:var(--info-bg);color:var(--info-fg);border-color:var(--info-bd);margin-left:6px}
.pill-soft{margin-left:6px}
/* Pill pertama di dalam sel/kartu tidak perlu jarak kiri. */
td > .pill:first-child, .head-chips > .pill:first-child, .pb-meta > .pill:first-child{margin-left:0}
.head-chips{gap:6px}
/* Prioritas & status "bertumpuk" tetap rapi di HP (boleh membungkus). */
@media (max-width:640px){
  .head-chips{flex-wrap:wrap;row-gap:4px}
}

/* ══════════════════════════════════════════════════════════════════════════
   FORM PERMINTAAN BARANG — RINCIAN PRODUK BERBENTUK KARTU PER BARIS
   Dulu satu tabel 7 kolom yang sempit (input berjejer, sulit dipakai di HP).
   Sekarang tiap baris = kartu berlabel yang melipat otomatis; kolom "Produk"
   dan "Alasan/Catatan" mendapat ruang lebih lebar, dan kolom angka tetap
   proporsional.
   ══════════════════════════════════════════════════════════════════════════ */
.pb-lines{display:flex;flex-direction:column;gap:12px}
.pb-line{
  display:grid;
  grid-template-columns:minmax(190px,2.1fr) 92px 118px minmax(150px,1.5fr) minmax(140px,1.2fr) 38px;
  gap:10px;align-items:end;
  padding:12px 13px;border:1px solid var(--line-strong);border-radius:12px;
  background:var(--tint-3);
}
.pb-line.is-new{border-color:var(--focus-border);background:var(--info-bg)}
.pb-f{display:flex;flex-direction:column;gap:4px;min-width:0}
.pb-f > span{
  font-size:.7rem;font-weight:700;letter-spacing:.04em;text-transform:uppercase;
  color:var(--ink-2);line-height:1.2;
}
.pb-f > span em{color:var(--err-fg);font-style:normal}
.pb-f input,.pb-f select{width:100%;min-width:0}
.pb-f-item{min-width:0}
.pb-del{align-self:end;justify-self:end;width:34px;min-width:34px;height:34px;padding:0}
.pb-lines-new .pb-line{grid-template-columns:minmax(200px,2.2fr) 92px 118px minmax(160px,1.6fr) 38px}
@media (max-width:1100px){
  .pb-line{grid-template-columns:minmax(180px,1.8fr) 84px 110px minmax(140px,1.2fr) 38px}
  .pb-line .pb-f:nth-child(5){grid-column:1 / -2}   /* catatan turun sebaris */
}
@media (max-width:900px){
  .pb-line,.pb-lines-new .pb-line{grid-template-columns:repeat(2,minmax(0,1fr));gap:9px}
  .pb-f-item,.pb-f-wide{grid-column:1 / -1}
  .pb-del{grid-column:1 / -1;justify-self:end}
  .pb-line .pb-f:nth-child(5){grid-column:1 / -1}
}
@media (max-width:520px){
  .pb-line,.pb-lines-new .pb-line{grid-template-columns:minmax(0,1fr)}
  .pb-del{justify-self:stretch;width:100%}
}

/* Kartu "Dari Permintaan Barang" pada form Rencana Pembelian (boleh >1 PB). */
.pb-picked{display:flex;align-items:center;gap:8px;flex-wrap:wrap;padding:10px 12px;
  border:1px solid var(--ok-bd);background:var(--ok-bg);border-radius:12px;margin-bottom:10px}
.pb-picked-label{font-size:.78rem;font-weight:700;color:var(--ok-fg)}
.pb-pick-chip{display:inline-flex;align-items:center;gap:6px;background:var(--panel);border:1px solid var(--line-strong)}
.pb-pick-form{margin:0}
.pb-pick-list{
  display:grid;grid-template-columns:repeat(auto-fill,minmax(min(260px,100%),1fr));gap:8px;
  max-height:230px;overflow:auto;padding:8px;border:1px solid var(--line-strong);
  border-radius:12px;background:var(--tint-3);
}
.pb-pick-item{display:flex;align-items:center;gap:9px;padding:8px 10px;border-radius:10px;
  border:1px solid transparent;cursor:pointer}
.pb-pick-item:hover{background:var(--btn-bg-hover)}
.pb-pick-item.is-picked{border-color:var(--focus-border);background:var(--nav-active-bg)}
.pb-pick-check{
  flex:0 0 auto;width:22px;height:22px;border-radius:7px;display:inline-flex;
  align-items:center;justify-content:center;font-weight:700;font-size:.86rem;
  border:1px solid var(--line-strong);background:var(--panel);color:var(--ink-2);
}
.pb-pick-item.is-picked .pb-pick-check{background:var(--cyan);border-color:transparent;color:#fff}
.pb-pick-item{text-decoration:none;color:inherit}
.pb-pick-body{display:flex;flex-direction:column;min-width:0;line-height:1.25}
.pb-pick-body .muted{font-size:.72rem}
.form-hint{margin:0;font-size:.8rem;color:var(--ink-2)}

/* ══════════════════════════════════════════════════════════════════════════
   RINCIAN PRODUK PADA DETAIL PERMINTAAN BARANG (PB) — SATU TABEL UTUH
   Permintaan pemilik: seluruh baris produk yang diajukan tampil sekaligus,
   TIDAK ada gulir internal di dalam tabel.
   Penyebab gulir internal: `.sheet-body .table-wrap{content-visibility:auto;
   contain-intrinsic-size:auto 240px}` membuat tinggi wadah "dikira-kira"
   (terukur 169px untuk tabel 13 baris / 574px isi) dan karena `overflow-x:auto`
   membuat `overflow-y` juga `auto`, isinya dipotong + punya scrollbar sendiri.
   Di sini optimasi itu DIMATIKAN khusus tabel rincian PB.
   ══════════════════════════════════════════════════════════════════════════ */
.sheet-body .pb-rows-wrap,
.sheet-body .pb-rows-wrap:has(details[open]){
  content-visibility:visible;
  contain:none;
  overflow:visible;
  max-height:none;
  height:auto;
}
.sheet-body .pb-rows-wrap table.data.pb-rows-table{
  min-width:0;
  width:100%;
  table-layout:auto;
}
/* Tidak ada pemotongan teks: alasan/catatan boleh membungkus seperlunya. */
.sheet-body .pb-rows-wrap table.data.pb-rows-table td{white-space:normal;overflow-wrap:anywhere}
@media (max-width:900px){
  /* Di HP tabel sudah menjadi kartu bertingkat → tetap tanpa gulir. */
  .sheet-body .pb-rows-wrap{overflow:visible}
}

/* ══════════════════════════════════════════════════════════════════════════
   BARIS "PRODUK BARU" PADA RENCANA PEMBELIAN
   Produk yang diminta belum ada di persediaan → kolom nama + jenis tampil
   langsung di bawah dropdown produk pada baris itu (disembunyikan default).
   ══════════════════════════════════════════════════════════════════════════ */
.pb-new-fields{display:none;gap:6px;margin-top:6px;align-items:center}
.pb-new-fields.is-on{display:flex;flex-wrap:wrap}
.pb-new-fields input[type=text]{flex:1 1 150px;min-width:0}
.pb-new-fields select{flex:0 0 96px;min-width:0}
@media (max-width:640px){
  .pb-new-fields{flex-direction:column;align-items:stretch}
  .pb-new-fields select{flex:1 1 auto}
}

/* ══════════════════════════════════════════════════════════════════════════
   MODUL PENERIMAAN BARANG (GRN) + TIMELINE PROSES BISNIS
   ══════════════════════════════════════════════════════════════════════════ */
.grn-list{display:flex;flex-direction:column;gap:14px}
.grn-line{
  border:1px solid var(--line-strong);border-radius:14px;background:var(--tint-3);
  padding:13px 14px;
}
.grn-line:focus-within{border-color:var(--focus-border)}
.grn-head{display:flex;justify-content:space-between;gap:12px;flex-wrap:wrap;align-items:flex-start}
.grn-item{display:flex;flex-direction:column;gap:2px;min-width:0}
.grn-item strong{color:var(--head-ink);font-size:.98rem}
.grn-facts{display:flex;gap:14px;flex-wrap:wrap;font-size:.82rem;color:var(--ink-2)}
.grn-facts strong{color:var(--ink-strong)}
.grn-left strong{color:var(--code-ink)}
.grn-grid{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(min(150px,100%),1fr));
  gap:10px;margin-top:11px;align-items:start;
}
.grn-grid .span-2{grid-column:span 2}
.grn-eq strong{font-size:1rem;color:var(--head-ink)}
.grn-bn{display:flex;gap:6px;align-items:center}
.grn-bn input{flex:1 1 auto;min-width:0}
.grn-bn .bc-btn{flex:0 0 auto}
.grn-reject{margin-top:10px;border-top:1px dashed var(--line);padding-top:9px}
.grn-reject summary{cursor:pointer;font-size:.84rem;color:var(--ink-2);padding:4px 0}
.grn-reject summary strong{color:var(--err-fg)}
.grn-reject[open] summary{color:var(--ink-strong)}
.grn-attach{display:flex;flex-direction:column;gap:6px}
.grn-attach .attach-actions{display:flex;gap:8px;flex-wrap:wrap;align-items:center}
.grn-cancel{margin-top:14px;border-top:1px dashed var(--line);padding-top:10px}
.grn-cancel summary{cursor:pointer;color:var(--err-fg);font-size:.86rem}
.grn-meta{display:flex;gap:14px;flex-wrap:wrap;padding:2px 0 10px;font-size:.8rem;color:var(--ink-2)}
.grn-meta strong{color:var(--ink-strong)}
.attach-inline{display:flex;gap:6px;flex-wrap:wrap}
.field.is-required > span{color:var(--err-fg)}
input.is-invalid{border-color:var(--err-bd)!important}

/* Toggle status pembayaran pada kartu nota: berbentuk sakelar penuh. */
label.pay-toggle.switch-line{
  display:flex;flex-wrap:wrap;align-items:center;gap:10px;cursor:pointer;
  padding:12px 14px;border-radius:12px;border:1px solid var(--line-strong);
  background:var(--tint-3);flex-direction:row;
}
label.pay-toggle.switch-line input[type=checkbox]{
  appearance:none;-webkit-appearance:none;flex:0 0 46px;width:46px;height:25px;
  border-radius:999px;background:var(--panel-2);border:1px solid var(--line-strong);
  position:relative;margin:0;cursor:pointer;transition:background .18s,border-color .18s;
}
label.pay-toggle.switch-line input[type=checkbox]::after{
  content:'';position:absolute;top:2px;left:2px;width:19px;height:19px;border-radius:50%;
  background:var(--ink-2);transition:transform .18s,background .18s;
}
label.pay-toggle.switch-line input[type=checkbox]:checked{background:var(--ok-bg);border-color:var(--ok-bd)}
label.pay-toggle.switch-line input[type=checkbox]:checked::after{transform:translateX(21px);background:var(--ok-fg)}
label.pay-toggle.switch-line > span[data-paid-title]{font-weight:600;color:var(--ink-strong)}
label.pay-toggle.switch-line .pt-hint{flex:1 1 100%;margin-left:56px}
label.pay-toggle.switch-line:has(input:checked){border-color:var(--ok-bd);background:var(--ok-bg)}
label.pay-toggle.switch-line:has(input:checked) > span[data-paid-title]{color:var(--ok-fg)}

.pay-now-card{
  margin-top:14px;padding:14px;border-radius:14px;
  border:1px solid var(--focus-border);background:var(--tint-3);
}
.pay-now-card[hidden]{display:none}
.pay-now-card .pay-proof-card{margin-top:12px}

/* Timeline dokumen: PB → RP → PO → Nota → Penerimaan (tanggal + jam). */
.doc-track{list-style:none;margin:6px 0 6px;padding:0 0 0 4px;display:flex;flex-direction:column;gap:2px}
.doc-track-item{display:flex;gap:12px;padding:9px 0 9px 0;position:relative}
.doc-track-item::before{
  content:'';position:absolute;left:4px;top:24px;bottom:-6px;width:2px;background:var(--line);
}
.doc-track-item:last-child::before{display:none}
.dt-dot{
  position:relative;z-index:1;flex:0 0 10px;width:10px;height:10px;margin-top:6px;border-radius:50%;
  background:var(--line-strong);box-shadow:0 0 0 3px var(--panel);
}
.doc-track-item.is-done .dt-dot{background:var(--cyan)}
.dt-body{display:flex;flex-wrap:wrap;gap:6px 10px;align-items:baseline;min-width:0}
.dt-stage{font-weight:700;color:var(--head-ink);font-size:.9rem}
.dt-code{font-size:.86rem}
.dt-at{font-size:.82rem;color:var(--ink-2);font-variant-numeric:tabular-nums}
.dt-note{flex:1 1 100%;font-size:.78rem;color:var(--ink-3)}

@media (max-width:900px){
  .grn-grid .span-2{grid-column:auto}
  .grn-head{flex-direction:column;gap:6px}
  .grn-facts{gap:10px}
}
@media (max-width:640px){
  .grn-grid{grid-template-columns:minmax(0,1fr)}
  label.pay-toggle.switch-line .pt-hint{margin-left:0}
  .dt-note{flex:1 1 100%}
}

/* ══════════════════════════════════════════════════════════════════════════
   PENERIMAAN BARANG — BEBERAPA NOMOR BATCH (BN) DALAM SATU PRODUK
   Permintaan pemilik: satu produk boleh datang dengan >1 BN (mis. dipesan 500
   tablet, datang 300 dengan BN-A + 200 dengan BN-B), dan penolakan juga punya
   satuan sendiri. Tiap BN = satu blok kecil di dalam baris produk.
   ══════════════════════════════════════════════════════════════════════════ */
.bn-rows{display:flex;flex-direction:column;gap:10px;margin-top:10px}
.bn-row{
  border:1px solid var(--line);border-radius:12px;background:var(--panel);
  padding:10px 11px;
}
.bn-row:focus-within{border-color:var(--focus-border)}
.bn-row.is-reject-only{border-color:var(--err-bd);background:var(--err-bg)}
.bn-row-head{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-bottom:6px}
.bn-badge{
  font-size:.72rem;font-weight:700;letter-spacing:.03em;text-transform:uppercase;
  color:var(--ink-2);
}
.btn-bn-del{width:30px;min-width:30px;height:30px;padding:0;line-height:1}
.bn-grid{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(min(160px,100%),1fr));
  gap:9px;align-items:start;
}
.bn-grid .span-2{grid-column:span 2}
.bn-note{margin-top:8px}
.bn-foot{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-top:9px}
.bn-foot .muted.small{font-variant-numeric:tabular-nums}
@media (max-width:900px){
  .bn-grid .span-2{grid-column:auto}
}
@media (max-width:640px){
  .bn-grid{grid-template-columns:minmax(0,1fr)}
  .btn-bn-del{width:38px;min-width:38px;height:38px}
}

/* ══════════════════════════════════════════════════════════════════════════
   CAKUPAN TOMBOL INFO DIPERLUAS (permintaan pemilik)
   "Jadikan bagian informasi sebagai bagian dari tombol show/hide Informasi."
   Subjudul JUDUL SEKSI (`section_head()`) dan keterangan kartu filter dulu TIDAK
   ikut tersembunyi sehingga teks penjelas masih tampil walau Info dimatikan.
   Yang disembunyikan tetap hanya teks PENJELAS — nilai/angka tidak.
   ══════════════════════════════════════════════════════════════════════════ */
html[data-hints="off"] .section-head .section-head-main > .muted,
html[data-hints="off"] .section-head .section-head-main > span.muted.small,
html[data-hints="off"] .section-head .muted.small,
html[data-hints="off"] .filter-head .muted.small{
  display:none!important;
}
/* ⚠️ ANGKA tidak boleh ikut hilang: `.grn-facts` (Dipesan / Sudah diterima /
   Sisa) dan total antar-batch adalah DATA yang dibutuhkan saat menerima barang,
   jadi keduanya TIDAK masuk daftar sembunyi. Nilai yang berubah karena input
   pengguna tetap ditandai `data-live-hint` (selalu tampil). */

/* ══════════════════════════════════════════════════════════════════════════
   PEMINDAI BARCODE / QR CODE — POP-UP KAMERA (global, semua menu)
   Permintaan pemilik: menekan tombol pindai membuka POP-UP kamera tanpa
   menutup konten di belakangnya, ada KOTAK PEMANDU, dan hasilnya muncul di
   pop-up dengan pilihan [Gunakan] / [Scan Ulang].
   ⚠️ z-index di atas `.sheet-backdrop` (70) & `.bottom-nav` (30) supaya bisa
   dipakai dari dalam kartu mengambang di HP.
   ══════════════════════════════════════════════════════════════════════════ */
.scan-backdrop{
  position:fixed;inset:0;z-index:120;display:none;
  align-items:center;justify-content:center;padding:18px;
  background:rgba(6,12,22,.62);
}
html[data-theme="light"] .scan-backdrop{background:rgba(20,32,58,.44)}
.scan-backdrop.is-open{display:flex}
body.scan-locked{overflow:hidden}

.scan-card{
  width:min(520px,100%);max-height:calc(100dvh - 32px);display:flex;flex-direction:column;
  background:var(--pop-bg);border:1px solid var(--line-strong);border-radius:16px;
  box-shadow:var(--shadow-lg,0 24px 60px rgba(0,0,0,.35));overflow:hidden;
}
.scan-head{
  display:flex;align-items:flex-start;justify-content:space-between;gap:12px;
  padding:14px 16px;border-bottom:1px solid var(--line);flex:0 0 auto;
}
.scan-head h3{margin:0;font-size:1.02rem;color:var(--head-ink)}
.scan-head small{display:block;margin-top:2px;color:var(--ink-2)}

.scan-stage{
  position:relative;background:#05080d;flex:0 0 auto;
  aspect-ratio:4/3;max-height:52dvh;overflow:hidden;
}
.scan-stage video{width:100%;height:100%;object-fit:cover;display:block}
.scan-stage.is-paused video{filter:saturate(.35) brightness(.7)}

/* KOTAK BINGKAI PEMANDU: sudut tebal + garis laser halus. */
.scan-guide{
  position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);
  width:min(72%,320px);aspect-ratio:1/1;pointer-events:none;
}
.scan-guide .sg-corner{
  position:absolute;width:26px;height:26px;border:3px solid #35e0b0;border-radius:3px;
}
.scan-guide .sg-corner.tl{top:0;left:0;border-right:0;border-bottom:0}
.scan-guide .sg-corner.tr{top:0;right:0;border-left:0;border-bottom:0}
.scan-guide .sg-corner.bl{bottom:0;left:0;border-right:0;border-top:0}
.scan-guide .sg-corner.br{bottom:0;right:0;border-left:0;border-top:0}
.scan-guide .sg-laser{
  position:absolute;left:6%;right:6%;top:12%;height:2px;border-radius:2px;
  background:linear-gradient(90deg,transparent,#35e0b0,transparent);
  animation:scanSweep 2.1s ease-in-out infinite;
}
@keyframes scanSweep{
  0%,100%{top:12%;opacity:.55}
  50%{top:88%;opacity:1}
}
.scan-stage.is-paused .sg-laser{animation:none;opacity:0}
.scan-tip{
  position:absolute;left:0;right:0;bottom:0;margin:0;padding:8px 12px;
  font-size:.76rem;text-align:center;color:#dff7ef;
  background:linear-gradient(180deg,transparent,rgba(3,8,14,.82));
}
@media (prefers-reduced-motion:reduce){
  .scan-guide .sg-laser{animation:none;opacity:.8}
}

.scan-status{
  margin:0;padding:9px 16px;font-size:.82rem;color:var(--ink-2);
  border-bottom:1px solid var(--line);min-height:34px;flex:0 0 auto;
}
.scan-status.neg{color:var(--err-fg)}
.scan-status.pos{color:var(--ok-fg)}

.scan-result{
  padding:12px 16px;border-bottom:1px solid var(--line);background:var(--ok-bg);flex:0 0 auto;
}
.scan-result[hidden]{display:none}
.sr-label{display:block;font-size:.74rem;letter-spacing:.03em;text-transform:uppercase;color:var(--ink-2)}
.sr-label b{color:var(--ok-fg);font-weight:700}
.sr-code{
  display:block;margin:5px 0 10px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;
  font-size:1.16rem;font-weight:700;color:var(--code-ink);word-break:break-all;
}
.sr-actions{display:flex;gap:8px;flex-wrap:wrap}
.sr-actions .btn{min-height:42px}

.scan-manual{padding:11px 16px 4px;flex:0 0 auto}
.scan-manual .field > span{font-size:.76rem}
.scan-manual input{width:100%}
.scan-foot{padding:8px 16px 14px;flex:0 0 auto}

@media (max-width:640px){
  .scan-backdrop{padding:0;align-items:flex-end}
  .scan-card{width:100%;max-height:calc(100dvh - 8px);border-radius:16px 16px 0 0}
  .scan-stage{aspect-ratio:3/4;max-height:46dvh}
  .scan-head h3{font-size:.98rem}
  .sr-actions .btn{flex:1 1 46%}
}

/* ══════════════════════════════════════════════════════════════════════════
   KARTU PENERIMAAN — baris barang dibuat HIJAU CERAH LEMBUT (permintaan pemilik)
   Sebelumnya `.grn-line` memakai `--tint-3` (hijau transparan 3%) sehingga
   praktis sama dengan latar kartu → tidak kontras. Sekarang memakai tint hijau
   ±10% dengan garis hijau tipis: kontras cukup, tetapi TIDAK pekat/menyilaukan.
   Token dipisah per tema supaya teks tetap terbaca di mode terang & gelap.
   ══════════════════════════════════════════════════════════════════════════ */
:root{
  /* Hijau CERAH (bukan teal) supaya benar-benar terbaca "hijau" di tema gelap,
     tetap lembut (alpha rendah) agar tidak menyilaukan. */
  --grn-tint:rgba(74,222,128,.14);
  --grn-tint-2:rgba(74,222,128,.08);
  --grn-bd:rgba(74,222,128,.42);
  --grn-bar:linear-gradient(90deg,#4ade80,#86efac);
}
html[data-theme="light"]{
  --grn-tint:rgba(22,163,74,.10);
  --grn-tint-2:rgba(22,163,74,.06);
  --grn-bd:rgba(22,163,74,.32);
  --grn-bar:linear-gradient(90deg,#15803d,#4ade80);
}
.grn-line{
  background:var(--grn-tint)!important;
  border-color:var(--grn-bd)!important;
}
.grn-line .bn-row{background:var(--grn-tint-2)}
.grn-line:focus-within{border-color:var(--focus-border)!important}

/* Progres kelengkapan (Sebagian / Lengkap) pada kartu penerimaan. */
.grn-progress{margin:12px 0 4px}
.gp-bar{height:7px;border-radius:999px;background:var(--tint-3);overflow:hidden}
.gp-bar > span{display:block;height:100%;border-radius:999px;background:var(--grn-bar);transition:width .25s}
.gp-text{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-top:7px;font-size:.82rem;color:var(--ink-2)}
.gp-text strong{color:var(--ink-strong)}
.gp-text .neg{color:var(--err-fg)}

/* Baris "Barang Tak Dipesan" pada formulir penerimaan. */
.grn-extra-rows{display:flex;flex-direction:column;gap:10px}
.grn-extra-row{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(min(150px,100%),1fr));
  gap:9px;align-items:end;padding:11px 12px;border-radius:12px;
  border:1px dashed var(--line-strong);background:var(--tint-3);
}
.grn-extra-row .span-2{grid-column:span 2}
.grn-extra-row .btn-danger{justify-self:end;width:34px;min-width:34px;height:34px;padding:0}
@media (max-width:900px){
  .grn-extra-row .span-2{grid-column:auto}
}
@media (max-width:640px){
  .grn-extra-row{grid-template-columns:minmax(0,1fr)}
  .grn-extra-row .btn-danger{width:100%;min-width:0;height:40px}
}

/* ══════════════════════════════════════════════════════════════════════════
   RENCANA PEMBELIAN — KETERANGAN ASAL BARIS (PB vs MANUAL) & SARAN PEMBELIAN
   Permintaan pemilik: pada tabel Detail Pembelian, baris yang diambil dari
   Permintaan Barang harus jelas berbeda dari baris manual; sekaligus tiap baris
   menampilkan saran pembelian (harga pembelian terakhir + supplier, dan harga
   termurah) yang bisa langsung dipakai dengan satu klik.
   ══════════════════════════════════════════════════════════════════════════ */
.row-src{display:flex;flex-wrap:wrap;align-items:center;gap:4px 6px;margin-top:6px}
.row-src:empty{display:none}
.src-chip{
  display:inline-flex;align-items:center;gap:4px;font-size:.7rem;font-weight:700;
  padding:2px 8px;border-radius:999px;line-height:1.55;border:1px solid transparent;
  white-space:nowrap;
}
.src-chip.is-pb{background:rgba(14,124,107,.13);border-color:rgba(14,124,107,.35);color:var(--ink)}
.src-chip.is-manual{background:var(--tint-3);border-color:var(--line);color:var(--ink-2)}
.src-chip.is-off{background:rgba(214,158,26,.16);border-color:rgba(214,158,26,.45);color:var(--ink)}
.src-note{font-size:.7rem;color:var(--ink-2);line-height:1.4}
.src-note.is-new{color:var(--ink);font-weight:650}

.plan-sug{display:flex;flex-direction:column;gap:4px;margin-top:6px}
.plan-sug:empty{display:none}
.sug-btn{
  display:grid;grid-template-columns:auto minmax(0,1fr);gap:0 6px;align-items:baseline;
  text-align:left;border:1px solid var(--line);background:var(--tint-3);
  border-radius:9px;padding:3px 7px;cursor:pointer;font:inherit;color:var(--ink);
  transition:border-color .15s ease, background .15s ease;
}
.sug-btn:hover,.sug-btn:focus-visible{border-color:var(--cyan);background:var(--tint-2)}
.sug-k{font-size:.62rem;font-weight:800;letter-spacing:.04em;text-transform:uppercase;color:var(--ink-2)}
.sug-v{font-size:.75rem;font-weight:750;text-align:right;font-variant-numeric:tabular-nums;white-space:nowrap}
.sug-m{grid-column:1 / -1;font-size:.64rem;line-height:1.35;color:var(--ink-2);overflow-wrap:anywhere}
.sug-btn.is-best{border-color:rgba(34,160,110,.55)}
.sug-btn.is-best .sug-k{color:var(--ink)}

@media (max-width:640px){
  .plan-sug{gap:5px}
  .sug-btn{padding:6px 9px;min-height:38px}
  .sug-m{font-size:.7rem}
  .src-chip{font-size:.72rem}
}

/* ══════════════════════════════════════════════════════════════════════════
   PENERIMAAN BARANG — BAGIAN OPSIONAL (BARANG TAK DIPESAN & KELEBIHAN KIRIM)
   Kedua bagian tertutup secara bawaan; toggle menampilkan tabel pengisian.
   ══════════════════════════════════════════════════════════════════════════ */
.opt-switch{margin-top:4px}
.opt-switch input[type=checkbox]{width:20px;height:20px;flex:0 0 20px}
.grn-opt-body{margin-top:12px;display:flex;flex-direction:column;gap:10px}
.grn-opt-body[hidden]{display:none!important}
.grn-excess .alert{margin:0}

/* Kartu karantina pada daftar penerimaan */
.grn-quarantine-card{border-left:3px solid var(--warn-bd)}
.grn-quarantine-card .purchase-hero strong{font-size:.92rem}

/* Tabel karantina pada kartu detail penerimaan */
.grn-quarantine-table td{vertical-align:top}
.grn-decide-form{display:grid;gap:6px;min-width:210px;margin:0}
.grn-decide-form select,.grn-decide-form input[type=text]{min-height:32px;font-size:.8rem}
.grn-decide-bn{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:6px}
.grn-decide-bn input{min-height:32px;font-size:.8rem}
.grn-decide-form .btn{justify-self:start}

@media (max-width:900px){
  .grn-decide-form{min-width:0}
}
@media (max-width:640px){
  .grn-decide-bn{grid-template-columns:minmax(0,1fr)}
  .grn-decide-form .btn{width:100%;justify-self:stretch}
  .opt-switch{align-items:flex-start}
}

/* ══════════════════════════════════════════════════════════════════════════
   BARANG TIDAK DIPESAN & LEBIH KIRIM — SATU BARIS PER ENTRI
   Permintaan pemilik: pengisian barang memakai SATU baris saja (bukan kotak
   bertingkat/auto-fit yang memecah kolom ke baris kedua).
   Kolom diatur eksplisit; hanya di layar sempit baris boleh membungkus.
   ══════════════════════════════════════════════════════════════════════════ */
.grn-opt-list{display:flex;flex-direction:column;gap:8px}
.grn-opt-row{
  display:grid;gap:8px;align-items:start;padding:9px 10px;border-radius:12px;
  border:1px dashed var(--line-strong);background:var(--tint-3);
}
/* 6 kolom: barang · jumlah · satuan · harga · catatan · hapus */
.grn-opt-row--extra{grid-template-columns:minmax(0,2.4fr) minmax(0,.72fr) minmax(0,.9fr) minmax(0,1fr) minmax(0,1.5fr) 34px}
/* 7 kolom: barang · jumlah · satuan · penanganan · harga · catatan · hapus */
.grn-opt-row--excess{grid-template-columns:minmax(0,2.1fr) minmax(0,.7fr) minmax(0,.85fr) minmax(0,1.5fr) minmax(0,.95fr) minmax(0,1.25fr) 34px}
.grn-opt-row .field{min-width:0;gap:4px}
.grn-opt-row .field > span{font-size:.7rem;line-height:1.25;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.grn-opt-row input,.grn-opt-row select{min-height:34px;font-size:.82rem}
.grn-opt-row .btn-danger{justify-self:end;align-self:end;width:34px;min-width:34px;height:34px;padding:0}

@media (max-width:1100px){
  /* dua kolom per baris supaya tidak ada kontrol yang terhimpit */
  .grn-opt-row--extra,
  .grn-opt-row--excess{grid-template-columns:repeat(2,minmax(0,1fr))}
  .grn-opt-row .btn-danger{grid-column:1 / -1;justify-self:end;width:40px;min-width:40px;height:38px}
}
@media (max-width:640px){
  .grn-opt-row--extra,
  .grn-opt-row--excess{grid-template-columns:minmax(0,1fr)}
  .grn-opt-row .btn-danger{grid-column:auto;width:100%;min-width:0;height:40px}
  .grn-opt-row .field > span{white-space:normal;overflow:visible}
}

/* Nomor dokumen (PO · SP · RP · GRN) pada kepala kartu detail penerimaan */
.doc-chipline{display:flex;flex-wrap:wrap;gap:6px;margin-top:8px}
.dchip{
  display:inline-flex;align-items:center;gap:6px;padding:3px 9px;border-radius:999px;
  border:1px solid var(--line);background:var(--tint-3);font-size:.78rem;line-height:1.5;
}
.dchip .dk{font-size:.64rem;font-weight:800;letter-spacing:.05em;color:var(--ink-2);text-transform:uppercase}
.dchip a{text-decoration:none}
@media (max-width:640px){
  .doc-chipline{gap:5px}
  .dchip{font-size:.74rem;padding:4px 8px;min-height:26px}
}

/* ══════════════════════════════════════════════════════════════════════════
   PIL TERBACA UTUH DI LAYAR SANGAT SEMPIT (320px)
   Label status panjang ("Sudah dihubungi — supplier ambil kemudian",
   "Faktur disesuaikan (barang tidak bisa dipasok)") tidak boleh menggeser
   halaman ke samping. Teksnya dibungkus, bukan dipotong.
   ══════════════════════════════════════════════════════════════════════════ */
@media (max-width:640px){
  .pill,.chip,.badge-soft,.status-pill{max-width:100%;white-space:normal;overflow-wrap:anywhere}
  .pill{margin-left:0}
  /* Tombol aksi kartu detail memakai lebar penuh kotak induk (tidak meluber). */
  .card-foot,.form-actions{max-width:100%;min-width:0}
  .card-foot>*,.form-actions>*{max-width:100%;min-width:0}
  .card-foot .btn,.form-actions .btn,.card-foot .inline-form,.form-actions .inline-form{max-width:100%}
  .card-foot .inline-form .btn,.form-actions .inline-form .btn{width:100%}
}

/* ==========================================================================
   BARIS DATA DI KEPALA KARTU (`.doc-meta`)
   Permintaan pemilik: TANGGAL & NAMA PT/SUPPLIER di bawah nomor dokumen adalah
   DATA — bukan teks penjelas — jadi TIDAK boleh ikut disembunyikan tombol Info.
   Karena itu kelasnya sengaja TIDAK memakai `.muted`/`.small` (keduanya termasuk
   cakupan penyembunyian) dan diberi aturan penegasan di bawah.
   ========================================================================== */
.doc-meta{
  display:block;
  margin-top:2px;
  font-size:.82rem;
  line-height:1.5;
  color:var(--ink-2);
}
.doc-meta b,.doc-meta strong{color:var(--ink);font-weight:700}
.doc-meta .chip,.doc-meta a{font-size:.78rem}
/* Penegasan: tetap tampil walau Info dimatikan (spesifisitas > `.card-head small.muted`). */
html[data-hints="off"] .card-head .doc-meta,
html[data-hints="off"] .lab-card .card-head .doc-meta,
html[data-hints="off"] .sheet-card .doc-meta{display:block!important}

/* ==========================================================================
   ALERT DATA (`.data-alert`) — RINGKAS & ON POINT KE DATA
   Menggantikan paragraf penjelasan panjang pada kartu detail: judul singkat,
   chip nomor dokumen, lalu baris angka per produk (nama · −kurang · dipesan vs
   diterima). Tidak ada kalimat bertele-tele.
   ========================================================================== */
.alert.data-alert{
  display:block;
  padding:13px 15px;
  border-radius:var(--radius-sm);
}
.data-alert .da-head{
  display:flex;flex-wrap:wrap;align-items:center;gap:8px 10px;margin-bottom:8px;
}
.data-alert .da-title{
  font-size:.8rem;font-weight:800;letter-spacing:.02em;color:var(--ink-strong);
}
.data-alert .da-chips{display:flex;flex-wrap:wrap;align-items:center;gap:6px}
.data-alert .da-chips .chip{font-size:.74rem;padding:2px 8px;margin:0}
.data-alert .da-lines{list-style:none;margin:0 0 8px;padding:0;display:grid;gap:5px}
.data-alert .da-line{
  display:flex;flex-wrap:wrap;align-items:baseline;gap:6px 10px;font-size:.85rem;
}
.data-alert .da-name{color:var(--ink-strong);font-weight:650}
.data-alert .da-short{
  font-weight:800;font-variant-numeric:tabular-nums;color:var(--red);
}
.data-alert .da-cmp{font-size:.79rem;color:var(--ink-2)}
.data-alert .da-cmp strong{color:var(--ink);font-weight:700;font-variant-numeric:tabular-nums}
.data-alert .da-foot{display:flex;flex-wrap:wrap;align-items:center;gap:8px}
.data-alert .da-cta{font-size:.8rem;color:var(--ink-2)}
.data-alert .da-val{
  font-weight:700;color:var(--ink);font-variant-numeric:tabular-nums;
}
/* Baris ringkasan perubahan (dipakai di pop-up). */
.short-sum{display:grid;gap:6px;margin:12px 0 4px;padding:12px 14px;
  border:1px solid var(--line);border-radius:var(--radius-sm);background:var(--tint-3)}
.short-sum .ss-row{display:flex;flex-wrap:wrap;align-items:baseline;justify-content:space-between;gap:6px 14px;font-size:.84rem}
.short-sum .ss-row>span{color:var(--ink-2)}
.short-sum .ss-row>strong{color:var(--ink-strong);font-weight:700;font-variant-numeric:tabular-nums;text-align:right}
.short-sum .ss-row.is-warn>strong{color:var(--red)}
.short-changes{list-style:none;margin:0;padding:0;display:grid;gap:5px;font-size:.84rem}
.short-changes li{display:flex;flex-wrap:wrap;align-items:baseline;gap:6px 8px;color:var(--ink)}
.short-changes .sc-doc{
  min-width:30px;text-align:center;font-size:.68rem;font-weight:800;letter-spacing:.04em;
  padding:1px 6px;border-radius:5px;background:var(--tint-3);border:1px solid var(--line);color:var(--ink-2)
}
.short-changes strong{font-variant-numeric:tabular-nums}
.short-lead{font-size:.84rem;color:var(--ink-2);margin:0 0 10px}
.short-actions{margin-top:10px}
.short-actions .btn{width:auto}
@media (max-width:640px){
  .data-alert .da-line{font-size:.82rem}
  .data-alert .da-cmp{flex:1 1 100%}
  .short-sum .ss-row>strong{text-align:left}
}

/* Tombol berlabel panjang (mis. "Faktur disesuaikan (Barang tidak bisa dipasok)")
   boleh TURUN BARIS. Tanpa ini label memaksa halaman melebar 4 px di 320 px
   (terukur: scrollWidth 324 vs clientWidth 320). */
.btn.btn-wrap{
  white-space:normal;text-align:center;line-height:1.25;height:auto;
  min-height:38px;padding:8px 14px;max-width:100%;
}
.card-foot .btn.btn-wrap,.form-actions .btn.btn-wrap{flex:1 1 auto;min-width:0}

/* ══════════════════════════════════════════════════════════════════════════
   KEPALA KARTU: TOMBOL KEMBALI SELALU DI POJOK KANAN ATAS
   (permintaan pemilik)
   Chip/pill status tetap mengisi bagian KIRI tombol Kembali. Tombolnya diberi
   `order:99` + `margin-left:auto` supaya tidak pernah tergeser oleh chip,
   termasuk saat chip membungkus ke baris berikutnya (tetap rata kanan).
   ══════════════════════════════════════════════════════════════════════════ */
.card-head > .head-chips,
.purchase-head > .head-chips{flex:0 1 auto;max-width:100%;align-items:flex-start}
.head-chips > .btn-back{
  order:99;margin-left:auto;flex:0 0 auto;align-self:flex-start;
}
/* Chip dokumen (PO · SP · RP · GRN) di kepala kartu kini bisa DIKLIK untuk
   membuka pop-up informasi — beri tanda kursor & garis bawah halus. */
.doc-chipline a[data-refinfo]{cursor:pointer;border-bottom:1px dashed currentColor}
.doc-chipline a[data-refinfo]:hover{border-bottom-style:solid}

/* ══════════════════════════════════════════════════════════════════════════
   STATUS DI DALAM PILL: HURUF KAPITAL DI AWAL KATA
   "selesai" → "Selesai", "diterima sebagian" → "Diterima Sebagian".
   Akar masalah: `.pill{text-transform:lowercase}` menurunkan seluruh teks.
   Kode dokumen (chip) TIDAK memakai `.pill`, jadi aman.
   ══════════════════════════════════════════════════════════════════════════ */
.pill{text-transform:capitalize}
/* Chip kelengkapan nota pada kepala kartu penerimaan — sedikit lebih besar. */
.pill.pill-lg{font-size:.78rem;padding:5px 12px;letter-spacing:.02em}

/* Tombol batal penerimaan yang dipindah ke BAWAH kartu detail. */
.grn-cancel-card .grn-cancel{margin:0;border-top:0;padding-top:0}
.grn-cancel-card .grn-cancel summary{font-weight:700}

/* ══════════════════════════════════════════════════════════════════════════
   TOMBOL KEMBALI TETAP DI POJOK KANAN ATAS PADA LAYAR SEMPIT
   Di HP kepala kartu menjadi kolom (`.card-head{flex-direction:column}`), jadi
   `.head-chips` selebar kartu. Dengan flex-wrap, tombol Kembali bisa terdorong
   ke baris berikutnya oleh chip. Solusi: `.head-chips` menjadi GRID 2 kolom —
   kolom 1 = chip/pill (boleh bertumpuk), kolom 2 = tombol Kembali yang selalu
   menempel di baris PERTAMA (pojok kanan atas kartu).
   ══════════════════════════════════════════════════════════════════════════ */
@media (max-width:640px){
  .card-head > .head-chips,
  .purchase-head > .head-chips{
    display:grid;
    grid-template-columns:minmax(0,1fr) auto;
    align-items:start;
    justify-items:end;
    gap:6px 8px;
    width:100%;
  }
  .head-chips > .btn-back{grid-column:2;grid-row:1;margin:0;justify-self:end}
  .head-chips > :not(.btn-back){grid-column:1;justify-self:end;min-width:0}
  .head-chips > .pill{white-space:normal}
}

/* Tanggal pada “Diterima oleh” adalah DATA → tetap tampil walau Info dimatikan.
   Aturan ini WAJIB lebih spesifik daripada
   `html[data-hints="off"] .metric-row small{display:none!important}`. */
html[data-hints="off"] .metric-row small[data-live-hint],
html[data-hints="off"] .metric-row [data-live-hint]{display:block!important}

/* ══════════════════════════════════════════════════════════════════════════
   BARIS BARANG DITOLAK (kartu "Barang Ditolak → Daftar Retur")
   Sel "Ditolak" pada tabel rincian kini HANYA berisi jumlah (permintaan
   pemilik), jadi nama barang + jumlah + alasan dipindah ke kartu retur.
   ══════════════════════════════════════════════════════════════════════════ */
.rej-line{display:flex;flex-wrap:wrap;align-items:baseline;gap:2px 8px;font-size:.86rem}
.rej-line + .rej-line{margin-top:4px}
.rej-line > strong{color:var(--ink-strong);font-weight:650;min-width:0;overflow-wrap:anywhere}
.rej-line > .neg{font-weight:750;font-variant-numeric:tabular-nums;white-space:nowrap}

/* ══════════════════════════════════════════════════════════════════════════
   JARAK IDEAL BLOK STATUS (alert) — SEMUA MODUL
   (permintaan pemilik: "berikan jarak antara Alert dengan KPI div.metric-row.wide;
   cek semua status harus memiliki jarak yang ideal")

   Akar masalah: alert yang dibuat sebagai `<div>` (mis. `short_supply_alert_html()`
   dan `short_supply_info_html()` yang memakai `.alert.data-alert`) TIDAK punya
   margin bawaan, sehingga baris KPI (`.metric-row.wide`) MENEMPEL tepat di
   bawahnya (terukur jarak 0 px pada detail nota). Alert berbentuk `<p>` hanya
   mendapat 10 px dari `p{margin:0 0 10px}` — terlalu rapat untuk blok status.

   Aturan di bawah berlaku untuk KEDUA bentuk (p/div) sehingga semua status
   (DRAFT · SIAP DITERIMA · SUDAH DITERIMA · FAKTUR MENYUSUL · KARANTINA ·
   INVOICE DUPLIKAT · NOTA LAIN · PESANAN DIKIRIM SEBAGIAN · FAKTUR DISESUAIKAN)
   punya jarak yang sama di modul mana pun.
   ══════════════════════════════════════════════════════════════════════════ */
.alert{margin:0 0 16px}
/* Dua status berurutan: beri napas 12 px (margin bertumpuk → tetap 16 px). */
.alert + .alert{margin-top:12px}
/* Status tepat DI ATAS ringkasan/KPI atau blok data: jarak lebih lega. */
.alert + .metric-row,
.alert + .metric-row.wide,
.alert + .grn-progress,
.alert + .preview-box,
.alert + .doc-track,
.alert + .form-section-head,
.alert + .detail-stack,
.alert + .table-wrap,
.alert + .attach-list{margin-top:18px}
/* Ringkasan/KPI di atas status: jarak sama lega (arah sebaliknya). */
.metric-row + .alert,
.preview-box + .alert,
.doc-track + .alert{margin-top:18px}
/* Wadah yang SUDAH punya `gap` (flex/grid): margin alert dinolkan supaya
   jaraknya tidak dobel (mis. `.detail-stack` gap 22 px, `.stack` gap 14 px). */
.detail-stack > .alert,
.approval-card > .alert,
.alert-list > .alert,
.stack > .alert,
.form-actions > .alert,
.grid-2 > .alert,
.detail-attach > .lab-card > .alert{margin:0}
/* Alert yang berfungsi sebagai isi kartu lampiran tetap di tengah kartu. */
.detail-attach > .lab-card > .alert{margin:auto 0}

/* Blok STATUS kelengkapan penerimaan (bar progres "Nota: Diterima sebagian …")
   juga butuh napas sebelum baris KPI — dulu hanya 4 px sehingga menempel. */
.grn-progress{margin:14px 0 14px}
@media (max-width:640px){ .grn-progress{margin:12px 0 12px} }

/* ══════════════════════════════════════════════════════════════════════════
   PENERIMAAN — [BARANG TIDAK DIKIRIM] (permintaan pemilik)
   Baris yang ditandai diredupkan & diberi garis kiri tegas supaya tidak
   tertukar dengan baris yang memang datang.
   ══════════════════════════════════════════════════════════════════════════ */
.btn-undelivered svg{width:16px;height:16px;fill:currentColor;flex:0 0 16px}
.btn.btn-undelivered.is-on{
  background:var(--err-bg);border-color:var(--err-bd);color:var(--err-fg);font-weight:700;
}
.grn-line.is-undelivered{box-shadow:inset 3px 0 0 var(--err-bd)}
.grn-line.is-undelivered [data-bn-rows]{opacity:.45;filter:grayscale(.4)}
.grn-undelivered-box{
  margin-top:10px;padding:12px 14px;border:1px dashed var(--err-bd);border-radius:var(--radius-sm);
  background:var(--err-bg);
}
.grn-undelivered-box .foot-note{margin:8px 0 0}
.grn-undelivered-list{
  margin:0 0 14px;padding:12px 14px;border:1px solid var(--line);border-radius:var(--radius-sm);
  background:var(--tint-3);
}
.grn-undelivered-list .gu-title{margin:0 0 8px;font-size:.86rem;color:var(--ink-strong)}
.grn-undelivered-list ul{margin:0;padding-left:18px;display:grid;gap:6px;font-size:.86rem}
.grn-undelivered-list li > strong{color:var(--ink-strong)}
.grn-undelivered-list li > .neg{font-weight:750;font-variant-numeric:tabular-nums}
.grn-undelivered-list li > .muted{margin-left:6px}

/* ══════════════════════════════════════════════════════════════════════════
   KUNCI DOKUMEN (RP · SP · PO) — setelah penerimaan lengkap + faktur terunggah
   ══════════════════════════════════════════════════════════════════════════ */
.doc-lock{
  display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin:0 0 16px;
  padding:11px 14px;border:1px solid var(--line-strong);border-radius:var(--radius-sm);
  background:var(--tint-3);font-size:.85rem;color:var(--ink);
}
.doc-lock svg{width:17px;height:17px;fill:currentColor;flex:0 0 17px;color:var(--ink-2)}
.doc-lock strong{color:var(--ink-strong)}
.doc-lock.is-open{border-color:var(--ok-bd);background:var(--ok-bg)}
.doc-lock .dl-actions{margin-left:auto;display:flex;flex-wrap:wrap;gap:8px}
.doc-lock-users{display:flex;flex-wrap:wrap;gap:6px;margin-top:4px;width:100%}
.doc-lock-users .chip{font-size:.72rem;padding:2px 8px;margin:0}
/* Kotak pilih pengguna (Administrator membuka akses ubah). */
.unlock-pick{display:grid;gap:8px;max-height:46vh;overflow:auto;padding-right:2px}
.unlock-pick label{
  display:flex;align-items:center;gap:10px;padding:9px 12px;border:1px solid var(--line);
  border-radius:var(--radius-sm);background:var(--tint-3);cursor:pointer;font-size:.86rem;
}
.unlock-pick label:hover{border-color:var(--line-strong)}
.unlock-pick input[type=checkbox]{width:18px;height:18px;flex:0 0 18px}
.unlock-pick .up-role{margin-left:auto;font-size:.74rem;color:var(--ink-2)}

/* ══════════════════════════════════════════════════════════════════════════
   WARNA BLOK STATUS (ALERT) — FONT & LATAR SELALU BERLAWANAN
   Permintaan pemilik: "Pada beberapa Alert warna Font putih dengan background
   hijau sehingga tulisannya tidak jelas — perbaiki agar warna font dan
   background berlawanan."

   Akar masalahnya: token alert DARK theme memakai huruf hijau-mint pucat
   (#C7F7E4) di atas latar hijau transparan (alpha .12) sehingga HUE teks dan
   latar sama → huruf "menyatu" dengan latarnya walau angka kontrasnya
   kelihatan tinggi. Selain itu latar transparan membuat warna alert BERUBAH
   tergantung apa yang ada di belakangnya (kartu, baris hijau, dsb).

   Perbaikan: setiap varian alert memakai LATAR SOLID (tidak transparan) dan
   huruf BERLAWANAN TERANG-GELAP:
     · tema gelap  → latar pekat (hijau/kuning/merah tua) + huruf PUTIH;
     · tema terang → latar sangat terang (mint/krem/merah muda) + huruf HITAM pekat.
   Semua anak alert memakai `color:inherit` supaya tidak ada aturan lain yang
   menyelipkan huruf putih di atas latar terang (atau sebaliknya).
   ══════════════════════════════════════════════════════════════════════════ */

/* Token warna solid per tema — dipakai `.alert-*` di bawah. */
:root,
html[data-theme="dark"]{
  --alert-ok-bg:#0B3B2C;   --alert-ok-fg:#FFFFFF;   --alert-ok-bd:rgba(52,211,153,.58);
  --alert-warn-bg:#3B2A06; --alert-warn-fg:#FFF4D8; --alert-warn-bd:rgba(251,191,36,.55);
  --alert-err-bg:#3D1214;  --alert-err-fg:#FFE6E6;  --alert-err-bd:rgba(248,113,113,.58);
  --alert-ok-accent:#7BF3C0; --alert-warn-accent:#FFB4A8; --alert-err-accent:#FFB4B4;
  --alert-info-bg:#0A2F33; --alert-info-fg:#E6FEFF; --alert-info-bd:rgba(45,212,167,.55);
  --alert-info-accent:#8FF2E4;
}
html:not([data-theme]),
html[data-theme="light"]{
  --alert-ok-bg:#E1F8EC;   --alert-ok-fg:#04281D;   --alert-ok-bd:rgba(16,185,129,.42);
  --alert-warn-bg:#FFF3D9; --alert-warn-fg:#3D2500; --alert-warn-bd:rgba(217,138,6,.42);
  --alert-err-bg:#FDEBEB;  --alert-err-fg:#58090B;  --alert-err-bd:rgba(220,38,38,.38);
  --alert-ok-accent:#0A5B44; --alert-warn-accent:#8A2E0B; --alert-err-accent:#7F1D1D;
  --alert-info-bg:#E6F6F5; --alert-info-fg:#04302E; --alert-info-bd:rgba(15,138,115,.36);
  --alert-info-accent:#0A5B52;
}

/* Setiap varian menetapkan latar/huruf/garis + warna penekanan (angka penting). */
.alert-ok{
  --alert-bg:var(--alert-ok-bg); --alert-fg:var(--alert-ok-fg);
  --alert-bd:var(--alert-ok-bd); --alert-accent:var(--alert-ok-accent);
}
.alert-warn{
  --alert-bg:var(--alert-warn-bg); --alert-fg:var(--alert-warn-fg);
  --alert-bd:var(--alert-warn-bd); --alert-accent:var(--alert-warn-accent);
}
.alert-err{
  --alert-bg:var(--alert-err-bg); --alert-fg:var(--alert-err-fg);
  --alert-bd:var(--alert-err-bd); --alert-accent:var(--alert-err-accent);
}
.alert-info{
  --alert-bg:var(--alert-info-bg); --alert-fg:var(--alert-info-fg);
  --alert-bd:var(--alert-info-bd); --alert-accent:var(--alert-info-accent);
}

/* Latar SOLID + huruf berlawanan. `background` (bukan background-color) supaya
   gradien/kilau dari aturan lain tidak ikut terbawa. */
.alert-ok,.alert-warn,.alert-err,.alert-info{
  background:var(--alert-bg);
  border-color:var(--alert-bd);
  color:var(--alert-fg);
  /* huruf dasar alert selalu punya bobot 500 agar tipis-tipis tetap terbaca */
  font-weight:500;
  /* `isolation` baru dipakai agar tidak ada lapisan ::before kartu di atasnya */
  isolation:isolate;
}
/* Semua teks di dalam alert MEWARISI warna alert (tidak boleh ada huruf putih
   di latar terang atau hitam di latar gelap dari aturan lain). */
.alert strong,.alert b,.alert em,.alert i,.alert span,.alert small,.alert code,
.alert p,.alert li,.alert div,.alert a,
.alert .da-title,.alert .da-name,.alert .da-val,.alert .da-cmp,.alert .da-cta,
.alert .da-cmp strong,.alert .nh-label,.alert .note-strong{
  color:inherit;
}
/* Angka/penanda penting (mis. −500 tablet, nilai rupiah) memakai warna aksen
   yang tetap kontras terhadap latar alert. */
.alert .neg,.alert .da-short,.alert .da-short strong{color:var(--alert-accent,currentColor)}
/* Ikon mengikuti warna huruf — dulu ikon alert-ok hijau terang di atas latar
   mint terang sehingga nyaris tak terlihat. */
.alert svg{fill:currentColor;color:inherit;opacity:.95}
.alert a{text-decoration:underline}
/* Tautan di dalam alert memakai warna aksen supaya tetap bisa diklik-terlihat. */
.alert a.btn,.alert .btn{color:inherit}
/* Baris keterangan di dalam alert sedikit lebih redup TAPI tetap satu keluarga
   warna huruf (opasitas, bukan warna lain) — aman di kedua tema. */
.alert .da-cta,.alert .da-cmp,.alert .nh-label{opacity:.86}

/* ══════════════════════════════════════════════════════════════════════════
   KARTU FILTER & PENCARIAN — SATU KOTAK YANG RAPI (tidak tumpang tindih)
   Permintaan pemilik: "form.global-search masuk ke dalam tombol pencarian
   (.btn.btn-sm.btn-search-toggle) dan rapihkan kartu filter agar tidak
   tumpang tindih; defaultnya kartu pencarian tetap tertutup."

   Struktur sekarang (satu kartu, satu tombol):
       [ Pencarian ▾ ]                  ← tombol (dibuat assets/app.js)
       ┌ .lab-card.filter-card ───────────────────────────────┐
       │ judul "Filter & pencarian" + keterangan singkat       │
       │ 🔍 [ kolom cari besar ..................... ] [Cari]  │
       │ ─────────────────────────────────────────────────── │
       │ [filter dropdown] [periode] [Terapkan] [Unduh CSV]   │
       └──────────────────────────────────────────────────────┘
   Saat kartu tertutup (bawaan), SEMUA kontrol di dalamnya ikut tertutup —
   tidak ada kolom pencarian yang mengambang di atas daftar.
   ══════════════════════════════════════════════════════════════════════════ */

/* Tombol [Pencarian] menempel ke kartu di bawahnya (jarak 24px milik
   `.content` dikurangi 8px) — sebelumnya ia berdiri sendiri sehingga terlihat
   seperti elemen yang lepas dari kartunya. */
.content > .search-toggle-bar{margin:0 0 -8px}
@media (max-width:900px){
  .content > .search-toggle-bar{margin:0 0 -6px}
}

/* Kotak pencarian DI DALAM kartu: bukan kartu kecil di dalam kartu. */
.filter-card > .global-search{
  margin:0 0 14px;
  padding:0 0 14px;
  border:0;
  border-bottom:1px dashed var(--line);
  border-radius:0;
  background:none;
}
.filter-card > .global-search .gs-field{flex:1 1 320px;min-width:0}
.filter-card > .global-search input[type=search]{min-height:44px;width:100%}
.filter-card > .global-search .btn{min-height:44px}
/* Tombol "Hapus kata kunci" hanya muncul saat ada kata pencarian aktif. */
.filter-card > .global-search .btn-clear-search{
  background:var(--err-bg);border-color:var(--err-bd);color:var(--err-fg);
}
.filter-card > .global-search .btn-clear-search:hover{background:var(--err-bg-hover)}
.filter-card > .global-search .live-count{margin:0}

/* Kepala kartu filter: judul kiri, keterangan kanan — tidak pernah berdesakan. */
.filter-card > .filter-head{margin:0 0 12px;gap:6px 14px;align-items:baseline}
.filter-card > .filter-head .filter-title{line-height:1.2}
.filter-card > .filter-head > .muted{
  flex:1 1 220px;min-width:0;text-align:right;
}
/* Baris filter (dropdown/periode/tombol) diberi jarak yang jelas dari kotak cari. */
.filter-card > form.search{margin:0}

@media (max-width:760px){
  .filter-card > .filter-head > .muted{text-align:left;flex:1 1 100%}
}
@media (max-width:640px){
  /* Di HP: kolom cari & tombol [Cari] tetap SATU BARIS (bukan dua baris penuh)
     supaya kartu tidak tinggi — tinggi kolomnya 46px, nyaman disentuh. */
  .filter-card > .global-search{gap:8px;padding-bottom:12px;margin-bottom:12px}
  /* `flex-basis` HARUS angka (bukan auto): input di dalamnya memakai
     `width:100%`, sehingga basis "auto" menjadi tak-tentu dan tombol [Cari]
     terlempar ke baris berikutnya. */
  .filter-card > .global-search .gs-field{flex:1 1 140px;min-width:0}
  .filter-card > .global-search input[type=search]{min-height:46px;font-size:16px;width:100%}
  .filter-card > .global-search .btn{flex:0 0 auto;min-height:46px;padding:0 14px}
  .filter-card > .global-search .btn-clear-search{flex:1 1 100%}
}

/* ══════════════════════════════════════════════════════════════════════════
   GULIR KARTU MENGAMBANG DIBUAT MULUS (keluhan: form [+ Item Baru] "patah-patah")
   Penyebabnya bukan jumlah elemen (form itu hanya ~1.066 node), melainkan
   pekerjaan PAINT/COMPOSITE tiap frame saat `.sheet-body` digulir:
     · `.sheet-card` tidak punya layer sendiri → latar + bayangan kartu
       (blur 80px) ikut dicat ulang setiap frame;
     · latar `radial-gradient` seluas layar ikut digambar ulang;
     · `overscroll-behavior` bawaan membuat gulir "menular" ke halaman di
       belakang saat isi kartu habis — terasa seperti tersendat/berhenti.
   Perbaikannya (diukur `.pw-tests/ab-scroll-form.js`, CPU 4× diperlambat):
   frame jatuh 3/65 → 0/64.
   ══════════════════════════════════════════════════════════════════════════ */
.sheet-card{
  /* ⚠️ JANGAN memakai `will-change:transform` di sini. Niatnya mempromosikan
     kartu ke layer sendiri, tetapi terukur justru MERUSAK: 4–5 frame jatuh per
     57 frame saat isi kartu digulir (dengan `will-change:auto` → 0). Biarkan
     `contain:layout paint` yang sudah ada melakukan tugasnya. */
  /* ⚠️ Bayangan kartu WAJIB kecil. Bayangan blur besar (mis. 48px) di atas
     seluruh layar membuat software-compositor mengecat ulang area itu setiap
     frame: terukur 4 frame jatuh per 58 frame saat isi kartu digulir.
     Dengan bayangan rapat (20px) hasilnya 0 frame jatuh & kedalaman visual
     tetap terjaga (offset/opacity dipertahankan). */
  box-shadow:0 8px 20px -14px rgba(0,0,0,.72);
}
/* Gulir TIDAK menular ke halaman di belakang + ruang scrollbar stabil
   (mencegah konten "melompat" saat scrollbar muncul/hilang). */
.sheet-body{overscroll-behavior:contain;scrollbar-gutter:stable}
html[data-theme="light"] .sheet-card{
  box-shadow:0 8px 20px -14px rgba(20,32,60,.42);
}
/* ⚠️ JANGAN menambahkan aturan `body.is-scrolling …` BARU: memasang/menghapus
   kelas itu meng-invalidate SELURUH dokumen, dan itu terukur menghasilkan satu
   frame tersendat tepat saat mulai/berhenti menggulir. Kelas tersebut sekarang
   hanya dipakai untuk mematikan backdrop-filter (yang sudah `none`), jadi tidak
   perlu aturan tambahan. */

/* ── AKAR "PATAH-PATAH" SAAT MENGGULIR (form [+ Item Baru] & kartu panjang) ──
   Terukur (CDP Performance, CPU 4× diperlambat): **55 kali RECALC STYLE per 20
   tick roda mouse** → turun menjadi **3** setelah transisi pada kontrol form
   dimatikan, dan beban tugas 122 ms → 50 ms.

   Penyebabnya bukan jumlah elemen, melainkan **TRANSISI CSS**: saat isi kartu
   bergulir, elemen bergerak di bawah kursor yang diam → status `:hover`
   berganti terus → setiap perubahan memicu transisi (background/border/
   box-shadow) + recalc style + repaint SETIAP FRAME.

   Perbaikan dipasang PERMANEN pada kontrol (bukan lewat kelas `is-scrolling`):
   memakai kelas global `body.is-scrolling *{transition:none}` justru membuat
   SELURUH dokumen di-invalidate saat kelas itu dipasang/dilepas → satu frame
   tersendat tepat saat mulai/berhenti menggulir. Dengan begini tidak ada
   toggle sama sekali, dan umpan balik hover hanya tampil seketika (tanpa
   animasi) — perbedaan yang tidak terasa, tetapi biayanya hilang.
   ⚠️ Jangan mengembalikan `transition` pada kontrol form tanpa mengukur ulang
   dengan `.pw-tests/profile-scroll.js`. */
:where(input, select, textarea),
.num-stepper button,
.cs-btn,
.paid-switch,
.paid-switch .ps-knob,
.perm-item,
.ref-chip,
.sug-btn,
.batch-ref{
  transition-property:none!important;
}

/* ══════════════════════════════════════════════════════════════════════════
   KEPALA KARTU MENGAMBANG DI HP: RINGKAS & TOMBOL JADI IKON KECIL
   Keluhan pemilik: kepala kartu pop-up di HP "terlalu tinggi menjorok ke bawah",
   dan tombol Kembali/Tutup sebaiknya kecil seperti tombol ganti tema.

   Akar masalah (terukur `.pw-tests/sheet-head-mobile.js`):
     · aturan HP `.row-actions{width:100%;flex-wrap:wrap}` juga mengenai
       `.sheet-head .row-actions` → tombol dipaksa ke BARIS KEDUA selebar kartu,
       jadi tombol "Kembali" & "Tutup" masing-masing melebar 116–294px;
     · akibatnya kepala kartu setinggi **116–143px (15–18% layar)** dengan dua
       baris tombol 41px.
   Sesudah: tombol menjadi **ikon 40×40** (label disembunyikan, `title`/`aria-label`
   tetap ada), tetap SATU baris dengan judul → kepala kartu **±62–86px (8–11%)**
   dan isi kartu mendapat ruang jauh lebih lega.
   ⚠️ Aturan ini WAJIB memakai `.sheet-head` agar tidak mengubah `.row-actions`
   di tempat lain (kaki kartu/tabel) yang memang butuh lebar penuh.
   ══════════════════════════════════════════════════════════════════════════ */
@media (max-width:900px){
  .sheet-head{
    padding:10px 12px;
    gap:10px;
    align-items:center;              /* judul & tombol sebaris, rata tengah */
  }
  .sheet-head > div:first-child{min-width:0;flex:1 1 auto}
  .sheet-head h2{
    font-size:.95rem;line-height:1.25;
    /* judul panjang dipotong maksimal 2 baris, bukan mendorong tombol ke bawah */
    display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;
    overflow:hidden;overflow-wrap:anywhere;
  }
  .sheet-head .muted{
    font-size:.72rem;line-height:1.3;
    display:-webkit-box;-webkit-line-clamp:1;-webkit-box-orient:vertical;
    overflow:hidden;
  }
  /* Tombol kepala kartu: ikon kecil seperti tombol tema. */
  .sheet-head .row-actions{
    width:auto!important;            /* batalkan aturan .row-actions{width:100%} */
    flex:0 0 auto;
    flex-wrap:nowrap;
    gap:6px;
  }
  .sheet-head .row-actions .btn{
    flex:0 0 auto;
    width:40px;height:40px;min-width:40px;min-height:40px;
    padding:0;border-radius:11px;
  }
  .sheet-head .row-actions .btn .lbl{display:none}
  .sheet-head .row-actions .btn svg{width:18px;height:18px;flex:0 0 18px;margin:0}
  /* Tombol Kembali pada kepala KARTU DETAIL halaman (bukan sheet) juga ikut kecil
     agar seragam di seluruh menu. */
  .head-chips > .btn-back,
  .card-head > .btn-back,
  .purchase-head .btn-back{
    width:40px;height:40px;min-width:40px;min-height:40px;padding:0;justify-content:center;
  }
  .head-chips > .btn-back .lbl,
  .card-head > .btn-back .lbl,
  .purchase-head .btn-back .lbl{display:none}
}
/* Layar sangat sempit: ikon sedikit lebih rapat supaya judul tetap dapat ruang. */
@media (max-width:400px){
  .sheet-head{padding:9px 10px;gap:8px}
  .sheet-head h2{font-size:.9rem}
  .sheet-head .row-actions{gap:5px}
  .sheet-head .row-actions .btn{width:38px;height:38px;min-width:38px;min-height:38px}
}

/* ══════════════════════════════════════════════════════════════════════════
   LABEL SEBARIS + COMBOBOX: TEKS TIDAK BOLEH TERTUTUP
   Keluhan pemilik: "tidak ada kalimat yang tertutup oleh input date picker atau
   apapun" pada kartu pencarian.

   Akar masalah (terukur `.pw-tests/filter-card-audit.js` → 0 temuan setelah
   diperbaiki, sebelumnya 32):
     `.field .cs-btn{width:100%}` (spesifisitas 0,2,0, ditulis SESUDAH
     `.search .cs-btn{width:auto}`) membuat tombol combobox selebar SELURUH
     label — padahal `.field.inline` adalah baris flex (teks + kontrol). Tombol
     lalu keluar dari kotaknya (terukur 171px pada ruang 132px) dan MENUTUPI
     teks label di sebelahnya ("Jenis", "Periode", "Semua status", dst).
   Perbaikan: di dalam `.field.inline` tombol combobox mengikuti ruang tersisa
   (bukan 100%), dan semua kontrol diberi `min-width:0` supaya bisa menyusut.
   ⚠️ Jangan mengubah `.field .cs-btn{width:100%}` untuk label BERTUMPUK
   (vertikal) — aturan itu benar di sana; yang salah hanya label SEBARIS.
   ══════════════════════════════════════════════════════════════════════════ */
.field.inline .cs-btn{
  width:auto;
  flex:1 1 auto;
  min-width:0;
  max-width:100%;
}
.field.inline > input,
.field.inline > select,
.field.inline > .cs-btn,
.field.inline > .num-wrap{min-width:0;flex:1 1 auto}
.field.inline > span{flex:0 0 auto;white-space:nowrap}
/* Kartu filter: kontrol sebaris tidak boleh meluber keluar kartu. */
.filter-card .search .field.inline,
.toolbar .search .field.inline{max-width:100%;min-width:0}
.filter-card .search .field.inline > .cs-btn,
.toolbar .search .field.inline > .cs-btn{flex:1 1 auto;min-width:0}

/* ══════════════════════════════════════════════════════════════════════════
   KEPALA HALAMAN (`.topbar-main`) DI HP TIDAK BOLEH MELAR KE BAWAH
   Keluhan pemilik: "sesuaikan semua div.topbar-main agar tidak terlalu panjang
   ke bawah".

   AKAR MASALAH (terukur `.pw-tests/topbar-mobile.js`): `.topbar-main` punya
   `flex:1 1 auto` dari aturan DESKTOP (benar di sana, karena `.topbar` adalah
   baris flex). Di HP `.topbar{display:contents}` menghapus kotak induk itu,
   sehingga `.topbar-main` menjadi anak langsung `.main` — dan `.main` adalah
   **flex kolom**. Akibatnya `flex-grow:1` membuat kepala MELAR mengisi seluruh
   sisa tinggi layar:
        Dashboard (banyak isi)   : 59px  ✔
        Pemeriksaan (isi pendek) : 309px  ✘
        Tagihan                  : 318px  ✘
   Isinya sendiri hanya 40px (tombol 40px + judul 26px) — jadi tingginya murni
   akibat `flex-grow`. Perbaikan: `flex:0 0 auto` (tinggi mengikuti isi) di HP.
   ⚠️ Jangan menghapus aturan ini: tanpa `flex:0 0 auto`, tinggi kepala berubah
   mengikuti panjang halaman (bug lama). Desktop TIDAK terpengaruh karena
   aturannya hanya di dalam media query ≤900px.
   ══════════════════════════════════════════════════════════════════════════ */
@media (max-width:900px){
  .topbar-main{
    flex:0 0 auto;          /* tinggi = isi (≈58px), bukan melar mengisi layar */
    min-height:0;
    max-height:none;
    align-items:center;
  }
  /* Baris tombol aksi halaman juga tidak boleh melar. */
  .page-actions{flex:0 0 auto}
}

/* ══════════════════════════════════════════════════════════════════════════
   SIDEBAR BISA DILIPAT DI DESKTOP (menu samping → rel ikon 76px)
   Permintaan pemilik: sidebar bisa di-minimize/open di layar desktop sehingga
   konten melebar.

   Rancangan:
     · tombol lipat (chevron) di paling atas menu samping, hanya tampil ≥901px;
     · saat dilipat, `.shell` berganti kolom **76px** (animasi halus), sehingga
       `.content` (max-width 1840px, margin auto) otomatis melebar;
     · label menu/grup, nama pengguna & tombol Keluar disembunyikan — hanya ikon
       yang tampil. **Semua ikon tetap bisa diklik** (klik grup = buka daftar
       menunya sebagai pop-up melayang di samping rel, lihat assets/app.js);
     · tooltip `title` di setiap menu tetap ada, jadi nama menu tetap terbaca;
     · pilihan disimpan di `localStorage['sentosa-sidebar-min']` dan dipulihkan
       SEBELUM halaman digambar (skrip kecil di <head>) supaya tidak berkedip;
     · tombol di topbar juga tersedia (ikon yang sama) agar mudah dibuka kembali;
     · pintasan keyboard **Ctrl+B** (dan ⌘B) untuk melipat/membuka.
   ⚠️ Aturan ini WAJIB `@media (min-width:901px)`; di HP menu samping adalah
   laci (transform), bukan kolom grid — mengubah grid di HP merusak tata letak.
   ══════════════════════════════════════════════════════════════════════════ */

/* Tombol lipat: tombol bulat kecil di pojok kanan-atas kepala menu samping. */
.sidebar-mini-toggle{
  position:absolute;top:14px;right:-14px;z-index:3;
  width:28px;height:28px;display:none;place-items:center;padding:0;
  border-radius:50%;border:1px solid var(--line-strong);
  background:var(--panel-2);color:var(--ink-2);cursor:pointer;
  box-shadow:0 4px 12px -6px rgba(0,0,0,.5);
  transition:color .14s, border-color .14s, background .14s;
}
.sidebar-mini-toggle:hover{color:var(--ink-strong);border-color:var(--focus-border);background:var(--tint-hover)}
.sidebar-mini-toggle svg{width:16px;height:16px;fill:currentColor;display:block}
.sidebar-mini-toggle .ico-expand{display:none}

@media (min-width:901px){
  .sidebar-mini-toggle{display:grid}
  /* ⚠️ Sidebar WAJIB punya z-index DI ATAS `.topbar` (z-index 5). Tanpa ini
     tombol lipat yang menonjol 14px ke kolom konten (`right:-14px`) TERTUTUP
     oleh kepala halaman yang menempel (sticky) — tombolnya terlihat tapi tidak
     bisa ditekan. `.sidebar` bersifat `position:sticky` sehingga membentuk
     stacking context sendiri; z-index tombol di dalamnya (3) tidak menolong. */
  .sidebar{z-index:6}
  /* Animasi lebar kolom: 272px ⇄ 76px. */
  .shell{transition:grid-template-columns .18s ease}
  .sidebar{transition:padding .18s ease}

  /* ---------- KEADAAN DILIPAT ---------- */
  html[data-sidebar="min"] .shell{grid-template-columns:76px 1fr}

  html[data-sidebar="min"] .sidebar{padding:14px 8px;gap:12px;align-items:center}
  html[data-sidebar="min"] .sidebar-mini-toggle{right:-14px;top:10px}
  html[data-sidebar="min"] .sidebar-mini-toggle .ico-collapse{display:none}
  html[data-sidebar="min"] .sidebar-mini-toggle .ico-expand{display:block}

  /* Merek: hanya kotak logo (nama & alamat klinik disembunyikan). */
  html[data-sidebar="min"] .brand{justify-content:center;gap:0}
  html[data-sidebar="min"] .brand-text{display:none}
  html[data-sidebar="min"] .brand-mark{width:38px;height:38px;flex-basis:38px}

  /* Menu: hanya ikon, tengah. Label, caret, dan lencana grup disembunyikan. */
  html[data-sidebar="min"] .nav-link,
  html[data-sidebar="min"] .nav-group{
    justify-content:center;gap:0;padding:10px 0;width:44px;margin-inline:auto;
  }
  html[data-sidebar="min"] .nav-link > span:not(.nav-badge),
  html[data-sidebar="min"] .nav-group-label,
  html[data-sidebar="min"] .nav-caret{display:none}
  html[data-sidebar="min"] .nav-items{display:none}
  html[data-sidebar="min"] .nav-group-ico,
  html[data-sidebar="min"] .nav-group-ico svg{width:19px;height:19px;flex-basis:19px}
  html[data-sidebar="min"] .nav-link > svg{width:19px;height:19px;flex:0 0 19px}

  /* Lencana angka: pojok kanan-atas ikon (tidak memakan lebar). */
  html[data-sidebar="min"] .nav-link{position:relative}
  html[data-sidebar="min"] .nav-badge{
    position:absolute;top:3px;right:3px;left:auto;margin:0;
    min-width:15px;height:15px;line-height:15px;padding:0 4px;font-size:.62rem;
  }
  html[data-sidebar="min"] .nav-group .nav-group-badge{
    left:auto;right:2px;top:-2px;
  }

  /* Kaki menu: avatar saja + tombol keluar jadi ikon. */
  html[data-sidebar="min"] .sidebar-foot{gap:10px;align-items:center}
  html[data-sidebar="min"] .user-chip{justify-content:center;gap:0;padding:0;background:none;border:0}
  html[data-sidebar="min"] .user-meta{display:none}
  html[data-sidebar="min"] .avatar{width:34px;height:34px;flex-basis:34px;font-size:.78rem}
  html[data-sidebar="min"] .btn-block{
    width:38px;height:38px;padding:0;margin-inline:auto;overflow:hidden;
    font-size:0;gap:0;
  }
  html[data-sidebar="min"] .btn-block::before{
    content:"";width:18px;height:18px;background:currentColor;
    -webkit-mask:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M10 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h5V3Zm-2 9H6v-2h2v2Zm4-9v18h7a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2h-7Z'/></svg>") center/18px no-repeat;
    mask:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M10 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h5V3Zm-2 9H6v-2h2v2Zm4-9v18h7a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2h-7Z'/></svg>") center/18px no-repeat;
    background-color:currentColor;
  }

  /* Konten melebar otomatis (max-width tetap 1840px agar baris teks tidak
     terlalu panjang di layar ultrawide). Padding kiri dikurangi sedikit karena
     rel sudah sempit. */
  html[data-sidebar="min"] .content{padding-left:clamp(14px,1.5vw,26px)}
  html[data-sidebar="min"] .topbar{padding-left:clamp(14px,1.5vw,26px)}
}

/* ---------- POP-UP DAFTAR MENU SAAT SIDEBAR DILIPAT ----------
   Klik ikon grup di rel membuka daftar menunya (melayang di samping rel).
   Dibuat assets/app.js dengan kelas `.nav-flyout`. */
.nav-flyout{
  position:fixed;z-index:60;min-width:212px;max-width:min(300px,86vw);
  padding:8px;border-radius:var(--radius-sm);border:1px solid var(--line-strong);
  background:var(--pop-bg,var(--panel-2));color:var(--ink);
  box-shadow:0 18px 40px -22px rgba(0,0,0,.75);
  display:flex;flex-direction:column;gap:2px;
}
.nav-flyout[hidden]{display:none}
.nav-flyout .nf-title{
  font-size:.72rem;font-weight:800;letter-spacing:.02em;color:var(--ink-2);
  padding:4px 10px 7px;border-bottom:1px dashed var(--line);margin-bottom:5px;
}
.nav-flyout a{
  display:flex;align-items:center;gap:9px;padding:9px 10px;border-radius:9px;
  color:var(--ink);text-decoration:none;font-size:.88rem;font-weight:600;
}
.nav-flyout a:hover,.nav-flyout a:focus-visible{background:var(--tint-hover);color:var(--ink-strong)}
.nav-flyout a.is-active{background:var(--nav-active-bg);border:1px solid var(--nav-active-border)}
.nav-flyout a svg{width:16px;height:16px;fill:currentColor;flex:0 0 16px}
.nav-flyout a .nf-badge{
  margin-left:auto;min-width:18px;height:18px;line-height:18px;padding:0 5px;
  border-radius:9px;background:var(--err-fg);color:#fff;font-size:.66rem;text-align:center;
}

/* Tombol lipat sidebar di TOPBAR **DIHAPUS** (permintaan pemilik) — tombol lipat
   cukup satu di kepala menu samping (`.sidebar-mini-toggle`). Aturan CSS lama
   (`.sidebar-toggle-top`) ikut dibuang supaya tidak ada sisa tombol tersembunyi. */

/* ══════════════════════════════════════════════════════════════════════════
   HALAMAN MASUK: TOMBOL GANTI TEMA DI POJOK KANAN ATAS PANEL BRAND (HP)
   Permintaan pemilik: pada tampilan HP, tombol ganti tema dipindah ke atas,
   di pojok kanan atas **di dalam** `aside.login-brand`.

   Rancangan:
     · markup tombol hanya SATU (`$themeBtn` di pages/login.php) dipakai dua kali;
     · desktop (>900px): tombol di `.lp-top` (pojok kanan atas area formulir) —
       tampilan lama TIDAK berubah, dan tombol di panel brand disembunyikan;
     · HP (≤900px): panel brand menjadi header hijau pendek (logo + nama), jadi
       tombol tema ditempatkan `position:absolute` di **pojok kanan atas** header
       itu, dengan gaya kontras di atas latar hijau (putih transparan) supaya
       tetap terbaca di kedua tema. Tombol lama di `.lp-top` disembunyikan
       (kalau tidak, tombolnya muncul DUA kali di HP).
     · `.login-brand{padding-right:58px}` di HP memberi ruang agar nama klinik
       tidak tertutup tombol.
   ══════════════════════════════════════════════════════════════════════════ */
.login-brand .lb-theme{display:none}

@media (max-width:900px){
  /* Tombol tema di panel brand: SEJAJAR dengan kotak logo di sebelahnya.
     Versi pertama memakai `position:absolute; top:10px` sehingga tombol melayang
     ~10–13px LEBIH TINGGI dari pusat logo (terukur: pusat tombol y=26 sedangkan
     pusat logo y=39,6 pada 320px) — keluhan pemilik "agak naik ke atas".
     Sekarang tombol ikut baris flex panel brand (`align-items:center` sudah
     memusatkan secara vertikal) dan hanya diurutkan ke kanan lewat `order:2`,
     jadi pusat tombol SELALU sama dengan pusat logo berapa pun tinggi teksnya. */
  .login-brand .lb-theme{
    display:block;
    position:static;
    order:2;               /* tampil di kanan, setelah logo + nama klinik */
    flex:0 0 auto;
    align-self:center;     /* jaga-jaga bila align-items panel berubah */
    z-index:3;
  }
  .login-brand .lb-theme .btn-theme{
    /* Latar panel brand selalu hijau (di kedua tema). Tombol memakai PUTIH PEKAT
       dengan ikon HIJAU TUA — sama seperti kotak logo (`.lb-mark`) di sebelahnya,
       sehingga kontrasnya kuat. Versi pertama memakai putih transparan + ikon
       putih: terukur hanya **2,90:1** (gagal WCAG AA) karena ikon putih di atas
       latar keputihan tombol itu sendiri. Sekarang terukur **6,4:1**. */
    background:#FFFFFF;
    border-color:rgba(255,255,255,.92);
    color:var(--brand-dark);
    padding:0;
    width:38px;
    height:38px;
    min-width:38px;
    min-height:38px;
    gap:0;
    border-radius:11px;
    box-shadow:0 6px 16px -10px rgba(0,0,0,.55);
  }
  .login-brand .lb-theme .btn-theme:hover{
    background:#F2FFFB;
    border-color:#FFFFFF;
    color:#084C42;
  }
  .login-brand .lb-theme .btn-theme svg{width:18px;height:18px;flex:0 0 18px}
  /* Ikon saja (tanpa teks "Light") supaya ringkas & tidak menutupi nama klinik. */
  .login-brand .lb-theme .theme-label{display:none}
  /* Nama klinik boleh menyusut (dengan elipsis) supaya tidak menabrak tombol;
     tidak perlu lagi padding kanan besar karena tombol sudah di dalam baris flex. */
  .login-brand{padding-right:14px}
  .login-brand .lb-top{flex:1 1 auto;min-width:0}
  .login-brand .lb-name{min-width:0}
  .login-brand .lb-name strong,
  .login-brand .lb-name small{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  /* Tombol tema lama di area formulir: jangan tampil dua kali. */
  .lp-top{display:none}
}
@media (max-width:380px){
  .login-brand .lb-theme .btn-theme{width:36px;height:36px;min-width:36px;min-height:36px}
  .login-brand{padding:16px 12px}
}

/* ══════════════════════════════════════════════════════════════════════════
   LAYAR PENDARATAN SETELAH LOGIN — "PILIH MENU"
   Permintaan pemilik: setelah login jangan langsung Dashboard, tetapi tampilkan
   layar berisi tombol KEPALA MENU yang boleh diakses akun itu; menekannya
   membuka sub-menu, lalu memilih sub-menu membawa ke halamannya. Sapaan
   "Selamat bertugas, <Nama> | <Divisi>".

   Rancangan visual:
     · KEPALA SAPAAN (`.landing-hero`): avatar huruf awal + nama besar + chip
       divisi + tanggal hari ini + jumlah tugas menunggu. Memakai gradien
       merek (hijau) agar terasa seperti "kartu penyambutan".
     · PINTASAN (`.landing-quick`): menu tanpa sub-menu (Dashboard, Investor)
       sebagai kartu baris lebar yang langsung membuka halamannya.
     · MENU ANDA (`.landing-grid`): satu kartu per KEPALA MENU
       (`<details class="landing-group">`). Tertutup/terbuka NATIF — tetap
       bekerja tanpa JavaScript. Kartu pertama dibuka otomatis.
       Di dalamnya daftar sub-menu (`.lg-item`): ikon + nama + keterangan +
       lencana tugas + panah.
     · Semua bisa diklik sebagai satu baris lebar (sasaran sentuh besar).
   ══════════════════════════════════════════════════════════════════════════ */
.landing{display:flex;flex-direction:column;gap:26px}

/* ---------- 1) Kepala sapaan ---------- */
.landing-hero{
  position:relative;overflow:hidden;
  display:flex;align-items:center;gap:18px;flex-wrap:wrap;
  padding:22px 24px;border-radius:18px;
  background:linear-gradient(120deg,var(--brand-dark),var(--brand) 55%,#14A38B);
  color:#F2FFFB;
  box-shadow:0 18px 40px -28px rgba(6,40,32,.85);
}
.landing-hero::after{
  /* Hiasan lingkaran redup — TIDAK memakai backdrop-filter (jaga performa gulir). */
  content:"";position:absolute;right:-90px;top:-110px;width:300px;height:300px;
  border-radius:50%;background:radial-gradient(circle,rgba(255,255,255,.16),transparent 68%);
  pointer-events:none;
}
.lh-avatar{
  position:relative;z-index:1;flex:0 0 auto;
  width:58px;height:58px;border-radius:16px;display:grid;place-items:center;
  background:rgba(255,255,255,.96);color:var(--brand-dark);
  font-weight:800;font-size:1.5rem;font-family:var(--mono);
  box-shadow:0 10px 22px -14px rgba(0,0,0,.6);
}
.lh-text{position:relative;z-index:1;flex:1 1 320px;min-width:0}
.landing-hero .lh-hi{
  margin:0 0 2px;font-size:.82rem;font-weight:600;letter-spacing:.04em;
  text-transform:uppercase;color:rgba(255,255,255,.88);
}
.landing-hero h1{
  margin:0;font-size:1.5rem;line-height:1.2;font-weight:800;letter-spacing:-.01em;
  color:#FFFFFF;overflow-wrap:anywhere;
}
.landing-hero .lh-divider{margin:0 10px;font-weight:400;opacity:.55}
.landing-hero .lh-div{
  font-weight:700;font-size:1rem;letter-spacing:.01em;
  padding:3px 11px;border-radius:20px;
  background:rgba(255,255,255,.18);border:1px solid rgba(255,255,255,.38);
  white-space:nowrap;vertical-align:middle;
}
.lh-meta{
  position:relative;z-index:1;flex:0 0 auto;margin-left:auto;
  display:flex;flex-direction:column;align-items:flex-end;gap:8px;
}
.lh-date{font-size:.8rem;font-family:var(--mono);color:rgba(255,255,255,.92);white-space:nowrap}
.lh-task{
  display:inline-flex;align-items:center;gap:6px;
  font-size:.78rem;font-weight:700;white-space:nowrap;
  padding:5px 11px;border-radius:20px;
  background:rgba(255,255,255,.20);border:1px solid rgba(255,255,255,.42);color:#FFFFFF;
}
.lh-task svg{width:15px;height:15px;fill:currentColor;flex:0 0 15px}

/* ---------- 2) Judul seksi ---------- */
.landing-section{display:flex;flex-direction:column;gap:14px}
.landing-sec-head{
  display:flex;align-items:baseline;gap:8px 14px;flex-wrap:wrap;
  padding:0 2px;
}
.landing-sec-head h2{
  margin:0;font-size:1.02rem;font-weight:800;letter-spacing:.01em;color:var(--head-ink);
}

/* ---------- 3) Pintasan (menu tanpa sub-menu) ---------- */
.landing-quick{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(320px,100%),1fr));gap:16px}
.lq-card{
  display:flex;align-items:center;gap:14px;
  padding:15px 16px;border-radius:14px;
  border:1px solid var(--line-strong);background:var(--panel);
  color:var(--ink);text-decoration:none;
  transition:border-color .14s, background .14s, transform .14s;
}
.lq-card:hover,.lq-card:focus-visible{
  border-color:var(--brand);background:var(--tint-hover);transform:translateY(-1px);
}
.lq-ico{
  flex:0 0 40px;width:40px;height:40px;border-radius:12px;display:grid;place-items:center;
  background:var(--nav-active-bg);border:1px solid var(--nav-active-border);color:var(--brand);
}
.lq-ico svg{width:19px;height:19px;fill:currentColor}
.lq-text{flex:1 1 auto;min-width:0;display:flex;flex-direction:column;gap:1px}
.lq-text strong{font-size:.92rem;font-weight:700;color:var(--head-ink)}
.lq-text small{font-size:.76rem;color:var(--ink-2);line-height:1.35}
.lq-badge{
  flex:0 0 auto;min-width:22px;height:22px;line-height:22px;padding:0 7px;border-radius:11px;
  background:var(--err-fg);color:#fff;font-size:.7rem;font-weight:800;text-align:center;
}
.lq-go{flex:0 0 16px;width:16px;height:16px;fill:var(--ink-3)}
.lq-card:hover .lq-go{fill:var(--brand)}

/* ---------- 4) Kartu kepala menu (details/summary) ---------- */
.landing-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(360px,100%),1fr));gap:18px;align-items:start}
.landing-group{
  border:1px solid var(--line-strong);border-radius:16px;background:var(--panel);
  overflow:hidden;
}
.landing-group[open]{
  border-color:var(--brand);
  box-shadow:0 16px 34px -30px rgba(6,40,32,.9);
}
.lg-head{
  display:flex;align-items:center;gap:13px;
  padding:14px 16px;cursor:pointer;list-style:none;
  background:var(--tint-3);
  transition:background .14s;
}
.lg-head::-webkit-details-marker{display:none}
.lg-head:hover{background:var(--tint-hover)}
.landing-group[open] .lg-head{
  background:var(--nav-active-bg);
  border-bottom:1px solid var(--line);
}
.lg-ico{
  flex:0 0 42px;width:42px;height:42px;border-radius:12px;display:grid;place-items:center;
  background:var(--panel-2);border:1px solid var(--line-strong);color:var(--brand);
}
.lg-ico svg{width:20px;height:20px;fill:currentColor}
.landing-group[open] .lg-ico{background:var(--brand);border-color:transparent;color:#fff}
.lg-title{flex:1 1 auto;min-width:0;display:flex;flex-direction:column;gap:1px}
.lg-title strong{
  font-size:.95rem;font-weight:800;color:var(--head-ink);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.lg-title small{font-size:.75rem;color:var(--ink-2)}
.lg-badge{
  flex:0 0 auto;min-width:22px;height:22px;line-height:22px;padding:0 7px;border-radius:11px;
  background:var(--err-fg);color:#fff;font-size:.7rem;font-weight:800;text-align:center;
}
.lg-caret{
  flex:0 0 18px;width:18px;height:18px;fill:var(--ink-2);
  transition:transform .16s ease;
}
.landing-group[open] .lg-caret{transform:rotate(180deg);fill:var(--brand)}

.lg-body{padding:8px}
.lg-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:2px}
.lg-item{
  display:flex;align-items:center;gap:12px;
  padding:11px 12px;border-radius:10px;
  color:var(--ink);text-decoration:none;
  transition:background .12s, color .12s;
}
.lg-item:hover,.lg-item:focus-visible{background:var(--tint-hover);color:var(--ink-strong)}
.li-ico{
  flex:0 0 32px;width:32px;height:32px;border-radius:9px;display:grid;place-items:center;
  background:var(--tint-3);border:1px solid var(--line);color:var(--ink-2);
}
.lg-item:hover .li-ico{color:var(--brand);border-color:var(--nav-active-border)}
.li-ico svg{width:16px;height:16px;fill:currentColor}
.li-text{flex:1 1 auto;min-width:0;display:flex;flex-direction:column;gap:1px}
.li-text strong{font-size:.88rem;font-weight:700;color:var(--head-ink)}
.li-text small{font-size:.75rem;color:var(--ink-2);line-height:1.35}
.li-badge{
  flex:0 0 auto;min-width:20px;height:20px;line-height:20px;padding:0 6px;border-radius:10px;
  background:var(--err-fg);color:#fff;font-size:.68rem;font-weight:800;text-align:center;
}
.li-go{flex:0 0 14px;width:14px;height:14px;fill:var(--ink-3)}
.lg-item:hover .li-go{fill:var(--brand)}

.landing-empty{padding:26px}
.landing-empty h2{margin:0 0 6px;font-size:1.05rem}

/* ---------- 5) Responsif HP ---------- */
@media (max-width:900px){
  .landing{gap:20px}
  .landing-hero{padding:18px;gap:14px;border-radius:16px}
  .lh-avatar{width:48px;height:48px;border-radius:14px;font-size:1.25rem}
  .landing-hero h1{font-size:1.22rem}
  .landing-hero .lh-div{font-size:.9rem;padding:2px 10px}
  .lh-meta{margin-left:0;align-items:flex-start;width:100%;flex-direction:row;flex-wrap:wrap;gap:8px 12px}
  .landing-grid,.landing-quick{grid-template-columns:1fr;gap:14px}
  .lg-head{padding:13px 14px;gap:11px}
  .lg-ico{flex-basis:38px;width:38px;height:38px;border-radius:11px}
  .lg-ico svg{width:18px;height:18px}
  .lg-title strong{white-space:normal}   /* judul grup panjang boleh 2 baris di HP */
  .lg-item{padding:12px 11px;min-height:52px}
  .landing-sec-head h2{font-size:.98rem}
}
@media (max-width:400px){
  .landing-hero{padding:15px 14px}
  .lh-avatar{width:42px;height:42px;flex-basis:42px;font-size:1.1rem}
  .landing-hero h1{font-size:1.1rem}
  .landing-hero .lh-divider{display:none}
  .landing-hero .lh-div{display:inline-block;margin-top:6px}
  .li-text small{font-size:.72rem}
}

/* ══════════════════════════════════════════════════════════════════════════
   SAPAAN LEVEL OWNER DI MENU INVESTOR (`.inv-welcome`)
   Pemilik usaha (role yang HANYA boleh membuka menu Investor) tidak melewati
   layar "Pilih Menu" — ia langsung mendarat di menu Investor, jadi halaman ini
   yang menyambutnya: "Selamat datang, <Nama>".

   Prinsip desain sama dengan kepala sapaan layar Pilih Menu: satu kartu gradien
   merek, huruf putih pekat (kontras kuat di kedua tema karena latarnya selalu
   hijau tua), dan HANYA data — tanpa kalimat penjelas (permintaan pemilik:
   fokus ke menu & nama menu).
   ⚠️ Jangan memakai `backdrop-filter` di sini (aturan performa gulir global).
   ══════════════════════════════════════════════════════════════════════════ */
.inv-welcome{
  display:flex;align-items:center;gap:16px;flex-wrap:wrap;
  padding:18px 22px;border-radius:16px;color:#F2FFFB;
  background:linear-gradient(120deg,var(--brand-dark),var(--brand) 58%,#14A38B);
  box-shadow:0 16px 36px -28px rgba(6,40,32,.85);
}
.inv-welcome .iw-avatar{
  flex:0 0 auto;width:52px;height:52px;border-radius:15px;display:grid;place-items:center;
  background:rgba(255,255,255,.96);color:var(--brand-dark);
  font-weight:800;font-size:1.35rem;font-family:var(--mono);
  box-shadow:0 10px 22px -16px rgba(0,0,0,.6);
}
.inv-welcome .iw-text{flex:1 1 240px;min-width:0}
.inv-welcome .iw-hi{
  /* Sengaja TANPA `text-transform:uppercase`: pemilik meminta bunyinya
     "Selamat datang, <Nama>" apa adanya. */
  margin:0 0 2px;font-size:.85rem;font-weight:700;letter-spacing:.01em;
  color:rgba(255,255,255,.94);
}
.inv-welcome h1{margin:0;font-size:1.45rem;line-height:1.2;font-weight:800;color:#FFFFFF;overflow-wrap:anywhere}
.inv-welcome .iw-meta{display:flex;flex-direction:column;align-items:flex-end;gap:6px;margin-left:auto}
.inv-welcome .iw-date{font-size:.78rem;font-family:var(--mono);color:rgba(255,255,255,.92);white-space:nowrap}
.inv-welcome .iw-role{
  font-size:.74rem;font-weight:700;white-space:nowrap;
  padding:4px 11px;border-radius:20px;
  background:rgba(255,255,255,.20);border:1px solid rgba(255,255,255,.44);color:#FFFFFF;
}
@media (max-width:640px){
  .inv-welcome{padding:15px 16px;gap:12px;border-radius:14px}
  .inv-welcome .iw-avatar{width:44px;height:44px;flex-basis:44px;font-size:1.15rem;border-radius:13px}
  .inv-welcome h1{font-size:1.18rem}
  .inv-welcome .iw-meta{margin-left:0;align-items:flex-start;flex-direction:row;flex-wrap:wrap;gap:8px}
}

/* ══════════════════════════════════════════════════════════════════════════
   PENDAFTARAN PASIEN & PEMERIKSAAN DOKTER
   - `.vital-grid`  : kolom tanda vital (7 angka) — rapat, rata, mudah diisi cepat
   - `.dx-panel`    : kartu Diagnosa & Rencana Terapi (fokus dokter)
   - `.steps .step` : tahapan proses pendaftaran (Menunggu → … → Selesai)
   ══════════════════════════════════════════════════════════════════════════ */
.vital-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:14px}
.vital-grid .field input{text-align:center;font-family:var(--mono);font-weight:600}
@media (max-width:640px){
  .vital-grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:12px}
  .vital-grid .field:last-child{grid-column:1 / -1}
}

/* Tahapan proses: setiap langkah ringkas, yang sudah dilalui diberi warna lembut. */
.steps.plan-steps{gap:10px}
.steps.plan-steps .step{
  padding:10px 12px;font-size:.8rem;font-weight:600;color:var(--ink-2);
  align-items:center;border-radius:10px;
}
.steps.plan-steps .step.is-done{
  color:var(--ok-fg);border-color:var(--ok-bd);background:var(--ok-bg);
}

/* Kartu diagnosa dokter: kolom utama lebih besar, ICD sejajar di kanannya. */
.dx-panel{border-color:var(--nav-active-border)}
.dx-grid{display:grid;grid-template-columns:minmax(0,1.35fr) minmax(0,1fr);gap:16px}
.dx-grid .field span{font-weight:700}
.dx-grid .dx-main textarea{min-height:96px}
@media (max-width:900px){ .dx-grid{grid-template-columns:1fr} }

/* ══════════════════════════════════════════════════════════════════════════
   RONDE RME: SUFFIX STATIS, FAKTA PENDAFTARAN, RACIKAN
   ══════════════════════════════════════════════════════════════════════════ */

/* --- SUFFIX / TRAILING ADDON STATIS -------------------------------------
   Teks satuan di DALAM kotak isian (mis. "x/menit", "°C", "kg", "mg/dL").
   Bukan input: tidak ikut terkirim dan tidak bisa diubah pengguna. */
.addon-field{position:relative;display:block;width:100%}
.addon-field > input,
.addon-field > select{width:100%;padding-right:64px}
.addon-field > .addon-suffix{
  position:absolute;right:1px;top:1px;bottom:1px;display:flex;align-items:center;
  padding:0 10px;pointer-events:none;white-space:nowrap;
  font-size:.78rem;font-weight:700;color:var(--ink-2);
  border-left:1px solid var(--line);border-radius:0 8px 8px 0;
  background:var(--tint-2);
}
.addon-field > .addon-suffix:empty{display:none}
.addon-field:has(> .addon-suffix:empty) > input,
.addon-field:has(> .addon-suffix:empty) > select{padding-right:12px}
.vital-grid .addon-field > input{text-align:right}
@media (max-width:640px){
  .addon-field > .addon-suffix{padding:0 8px;font-size:.74rem}
}

/* --- FAKTA PENDAFTARAN (pengganti metric-row.wide di kartu dokter) -------
   Semua data yang diambil petugas pendaftaran/perawat tampil lengkap tapi
   PADAT: label kecil di atas, nilai tegas di bawah, dua–tiga kolom. */
.fact-grid{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));
  gap:10px 16px;padding:14px 16px;border:1px solid var(--line);
  border-radius:var(--radius-sm);background:var(--tint-3);
}
.fact{min-width:0;padding-left:10px;border-left:2px solid var(--nav-active-border)}
.fact > span{
  display:block;font-size:.7rem;letter-spacing:.06em;text-transform:uppercase;
  font-weight:700;color:var(--ink-2);margin-bottom:2px;
}
.fact > strong{display:block;font-size:.94rem;line-height:1.35;overflow-wrap:anywhere}
.fact > strong.mono{font-family:var(--mono);font-size:.9rem}
.fact > small{display:block;font-size:.74rem;color:var(--ink-2);margin-top:1px}
.fact.span-all{grid-column:1 / -1}
@media (max-width:640px){
  .fact-grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:10px 12px;padding:12px}
  .fact > strong{font-size:.9rem}
}

/* Diagnosa (A) & Rencana terapi (P) SEJAJAR; ICD & kontrol di bawahnya. */
.dx-grid.dx-grid-2{grid-template-columns:repeat(2,minmax(0,1fr))}
.dx-grid.dx-grid-2 textarea{min-height:110px}
@media (max-width:900px){ .dx-grid.dx-grid-2{grid-template-columns:1fr} }

/* --- RACIKAN (compounding) ---------------------------------------------- */
.cmp-card{
  border:1px solid var(--line);border-radius:var(--radius-sm);
  background:var(--tint-2);padding:12px;margin-bottom:12px;
}
.cmp-card:last-of-type{margin-bottom:0}
.cmp-head{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(170px,1fr));
  gap:10px 12px;align-items:end;margin-bottom:10px;
}
.cmp-head .field{gap:4px}
.cmp-head .field > span{font-size:.74rem;font-weight:700;color:var(--ink-2)}
.cmp-head .cmp-del{grid-column:1 / -1;justify-self:start;margin-top:2px}
.cmp-card > .table-wrap{margin-bottom:8px}
.cmp-card table.data{background:var(--panel)}
.cmp-card > .btn{min-height:34px}
[data-cmp-empty]{margin-top:4px}
@media (max-width:640px){
  .cmp-head{grid-template-columns:repeat(2,minmax(0,1fr));gap:8px 10px}
  .cmp-head .field.span-2{grid-column:1 / -1}
}

/* --- DROPDOWN + TOMBOL [+] DI SAMPINGNYA --------------------------------
   Dipakai pemilih pasien pada kartu Pendaftaran: dropdown memilih pasien yang
   sudah ada, tombol [+] membuka kartu "Pasien Baru" (form lengkap). */
.field-with-addon{display:flex;align-items:stretch;gap:8px;width:100%}
.field-with-addon > select{flex:1 1 auto;min-width:0}
.field-with-addon > .btn-addon{
  flex:0 0 auto;display:inline-flex;align-items:center;gap:6px;
  padding:0 12px;min-height:38px;border-radius:var(--radius-sm);
  border:1px solid var(--nav-active-border);background:var(--tint-2);color:var(--ink);
  font-weight:700;text-decoration:none;
}
.field-with-addon > .btn-addon svg{width:16px;height:16px;fill:currentColor}
.field-with-addon > .btn-addon:hover{background:var(--tint-3)}
@media (max-width:640px){
  .field-with-addon > .btn-addon{padding:0 10px;min-height:44px}
  .field-with-addon > .btn-addon .lbl{display:none}
}
/* Baris centang di dalam kolom isian (mis. "Pasien puasa?"). */
.switch-line.switch-inline{
  display:flex;align-items:center;gap:8px;min-height:38px;padding:0 10px;
  border:1px solid var(--line);border-radius:var(--radius-sm);background:var(--tint-2);
  font-weight:600;font-size:.86rem;
}
.switch-line.switch-inline input{width:18px;height:18px;flex:0 0 auto}

/* Dropdown yang ditingkatkan menjadi combobox (.cs-btn) tidak bisa memakai
   suffix absolut — tombol combobox selebar kotak & panahnya di kanan. Untuk
   kasus itu suffix diletakkan sebagai chip DI SAMPING kontrol (flex). */
.addon-field:has(> .cs-btn){display:flex;align-items:stretch;gap:6px}
.addon-field:has(> .cs-btn) > .cs-btn{flex:1 1 auto;min-width:0;width:auto}
.addon-field:has(> .cs-btn) > .addon-suffix{
  position:static;padding:0 9px;border:1px solid var(--line);border-left:1px solid var(--line);
  border-radius:8px;background:var(--tint-2);font-size:.76rem;
}
.addon-field:has(> .cs-btn) > .addon-suffix:empty{display:none}

/* ═══════════════════════════════════════════════════════════════════════════
   CATATAN PENCARIAN PADA DAFTAR DROPDOWN PANJANG
   Daftar item (obat/alkes) memuat 2.268+ pilihan; server hanya mengirim 150
   pertama dan sisanya diambil dari `index.php?page=itemsearch` saat pengguna
   mengetik. Baris kecil ini menjelaskan caranya (bukan tombol Info — pengguna
   butuh tahu di dalam daftar yang sedang terbuka).
   ═══════════════════════════════════════════════════════════════════════════ */
.cs-note{
  padding:8px 12px;border-top:1px solid var(--line);
  font-size:.74rem;color:var(--ink-2);background:var(--tint-2);
}
.cs-note[hidden]{display:none}

/* ═══════════════════════════════════════════════════════════════════════════
   TANDA VITAL & PEMERIKSAAN DARAH (kartu Anamnesa perawat)
   Permintaan pemilik: beri JARAK antar kolom angka (Tekanan darah … Kolesterol)
   supaya tidak berdesakan, dan ceklis "Pasien puasa" menempel pada kolom GDS
   (puasa hanya relevan untuk gula darah).
   ═══════════════════════════════════════════════════════════════════════════ */
.vital-grid{gap:18px 20px}
.vital-grid .field{gap:7px}
.vital-grid .field > span{letter-spacing:.1px}
.vital-grid .addon-field > input{padding-left:10px}
/* Baris pemeriksaan darah: GDS + ceklis puasa berdampingan, lalu asam urat &
   kolesterol. Di HP menjadi 2 kolom dengan ceklis pas di bawah GDS. */
.vital-grid.vital-lab{grid-template-columns:repeat(auto-fit,minmax(170px,1fr))}
.lab-fasting{min-width:150px}
.lab-fasting .switch-line.switch-inline{height:100%;min-height:42px;font-weight:600}
@media (max-width:640px){
  .vital-grid{gap:14px 14px}
  .vital-grid.vital-lab{grid-template-columns:repeat(2,minmax(0,1fr))}
  .vital-grid.vital-lab .field.lab-fasting{grid-column:auto}
}

/* ═══════════════════════════════════════════════════════════════════════════
   ANAMNESA & PEMERIKSAAN FISIK (kartu Pendaftaran) — DIPERBAIKI
   Masalah sebelumnya:
     · "Pemeriksaan Darah" adalah `.form-section` BERSARANG di dalam
       `.form-section`, sementara `.sheet-body .form-section{content-visibility:auto}`
       memberi tinggi perkiraan 240px → blok isinya terpotong/berkedip saat kartu
       dibuka (tampak "kacau").
     · Ceklis puasa memakai `<label>` di dalam `<label>` → seluruh kotak ikut
       men-toggle centang dan grid bergeser.
   Sekarang: pemisah memakai `.sub-head` biasa (bukan section bersarang), wadah
   ceklis memakai `<div class="field">`, dan section ini dikecualikan dari
   optimasi `content-visibility` supaya isinya selalu tampil utuh.
   ═══════════════════════════════════════════════════════════════════════════ */
.form-section.vital-section{content-visibility:visible;contain:none;gap:16px}
.vital-section .sub-head{display:flex;align-items:baseline;justify-content:space-between;gap:12px;flex-wrap:wrap;margin-top:2px}
.vital-section .sub-head h3{margin:0;font-size:.82rem;letter-spacing:.02em;color:var(--ink-strong)}
.vital-section .sub-head::before{content:none}
/* Garis pemisah antar kelompok (vital ⇄ pemeriksaan darah) tanpa membuat
   section bersarang. */
.vital-section .sub-head + .vital-grid{margin-bottom:6px}
.vital-grid + .sub-head{margin-top:10px;padding-top:14px;border-top:1px dashed var(--line)}
/* Ceklis puasa: satu baris penuh setinggi kontrol lain, tidak melar mengikuti
   tinggi baris grid. */
.vital-grid .lab-fasting .switch-line.switch-inline{width:100%;min-height:42px}
.vital-grid .lab-fasting > span{color:var(--ink-2);font-weight:600}
/* Placeholder angka tanda vital dibuat LEBIH PUDAR (permintaan pemilik) supaya
   tidak terbaca seperti nilai yang sudah terisi. */
.vital-grid input::placeholder,
.vital-grid .addon-field > input::placeholder{opacity:.38;font-weight:500;color:var(--ink-2)}
.vital-grid .addon-field > input{font-variant-numeric:tabular-nums}

/* ═══════════════════════════════════════════════════════════════════════════
   KARTU e-RESEP — DEFAULT TERTUTUP + TOMBOL [Resep]
   Tidak semua pasien diresepkan, jadi kartu resep tidak boleh langsung terbuka
   dan memakan ruang. Memakai <details>/<summary> (tanpa JavaScript tetap bisa
   dibuka). Tombol [Resep] hanyalah tampilan — seluruh kepala kartu bisa diklik.
   ═══════════════════════════════════════════════════════════════════════════ */
.rx-card{padding:0}
.rx-details{display:block}
.rx-details > .rx-summary{
  list-style:none;display:flex;align-items:center;justify-content:space-between;
  gap:12px;flex-wrap:wrap;cursor:pointer;padding:14px 16px;margin:0;
  border-bottom:1px solid transparent;
}
.rx-details > .rx-summary::-webkit-details-marker{display:none}
.rx-details > .rx-summary::marker{content:""}
.rx-details[open] > .rx-summary{border-bottom-color:var(--line)}
.rx-details > .rx-summary:hover{background:var(--tint-2)}
.rx-details > .rx-summary h2{margin:0}
.rx-body{padding:16px;display:flex;flex-direction:column;gap:14px}
.rx-details:not([open]) > .rx-body{display:none}
/* Tombol [Resep] — warna mengikuti tombol utama; saat terbuka berubah menjadi
   "Tutup" lewat teks yang ditukar JavaScript (tanpa JS tetap menutup saat diklik). */
.rx-open{pointer-events:none;white-space:nowrap}
.rx-details[open] .rx-open{background:var(--tint-2);color:var(--ink);border:1px solid var(--line)}
/* Chip kode resep di kepala kartu tidak boleh men-toggle kartu saat diklik. */
.rx-summary .ref-chip{position:relative;z-index:1}
@media (max-width:640px){
  .rx-details > .rx-summary{padding:12px 14px}
  .rx-body{padding:14px}
}

/* ═══════════════════════════════════════════════════════════════════════════
   TANDA-TANDA VITAL & PEMERIKSAAN DARAH — GRID DIRAPIKAN (permintaan pemilik)
   ───────────────────────────────────────────────────────────────────────────
   Masalah sebelumnya (terukur dengan Playwright):
     · dua grid memakai template BERBEDA → lebar kolom tidak sama
       (tanda vital 163px, pemeriksaan darah 301px pada 1440px);
     · `auto-fit` menyisakan kolom tak terpakai sehingga baris terakhir
       melebar (325px) dan pada 1024px vital pecah 5+2;
     · `.field:last-child{grid-column:1/-1}` di HP membuat sel terakhir
       selebar penuh sementara sel lain setengah → jarak tidak merata;
     · `.lab-fasting{min-width:150px}` pada 320px (kolom 121px) membuat sel
       meluber & labelnya turun 2 baris (tinggi 93px vs 72px).
   Perbaikan (TANPA mengubah markup/logika):
     · SATU variabel kolom `--vg-cols` dipakai KEDUA grid → lebar selalu sama;
     · jumlah kolom tetap: 4 (≥901px) · 3 (641–900px) · 2 (≤640px) — semua
       `minmax(0,1fr)` supaya proporsional & tidak meluber;
     · setiap `.field` memakai baris label tetap (18px, 2 baris di HP) +
       baris kontrol 42px sehingga SEMUA input sejajar rapi;
     · gap tunggal `--vg-gap` (16px) horizontal & vertikal, sama untuk kedua grid;
     · suffix statis disamakan lebarnya (56px) agar garis pemisah sejajar;
     · ceklis "Pasien puasa" memakai tinggi kontrol yang sama (42px).
   ═══════════════════════════════════════════════════════════════════════════ */
.vital-section{
  --vg-gap:16px;
  --vg-cols:repeat(4,minmax(0,1fr));
  --vg-label-h:18px;
  /* Lebar STATIC SUFFIX (mmHg · x/menit · °C · kg · cm · % · mg/dL) diseragamkan.
     Sebelumnya suffix memakai `min-width`, sehingga "x/menit" (61px) lebih lebar
     dari "kg"/"cm" (56px): garis pemisah tidak sejajar antar kolom dan sisa ruang
     angka di kolom Nadi/Respirasi hanya 3px (kolom lain 8px) → terlihat rapat.
     Dengan lebar TETAP + padding kanan yang dihitung dari variabel ini, jarak
     angka→garis sama di SEMUA kolom (12px). */
  --vg-suf-w:64px;
  --vg-suf-gap:12px;
}
/* Kartu detail (Rekam Medis tersimpan) memakai <section class="lab-card"> →
   beri jarak antar kelompok yang seragam tanpa menambah margin per elemen. */
.lab-card.vital-section{display:flex;flex-direction:column;gap:14px}

.vital-section .sub-head{
  display:flex;align-items:baseline;justify-content:space-between;
  gap:8px 12px;flex-wrap:wrap;margin:0;padding:0;border:0;
}
.vital-section .sub-head h3{margin:0;font-size:.82rem;letter-spacing:.02em;color:var(--ink-strong)}
.vital-section .sub-head > .muted{margin-left:auto}

/* SATU grid untuk kedua kelompok (tanda vital & pemeriksaan darah). */
.vital-section .vital-grid{
  display:grid;
  grid-template-columns:var(--vg-cols);
  gap:var(--vg-gap);
  align-items:start;
  margin:0;
}
/* Sel: baris label + baris kontrol 42px → label & input sejajar antar kolom. */
.vital-section .vital-grid > .field{
  display:grid;
  grid-template-rows:auto auto;
  align-content:start;
  gap:6px;
  min-width:0;
  margin:0;
  grid-column:auto;          /* batalkan `grid-column:1/-1` aturan lama di HP */
}
.vital-section .vital-grid > .field > span:not(.addon-field):not(.field-with-addon){
  display:flex;align-items:flex-end;
  /* TINGGI TETAP (bukan min-height): label 1 baris dan 2 baris dalam satu baris
     grid harus menempati kotak yang sama, kalau tidak input di sebelahnya
     bergeser 2–4px (terukur: label "GDS (gula darah sewaktu)" 2 baris = 34px
     sedangkan "Pasien puasa?" 1 baris = 32px). */
  height:var(--vg-label-h);
  min-height:var(--vg-label-h);
  overflow:hidden;
  line-height:1.3;
  font-size:.78rem;font-weight:600;color:var(--ink-2);
  margin:0;
}
.vital-section .vital-grid .addon-field{width:100%;display:block;height:auto;overflow:visible}
.vital-section .vital-grid input:not([type=checkbox]):not([type=radio]){
  height:42px;width:100%;
  /* Ruang kanan = lebar suffix + jarak tetap → angka tidak pernah menyentuh
     garis pemisah, berapa pun panjang label satuannya. */
  padding-right:calc(var(--vg-suf-w) + var(--vg-suf-gap));
}
/* Suffix statis (mmHg, x/menit, °C, kg, cm, %, mg/dL) disamakan lebarnya
   supaya garis pemisah + angka rata di semua kolom. */
.vital-section .vital-grid .addon-field > .addon-suffix{
  width:var(--vg-suf-w);min-width:var(--vg-suf-w);max-width:var(--vg-suf-w);
  justify-content:center;padding:0;font-size:.76rem;
  white-space:nowrap;overflow:hidden;text-overflow:clip;
}
/* Ceklis "Pasien puasa": tinggi kontrol SAMA dengan input (42px). */
.vital-section .vital-grid .lab-fasting{min-width:0}
.vital-section .vital-grid .lab-fasting .switch-line.switch-inline{
  width:100%;height:42px;min-height:42px;margin:0;padding:0 10px;
}
.vital-section .vital-grid .lab-fasting > span{color:var(--ink-2);font-weight:600}

/* Lebar layar → jumlah kolom tetap (bukan auto-fit, agar tidak ada baris
   terakhir yang melebar). */
@media (max-width:1100px){
  .vital-section{--vg-cols:repeat(3,minmax(0,1fr))}
}
@media (max-width:900px){
  .vital-section{--vg-cols:repeat(3,minmax(0,1fr))}
}
@media (max-width:760px){
  .vital-section{--vg-cols:repeat(2,minmax(0,1fr));--vg-gap:14px;--vg-label-h:34px}
}
@media (max-width:360px){
  /* Layar sangat sempit: suffix & jaraknya ikut menyusut, TAPI tetap seragam
     untuk semua kolom (termasuk Nadi/Respirasi) supaya tidak ada yang menempel. */
  /* Suffix 48px + jarak 8px: angka terpanjang ("120/80" pada Tekanan darah) masih
     muat di sel 122px tanpa terpotong, dan semuanya tetap SERAGAM. */
  .vital-section{--vg-gap:12px;--vg-suf-w:48px;--vg-suf-gap:6px}
  .vital-section .vital-grid .addon-field > .addon-suffix{font-size:.68rem}
  /* Padding kiri dirapatkan di layar sangat sempit supaya angka terpanjang
     ("120/80" pada Tekanan darah) tetap muat utuh — jarak angka→garis tetap
     SERAGAM untuk semua kolom (termasuk Nadi & Respirasi). */
  .vital-section .vital-grid .addon-field > input{padding-left:6px}
}

/* ═══════════════════════════════════════════════════════════════════════════
   RME DOKTER — TABEL TINDAKAN (permintaan pemilik)
   Masalah nyata (terukur): kolom Tarif hanya 112px sedangkan input nominal
   butuh ±104–113px (prefix "Rp" 38px + "250.000"), dan kolom Subtotal 90px
   (butuh 76px) → ANGKA TERPOTONG. Lebar kolom juga tidak proporsional sehingga
   kolom "Tindakan" kebesaran dan kolom uang kesempitan.
   Perbaikan: lebar kolom EKSPLISIT & proporsional (table-layout fixed) hanya
   untuk layar ≥901px; di HP tabel tetap menjadi kartu bertingkat (tidak diubah).
   ═══════════════════════════════════════════════════════════════════════════ */
@media (min-width:901px){
  table.data.act-table{table-layout:fixed;width:100%}
  /* Proporsi kolom: nama tindakan paling lebar, kolom uang cukup untuk
     "Rp 1.234.567", kolom aksi hanya selebar tombolnya. */
  table.data.act-table col,
  table.data.act-table th.col-act-item{width:32%}
  table.data.act-table th.col-act-qty{width:12%}
  table.data.act-table th.col-act-money{width:24%}
  table.data.act-table th.col-act-del{width:8%}
  /* Kolom jumlah: padding dirapatkan supaya angka + tombol spin tidak terpotong. */
  table.data.act-table input[data-row-qty]{padding-left:8px;padding-right:8px}
  /* Angka uang: rata kanan + tabular supaya digit sejajar & mudah dibaca. */
  table.data.act-table input[data-money],
  table.data.act-table input[data-row-sub]{
    text-align:right;font-variant-numeric:tabular-nums;min-width:0;width:100%;
  }
  table.data.act-table .money-prefix{font-size:.78rem}
  /* Input jumlah & uang tidak boleh lebih sempit dari isinya. */
  table.data.act-table input[data-row-qty]{width:100%;min-width:0;text-align:right}
}
/* Layar sangat sempit (tabel sudah menjadi kartu): prefix "Rp" dirapatkan supaya
   nominal terbesar ("Rp 250.000") tetap utuh di dalam sel. */
@media (max-width:420px){
  table.data.act-table .money-wrap>input[data-money]{padding-left:30px!important}
  table.data.act-table .money-prefix{left:8px;font-size:.72rem}
  table.data.act-table input[data-money]{font-size:.94rem}
}
/* Di HP tabel menjadi kartu bertingkat: kolom Jumlah/Tarif/Subtotal dibuat
   PENUH (label di atas, nilai di bawah) supaya nominal besar tetap utuh —
   dengan grid label 100px + nilai, "Rp 1.234.567" tidak muat. */
@media (max-width:900px){
  table.data.act-table[data-stack] td:nth-child(2),
  table.data.act-table[data-stack] td:nth-child(3),
  table.data.act-table[data-stack] td:nth-child(4){display:block}
  table.data.act-table[data-stack] td:nth-child(2)::before,
  table.data.act-table[data-stack] td:nth-child(3)::before,
  table.data.act-table[data-stack] td:nth-child(4)::before{display:block;margin-bottom:3px}
  table.data.act-table[data-stack] .money-wrap{min-width:0}
}
/* Tabel tindakan versi BACA-SAJA (rekam medis terkunci / tanpa izin): nominal
   rata kanan & tidak boleh terpotong. */
table.data.act-table-read td:nth-child(3),
table.data.act-table-read td:nth-child(4){text-align:right;white-space:nowrap;
  font-variant-numeric:tabular-nums;font-weight:600}
@media (max-width:900px){
  /* Saat menumpuk menjadi kartu, nominal tetap rata kanan & utuh. */
  table.data.act-table[data-stack] td:nth-child(3),
  table.data.act-table[data-stack] td:nth-child(4){text-align:right}
}

/* Tombol nonaktif (mis. [Periksa] saat pasien sudah di tahap Pemeriksaan). */
.btn.is-disabled{opacity:.45;pointer-events:none;cursor:not-allowed;filter:grayscale(.4)}

/* Pesan hasil di dalam kartu (mis. pengajuan tindakan baru). */
.form-msg{margin:0;padding:9px 12px;border-radius:10px;font-size:.82rem;font-weight:600}
.form-msg.is-ok{background:var(--ok-bg);color:var(--ok-fg);border:1px solid var(--ok-bd)}
.form-msg.is-err{background:var(--err-bg);color:var(--err-fg);border:1px solid var(--err-bd)}

/* Kartu pengajuan tindakan baru: kolom alasan + tombol keputusan sejajar. */
.pending-card .card-foot{gap:8px;flex-wrap:wrap;align-items:center}
.pending-card .card-foot .reject-note{flex:1 1 200px;min-width:0}

/* ═══════════════════════════════════════════════════════════════════════════
   DETAIL PENDAFTARAN — RINGKASAN DATA KUNJUNGAN (rancang ulang)
   Pengganti `div.metric-row.wide` yang dulu menumpuk semua data dalam satu baris:
   tanda vital menjadi teks panjang yang membungkus acak dan parameter
   laboratorium tidak terbaca satu per satu (permintaan pemilik).
   Struktur sekarang: kartu 2 kolom (Dokter · Pasien), lalu baris PENUH untuk
   Keluhan awal / Anamnesa / Tanda vital / Pemeriksaan darah.
   ═══════════════════════════════════════════════════════════════════════════ */
.reg-info{
  display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
  gap:14px;margin:16px 0 4px;
}
.reg-block{
  display:flex;flex-direction:column;gap:8px;min-width:0;
  padding:12px 14px;border:1px solid var(--line);border-radius:var(--radius-sm);
  background:var(--tint-2);
}
.reg-block.span-all{grid-column:1 / -1}
.reg-block-head{display:flex;align-items:baseline;justify-content:space-between;gap:10px;flex-wrap:wrap}
.reg-block-head h3{
  margin:0;font-size:.72rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;
  color:var(--ink-2);
}
.reg-block-body{display:flex;flex-direction:column;gap:2px;min-width:0}
.reg-value{font-size:.95rem;font-weight:700;color:var(--ink-strong);line-height:1.35;overflow-wrap:anywhere}
.reg-value-wrap{font-weight:600;line-height:1.5;white-space:pre-wrap}
/* Petak parameter (tanda vital & pemeriksaan darah): label di atas, angka besar,
   satuan kecil di bawah. Lebar seimbang & jarak seragam. */
.param-grid{display:grid;gap:10px;min-width:0}
.param-grid.vital-param-grid{grid-template-columns:repeat(auto-fit,minmax(118px,1fr))}
.param-grid.lab-param-grid{grid-template-columns:repeat(auto-fit,minmax(158px,1fr))}
.param-tile{
  display:flex;flex-direction:column;gap:2px;min-width:0;
  padding:9px 11px;border:1px solid var(--line);border-radius:10px;background:var(--panel);
}
.param-label{font-size:.68rem;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:var(--ink-2)}
/* NILAI + SATUAN SATU BARIS (permintaan pemilik): "120/80 mmHg", "36,5 °C".
   `nowrap` menjaga satuan tidak turun ke baris bawah; bila petak sempit, huruf
   sedikit menyusut (clamp + cqi) alih-alih membungkus. */
.param-line{
  display:flex;align-items:baseline;gap:5px;min-width:0;
  flex-wrap:nowrap;white-space:nowrap;
  container-type:inline-size;
}
.param-value{
  font-size:clamp(.86rem,13.2cqi,1.06rem);font-weight:700;color:var(--ink-strong);
  line-height:1.25;font-variant-numeric:tabular-nums;white-space:nowrap;
}
.param-unit{font-size:.7rem;color:var(--ink-2);white-space:nowrap;flex:0 0 auto}
.param-line .param-tag{margin:0 0 0 2px;flex:0 0 auto}
.param-tile.is-empty{background:var(--tint-3)}
.param-tile.is-empty .param-value{color:var(--ink-3);font-weight:600}
.param-tag{
  align-self:flex-start;margin-top:4px;padding:1px 7px;border-radius:999px;
  font-size:.64rem;font-weight:700;letter-spacing:.03em;
  border:1px solid var(--line-strong);background:var(--tint-3);color:var(--ink-2);
}
.param-tag.is-on{background:var(--ok-bg);border-color:var(--ok-bd);color:var(--ok-fg)}
@media (max-width:760px){
  .reg-info{grid-template-columns:1fr;gap:12px}
  .param-grid.vital-param-grid{grid-template-columns:repeat(2,minmax(0,1fr))}
  .param-grid.lab-param-grid{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media (max-width:380px){
  .param-grid.vital-param-grid,
  .param-grid.lab-param-grid{grid-template-columns:1fr}
}

/* ═══════════════════════════════════════════════════════════════════════════
   CABANG & IZIN — daftar dokumen legal per cabang
   ═══════════════════════════════════════════════════════════════════════════ */
.lic-list{display:flex;flex-direction:column;gap:8px;min-width:0}
.lic-item{
  display:flex;flex-direction:column;gap:3px;min-width:0;
  padding:9px 11px;border:1px solid var(--line);border-radius:10px;background:var(--panel);
}
.lic-head{display:flex;align-items:center;justify-content:space-between;gap:8px;flex-wrap:wrap}
.lic-head strong{font-size:.85rem;color:var(--ink-strong)}
.lic-meta{display:flex;align-items:baseline;gap:8px;flex-wrap:wrap;min-width:0}
.lic-meta .mono{font-size:.85rem;font-weight:700}
.lic-item .inline-form{align-self:flex-start}
.lic-form{margin-top:4px}
.lic-actions{display:flex;justify-content:flex-end;gap:8px;margin-top:10px}
.branch-card .metric-row{grid-template-columns:repeat(auto-fit,minmax(120px,1fr))}

/* ═══════════════════════════════════════════════════════════════════════════
   RME DOKTER — KARTU AKSI REKAM MEDIS + PENANDA "TIDAK ADA RESEP DOKTER"
   · Tombol aksi utama (Simpan Rekam Medis · Rekam Medis Pasien · Batalkan Rekam
     Medis) dipindah ke kartu tersendiri DI BAWAH kartu e-Resep (permintaan
     pemilik) supaya selalu terjangkau tanpa menggulir balik ke atas form.
   · Pasien yang tidak diresepkan diberi penanda tegas di kepala & badan kartu
     e-Resep — bukan kartu kosong tanpa penjelasan.
   ═══════════════════════════════════════════════════════════════════════════ */
.enc-actions-card .enc-actions{
  display:flex;align-items:center;gap:10px;flex-wrap:wrap;
}
.enc-actions-card .enc-actions .btn{min-height:42px}
.enc-actions-card .enc-actions .btn-lg{min-height:46px;font-size:.95rem;padding:0 20px}
.enc-actions-card .enc-actions .inline-form{display:inline-flex;margin:0}
@media (max-width:640px){
  /* Di HP tombol utama selebar kartu supaya mudah ditekan. */
  .enc-actions-card .enc-actions{flex-direction:column;align-items:stretch}
  .enc-actions-card .enc-actions .btn,
  .enc-actions-card .enc-actions .inline-form,
  .enc-actions-card .enc-actions .inline-form .btn{width:100%}
}
/* Penanda tidak ada resep (chip di kepala kartu). */
.rx-empty{
  display:inline-flex;align-items:center;padding:2px 9px;border-radius:999px;
  font-size:.68rem;font-weight:800;letter-spacing:.04em;white-space:nowrap;
  border:1px dashed var(--line-strong);background:var(--tint-3);color:var(--ink-2);
}
/* Catatan di dalam badan kartu e-Resep saat belum ada resep. */
.rx-empty-note{
  margin:0;padding:10px 12px;border-radius:10px;font-size:.82rem;line-height:1.45;
  border:1px dashed var(--line-strong);background:var(--tint-2);color:var(--ink-2);
}
.rx-empty-note strong{color:var(--err-fg);letter-spacing:.02em}

/* ═══════════════════════════════════════════════════════════════════════════
   INPUT ANGKA = ANGKA BIASA (permintaan pemilik, SEMUA modul)
   · spinner bawaan browser disembunyikan (Chrome/Edge/Safari/Firefox),
   · tombol −/+ buatan aplikasi (.num-stepper) TIDAK dipakai lagi — tetap ada
     di CSS supaya sisa markup lama tidak merusak tata letak,
   · nilai tidak berubah karena scroll mouse (ditangani assets/app.js),
   · ukuran kolom, padding, dan rata kanan nominal tetap seperti sebelumnya.
   ═══════════════════════════════════════════════════════════════════════════ */
input[type=number]{
  -moz-appearance:textfield;
  appearance:textfield;
}
input[type=number]::-webkit-outer-spin-button,
input[type=number]::-webkit-inner-spin-button{
  -webkit-appearance:none;appearance:none;margin:0;display:none;
}
/* Sisa stepper lama (bila ada markup lama / cache) tidak ditampilkan. */
.num-stepper{display:none!important}
/* Tanpa stepper, kolom angka tidak butuh ruang tambahan di kanan. */
.num-wrap>input[type=number]{padding-right:12px!important}
/* Angka kuantitas tetap RATA KANAN seperti sebelumnya (dulu diatur oleh
   `.num-wrap>input[type=number]` yang kini tidak dibuat lagi). */
input[type=number]{text-align:right;font-variant-numeric:tabular-nums}
/* Kecuali yang memang teks (mis. tahun/durasi di kartu pengaturan) tetap kanan —
   tidak ada input angka yang butuh rata kiri pada aplikasi ini. */

/* Nomor RME pada kepala kartu pemeriksaan — sedikit lebih besar (permintaan pemilik). */
.lab-card .rme-code,
h2.rme-code{
  font-size:1.42rem;
  line-height:1.2;
  letter-spacing:.01em;
}
@media (max-width:640px){
  .lab-card .rme-code,
  h2.rme-code{font-size:1.24rem}
}

/* ═══════════════════════════════════════════════════════════════════════════
   POP-UP RANGKUMAN e-RESEP (permintaan pemilik)
   Rangkuman disusun sebagai TABEL yang jelas (bukan teks gabung):
     · "Obat disediakan"  : Obat · Zat aktif (biru) · Jumlah · Aturan pakai
     · "Racikan"          : kartu per racikan + tabel bahan
   Kaki kartu: [Batal] di KIRI, [Ya, Kirim e-Resep] di KANAN.
   ═══════════════════════════════════════════════════════════════════════════ */
.modal-card.rx-sum{
  width:min(760px,100%);
  display:flex;flex-direction:column;min-height:0;max-height:calc(100dvh - 40px);
}
.rx-sum-body{
  display:flex;flex-direction:column;gap:16px;
  padding:16px 20px;overflow-y:auto;min-height:0;
}
.rx-sum-sec{display:flex;flex-direction:column;gap:8px;min-width:0}
.rx-sum-sec-head{display:flex;align-items:baseline;justify-content:space-between;gap:10px}
.rx-sum-sec-head h4{margin:0;font-size:.82rem;font-weight:700;letter-spacing:.02em;color:var(--head-ink)}
.rx-sum-count{font-size:.72rem;font-weight:700;color:var(--ink-2);white-space:nowrap}
.rx-sum-tablewrap{
  border:1px solid var(--line);border-radius:10px;overflow-x:auto;background:var(--panel);
}
.rx-sum-table{width:100%;border-collapse:collapse;font-size:.82rem;min-width:0}
.rx-sum-table th,.rx-sum-table td{
  padding:8px 10px;border-bottom:1px solid var(--row-border);text-align:left;vertical-align:top;
}
.rx-sum-table thead th{
  font-size:.68rem;font-weight:700;letter-spacing:.05em;text-transform:uppercase;
  color:var(--ink-2);background:var(--tint-2);white-space:nowrap;
}
.rx-sum-table tbody tr:last-child td{border-bottom:0}
.rx-sum-table .num{text-align:right;white-space:nowrap;font-variant-numeric:tabular-nums}
.rx-sum-name{font-weight:600}
.rx-sum-dose{color:var(--ink-2)}
/* Satu kartu per racikan */
.rx-sum-cmp{
  display:flex;flex-direction:column;gap:6px;padding:10px 12px;
  border:1px solid var(--line);border-radius:10px;background:var(--tint-2);
}
.rx-sum-cmp-head{display:flex;align-items:baseline;justify-content:space-between;gap:10px;flex-wrap:wrap}
.rx-sum-cmp-head strong{font-size:.84rem;color:var(--head-ink)}
.rx-sum-meta{font-size:.74rem;font-weight:600;color:var(--ink-2)}
/* Kaki kartu: [Batal] kiri, [Ya, Kirim e-Resep] kanan */
.modal-foot.rx-sum-foot{align-items:center;gap:10px}
.rx-sum-note{margin-right:auto;font-size:.72rem;color:var(--ink-2)}
.rx-sum-actions{display:flex;gap:8px;align-items:center;flex-wrap:wrap}
@media (max-width:640px){
  .modal-card.rx-sum{width:100%;max-height:calc(100dvh - 16px)}
  .rx-sum-body{padding:14px}
  .rx-sum-foot{flex-direction:column-reverse;align-items:stretch}
  .rx-sum-actions{display:grid;grid-template-columns:1fr 1fr;width:100%}
  .rx-sum-actions .btn{width:100%;min-height:44px}
  .rx-sum-note{margin:0;text-align:center;order:2}
}

/* Kolom "Zat aktif" pada tabel e-Resep: HURUF BIRU (permintaan pemilik).
   Beberapa zat aktif tetap dalam SATU baris data (dipisah " + "). */
.ing-cell{
  display:inline-block;color:#2563EB;font-weight:700;line-height:1.35;
  overflow-wrap:anywhere;
}
.ing-cell.is-empty{color:var(--ink-3);font-weight:600}
html[data-theme="light"] .ing-cell{color:#1D4ED8}
table.data td.col-ing{min-width:120px}
/* Baris yang berbagi zat aktif sama (informasi visual sebelum disimpan). */
table.data tr.is-dup-ing > td{background:rgba(37,99,235,.07)}
table.data tr.is-dup-ing .ing-cell{text-decoration:underline dotted}

/* ═══════════════════════════════════════════════════════════════════════════
   e-RESEP — HARGA JUAL PER BARIS · CATATAN PER BARIS · KAKI KARTU RACIKAN
   (permintaan pemilik)
   · kolom "Harga jual" menampilkan harga satuan terpilih dalam satu baris obat;
   · kolom "Catatan" berada TEPAT SEBELUM tombol hapus (✕);
   · tombol [Hapus racikan] pindah ke KAKI kartu (pojok kanan bawah, sejajar
     dengan [+ Tambah Bahan]).
   ═══════════════════════════════════════════════════════════════════════════ */
#form-resep table.data td.col-price,
#form-resep table.data th.col-price{white-space:nowrap;text-align:right}
.price-cell{
  display:inline-block;font-variant-numeric:tabular-nums;font-weight:700;
  color:var(--ink-strong);white-space:nowrap;
}
.price-cell.is-empty{color:var(--ink-3);font-weight:600}
#form-resep table.data td.col-note{min-width:130px}
#form-resep table.data td.col-note input{width:100%;min-width:0}
#form-resep table.data th.col-qty{width:82px}

/* Kaki kartu racikan: [+ Tambah Bahan] di kiri, [Hapus racikan] di KANAN. */
.cmp-foot{
  display:flex;align-items:center;justify-content:space-between;
  gap:10px;flex-wrap:wrap;margin-top:8px;
}
.cmp-foot .cmp-del{margin-left:auto}
@media (max-width:640px){
  /* Di HP kedua tombol menumpuk selebar kartu agar mudah ditekan;
     [Hapus racikan] tetap di bawah (pojok kanan). */
  .cmp-foot{flex-direction:column;align-items:stretch}
  .cmp-foot .cmp-del{margin-left:0}
  .cmp-foot .btn{width:100%;min-height:42px}
}

/* ═══════════════════════════════════════════════════════════════════════════
   JEJAK AUDIT REKAM MEDIS & e-RESEP — BLOK KECIL, TERTUTUP BAWAAN
   (permintaan pemilik: perubahan terdokumentasi sistem, "rangkum kecil di bawah,
   posisi tertutup, dibuka jika perlu"). Dipakai `audit_log_block()`.
   ═══════════════════════════════════════════════════════════════════════════ */
.audit-log{
  margin-top:14px;border:1px solid var(--line);border-radius:var(--radius-sm);
  background:var(--tint-2);min-width:0;
}
.audit-log > summary{
  display:flex;align-items:center;gap:8px;flex-wrap:wrap;
  padding:9px 12px;cursor:pointer;list-style:none;font-size:.8rem;color:var(--ink-2);
}
.audit-log > summary::-webkit-details-marker{display:none}
.audit-log > summary::marker{content:""}
.audit-log > summary:hover{background:var(--tint-hover)}
.audit-log .al-title{font-weight:700;color:var(--ink);font-size:.83rem}
.audit-log .al-count{
  border:1px solid var(--line);border-radius:999px;padding:0 7px;
  font:700 .72rem/1.6 var(--mono);color:var(--ink);background:var(--tint-3);
}
.audit-log .al-last{color:var(--ink-3);font-size:.76rem;min-width:0;overflow-wrap:anywhere}
.audit-log .al-caret{
  margin-left:auto;flex:0 0 auto;width:0;height:0;
  border-left:4px solid transparent;border-right:4px solid transparent;
  border-top:5px solid var(--ink-3);
}
.audit-log[open] .al-caret{transform:rotate(180deg)}
.audit-log-body{padding:2px 12px 12px;border-top:1px dashed var(--line)}
.audit-log .al-hint{margin:9px 0 0;font-size:.76rem;color:var(--ink-3);line-height:1.45}
.audit-log .al-list{
  list-style:none;margin:10px 0 0;padding:0;display:flex;flex-direction:column;gap:10px;
  max-height:320px;overflow-y:auto;padding-right:4px;
}
.audit-log .al-item{
  border-left:2px solid var(--line);padding:0 0 0 10px;font-size:.79rem;min-width:0;
}
.audit-log .al-item.is-unlock{border-left-color:var(--amber)}
.audit-log .al-item.is-edit{border-left-color:var(--cyan)}
.audit-log .al-item.is-approve,.audit-log .al-item.is-siapkan{border-left-color:var(--cyan)}
.audit-log .al-item.is-tolak,.audit-log .al-item.is-batal,
.audit-log .al-item.is-tagihan_batal{border-left-color:var(--neg,#dc2626)}
.audit-log .al-item.is-serahkan{border-left-color:var(--pos,#16a34a)}
.audit-log .al-line{display:flex;align-items:baseline;gap:8px;flex-wrap:wrap}
.audit-log .al-act{font-weight:700;color:var(--ink-strong)}
.audit-log .al-time{margin-left:auto;font-family:var(--mono);font-size:.72rem;color:var(--ink-3);white-space:nowrap}
.audit-log .al-who{color:var(--ink-2);font-size:.75rem;overflow-wrap:anywhere}
.audit-log .al-note{color:var(--ink-2);margin-top:2px;overflow-wrap:anywhere}
.audit-log .al-changes{list-style:none;margin:5px 0 0;padding:0;display:flex;flex-direction:column;gap:3px}
.audit-log .al-changes li{
  display:flex;align-items:baseline;gap:6px;flex-wrap:wrap;
  font-size:.75rem;color:var(--ink-2);min-width:0;
}
.audit-log .al-k{font-weight:650;color:var(--ink);white-space:nowrap}
.audit-log .al-from{color:var(--ink-3);text-decoration:line-through;overflow-wrap:anywhere}
.audit-log .al-arrow{color:var(--ink-3)}
.audit-log .al-to{color:var(--ink-strong);overflow-wrap:anywhere}
@media (max-width:640px){
  .audit-log .al-time{margin-left:0}
  .audit-log .al-list{max-height:260px}
}

/* ══════════════════════════════════════════════════════════════════════
   PRODUK BUNDLING TINDAKAN (Master Tindakan) — tabel komponen BMHP/Alkes/Obat
   Satu baris per produk: Produk · Jumlah · Satuan · HJO · Subtotal · hapus.
   Di layar sempit tabel menjadi kartu bertingkat seperti tabel lain.
   ══════════════════════════════════════════════════════════════════════ */
/* ⚠️ `.sheet-body .table-wrap` memakai `content-visibility:auto` (tinggi
   "dikira-kira" 240px) sehingga tabel bundling yang panjang DIPOTONG dengan
   gulir internal — sama seperti kasus tabel rincian PB. Di sini dimatikan
   supaya semua baris bundling tampil utuh di dalam gulir kartu. */
.sheet-body .bundle-wrap,
.sheet-body .form-section:has(.bundle-table){
  content-visibility:visible;
  contain:none;
  overflow:visible;
  max-height:none;
  height:auto;
}
.bundle-wrap{overflow-x:auto}
table.data.bundle-table{width:100%;table-layout:fixed}
table.data.bundle-table .b-prod{width:auto;min-width:0}
table.data.bundle-table .b-qty{width:92px}
table.data.bundle-table .b-unit{width:108px}
table.data.bundle-table .b-money{width:118px;text-align:right;white-space:nowrap}
/* ⚠️ Kolom aksi WAJIB memuat DUA tombol (pensil edit + hapus ✕) yang disisipkan
   baris-terkunci. Dulu 52px sehingga tombol hapus KELUAR dari tabel
   (terukur: del.right 1383 > tabel 1343, gulir horizontal 40px). */
table.data.bundle-table .b-del{width:86px;text-align:center;white-space:nowrap}
table.data.bundle-table .b-del .row-act-line{display:inline-flex;align-items:center;
  justify-content:center;gap:6px;white-space:nowrap}
table.data.bundle-table .b-del .btn{flex:0 0 auto}
table.data.bundle-table .b-del .btn-sm{height:30px;min-height:30px;padding:0 7px}
table.data.bundle-table td .cs-btn{width:100%}
table.data.bundle-table .b-static{font-weight:650;color:var(--ink-strong);overflow-wrap:anywhere}
table.data.bundle-table td.b-money span{font-family:var(--mono);font-variant-numeric:tabular-nums;
  font-weight:650;color:var(--ink-strong)}
table.data.bundle-table td.b-qty input{text-align:right}
.chip.chip-bundle{border-color:var(--cyan);color:var(--ink-strong);font-weight:650}

/* ── MODE PRODUK BUNDLING: segmented [Bundling Tetap] [Bundling Opsional] ── */
/* ⚠️ `.stack` adalah flex-column (align-items:stretch) sehingga segmented ini
   DULU ikut melar sampai tepi kanan kartu. `align-self:flex-start` + width auto
   membuatnya hanya selebar isinya (permintaan pemilik: "jangan melebar ke kanan"). */
.segmented.bundle-mode{display:inline-flex;align-self:flex-start;width:auto;max-width:100%;
  gap:0;border:1px solid var(--line);border-radius:12px;
  overflow:hidden;background:var(--tint-3);margin:0 0 14px;flex-wrap:wrap}
.segmented .seg-item{position:relative;display:flex}
.segmented .seg-item input{position:absolute;opacity:0;width:0;height:0}
.segmented .seg-item span{display:flex;align-items:center;min-height:40px;padding:0 16px;
  font-weight:650;font-size:.86rem;color:var(--ink-2);cursor:pointer;white-space:nowrap;
  border-right:1px solid var(--line);transition:none}
.segmented .seg-item:last-child span{border-right:0}
.segmented .seg-item input:checked + span{background:var(--brand,#0E7C6B);color:#fff}
.segmented .seg-item input:focus-visible + span{outline:2px solid var(--cyan);outline-offset:-2px}
[data-bundle-section][hidden]{display:none!important}

/* ── TOMBOL PRODUK BUNDLING pada baris tindakan (RME) ── */
.act-bundle-line{display:flex;align-items:center;gap:6px;margin-top:6px}
.act-bundle-btn{display:inline-flex;align-items:center;gap:5px;min-height:32px;padding:0 9px}
.act-bundle-btn svg{width:16px;height:16px;fill:currentColor;flex:0 0 auto}
.act-bundle-count{font-family:var(--mono);font-weight:700;font-size:.76rem;
  min-width:16px;text-align:center}
/* Kartu pop-up bundling: mode `tetap` = baca-saja (tanpa tombol tambah/hapus). */
#sheet-act-bundle.is-readonly [data-bundle-add]{display:none}
#sheet-act-bundle.is-readonly .b-del{display:none}

/* ── BARIS TERKUNCI (barang + jumlah sudah terisi) → teks statis + pensil ── */
.is-row-locked .cs-btn{display:none!important}
.is-row-locked select.cs-native{display:none!important}
.row-static{display:block;padding:7px 9px;border:1px dashed transparent;border-radius:9px;
  font-weight:650;color:var(--ink-strong);overflow-wrap:anywhere;min-height:36px;line-height:1.3}
.row-unlock{flex:0 0 auto}
.row-unlock svg{width:15px;height:15px;fill:currentColor}
.is-row-finalized .row-static{background:var(--tint-3)}
@media (max-width:640px){
  /* Tetap selebar isinya (tidak melar), hanya tombolnya dibuat lebih mudah ditekan. */
  .segmented.bundle-mode{display:inline-flex;width:auto}
  .segmented .seg-item span{min-height:44px;font-size:.82rem;padding:0 12px}
}
/* Petunjuk bundling di lembar RME (di bawah dropdown tindakan dokter). */
.svc-bundle{display:block;margin-top:4px;font-size:.74rem;line-height:1.35;
  color:var(--ink-2);overflow-wrap:anywhere}
.svc-bundle[hidden]{display:none}
@media (max-width:900px){
  /* Tabel bundling ikut menjadi kartu bertingkat (label kolom di atas nilai). */
  table.data.bundle-table{min-width:0}
}

/* ══════════════════════════════════════════════════════════════════════
   TABEL TINDAKAN RME — KOLOM AKSI (Bundling · Edit · Hapus) + RESPONSIF
   Permintaan pemilik: tombol [Bundling] sejajar dengan tombol Edit (pensil)
   dan Hapus [✕] DI DALAM section Tindakan, dan kolom Jumlah/Tarif/Tindakan/
   Subtotal mengikuti lebar tabel (tidak ada kolom yang meluber).
   ══════════════════════════════════════════════════════════════════════ */
/* Sel aksi: satu baris, tidak membungkus, hanya selebar tombolnya. */
table.data.act-table th.col-act-aksi{text-align:center}
table.data.act-table td.col-act-aksi{white-space:nowrap;vertical-align:middle}
table.data.act-table td.col-act-aksi .act-row{
  display:flex;align-items:center;justify-content:center;gap:6px;flex-wrap:nowrap;
}
table.data.act-table td.col-act-aksi .act-row > form,
table.data.act-table td.col-act-aksi .act-row > .row-actions{display:contents}
table.data.act-table td.col-act-aksi .btn.icon-btn{
  flex:0 0 auto;width:34px;min-width:34px;height:34px;padding:0;
}
table.data.act-table td.col-act-aksi .act-bundle-btn{width:auto;min-width:38px;gap:4px}
table.data.act-table td.col-act-aksi .act-bundle-btn svg{width:15px;height:15px;flex:0 0 auto}
table.data.act-table td.col-act-aksi .act-bundle-count{
  font-family:var(--mono);font-size:.72rem;font-weight:700;line-height:1;
}
table.data.act-table td.col-act-item{min-width:0}
table.data.act-table td.col-act-item .cs-btn{width:100%;min-width:0}
table.data.act-table td.col-act-item > small{display:block;margin-top:3px}

/* Lebar kolom PROPORSIONAL (bukan persentase kaku) hanya di desktop:
   Tindakan mengambil SISA ruang, kolom uang cukup untuk "Rp 1.234.567". */
/* ⚠️ `table-layout:fixed` WAJIB di sini: dengan `auto`, lebar kolom mengikuti
   ISI sehingga tabel meluber (terukur 1024px: tabel 754px vs wadah 667px) saat
   tombol Bundling + pensil + hapus muncul. Dengan fixed, kolom "Tindakan"
   mengambil SISA ruang dan tabel selalu muat (responsif). */
@media (min-width:901px){
  table.data.act-table{table-layout:fixed;width:100%}
  table.data.act-table th.col-act-item{width:auto}
  table.data.act-table th.col-act-qty{width:86px}
  table.data.act-table th.col-act-money{width:126px}
  /* Aksi memuat [Bundling] + [pensil] + [✕] dalam satu baris (perlu ±112px). */
  table.data.act-table th.col-act-aksi{width:140px}
  table.data.act-table td.col-act-qty,
  table.data.act-table td.col-act-money{padding-left:6px;padding-right:6px}
  /* Input uang mengikuti lebar kolom, tidak boleh mendorong kolom lain. */
  table.data.act-table td.col-act-money .money-wrap,
  table.data.act-table td.col-act-money input{width:100%;min-width:0}
}
/* Layar 901–1180px: kolom uang & aksi dirapatkan supaya nama tindakan tetap lega
   dan tabel TIDAK perlu digeser ke samping. */
@media (min-width:901px) and (max-width:1180px){
  table.data.act-table th.col-act-qty{width:58px}
  /* Nominal "Rp 250.000" butuh ±104px pada layar 901–1180 (terukur terpotong 6px
     saat kolom hanya 96px). */
  table.data.act-table th.col-act-money{width:104px}
  table.data.act-table th.col-act-aksi{width:124px}
  table.data.act-table td.col-act-qty,
  table.data.act-table td.col-act-money{padding-left:4px;padding-right:4px}
  table.data.act-table td.col-act-aksi .act-row{gap:4px}
  table.data.act-table td.col-act-aksi .btn.icon-btn{width:30px;min-width:30px;height:30px}
  table.data.act-table td.col-act-aksi .act-bundle-btn{min-width:32px}
  table.data.act-table td.col-act-money .money-wrap{min-width:0}
  table.data.act-table td.col-act-money input{font-size:.86rem}
  table.data.act-table .money-prefix{left:6px;font-size:.7rem}
  table.data.act-table .money-wrap>input[data-money]{padding-left:26px!important}
}

/* BARIS TERKUNCI: teks statis satu baris (ellipsis bila nama panjang) —
   permintaan pemilik: tetap 1 baris selama lebar layar masih mendukung. */
.row-static{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}
.is-row-locked .row-static{display:block}
@media (max-width:900px){
  /* Kartu bertingkat: teks statis boleh membungkus (tidak ada ruang 1 baris). */
  .row-static{white-space:normal;overflow:visible;text-overflow:clip}
  table.data.act-table td.col-act-aksi .act-row{justify-content:flex-start;flex-wrap:wrap}
}

/* ── PENSIL EDIT + HAPUS: SATU BARIS di sel aksi tabel mana pun ─────────── */
td.row-act-cell{white-space:nowrap;width:1%}
.row-act-line{display:inline-flex;align-items:center;gap:6px;flex-wrap:nowrap}
.row-act-line .btn.icon-btn{flex:0 0 auto}
/* Tombol [Bundling] yang disembunyikan (mode Bundling Tetap) tidak boleh tampil
   walau kelas `.btn` memakai display:inline-flex. */
.act-bundle-btn[hidden]{display:none!important}

/* ══════════════════════════════════════════════════════════════════════
   TOMBOL AKSI BARIS TINDAKAN RME — RAMPING & TIDAK TUMPANG TINDIH
   [Bundling] + [pensil] + [✕] harus muat dalam kolom Aksi (±140px) dan
   tetap berada DI DALAM tabel pada semua lebar ≥901px (permintaan pemilik:
   "button terlihat jelas tanpa tumpang tindih, tanpa scroll ke samping").
   ══════════════════════════════════════════════════════════════════════ */
table.data.act-table td.col-act-aksi .act-row{gap:5px;flex-wrap:nowrap;justify-content:center}
table.data.act-table td.col-act-aksi .act-row > .btn,
table.data.act-table td.col-act-aksi .act-row > .row-act-line > .btn{
  flex:0 0 auto;min-width:0;height:32px;min-height:32px;padding:0 7px;font-size:.78rem;
  border-radius:9px;line-height:1;
}
table.data.act-table td.col-act-aksi .act-row .btn svg{width:14px;height:14px;min-width:14px}
table.data.act-table td.col-act-aksi .act-bundle-btn{padding:0 6px;gap:4px;min-width:34px}
table.data.act-table td.col-act-aksi .act-bundle-count{font-size:.7rem;min-width:11px}
table.data.act-table td.col-act-aksi .row-act-line{display:inline-flex;align-items:center;gap:5px;flex-wrap:nowrap}
table.data.act-table td.col-act-aksi .row-static + .row-act-line,
table.data.act-table td.col-act-item .row-static{margin-top:0}
/* Tombol hapus di dalam kolom aksi tidak boleh melebar mengikuti `.btn-danger`. */
table.data.act-table td.col-act-aksi .btn-danger{width:32px;padding:0}
/* Laptop 901–1180px: tombol aksi dirapatkan sedikit lagi supaya kolom "Tindakan"
   tidak terlalu sempit dan semuanya tetap di dalam tabel. */
@media (min-width:901px) and (max-width:1180px){
  table.data.act-table td.col-act-aksi .act-row{gap:4px}
  table.data.act-table td.col-act-aksi .act-bundle-btn{padding:0 5px;min-width:30px;gap:3px}
  table.data.act-table td.col-act-aksi .btn-danger,
  table.data.act-table td.col-act-aksi .row-unlock{width:30px;padding:0}
  table.data.act-table td.col-act-aksi .act-row > .btn,
  table.data.act-table td.col-act-aksi .act-row > .row-act-line > .btn{height:30px;min-height:30px}
}

/* ══════════════════════════════════════════════════════════════════════
   e-RESEP — RINCIAN OBAT (permintaan pemilik)
   · zat aktif di bawah nama obat: 1 baris, huruf lebih kecil, BIRU;
   · tabel racikan: satu baris judul per sediaan (jumlah kemasan sekali saja);
   · kolom Jumlah/Harga mengikuti lebar tabel (tidak meluber).
   ══════════════════════════════════════════════════════════════════════ */
.ing-line{margin-top:2px;font-size:.72rem;line-height:1.25;color:#2563EB;font-weight:650;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}
html[data-theme="light"] .ing-line{color:#1D4ED8}
@media (max-width:900px){
  /* Di HP tabel sudah menjadi kartu bertingkat → zat aktif boleh membungkus. */
  .ing-line{white-space:normal;overflow:visible;text-overflow:clip}
}
table.data.rx-plain-table,
table.data.rx-cmp-table{table-layout:auto}
table.data.rx-plain-table .col-qty,
table.data.rx-cmp-table .col-qty{width:1%;white-space:nowrap;text-align:right}
table.data.rx-plain-table .col-price,
table.data.rx-cmp-table .col-price{width:1%;white-space:nowrap;text-align:right}
.rx-cmp-head-cell{vertical-align:top;background:var(--tint-3)}
.rx-cmp-head-cell .cmp-pack{font-family:var(--mono);font-weight:700;margin-top:2px;color:var(--ink-strong)}
tr.cmp-head-row > td{background:var(--tint-3);font-size:.86rem;border-top:2px solid var(--line)}
.rx-cmp-head-cell .cmp-signa{margin-top:2px;font-size:.78rem;color:var(--ink-2);font-weight:650}

/* ══════════════════════════════════════════════════════════════════════
   OBAT RACIKAN — SATU BLOK PER RACIKAN (permintaan pemilik)
   Satu racikan boleh berisi beberapa obat; satu resep boleh berisi beberapa
   racikan (jenis sediaan berbeda). Bentuk:
     | Racikan 1
     | [Puyer / Serbuk] • [10 Bungkus]
     | 3 x 1 Sesudah Makan
     | Dextamine Kaplet            | 10 Tablet | Rp 2.398 | Catatan
   ══════════════════════════════════════════════════════════════════════ */
table.data.rx-cmp-table{margin-bottom:0}
table.data.rx-cmp-table tbody.rx-cmp-group + tbody.rx-cmp-group > tr.rx-cmp-head-row > td{
  border-top:2px solid var(--line);
}
tr.rx-cmp-head-row > td{background:var(--tint-3);padding:10px 12px}
/* Satu baris: Racikan 1 • [Sediaan] • [Jumlah kemasan] */
.rx-cmp-line{display:flex;align-items:center;gap:7px;flex-wrap:wrap}
.rx-cmp-title{font-weight:800;font-size:.92rem;color:var(--head-ink);letter-spacing:.2px;white-space:nowrap}
.rx-cmp-meta{display:flex;align-items:center;gap:6px;flex-wrap:wrap;margin-top:5px}
.rx-chip{display:inline-flex;align-items:center;gap:4px;padding:3px 9px;border-radius:999px;
  border:1px solid var(--line);background:var(--panel);font-size:.78rem;font-weight:700;
  color:var(--ink-strong);white-space:nowrap}
.rx-dot{color:var(--ink-3);font-weight:800}
/* "Aturan Pakai : 3 x 1 Sesudah Makan" — baris kedua di bawah judul racikan. */
.rx-cmp-signa{margin-top:5px;display:flex;align-items:baseline;gap:5px;flex-wrap:wrap;
  font-weight:700;color:var(--ink-strong)}
.rx-cmp-signa .rx-signa-label{font-size:.76rem;font-weight:700;letter-spacing:.3px;
  text-transform:uppercase;color:var(--ink-2)}
.rx-cmp-signa .rx-signa-sep{color:var(--ink-3)}
.rx-cmp-signa strong{font-weight:800}
.rx-cmp-note{margin-top:3px;font-size:.78rem;color:var(--ink-2)}
tr.rx-cmp-item > td{padding-top:9px;padding-bottom:9px}
tr.rx-cmp-item > td:first-child{padding-left:18px}
/* Kolom tabel rincian: jumlah & harga hanya selebar isinya. */
table.data.rx-plain-table .col-qty,
table.data.rx-cmp-table .col-qty,
table.data.rx-plain-table .col-price,
table.data.rx-cmp-table .col-price{width:1%;white-space:nowrap;text-align:right}
table.data.rx-plain-table .col-price,
table.data.rx-cmp-table .col-price{font-variant-numeric:tabular-nums;font-weight:650}
@media (max-width:900px){
  /* Kartu bertingkat: judul racikan tetap tampil penuh & tidak terpotong. */
  table.data.rx-cmp-table .rx-cmp-head-row > td{display:block}
  tr.rx-cmp-item > td:first-child{padding-left:10px}
}

/* ── KARTU PERSIAPAN & PENYERAHAN OBAT ── */
.rx-prep-card .rx-staff-grid{margin-bottom:14px}
.rx-prep-card .field > select{max-width:100%}
.rx-prep-foot{display:flex;flex-wrap:wrap;gap:10px;align-items:center}
.rx-approve-actions{display:flex;gap:10px;flex-wrap:wrap;align-items:center}
.rx-approve-actions .btn{flex:1 1 auto;min-width:150px;justify-content:center}
@media (max-width:640px){
  .rx-approve-actions .btn{flex:1 1 100%}
  .rx-prep-foot .btn{flex:1 1 100%}
}

/* ══════════════════════════════════════════════════════════════════════
   KARTU e-RESEP — JARAK & TABEL YANG TIDAK MELEBAR KE KANAN
   Permintaan pemilik:
     · beri JARAK antara tabel Obat Non-Racik dan Obat Racikan;
     · tabel obat/racikan harus muat dalam satu layar (tidak melebar ke kanan)
       tetapi kolomnya tetap mengikuti isi (responsif).
   ══════════════════════════════════════════════════════════════════════ */
/* Jarak antar kartu rincian e-Resep (komponen bersama dipakai di 2 halaman). */
.rx-readonly-items > .lab-card + .lab-card{margin-top:18px}
.rx-readonly-items > .lab-card{margin-bottom:0}
.rx-plain-card + .rx-cmp-card{margin-top:18px}
.rx-cmp-card{margin-top:18px}
/* Kartu rincian di dalam kartu lain (lembar pemeriksaan) dibuat lebih ringkas. */
.rx-readonly-items .lab-card{background:var(--panel)}
.rx-readonly-items .lab-card .card-head{margin-bottom:8px}

/* Zat aktif: kecil, biru, di bawah nama obat (bukan kolom sendiri). */
.ing-line{font-size:.7rem;line-height:1.3;margin-top:2px;color:#2563EB;font-weight:600;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}
html[data-theme="light"] .ing-line{color:#1D4ED8}
.ing-cell.is-empty{color:var(--ink-3)}

/* Tabel e-Resep (form dokter): layout tetap supaya TIDAK melebar ke kanan, dengan
   lebar kolom PROPORSIONAL terhadap lebar tabel.
   Permintaan pemilik: kolom **Obat/Alkes** (beserta baris zat aktif di bawahnya)
   tidak boleh mendominasi tabel, sedangkan kolom Jumlah, Satuan, Aturan pakai,
   Harga jual, dan Catatan harus tetap terbaca utuh.
   Karena tabel memakai `table-layout:fixed`, kolom teks diberi PERSENTASE (ikut
   lebar tabel) dan hanya kolom aksi yang memakai px (2 tombol 30px). Kolom
   Obat/Alkes `width:auto` menerima SISA ruang — terukur 27–29% pada 1280–1440px
   (sebelumnya 40% di 1440px). */
table.data.rx-form-table{table-layout:fixed;width:100%;min-width:0}
table.data.rx-form-table .col-drug{width:auto;min-width:0}
table.data.rx-form-table .col-qty{width:7%}
table.data.rx-form-table .col-unit{width:10%}
table.data.rx-form-table .col-signa{width:21%}
table.data.rx-form-table .col-price{width:14%;text-align:right;white-space:nowrap}
table.data.rx-form-table .col-note{width:14%}
/* Kolom Aturan pakai: label combobox BOLEH MEMBUNGKUS (2 baris) supaya aturan
   pakai tampil UTUH — tidak dipotong "…" walau kolomnya sempit. Tinggi baris
   tidak bertambah karena sel Obat/Alkes (dropdown + zat aktif) sudah paling tinggi. */
table.data.rx-form-table .col-signa .cs-btn{align-items:center;height:auto;min-height:38px;padding-block:6px}
table.data.rx-form-table .col-signa .cs-btn .cs-label{
  white-space:normal;overflow:visible;text-overflow:clip;line-height:1.25;font-weight:600;
}
/* Combobox di dalam tabel e-Resep dirapatkan (padding 41px → 30px) supaya label
   pendek seperti "kapsul"/"tablet" TIDAK terpotong di kolom yang ramping. */
table.data.rx-form-table td .cs-btn{padding:9px 22px 9px 8px}
table.data.rx-form-table td .cs-btn .cs-caret{right:5px;width:14px;height:14px}
/* Aturan pakai: chip satuan di samping dropdown MENGULANG informasi yang sudah
   ada di labelnya ("3 × 1 Sesudah Makan (1 tablet)") dan memakan ±66px kolom —
   akibatnya dropdown hanya menyisakan ±71px dan labelnya terpotong. Di tabel
   formulir ini chip tersebut disembunyikan supaya label aturan pakai tampil utuh;
   di form lain (tanda vital dsb.) suffix tetap seperti semula. */
table.data.rx-form-table .addon-field > .addon-suffix{display:none}
/* Kolom aksi baris e-Resep memuat tombol hapus [X] DAN (setelah baris terisi)
   ikon pensil edit. Keduanya WAJIB tetap DI DALAM tabel — dulu kolomnya 38px
   sehingga tombol KELUAR 54px dari tepi tabel (tombol bahkan tidak bisa ditekan).
   Lebar 78px = pensil 30 + gap 4 + hapus 30 + padding sel. */
table.data.rx-form-table .col-x{width:78px}
table.data.rx-form-table td.col-x{padding-left:2px;padding-right:4px;text-align:center;overflow:visible;
  white-space:nowrap}
table.data.rx-form-table td.col-x .row-act-line{gap:4px;justify-content:center}
table.data.rx-form-table td.col-x .btn{width:30px;min-width:30px;height:30px;min-height:30px;padding:0}
table.data.rx-form-table td.col-x .btn svg{width:15px;height:15px}
table.data.rx-form-table td .cs-btn{width:100%;min-width:0}
table.data.rx-form-table td{overflow:hidden}
table.data.rx-form-table td input,
table.data.rx-form-table td select{max-width:100%}
/* Jendela 901–1180px tidak cukup untuk 7 kolom (kalau dipaksa, ada kolom yang
   terpotong atau tabel harus digeser). Di rentang itu baris e-Resep disusun
   menjadi KARTU BERTINGKAT — setiap isian diberi label kolomnya, lebarnya penuh,
   jadi tidak ada yang terpotong dan tidak ada gulir horizontal.
   Aturan ini KHUSUS tabel formulir e-Resep (#form-resep); tabel rincian lain
   tetap seperti semula. */
@media (min-width:901px) and (max-width:1100px){
  #form-resep table.data.rx-form-table{
    display:block;width:100%;min-width:0;border-collapse:separate;border-spacing:0;
  }
  #form-resep table.data.rx-form-table thead{display:none}
  #form-resep table.data.rx-form-table tbody{display:block;width:auto}
  #form-resep table.data.rx-form-table tbody tr{
    display:block;width:auto;margin:0 0 10px;padding:10px 12px;
    border:1px solid var(--line);border-radius:var(--radius-sm);background:var(--tint-3);
  }
  #form-resep table.data.rx-form-table tbody tr:last-child{margin-bottom:0}
  #form-resep table.data.rx-form-table td{
    display:grid;grid-template-columns:minmax(0,132px) minmax(0,1fr);
    gap:4px 12px;align-items:center;width:auto;padding:5px 0;border:0;
    border-bottom:1px dashed var(--row-border);overflow:visible;text-align:left;
  }
  #form-resep table.data.rx-form-table tr > td:last-child{border-bottom:0}
  #form-resep table.data.rx-form-table td::before{
    font-size:.65rem;font-weight:700;letter-spacing:.05em;text-transform:uppercase;
    color:var(--ink-2);
  }
  #form-resep table.data.rx-form-table td.col-qty::before{content:"Jumlah"}
  #form-resep table.data.rx-form-table td.col-unit::before{content:"Satuan"}
  #form-resep table.data.rx-form-table td.col-signa::before{content:"Aturan pakai"}
  #form-resep table.data.rx-form-table td.col-price::before{content:"Harga jual"}
  #form-resep table.data.rx-form-table td.col-note::before{content:"Catatan"}
  #form-resep table.data.rx-form-table tbody[data-line-rows] td.col-drug::before{content:"Obat / alkes"}
  #form-resep table.data.rx-form-table tbody[data-cmp-rows] td.col-drug::before{content:"Bahan obat"}
  /* Sel Obat/Alkes memuat dropdown + baris zat aktif → label di ATAS, isian penuh. */
  #form-resep table.data.rx-form-table td.col-drug{display:block}
  #form-resep table.data.rx-form-table td.col-drug::before{display:block;margin-bottom:4px}
  /* Sel aksi: label tidak perlu, tombol rata kiri & tetap nyaman ditekan. */
  #form-resep table.data.rx-form-table td.col-x{display:block;padding-top:8px}
  #form-resep table.data.rx-form-table td.col-x::before{content:none}
  #form-resep table.data.rx-form-table td.col-x .row-act-line{justify-content:flex-start;gap:8px}
  #form-resep table.data.rx-form-table td.col-x .btn{width:34px;min-width:34px;height:34px;min-height:34px}
  #form-resep table.data.rx-form-table td.col-x .btn svg{width:16px;height:16px}
  /* Nominal tetap rata kanan, isian selebar kartu. */
  #form-resep table.data.rx-form-table td.col-price{justify-items:end}
  #form-resep table.data.rx-form-table td.col-price .price-cell{white-space:nowrap}
  /* Isian mengisi kolom kartu (input angka tidak lagi selebar bawaan 87px). */
  #form-resep table.data.rx-form-table td > input,
  #form-resep table.data.rx-form-table td > select,
  #form-resep table.data.rx-form-table td > .num-wrap,
  #form-resep table.data.rx-form-table td > .addon-field{width:100%;max-width:none}
  #form-resep table.data.rx-form-table td .num-wrap > input{width:100%}
}
/* ≤900px: tabel e-Resep memakai tata letak KARTU BERTINGKAT global. Lebar kolom
   berbasis persentase/px di atas TIDAK boleh ikut berlaku di sini — tanpa aturan
   ini setiap sel menyusut selebar persentase (dropdown aturan pakai jadi 32px dan
   teksnya membungkus ke bawah). Di mode kartu semua isian selebar kartu. */
@media (max-width:900px){
  table.data.rx-form-table{table-layout:auto;min-width:0}
  table.data.rx-form-table .col-drug,
  table.data.rx-form-table .col-qty,
  table.data.rx-form-table .col-unit,
  table.data.rx-form-table .col-signa,
  table.data.rx-form-table .col-price,
  table.data.rx-form-table .col-note,
  table.data.rx-form-table .col-x{width:auto}
  table.data.rx-form-table td{overflow:visible}
  table.data.rx-form-table td > input,
  table.data.rx-form-table td > select,
  table.data.rx-form-table td > .num-wrap,
  table.data.rx-form-table td > .addon-field{width:100%}
  table.data.rx-form-table td .num-wrap > input{width:100%}
}

/* Jendela 1101–1180px masih cukup untuk 7 kolom dengan lebar MINIMUM yang
   terbaca (tidak ada label/nominal terpotong, tidak perlu digeser). */
@media (min-width:1101px) and (max-width:1180px){
  table.data.rx-form-table{min-width:720px}
  table.data.rx-form-table .col-qty{width:66px}
  table.data.rx-form-table .col-unit{width:88px}
  table.data.rx-form-table .col-signa{width:140px}
  table.data.rx-form-table .col-price{width:114px}
  table.data.rx-form-table .col-note{width:110px}
  table.data.rx-form-table .col-x{width:70px}
  table.data.rx-form-table td.col-x .btn{width:28px;min-width:28px;height:28px;min-height:28px}
  table.data.rx-form-table td.col-x .btn svg{width:14px;height:14px}
}
/* Penanda wajib pada judul kolom Aturan pakai. */
.req-mark{color:#dc2626;font-weight:800}

/* Tabel rincian racikan (baca-saja): tetap di dalam layar. */
table.data.rx-cmp-table,table.data.rx-plain-table{table-layout:auto;min-width:0;width:100%}
table.data.rx-cmp-table td,table.data.rx-plain-table td{overflow-wrap:anywhere}

/* ── ANTREAN PASIEN (menu Pemeriksaan Dokter) ───────────────────────────── */
.queue-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(320px,1fr));gap:18px}
.queue-card{display:flex;align-items:center;justify-content:space-between;gap:14px;padding:14px 16px}
.queue-main{display:flex;align-items:center;gap:12px;min-width:0}
.queue-no{font-size:1.06rem;font-weight:800;white-space:nowrap}
.queue-info{display:flex;flex-direction:column;gap:2px;min-width:0}
.queue-info strong{overflow-wrap:anywhere}
.queue-actions{display:flex;align-items:center;gap:8px;flex:0 0 auto}
.btn-stetho{gap:6px;min-height:38px;padding:0 12px}
.btn-stetho svg{width:17px;height:17px;flex:0 0 auto}
@media (max-width:640px){
  .queue-grid{grid-template-columns:1fr;gap:14px}
  .queue-card{flex-wrap:wrap}
  .queue-actions{width:100%;justify-content:space-between}
  .btn-stetho{flex:1 1 auto;justify-content:center;min-height:42px}
}

/* Zat aktif yang DUPLIKAT disorot MERAH pada pop-up peringatan (permintaan pemilik). */
.ing-dup{color:#dc2626;font-weight:800}
.notice-list .ing-dup{color:#dc2626;font-weight:800;text-decoration:underline}
/* Baris antrean "belum diperiksa" di daftar Pemeriksaan (satu tabel). */
#form-resep table.rx-form-table td.col-x .row-act-line{flex-wrap:nowrap}
.queue-card-inline .btn-stetho{min-height:38px}
/* Identitas tindakan khusus (permintaan pemilik): tanda pada kartu/tabel. */
.chip.chip-noexam{border-color:var(--amber);color:var(--ink-strong);font-weight:650}
.chip.chip-jasa{border-color:var(--cyan);color:var(--ink-strong);font-weight:650}
/* Tabel "Tanpa Pemeriksaan Dokter" (Pendaftaran). */
table.data.ne-table .ne-pick{width:52px;text-align:center}
table.data.ne-table tr.is-picked td{background:var(--tint-3)}
table.data.ne-table tbody label{cursor:pointer}
.jasa-card .jasa-table td.col-num{white-space:nowrap;text-align:right;font-variant-numeric:tabular-nums}
.jasa-card .jasa-switch{margin:0}

/* ══════════════════════════════════════════════════════════════════════════
   ROLE / PERAN — MATRIKS IZIN & KONTROL DATA/KPI (rancang ulang)
   Permintaan pemilik:
     · hak akses bisa benar-benar diubah per role (lihat perbaikan seed_roles),
     · administrator bisa menentukan DATA (bagian halaman) yang tampil,
     · pengaturan KPI ringkas — bukan daftar raksasa.
   Bentuk baru: kolom cari + penghitung hidup, satu BARIS per menu, chip kecil
   per pilihan, sakelar "Semua" per menu. Semua tetap <input checkbox> biasa
   sehingga berfungsi tanpa JavaScript.
   ══════════════════════════════════════════════════════════════════════════ */
[data-perm-item][hidden],
[data-vis-chip][hidden],
[data-vis-item][hidden],
.perm-sec[hidden]{display:none!important}

.perm-tools,.vis-tools{
  display:flex;align-items:flex-end;gap:12px;flex-wrap:wrap;
  padding:10px 12px;margin:2px 0 12px;
  border:1px solid var(--line-strong);border-radius:var(--radius-sm);
  background:var(--tint-3);
}
.perm-tools .field,.vis-tools .field{margin:0;flex:1 1 260px;min-width:0}
.perm-tools .badge,.vis-tools .badge{white-space:nowrap}
.perm-tools .btn.is-on{background:var(--nav-active-bg);border-color:var(--nav-active-border);color:var(--head-ink)}
.perm-sec-tools{display:inline-flex;align-items:center;gap:6px;flex-wrap:wrap}
.perm-sec .perm-grid{gap:10px}
.perm-item{padding:8px 10px;border:1px solid var(--line);border-radius:10px;background:var(--panel)}
.perm-item span strong{display:block;font-size:.82rem;line-height:1.25}
.perm-item span small{font-size:.72rem;line-height:1.25}

/* Satu baris per menu pada panel Kontrol Data & KPI */
.vis-row{
  display:grid;grid-template-columns:minmax(140px,208px) minmax(0,1fr);
  gap:10px 14px;align-items:start;
  padding:10px 0;border-bottom:1px dashed var(--row-border);
}
.vis-row:last-child{border-bottom:0}
.vis-row-head{display:flex;align-items:center;gap:8px;flex-wrap:wrap;min-width:0}
.vis-row-head > strong{font-size:.84rem;color:var(--head-ink)}
.vis-row-count{
  font-size:.7rem;font-weight:700;font-variant-numeric:tabular-nums;
  color:var(--ink-2);padding:1px 7px;border-radius:999px;border:1px solid var(--line);
  background:var(--tint-2);white-space:nowrap;
}
.vis-row-all{margin:0}
.vis-row-all span{font-size:.72rem;font-weight:600}
.vis-chips{display:flex;flex-wrap:wrap;gap:6px;min-width:0}
.vis-chip{
  display:inline-flex;align-items:center;gap:6px;
  padding:4px 9px;border-radius:999px;border:1px solid var(--line);
  background:var(--tint-2);font-size:.76rem;line-height:1.2;cursor:pointer;
  max-width:100%;
}
.vis-chip input{margin:0;flex:0 0 auto;width:15px;height:15px}
.vis-chip span{overflow-wrap:anywhere}
.vis-chip:has(input:checked){background:var(--nav-active-bg);border-color:var(--nav-active-border);color:var(--head-ink);font-weight:650}
.vis-scope{margin-bottom:12px}
.vis-reset{margin-top:12px}
@media (max-width:760px){
  .vis-row{grid-template-columns:1fr}
  .vis-chip{font-size:.74rem}
  .perm-tools .btn,.vis-tools .btn{flex:1 1 auto;min-height:40px}
}

/* ══════════════════════════════════════════════════════════════════════════
   KARTU KPI MINIMALIS (permintaan pemilik)
   Kartu ringkasan dibuat lebih KECIL & lapang: angka tetap menonjol (target
   tetap terbaca), label ringkas, tanpa bayangan besar. Ukuran huruf angka
   memakai container query supaya nominal panjang tetap utuh (tidak terpotong
   dan tidak menggeser halaman).
   ══════════════════════════════════════════════════════════════════════════ */
.kpi-grid.compact{grid-template-columns:repeat(auto-fit,minmax(min(168px,100%),1fr));gap:12px}
.lab-card.kpi{padding:11px 13px;gap:1px;border-radius:12px}
.kpi-grid .kpi-label{
  font-size:.66rem;letter-spacing:.07em;font-weight:700;
  white-space:normal;overflow:visible;text-overflow:clip;line-height:1.2;
}
.kpi-grid .kpi-value{font-size:clamp(.98rem,11.6cqi,1.34rem);line-height:1.18;margin-top:1px}
.kpi-grid .kpi-foot{font-size:.68rem;line-height:1.25}
@media (max-width:640px){
  .kpi-grid.compact{grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}
  .lab-card.kpi{padding:10px 11px}
  .kpi-grid .kpi-label{font-size:.64rem}
  .kpi-grid .kpi-value{font-size:clamp(.92rem,12cqi,1.18rem)}
  .kpi-grid .kpi-foot{font-size:.66rem}
}

/* ══════════════════════════════════════════════════════════════════════════
   PENDAFTARAN — BAGIAN "TANPA PEMERIKSAAN DOKTER" (toggle di formulir)
   Permintaan pemilik: bukan lagi kartu/menu tersendiri, tetapi satu bagian
   pada formulir [+ Pendaftaran Baru] dengan sakelar Aktif/Nonaktif (bawaan
   NONAKTIF). Tabel tindakan memakai dropdown pencarian (konsep modul RME).
   ══════════════════════════════════════════════════════════════════════════ */
.ne-section.is-off{border-color:var(--line)}
.ne-body.is-off{display:none}
.ne-section .ne-toggle{margin:0}
.ne-section .ne-toggle span{font-size:.78rem;font-weight:650}
.ne-section .ne-body{margin-top:6px}
.ne-table .ne-qty{width:104px}
.ne-table .ne-price{width:132px;text-align:right;white-space:nowrap}
.ne-table .ne-x{width:56px;text-align:center}
.ne-table td .cs-btn{width:100%;min-width:0}
.ne-table td.ne-price .price-cell{white-space:nowrap}
@media (max-width:900px){
  /* Tabel sudah menjadi kartu bertingkat; lebar kolom tidak berlaku lagi. */
  .ne-table .ne-qty,.ne-table .ne-price,.ne-table .ne-x{width:auto}
}

/* ══════════════════════════════════════════════════════════════════════════
   e-RESEP — ZAT AKTIF TAMPIL PENUH & PROPORSI KOLOM (permintaan pemilik)
   ──────────────────────────────────────────────────────────────────────────
   1) ZAT AKTIF tidak lagi dipotong "…": teks membungkus penuh (full text
      wrapping). Dulu `.ing-line` memakai `white-space:nowrap` +
      `text-overflow:ellipsis`, sehingga nama zat aktif panjang terpotong.
   2) PROPORSI KOLOM: kolom Obat/Alkes (beserta zat aktif di bawahnya) tidak
      lagi mendominasi tabel — lebarnya dipatok PERSENTASE, sehingga Jumlah,
      Satuan, Aturan pakai (+ chip satuan), Harga jual, dan Catatan tetap
      tampil utuh. Kolom aksi tetap px karena berisi 2 tombol ikon.
   3) CHIP SATUAN pada kolom Aturan pakai DITAMPILKAN kembali (permintaan
      pemilik) — dulu disembunyikan karena memakan ruang.
   ══════════════════════════════════════════════════════════════════════════ */
.ing-line{
  white-space:normal!important;overflow:visible!important;text-overflow:clip!important;
  overflow-wrap:anywhere;word-break:break-word;max-width:100%;
  font-size:.7rem;line-height:1.32;
}
.ing-cell{white-space:normal;overflow-wrap:anywhere}

table.data.rx-form-table{table-layout:fixed;width:100%;min-width:0}
/* ⚠️ Selector WAJIB `table.data.rx-form-table thead th.col-…` (0,3,2): kelas
   `.col-num` dipasang otomatis `proportionTable()` untuk kolom "Jumlah" &
   "Harga jual" dan aturannya `table.data th.col-num{width:1%}` (0,2,1) —
   tanpa spesifisitas lebih tinggi, lebar persentase di bawah DIABAIKAN
   (terukur: kolom Jumlah melebar 21% dan kolom aksi 20%). */
/* Dua tingkat (diukur ulang dengan harga besar "Rp 1.188.894" + chip satuan
   panjang): pada jendela sempit kolom Harga & aksi butuh lebih banyak ruang,
   kolom Satuan/Obat sedikit dikurangi. Semua kombinasi diuji 0 pemotongan. */
#form-resep table.data.rx-form-table thead th.col-drug{width:24%;min-width:0}
#form-resep table.data.rx-form-table thead th.col-qty{width:7%}
#form-resep table.data.rx-form-table thead th.col-unit{width:10%}
#form-resep table.data.rx-form-table thead th.col-signa{width:25%}
#form-resep table.data.rx-form-table thead th.col-price{width:12%}
#form-resep table.data.rx-form-table thead th.col-note{width:13%}
#form-resep table.data.rx-form-table thead th.col-x{width:9%}
@media (min-width:901px) and (max-width:1300px){
  #form-resep table.data.rx-form-table thead th.col-drug{width:23%}
  #form-resep table.data.rx-form-table thead th.col-unit{width:9%}
  #form-resep table.data.rx-form-table thead th.col-signa{width:24%}
  #form-resep table.data.rx-form-table thead th.col-price{width:14%}
  #form-resep table.data.rx-form-table thead th.col-note{width:13%}
  #form-resep table.data.rx-form-table thead th.col-x{width:10%}
}
/* ── TABEL RACIKAN (6 kolom: tanpa Aturan pakai) ──────────────────────────
   Persentase di atas disusun untuk 7 kolom; pada tabel 6 kolom sisa ruangnya
   jatuh ke kolom pertama sehingga "Bahan obat" melebar 32% (terukur). Karena
   itu tabel racikan punya profilnya sendiri. */
#form-resep table.data.rx-cmp-form-table thead th.col-drug{width:30%}
#form-resep table.data.rx-cmp-form-table thead th.col-qty{width:8%}
#form-resep table.data.rx-cmp-form-table thead th.col-unit{width:12%}
#form-resep table.data.rx-cmp-form-table thead th.col-price{width:15%}
#form-resep table.data.rx-cmp-form-table thead th.col-note{width:25%}
#form-resep table.data.rx-cmp-form-table thead th.col-x{width:10%}
@media (min-width:901px) and (max-width:1300px){
  #form-resep table.data.rx-cmp-form-table thead th.col-drug{width:28%}
  #form-resep table.data.rx-cmp-form-table thead th.col-unit{width:11%}
  #form-resep table.data.rx-cmp-form-table thead th.col-price{width:17%}
  #form-resep table.data.rx-cmp-form-table thead th.col-note{width:24%}
}
/* Kolom Jumlah: isian mengisi sel (tidak terpotong / tidak menonjol keluar). */
#form-resep table.data.rx-form-table td.col-qty input{width:100%;min-width:0;text-align:right}
/* Aturan pakai: dropdown + CHIP SATUAN sejajar; chip tidak memotong label. */
table.data.rx-form-table .addon-field{display:flex;align-items:center;gap:6px;min-width:0}
table.data.rx-form-table .addon-field > select{flex:1 1 auto;min-width:0}
table.data.rx-form-table .addon-field > .addon-suffix{
  display:inline-flex;flex:0 0 auto;align-items:center;
  font-size:.74rem;font-weight:650;color:var(--ink-2);white-space:nowrap;
}
/* Nama obat & zat aktif boleh membungkus; tidak ada teks yang terpotong. */
table.data.rx-form-table td.col-drug{overflow:visible}
table.data.rx-form-table td.col-drug .ing-line{display:block}

/* ≤900px: tabel e-Resep memakai tata letak KARTU BERTINGKAT — lebar persentase
   di atas harus dinetralkan (kalau tidak, isian menyusut jadi beberapa puluh px). */
@media (max-width:900px){
  table.data.rx-form-table{table-layout:auto}
  table.data.rx-form-table .col-drug,
  table.data.rx-form-table .col-qty,
  table.data.rx-form-table .col-unit,
  table.data.rx-form-table .col-signa,
  table.data.rx-form-table .col-price,
  table.data.rx-form-table .col-note,
  table.data.rx-form-table .col-x{width:auto}
  table.data.rx-form-table .addon-field{flex-wrap:wrap}
  table.data.rx-form-table .addon-field > .addon-suffix{white-space:normal}
}

/* e-RESEP — NAMA OBAT ikut tampil UTUH (boleh 2 baris) di kolom Obat/Alkes.
   Dulu label combobox dipaksa satu baris + elipsis, sehingga nama obat panjang
   terpotong "...". Sekarang label boleh membungkus; tinggi tombol mengikuti. */
table.data.rx-form-table td.col-drug .cs-btn{
  height:auto;min-height:38px;padding-block:6px;align-items:center;
}
table.data.rx-form-table td.col-drug .cs-btn .cs-label{
  white-space:normal;overflow:visible;text-overflow:clip;
  line-height:1.25;font-weight:600;overflow-wrap:anywhere;
}

/* ══════════════════════════════════════════════════════════════════════════
   TABEL RINCIAN e-RESEP — PROPORSI KOLOM SERAGAM DI SEMUA MENU
   (permintaan pemilik: "cek dan terapkan juga pada menu lain yang menampilkan
   Tabel Obat Non-Racik dan Obat Racik")

   Komponen `prescription_items_cards()` dipakai DUA menu (e-Resep & lembar
   Pemeriksaan Dokter), jadi aturannya cukup di sini. Tabel **Persiapan &
   Penyerahan Obat** (farmasi) juga memakai profil yang sama supaya kolom Obat
   tidak pernah terjepit.

   Sebelumnya tabel rincian memakai `table-layout:auto` + petunjuk lebar dari
   `balanceColumns()`; di AUTO layout petunjuk itu hanya SARAN — browser tetap
   melebarkan kolom yang isinya panjang (terukur: Obat 43%, Catatan 33%, dan
   kolom "Diminta"/"Harga" terpotong). Sekarang `table-layout:fixed` dengan
   persentase hasil ukur konten:
     · Obat/Alkes  tidak mendominasi (≤44%) tetapi tetap cukup untuk nama +
       zat aktif (membungkus, bukan terpotong);
     · Jumlah & Harga hanya selebar isinya;
     · Aturan pakai & Catatan berbagi sisa ruang.
   ══════════════════════════════════════════════════════════════════════════ */
@media (min-width:901px){
  table.data.rx-plain-table,
  table.data.rx-cmp-table,
  #form-farmasi table.data{table-layout:fixed;width:100%;min-width:0}

  /* Obat Non-Racik: Obat · Jumlah · Harga · Aturan pakai · Catatan */
  table.data.rx-plain-table thead th:nth-child(1){width:28%}
  table.data.rx-plain-table thead th:nth-child(2){width:11%}
  table.data.rx-plain-table thead th:nth-child(3){width:14%}
  table.data.rx-plain-table thead th:nth-child(4){width:28%}
  table.data.rx-plain-table thead th:nth-child(5){width:19%}

  /* Obat Racikan: Obat/bahan · Jumlah · Harga · Catatan.
     Obat 38% (dulu 44%) supaya tidak mendominasi; sisa ruang dibagi ke kolom
     Jumlah/Harga/Catatan sehingga isinya tetap utuh. */
  table.data.rx-cmp-table thead th:nth-child(1){width:38%}
  table.data.rx-cmp-table thead th:nth-child(2){width:13%}
  table.data.rx-cmp-table thead th:nth-child(3){width:14%}
  table.data.rx-cmp-table thead th:nth-child(4){width:35%}

  /* Persiapan & Penyerahan Obat (farmasi):
     Obat · Diminta · Stok kini · Diserahkan · Batch (FEFO) · Harga · Aturan pakai */
  #form-farmasi thead th:nth-child(1){width:26%}
  #form-farmasi thead th:nth-child(2){width:9%}
  #form-farmasi thead th:nth-child(3){width:9%}
  #form-farmasi thead th:nth-child(4){width:9%}
  #form-farmasi thead th:nth-child(5){width:20%}
  #form-farmasi thead th:nth-child(6){width:11%}
  #form-farmasi thead th:nth-child(7){width:16%}
}
@media (min-width:901px) and (max-width:1300px){
  /* Jendela sempit: Harga & aksi butuh lebih banyak ruang → geser dari Obat. */
  table.data.rx-plain-table thead th:nth-child(1){width:26%}
  table.data.rx-plain-table thead th:nth-child(4){width:27%}
  table.data.rx-cmp-table thead th:nth-child(1){width:36%}
  table.data.rx-cmp-table thead th:nth-child(4){width:37%}
  #form-farmasi thead th:nth-child(1){width:24%}
  #form-farmasi thead th:nth-child(5){width:18%}
  #form-farmasi thead th:nth-child(6){width:14%}
  #form-farmasi thead th:nth-child(7){width:17%}
}
/* Isi sel WAJIB boleh membungkus — dulu `.col-qty`/`.col-num`/`.col-price`
   memakai `white-space:nowrap` sehingga "5 FLS (kemasan pabrik)" / nominal
   panjang TERPOTONG (bukan turun baris). Nominal tetap tabular & rata kanan. */
table.data.rx-plain-table td,
table.data.rx-cmp-table td,
#form-farmasi table.data td{white-space:normal;overflow-wrap:anywhere}
table.data.rx-plain-table td.col-qty,
table.data.rx-cmp-table td.col-qty,
#form-farmasi table.data td:nth-child(2),
#form-farmasi table.data td:nth-child(3),
#form-farmasi table.data td:nth-child(4){white-space:normal}
table.data.rx-plain-table td.col-price,
table.data.rx-cmp-table td.col-price,
#form-farmasi table.data td:nth-child(6){
  white-space:nowrap;text-align:right;font-variant-numeric:tabular-nums;
}
/* Select/isuian di tabel persiapan tidak boleh melebar keluar selnya. */
#form-farmasi table.data td select,
#form-farmasi table.data td input{width:100%;max-width:100%;min-width:0}

/* Kolom SATUAN pada tabel e-Resep: label combobox (mis. "FLS (kemasan pabrik)",
   atau placeholder "— pilih satuan —") BOLEH membungkus — dulu dipaksa satu
   baris + elipsis sehingga terpotong "…" pada kolom yang ramping. */
table.data.rx-form-table td.col-unit .cs-btn{height:auto;min-height:38px;padding-block:6px;align-items:center}
table.data.rx-form-table td.col-unit .cs-btn .cs-label{
  white-space:normal;overflow:visible;text-overflow:clip;line-height:1.25;font-weight:600;
  overflow-wrap:anywhere;
}

/* ══════════════════════════════════════════════════════════════════════════
   e-RESEP — JARAK ANTAR RACIKAN DALAM SATU TABEL (permintaan pemilik)
   Sebelumnya Racikan 1 dan Racikan 2 hanya dipisah garis 2px sehingga menyatu.
   Sekarang ada baris pemisah setinggi 14px (`tr.rx-cmp-gap`) + judul racikan
   berikutnya diberi latar lebih tegas, jadi batas antar racikan langsung jelas
   walau tetap berada di dalam SATU tabel.
   ══════════════════════════════════════════════════════════════════════════ */
table.data.rx-cmp-table tr.rx-cmp-gap > td,
table.data.rx-cmp-table tr.cmp-gap-row > td{
  height:14px;padding:0!important;border:0!important;background:transparent!important;
}
table.data.rx-cmp-table tbody.rx-cmp-group + tbody.rx-cmp-group > tr.rx-cmp-head-row > td{
  border-top:1px solid var(--line-strong);
  padding-top:14px;
}
/* Tabel PERSIAPAN (farmasi) juga memakai baris judul racikan. */
#form-farmasi table.data tr.cmp-head-row > td{background:var(--tint-3)}
#form-farmasi table.data tr.cmp-head-row + tr > td{border-top:1px solid var(--line-strong)}
/* Baris pemisah racikan tidak perlu di tampilan KARTU BERTINGKAT (≤900px):
   di sana tiap baris sudah menjadi kartu dengan jarak sendiri. */
@media (max-width:900px){
  table.data.rx-cmp-table tr.rx-cmp-gap{display:none!important}
}

/* ══════════════════════════════════════════════════════════════════════════
   BILAH PROGRES NAVIGASI (umpan balik instan saat membuka halaman/pop-up)
   Tipis 2px di paling atas, hanya mengubah `transform` (murah, tanpa reflow).
   Muncul saat tautan internal ditekan dan selesai saat halaman baru siap —
   menghilangkan kesan "menggantung" ketika membuka kartu penginputan.
   ══════════════════════════════════════════════════════════════════════════ */
.nav-progress{
  position:fixed;left:0;top:0;height:2px;width:100%;z-index:130;
  transform:scaleX(0);transform-origin:left center;
  background:linear-gradient(90deg,var(--brand,#0E7C6B),var(--cyan,#14A38B));
  box-shadow:0 0 8px rgba(20,163,139,.55);
  opacity:0;pointer-events:none;
  transition:transform .18s ease-out,opacity .16s linear;
}
.nav-progress.is-on{opacity:1}
.nav-progress.is-done{transition:transform .12s linear,opacity .2s linear .06s}
@media (prefers-reduced-motion:reduce){
  .nav-progress{transition:none}
}

/* Baris penjualan yang melebihi stok tersedia (stok − booking e-Resep) —
   penanda visual ringan; penjelasan lengkapnya ada di pop-up. */
tr.is-booked-over > td{background:rgba(225,29,72,.10)}
html[data-theme="light"] tr.is-booked-over > td{background:rgba(190,18,60,.07)}

/* ══════════════════════════════════════════════════════════════════════════
   e-RESEP — KOLOM EMBALASE · TOTAL DI BAWAH TABEL · RACIKAN SATU BARIS TEKS
   Permintaan pemilik:
     · kolom **Embalase** pada tabel Obat Non-Racik & Obat Racikan
       (datanya dari centang embalase di master obat);
     · **TOTAL di bawah tabel**, sudah termasuk embalase;
     · keterangan racikan berupa **TEKS sejajar satu baris** (bukan chip):
       "Racikan 1 • Puyer / Serbuk • 10 Bungkus • 3 × 1 Sesudah Makan (1 Bungkus)".
   ══════════════════════════════════════════════════════════════════════════ */
table.data.rx-plain-table .col-emb,
table.data.rx-cmp-table .col-emb,
#form-resep table.data.rx-form-table thead th.col-emb{
  width:12%;text-align:right;white-space:nowrap;font-variant-numeric:tabular-nums;
}
table.data.rx-plain-table td.col-emb,
table.data.rx-cmp-table td.col-emb{text-align:right;font-variant-numeric:tabular-nums}

/* Baris TOTAL di bawah tabel rincian (disamakan dengan kaki tabel). */
.rx-total{
  display:flex;align-items:baseline;justify-content:flex-end;gap:10px;flex-wrap:wrap;
  margin-top:10px;padding:10px 12px;border-radius:10px;
  border:1px solid var(--line-strong);background:var(--tint-3);
}
.rx-total-label{font-size:.78rem;font-weight:700;letter-spacing:.03em;text-transform:uppercase;color:var(--ink-2)}
.rx-total-part{font-size:.78rem;color:var(--ink-2)}
.rx-total-value{font-family:var(--mono);font-variant-numeric:tabular-nums;font-size:1.02rem;color:var(--head-ink)}
@media (max-width:640px){
  .rx-total{padding:9px 10px;gap:6px}
  .rx-total-label,.rx-total-part{font-size:.72rem}
  .rx-total-value{font-size:.95rem}
}

/* Keterangan racikan = SATU BARIS TEKS yang sejajar (sediaan • kemasan • aturan
   pakai). Tidak memakai chip lagi; hanya membungkus bila layar sempit. */
.rx-cmp-line{display:flex;align-items:baseline;gap:7px;flex-wrap:wrap}
.rx-cmp-text{
  font-size:.86rem;font-weight:650;color:var(--ink-strong);
  overflow-wrap:anywhere;line-height:1.35;
}
.rx-cmp-line .rx-sep{color:var(--ink-3);font-weight:800}

/* Kolom "Jumlah per minum" (dropdown) pada tabel e-Resep dokter. */
#form-resep table.data.rx-form-table thead th.col-dose{width:11%}
#form-resep table.data.rx-form-table td.col-dose .cs-btn{width:100%;min-width:0}
@media (min-width:901px) and (max-width:1300px){
  #form-resep table.data.rx-form-table thead th.col-dose{width:12%}
}

/* ── PROPORSI KOLOM SETELAH KOLOM BARU (Embalase & Jumlah per minum) ──────
   Tabel e-Resep dokter kini 8 kolom (tambah "Jumlah per minum") dan tabel
   rincian 5–6 kolom (tambah "Embalase"). Angka di bawah MENGIKUATI aturan
   persentase sebelumnya (blok ini paling akhir). */
@media (min-width:1301px){
  #form-resep table.data.rx-form-table thead th.col-drug{width:18%}
  #form-resep table.data.rx-form-table thead th.col-qty{width:6.5%}
  #form-resep table.data.rx-form-table thead th.col-unit{width:9%}
  #form-resep table.data.rx-form-table thead th.col-signa{width:19%}
  #form-resep table.data.rx-form-table thead th.col-dose{width:11%}
  #form-resep table.data.rx-form-table thead th.col-price{width:12%}
  #form-resep table.data.rx-form-table thead th.col-note{width:14.5%}
  #form-resep table.data.rx-form-table thead th.col-x{width:10%}

  table.data.rx-plain-table thead th:nth-child(1){width:26%}
  table.data.rx-plain-table thead th:nth-child(2){width:10%}
  table.data.rx-plain-table thead th:nth-child(3){width:13%}
  table.data.rx-plain-table thead th:nth-child(4){width:24%}
  table.data.rx-plain-table thead th:nth-child(5){width:12%}
  table.data.rx-plain-table thead th:nth-child(6){width:15%}

  table.data.rx-cmp-table thead th:nth-child(1){width:36%}
  table.data.rx-cmp-table thead th:nth-child(2){width:13%}
  table.data.rx-cmp-table thead th:nth-child(3){width:14%}
  table.data.rx-cmp-table thead th:nth-child(4){width:12%}
  table.data.rx-cmp-table thead th:nth-child(5){width:25%}
}
@media (min-width:901px) and (max-width:1300px){
  #form-resep table.data.rx-form-table thead th.col-drug{width:16%}
  #form-resep table.data.rx-form-table thead th.col-qty{width:6.5%}
  #form-resep table.data.rx-form-table thead th.col-unit{width:8%}
  #form-resep table.data.rx-form-table thead th.col-signa{width:18%}
  #form-resep table.data.rx-form-table thead th.col-dose{width:11%}
  #form-resep table.data.rx-form-table thead th.col-price{width:13%}
  #form-resep table.data.rx-form-table thead th.col-note{width:12.5%}
  #form-resep table.data.rx-form-table thead th.col-x{width:10%}

  table.data.rx-plain-table thead th:nth-child(1){width:24%}
  table.data.rx-plain-table thead th:nth-child(4){width:22%}
  table.data.rx-plain-table thead th:nth-child(4){width:22%}
  table.data.rx-cmp-table thead th:nth-child(1){width:34%}
  table.data.rx-cmp-table thead th:nth-child(4){width:13%}
}

/* Kolom "Jumlah per minum": satuan ditulis kecil di samping dropdown (mis.
   "2" + "Tablet") sehingga terbaca "2 Tablet" pada satu baris. Chip satuan di
   kolom Aturan pakai disembunyikan karena informasinya sudah ada di kolom ini. */
#form-resep table.data.rx-form-table .col-dose .addon-field{display:flex;align-items:center;gap:6px;min-width:0}
#form-resep table.data.rx-form-table .col-dose .addon-field > select{flex:1 1 auto;min-width:0}
#form-resep table.data.rx-form-table .col-dose .addon-suffix{
  flex:0 0 auto;font-size:.74rem;font-weight:650;color:var(--ink-2);white-space:nowrap;
}
#form-resep table.data.rx-form-table .col-signa .addon-suffix{display:none}

/* Kolom "Jumlah per minum" (dropdown + satuan) — kolom ini ramping, jadi isinya
   DIBOLEHKAN membungkus & tidak boleh meluber keluar sel (dulu chip satuan
   keluar dari sel dan label "— jumlah —" terpotong). */
#form-resep table.data.rx-form-table .col-dose .addon-field{flex-wrap:wrap;gap:2px 6px;align-items:center}
#form-resep table.data.rx-form-table .col-dose .addon-field > select{flex:1 1 56px;min-width:0}
#form-resep table.data.rx-form-table .col-dose .addon-field > .addon-suffix{white-space:normal;line-height:1.15}
#form-resep table.data.rx-form-table .col-dose .cs-btn{padding:8px 18px 8px 7px}
#form-resep table.data.rx-form-table .col-dose .cs-btn .cs-caret{right:4px;width:13px;height:13px}
#form-resep table.data.rx-form-table .col-dose .cs-btn .cs-label{
  white-space:normal;overflow:visible;text-overflow:clip;line-height:1.2;font-weight:600;
}

/* ⚠️ Kepala kolom "Jumlah per minum" mengandung kata "Jumlah" sehingga
   `proportionTable()` otomatis memberinya kelas `.col-num` (white-space:nowrap).
   Tanpa pengecualian ini isi kolom TIDAK bisa membungkus dan chip satuan panjang
   (mis. "kapsul lunak") meluber keluar sel. */
#form-resep table.data.rx-form-table td.col-dose.col-num,
#form-resep table.data.rx-form-table th.col-dose.col-num{white-space:normal;width:11%}
#form-resep table.data.rx-form-table td.col-dose{overflow:visible}
#form-resep table.data.rx-form-table .col-dose .addon-field > .addon-suffix{
  flex:0 1 auto;min-width:0;max-width:100%;overflow-wrap:anywhere;white-space:normal;
}

/* ≤900px: tabel e-Resep menjadi KARTU BERTINGKAT → lebar persentase & nowrap
   kolom Embalase dinetralkan (tanpa ini nominal "Rp 1.000" terpotong). */
@media (max-width:900px){
  table.data.rx-plain-table .col-emb,
  table.data.rx-cmp-table .col-emb{width:auto;white-space:normal;text-align:left}
}

/* ══════════════════════════════════════════════════════════════════════════
   RONDE: RINCIAN e-RESEP & FORMULIR PEMERIKSAAN DOKTER (permintaan pemilik)
   ──────────────────────────────────────────────────────────────────────────
   1. Stempel TANGGAL & JAM:MENIT petugas farmasi di bawah nama user.
   2. Baris TOTAL rincian e-Resep menjadi BAGIAN TABEL (`<tfoot>`) dan nominalnya
      sejajar di bawah kolom Subtotal — bukan kartu terpisah.
   3. Total Tindakan pada detail rekam medis memakai huruf yang SAMA dengan
      baris tabel (bukan gaya `tfoot th` monospace).
   4. Formulir e-Resep: kolom **Dosis** (angka + satuan dosis searchable),
      lebar kolom Jumlah/Satuan/Dosis proporsional, dan MODE BACA untuk baris
      resep yang sudah final (ikon pensil untuk mengedit).
   ══════════════════════════════════════════════════════════════════════════ */

/* 1 ── Stempel waktu petugas (DATA, bukan teks bantuan → tetap tampil walau
       tombol Info dimatikan). */
.rx-when{
  display:block;margin-top:5px;font-size:.76rem;font-weight:650;color:var(--ink-2);
  font-variant-numeric:tabular-nums;letter-spacing:.01em;
}
html[data-hints="off"] .rx-when{display:block!important}
html[data-theme="light"] .rx-when{color:var(--ink-2)}

/* 2 ── TOTAL + EMBALASE di dalam tabel rincian e-Resep. */
table.data.rx-plain-table tfoot td,
table.data.rx-cmp-table tfoot td{
  /* Ukuran & jenis huruf MENGIKUTI baris tabel (permintaan pemilik). */
  font-family:inherit;font-size:inherit;line-height:inherit;padding:10px 8px;vertical-align:top;
  background:var(--foot-bg);border-top:1px solid var(--line-strong);color:var(--ink);
  white-space:normal;
}
table.data.rx-plain-table tfoot td.rx-foot-value,
table.data.rx-cmp-table tfoot td.rx-foot-value{
  text-align:right;font-weight:800;white-space:nowrap;font-variant-numeric:tabular-nums;
  color:var(--ink-strong);
}
/* Label "Total + Embalase" + rinciannya berdiri TEPAT DI BAWAH KOLOM HARGA
   (permintaan pemilik), rata kanan agar menempel pada angka totalnya.
   ⚠️ Lebar kolom Harga sempit → rincian boleh membungkus 2 baris (jangan
   dipotong dengan ellipsis). */
table.data.rx-plain-table tfoot td.rx-foot-label,
table.data.rx-cmp-table tfoot td.rx-foot-label{
  text-align:right;vertical-align:top;overflow-wrap:anywhere;
}
.rx-foot-title{display:block;font-weight:700;color:var(--ink-strong);line-height:1.25}
.rx-foot-note{
  display:block;margin-top:2px;font-size:.74rem;font-weight:650;color:var(--ink-2);
  line-height:1.3;white-space:normal;overflow-wrap:anywhere;
}
/* Kolom Subtotal pada baris isi (rata kanan, angka tabular). */
table.data.rx-plain-table td.col-sub,
table.data.rx-cmp-table td.col-sub{
  text-align:right;white-space:nowrap;font-variant-numeric:tabular-nums;font-weight:650;
}
table.data.rx-plain-table th.col-sub,
table.data.rx-cmp-table th.col-sub{text-align:right}
/* Nama obat: pemenggalan kata yang aman (nama panjang tidak mendorong kolom). */
table.data.rx-plain-table td.rx-name,
table.data.rx-cmp-table td.rx-name{overflow-wrap:anywhere}

/* Lebar kolom tabel rincian mengikuti URUTAN BARU
   Non-Racik: Obat · Jumlah · Aturan Pakai · Harga · Subtotal · Catatan
   Racikan  : Obat/Bahan · Jumlah · Harga · Subtotal · Catatan */
@media (min-width:901px){
  table.data.rx-plain-table thead th:nth-child(1){width:26%}
  table.data.rx-plain-table thead th:nth-child(2){width:10%}
  table.data.rx-plain-table thead th:nth-child(3){width:23%}
  table.data.rx-plain-table thead th:nth-child(4){width:13%}
  table.data.rx-plain-table thead th:nth-child(5){width:13%}
  table.data.rx-plain-table thead th:nth-child(6){width:15%}

  table.data.rx-cmp-table thead th:nth-child(1){width:38%}
  table.data.rx-cmp-table thead th:nth-child(2){width:12%}
  table.data.rx-cmp-table thead th:nth-child(3){width:14%}
  table.data.rx-cmp-table thead th:nth-child(4){width:14%}
  table.data.rx-cmp-table thead th:nth-child(5){width:22%}
}
/* Di HP tabel menjadi kartu bertingkat: baris total tetap rapi & labelnya jelas. */
@media (max-width:900px){
  table.data[data-stack] tfoot td{
    display:flex;align-items:baseline;justify-content:space-between;gap:10px;
    width:auto;padding:7px 2px;border:0;font-size:.86rem;
  }
  table.data[data-stack] tfoot td.rx-foot-value{justify-content:flex-end;font-size:.95rem}
  table.data[data-stack] tfoot td.rx-foot-empty{display:none}
  /* Label + rincian ditumpuk (bukan sejajar) agar terbaca di kartu bertingkat. */
  table.data[data-stack] tfoot td.rx-foot-label{display:block;text-align:right;padding-bottom:0}
  table.data[data-stack] tfoot td.rx-foot-label .rx-foot-title,
  table.data[data-stack] tfoot td.rx-foot-label .rx-foot-note{display:block}
  .rx-foot-note{white-space:normal;overflow:visible;text-overflow:clip}
  /* ⚠️ Di mode kartu, kolom TIDAK boleh memakai lebar persentase/pixel dari
     aturan desktop (`.col-qty`/`.col-price` = `width:1%` + nowrap) — tanpa
     penetralan ini sel menyusut jadi 16px dan isinya TERPOTONG
     ("10 botol" / "Rp 25.000" terukur meluber). */
  table.data.rx-plain-table td.col-qty,
  table.data.rx-cmp-table td.col-qty,
  table.data.rx-plain-table td.col-price,
  table.data.rx-cmp-table td.col-price,
  table.data.rx-plain-table td.col-sub,
  table.data.rx-cmp-table td.col-sub,
  table.data.rx-plain-table th,
  table.data.rx-cmp-table th{width:auto;white-space:normal;text-align:left}
}

/* 3 ── Total Tindakan (detail rekam medis): huruf sama dengan baris tabel,
       nominal sejajar di bawah kolom Subtotal. */
table.data.act-table tfoot tr.act-total-row td{
  /* Huruf SAMA dengan baris tindakan (bukan gaya `tfoot th` monospace). */
  font-family:inherit;font-size:inherit;font-weight:700;line-height:inherit;
  padding:10px 8px;background:var(--foot-bg);border-top:1px solid var(--line-strong);
  color:var(--ink-strong);white-space:normal;
}
table.data.act-table tfoot tr.act-total-row td.col-act-money{
  text-align:right;white-space:nowrap;font-variant-numeric:tabular-nums;
}

/* 4a ── Formulir e-Resep: kolom Jumlah/Satuan/Dosis proporsional & ringkas. */
#form-resep table.data.rx-form-table thead th.col-qty{width:7%}
#form-resep table.data.rx-form-table thead th.col-unit{width:11%}
#form-resep table.data.rx-form-table thead th.col-dose{width:16%}
#form-resep table.data.rx-form-table td.col-qty > input{
  width:100%;min-width:0;max-width:none;padding-left:6px;padding-right:6px;
  font-variant-numeric:tabular-nums;
}
/* Dosis = angka dosis (ringkas) + SATUAN DOSIS (dropdown searchable) sejajar. */
#form-resep table.data.rx-form-table .col-dose .dose-line{
  display:flex;align-items:center;gap:5px;min-width:0;flex-wrap:nowrap;
}
/* Angka dosis = ringkas (62px); satuan dosis menerima sisa lebar kolom.
   Kedua kontrol dibungkus `.dose-qty-wrap`/`.dose-unit-wrap` sehingga
   combobox (`.cs-btn`) yang dibuat JavaScript ikut aturan flex yang sama. */
#form-resep table.data.rx-form-table .col-dose .dose-qty-wrap{flex:0 0 62px;min-width:0;display:flex}
#form-resep table.data.rx-form-table .col-dose .dose-unit-wrap{flex:1 1 auto;min-width:0;display:flex}
#form-resep table.data.rx-form-table .col-dose .dose-qty-wrap > select,
#form-resep table.data.rx-form-table .col-dose .dose-qty-wrap > .cs-btn{flex:1 1 100%;min-width:0}
#form-resep table.data.rx-form-table .col-dose .dose-unit-pick{flex:1 1 auto;min-width:0}
#form-resep table.data.rx-form-table .col-dose .cs-btn{padding:8px 18px 8px 7px;min-height:36px}
#form-resep table.data.rx-form-table .col-dose .addon-suffix{display:none}
/* Label combobox pada kolom Satuan & Dosis: SATU BARIS + elipsis (judul lengkap
   muncul sebagai tooltip) supaya placeholder tidak memakan dua baris. */
#form-resep table.data.rx-form-table td.col-unit .cs-btn .cs-label,
#form-resep table.data.rx-form-table td.col-dose .cs-btn .cs-label{
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block;min-width:0;
}
#form-resep table.data.rx-form-table td.col-unit .cs-btn,
#form-resep table.data.rx-form-table td.col-dose .cs-btn{min-height:36px;padding:8px 20px 8px 8px}
#form-resep table.data.rx-form-table td.col-note input{padding-left:8px;padding-right:8px}

/* 4b ── BARIS RESEP FINAL = MODE BACA (teks). Semua isian DISEMBUNYIKAN secara
       visual (nilainya tetap ada di DOM & tetap terkirim saat form disimpan). */
table.data.rx-form-table tr.is-rx-readonly > td.col-qty > input,
table.data.rx-form-table tr.is-rx-readonly > td.col-unit > select,
table.data.rx-form-table tr.is-rx-readonly > td.col-unit > .cs-btn,
table.data.rx-form-table tr.is-rx-readonly > td.col-signa > .addon-field,
table.data.rx-form-table tr.is-rx-readonly > td.col-dose > .addon-field,
table.data.rx-form-table tr.is-rx-readonly > td.col-note > input{display:none!important}
table.data.rx-form-table tr.is-rx-readonly > td .rx-ro{
  display:block;padding:7px 2px;border:1px dashed transparent;border-radius:9px;
  font-weight:650;color:var(--ink-strong);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  max-width:100%;
}
/* Angka jumlah tetap RATA KANAN (konsisten dengan kolom angka lain di aplikasi);
   kolom Dosis memuat teks "2 mg" sehingga rata kiri seperti kolom teks. */
table.data.rx-form-table tr.is-rx-readonly > td.col-qty .rx-ro{
  font-variant-numeric:tabular-nums;text-align:right;
}
table.data.rx-form-table tr.is-rx-readonly > td.col-dose .rx-ro{
  font-variant-numeric:tabular-nums;text-align:left;
}
table.data.rx-form-table tr.is-rx-readonly > td.col-note .rx-ro{font-weight:500;color:var(--ink-2)}
#form-resep table.data.rx-form-table tr.is-rx-readonly > td{background:transparent}
#form-resep table.data.rx-form-table tr.is-rx-readonly:hover > td{background:var(--tint-3)}

@media (max-width:900px){
  /* Kartu bertingkat: nilai mode-baca mengikuti lebar kartu (boleh membungkus). */
  table.data.rx-form-table tr.is-rx-readonly > td .rx-ro{white-space:normal;overflow:visible;text-overflow:clip}
}

/* ══════════════════════════════════════════════════════════════════════════
   KOLOM WAJIB e-RESEP YANG BELUM TERISI (permintaan pemilik)
   ──────────────────────────────────────────────────────────────────────────
   Begitu OBAT/BAHAN dipilih, kolom Jumlah · Satuan · Aturan pakai · Dosis
   menjadi WAJIB; kolom yang masih kosong diberi penanda visual halus supaya
   pengguna tahu mengapa tombol [+ Tambah Obat] / [+ Tambah Bahan] belum bisa
   dipakai. Penandanya (`.is-req-missing`) dipasang `assets/klinik.js`
   (`markRxRequired`) dan TIDAK menghalangi pengisian (hanya tanda).
   ══════════════════════════════════════════════════════════════════════════ */
#form-resep td.is-req-missing,
[data-cmp-form] td.is-req-missing{position:relative}
#form-resep td.is-req-missing .cs-btn,
#form-resep td.is-req-missing input:not([type=hidden]),
[data-cmp-form] td.is-req-missing .cs-btn,
[data-cmp-form] td.is-req-missing input:not([type=hidden]){
  border-color:var(--amber,#D97706);
  box-shadow:0 0 0 2px rgba(217,119,6,.16) inset;
}
#form-resep td.is-req-missing::after,
[data-cmp-form] td.is-req-missing::after{
  content:"";position:absolute;inset:1px;border-radius:9px;pointer-events:none;
  border:1px dashed rgba(217,119,6,.55);
}
/* Kolom racikan (Sediaan / Jumlah kemasan / Satuan kemasan / Aturan pakai). */
.cmp-head .field.is-req-missing > span{color:var(--amber,#B45309)}
.cmp-head .field.is-req-missing .cs-btn,
.cmp-head .field.is-req-missing input{
  border-color:var(--amber,#D97706);
  box-shadow:0 0 0 2px rgba(217,119,6,.16) inset;
}
/* Setelah baris selesai (mode baca) penanda wajib tidak boleh muncul lagi. */
#form-resep tr.is-rx-readonly td.is-req-missing::after{content:none}

/* ══════════════════════════════════════════════════════════════════════════
   KARTU e-RESEP PADA REKAM MEDIS FINAL (permintaan pemilik)
   ──────────────────────────────────────────────────────────────────────────
   Setelah [Selesaikan Pemeriksaan], kartu e-Resep menampilkan **Obat Non-Racik**
   dan **Obat Racikan** (komponen `prescription_items_cards()`), ditambah:
     · strip **Total e-Resep** (obat non-racik + bahan racikan + embalase),
     · keterangan siapa & kapan obat disiapkan/diserahkan,
     · tombol [Buka kartu e-Resep] & [Cetak e-Resep].
   ══════════════════════════════════════════════════════════════════════════ */
.rx-readonly-items{margin-top:2px}
.rx-readonly-items .rx-grand{display:none}   /* jaga-jaga: strip hanya di luar kartu */

/* Strip total seluruh resep — sejajar dengan baris TOTAL di dalam tabel. */
.rx-grand{
  display:flex;align-items:baseline;justify-content:flex-end;gap:10px 14px;flex-wrap:wrap;
  margin:14px 0 0;padding:11px 14px;border-radius:var(--radius-sm);
  background:var(--foot-bg);border:1px solid var(--line-strong);
}
.rx-grand-title{font-weight:700;color:var(--ink-strong)}
.rx-grand-parts{
  font-size:.78rem;font-weight:650;color:var(--ink-2);margin-left:auto;text-align:right;
  overflow-wrap:anywhere;
}
.rx-grand-value{
  font-variant-numeric:tabular-nums;font-weight:800;color:var(--ink-strong);white-space:nowrap;
  font-size:1.02rem;
}
/* Siapa & kapan obat disiapkan/diserahkan (DATA → tetap tampil walau Info mati). */
.rx-disp-meta{
  margin:10px 0 0;font-size:.78rem;font-weight:650;color:var(--ink-2);
  display:flex;flex-wrap:wrap;gap:6px 16px;align-items:baseline;
}
.rx-disp-meta strong{color:var(--ink-strong)}
html[data-hints="off"] .rx-disp-meta{display:flex!important}

@media (max-width:640px){
  .rx-grand{justify-content:space-between;padding:10px 12px}
  .rx-grand-parts{margin-left:0;text-align:left;order:3;flex:1 1 100%}
  .rx-grand-value{order:2}
}

/* ══════════════════════════════════════════════════════════════════════════
   KARTU PEMBAYARAN TAGIHAN (Kasir) — DESAIN DUA KOLOM
   ──────────────────────────────────────────────────────────────────────────
   Mengikuti contoh desain pemilik: kartu **Daftar Obat yang Dibeli** di kiri
   (tabel + Total Tagihan), dan di kanan tiga petak ringkasan
   (**Sudah Dibayar · Sisa Tagihan · Kembalian**), baris isian
   (Tanggal Bayar · Jenis Pembayaran · Akun Kas · Jumlah Diterima), Catatan,
   serta kartu **Bukti Pembayaran** (Kamera / Galeri-File).
   ══════════════════════════════════════════════════════════════════════════ */
.pay-sheet .pay-head{align-items:flex-start}
.pay-head-text{min-width:0}
.pay-head-text h2{margin:0;font-size:1.34rem;line-height:1.2}
.pay-sub{display:block;margin-top:3px;font-size:.86rem;font-weight:600;color:var(--ink-2)}
.pay-body{padding-bottom:6px}
.pay-grid{display:grid;grid-template-columns:minmax(0,1.06fr) minmax(0,1fr);gap:20px;align-items:start}

/* ── KIRI: kartu daftar obat ───────────────────────────────────────────── */
.pay-items-card{
  display:flex;flex-direction:column;min-width:0;
  border:1px solid var(--line);border-radius:var(--radius);background:var(--panel);
  padding:14px 14px 12px;
}
.pay-items-head{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:10px}
.pay-items-head h3{margin:0;font-size:1.02rem;font-weight:800;color:var(--head-ink)}
.pay-items-icon{
  width:34px;height:34px;flex:0 0 auto;border-radius:11px;display:grid;place-items:center;
  background:rgba(14,124,107,.12);color:var(--brand,#0E7C6B);
}
.pay-items-icon svg{width:19px;height:19px;fill:currentColor}
.pay-item-count{margin-left:auto;white-space:nowrap}
.pay-items-wrap{border:1px solid var(--line);border-radius:var(--radius-sm);overflow:auto;max-height:46vh}
table.data.pay-items-table{width:100%;min-width:0;margin:0;table-layout:fixed}
table.data.pay-items-table thead th{
  font-size:.7rem;letter-spacing:.04em;text-transform:uppercase;background:var(--foot-bg);
  padding:9px 8px;border-bottom:1px solid var(--line);
}
table.data.pay-items-table td{padding:9px 8px;vertical-align:top;white-space:normal;overflow-wrap:anywhere}
table.data.pay-items-table .col-no{width:38px;text-align:center}
table.data.pay-items-table .col-qty{width:52px;text-align:right}
table.data.pay-items-table .col-unit{width:72px}
table.data.pay-items-table .col-price{width:96px;text-align:right;white-space:nowrap}
table.data.pay-items-table .col-sub{width:104px;text-align:right;white-space:nowrap;font-weight:700}
table.data.pay-items-table td.col-price,
table.data.pay-items-table td.col-sub,
table.data.pay-items-table td.col-qty{font-variant-numeric:tabular-nums}
.pay-item-name strong{display:block;font-weight:750;color:var(--ink-strong);line-height:1.25}
.pay-item-sub{display:block;margin-top:2px;font-size:.73rem;line-height:1.25;color:var(--ink-3)}
.pay-items-empty{padding:18px 4px;color:var(--ink-3)}
.pay-total-row{
  display:flex;align-items:baseline;justify-content:space-between;gap:12px;
  margin-top:12px;padding:12px 16px;border-radius:var(--radius-sm);
  background:rgba(14,124,107,.10);border:1px solid rgba(14,124,107,.22);
}
.pay-total-row span{font-size:1.02rem;font-weight:800;color:var(--ink-strong)}
.pay-total-row strong{
  font-size:1.42rem;font-weight:900;letter-spacing:-.01em;
  color:var(--brand,#0E7C6B);font-variant-numeric:tabular-nums;white-space:nowrap;
}
html[data-theme="dark"] .pay-total-row{background:rgba(45,212,167,.12);border-color:rgba(45,212,167,.28)}
html[data-theme="dark"] .pay-total-row strong{color:#2DD4A7}

/* ── KANAN: ringkasan + isian ──────────────────────────────────────────── */
.pay-side{display:flex;flex-direction:column;gap:14px;min-width:0}
.pay-stats{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:10px}
.pay-stat{
  display:flex;align-items:center;gap:10px;min-width:0;
  padding:12px 13px;border-radius:var(--radius-sm);border:1px solid var(--line);
  background:var(--tint-3);
}
.pay-stat-icon{width:32px;height:32px;flex:0 0 auto;border-radius:10px;display:grid;place-items:center}
.pay-stat-icon svg{width:19px;height:19px;fill:currentColor}
.pay-stat-text{min-width:0}
.pay-stat-label{display:block;font-size:.74rem;font-weight:700;color:var(--ink-2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.pay-stat-value{display:block;margin-top:2px;font-size:1.16rem;font-weight:900;letter-spacing:-.01em;
  font-variant-numeric:tabular-nums;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.pay-stat.is-paid{background:rgba(14,124,107,.10);border-color:rgba(14,124,107,.24)}
.pay-stat.is-paid .pay-stat-icon{background:rgba(14,124,107,.16);color:var(--brand,#0E7C6B)}
.pay-stat.is-paid .pay-stat-value{color:var(--brand,#0E7C6B)}
.pay-stat.is-due{background:rgba(220,38,38,.08);border-color:rgba(220,38,38,.22)}
.pay-stat.is-due .pay-stat-icon{background:rgba(220,38,38,.14);color:#DC2626}
.pay-stat.is-due .pay-stat-value{color:#DC2626}
.pay-stat.is-change{background:rgba(22,163,74,.10);border-color:rgba(22,163,74,.24)}
.pay-stat.is-change .pay-stat-icon{background:rgba(22,163,74,.16);color:#15803D}
.pay-stat.is-change .pay-stat-value{color:#15803D}
.pay-stat.is-change.is-zero{opacity:.72}
html[data-theme="dark"] .pay-stat.is-paid{background:rgba(45,212,167,.12);border-color:rgba(45,212,167,.26)}
html[data-theme="dark"] .pay-stat.is-paid .pay-stat-value{color:#2DD4A7}
html[data-theme="dark"] .pay-stat.is-due{background:rgba(248,113,113,.12);border-color:rgba(248,113,113,.26)}
html[data-theme="dark"] .pay-stat.is-due .pay-stat-value{color:#FCA5A5}
html[data-theme="dark"] .pay-stat.is-change{background:rgba(74,222,128,.12);border-color:rgba(74,222,128,.26)}
html[data-theme="dark"] .pay-stat.is-change .pay-stat-value{color:#86EFAC}

/* baris isian: 4 kolom seperti contoh (Tanggal · Jenis · Akun · Jumlah) */
.pay-fields{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:12px}
.pay-fields .field{margin:0}
.pay-fields .field > span{font-size:.78rem;font-weight:700;color:var(--ink-2)}
.pay-fields .req-mark{color:#DC2626;font-style:normal;font-weight:800}
.pay-note{margin:0}
.pay-note textarea{min-height:62px;resize:vertical}

/* Catatan hasil: sisa menjadi piutang / kembalian */
.pay-due-note,.pay-change-note{
  display:flex;align-items:flex-start;gap:8px;margin:0;padding:10px 12px;border-radius:var(--radius-sm);
  font-size:.8rem;font-weight:650;line-height:1.35;
}
.pay-due-note{background:rgba(217,119,6,.10);border:1px solid rgba(217,119,6,.28);color:var(--ink)}
.pay-change-note{background:rgba(22,163,74,.10);border:1px solid rgba(22,163,74,.26);color:var(--ink)}
.pay-due-note svg,.pay-change-note svg{width:16px;height:16px;flex:0 0 auto;margin-top:1px;fill:currentColor}
.pay-due-note svg{color:#B45309}
.pay-change-note svg{color:#15803D}
.pay-due-note a{margin-left:auto;white-space:nowrap;font-weight:750;color:var(--brand,#0E7C6B)}
.pay-due-note.is-hidden,.pay-change-note.is-hidden{display:none}

/* Kartu bukti pembayaran */
.pay-proof-card{
  border:1px solid var(--line);border-radius:var(--radius-sm);background:var(--panel);
  padding:12px 13px;
}
.pay-proof-head{display:flex;align-items:center;gap:9px;flex-wrap:wrap;margin-bottom:8px}
.pay-proof-head h3{margin:0;font-size:.95rem;font-weight:800;color:var(--head-ink)}
.pay-proof-icon{
  width:28px;height:28px;flex:0 0 auto;border-radius:9px;display:grid;place-items:center;
  background:rgba(14,124,107,.12);color:var(--brand,#0E7C6B);
}
.pay-proof-icon svg{width:16px;height:16px;fill:currentColor}
.pay-proof-head .badge{margin-left:auto}
.pay-proof-body{display:flex;align-items:center;gap:12px;flex-wrap:wrap}
.pay-proof-body .attach-widget{flex:1 1 240px;min-width:0}
.pay-proof-body .attach-actions{gap:8px;flex-wrap:wrap}
.pay-proof-body .attach-label{display:none}
.pay-proof-hint{flex:1 1 200px;margin:0;min-width:0}
.pay-proof-card.is-warn{border-color:rgba(217,119,6,.45)}

/* Riwayat pembayaran sebelumnya (ringkas) */
.pay-history{display:flex;flex-direction:column;gap:4px;padding:10px 12px;
  border:1px dashed var(--line);border-radius:var(--radius-sm);background:var(--tint-3)}
.pay-history-title{font-size:.74rem;font-weight:750;letter-spacing:.03em;text-transform:uppercase;color:var(--ink-2)}
.pay-history-row{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap;font-size:.82rem}
.pay-history-row strong{font-variant-numeric:tabular-nums}

/* Kaki kartu */
.pay-foot{gap:10px}
.pay-foot .foot-note{margin-right:auto;text-align:left}
.pay-foot .btn-ok{display:inline-flex;align-items:center;gap:8px;min-height:44px;padding-inline:20px;font-weight:750}
.pay-foot .btn-ok svg{width:18px;height:18px;fill:currentColor}

/* Kolom "Jumlah Diterima" memakai prefix Rp di dalam kotak (komponen global) */
.pay-fields .money-wrap{width:100%}

/* ── Responsif ─────────────────────────────────────────────────────────── */
@media (max-width:1180px){
  .pay-grid{grid-template-columns:minmax(0,1fr)}
  .pay-items-wrap{max-height:none}
}
@media (max-width:900px){
  .pay-fields{grid-template-columns:repeat(2,minmax(0,1fr))}
  .pay-stats{grid-template-columns:repeat(3,minmax(0,1fr))}
  .pay-stat-value{font-size:1.06rem}
}
@media (max-width:640px){
  .pay-head-text h2{font-size:1.16rem}
  .pay-stats{grid-template-columns:minmax(0,1fr);gap:8px}
  .pay-stat{padding:10px 12px}
  .pay-stat-value{font-size:1.1rem}
  .pay-fields{grid-template-columns:minmax(0,1fr)}
  .pay-total-row strong{font-size:1.24rem}
  .pay-foot{flex-wrap:wrap}
  .pay-foot .foot-note{flex:1 1 100%;margin:0}
  .pay-foot .btn{flex:1 1 100%;justify-content:center}
  /* Tabel daftar obat menjadi kartu bertingkat (aturan global) — label kolom
     tetap terbaca dan tidak perlu geser ke samping. */
  table.data.pay-items-table{min-width:0}
}

/* Tabel daftar obat pada kartu pembayaran: di HP menjadi tabel RINGKAS 3 kolom
   (Obat · Qty · Subtotal) — bukan kartu bertingkat 6 label yang membuat kartu
   pembayaran sangat tinggi. Harga & satuan tetap terbaca di desktop. */
@media (max-width:900px){
  table.data.pay-items-table{display:table;width:100%;min-width:0;table-layout:fixed}
  table.data.pay-items-table thead{display:none}
  table.data.pay-items-table tbody{display:table-row-group}
  table.data.pay-items-table tr{display:table-row;padding:0;border:0;background:none}
  table.data.pay-items-table td{display:table-cell;padding:8px 6px;border-bottom:1px solid var(--row-border)}
  /* Tabel ringkas: Produk & Layanan · Qty · Subtotal */
  table.data.pay-items-table .col-no,
  table.data.pay-items-table .col-unit,
  table.data.pay-items-table .col-price{display:none}
  table.data.pay-items-table .col-qty{width:42px;text-align:center}
  table.data.pay-items-table .col-sub{width:100px}
  table.data.pay-items-table tr:last-child td{border-bottom:0}
  .pay-items-wrap{max-height:none}
}

/* ══════════════════════════════════════════════════════════════════════════
   KARTU PEMBAYARAN TAGIHAN — PENYEMPURNAAN UI/UX (mengikuti contoh pemilik)
   ──────────────────────────────────────────────────────────────────────────
   Butir yang dirapikan dari versi sebelumnya:
     · kepala kartu: kotak ikon toko + remah **Kasir › Pembayaran Tagihan**
       (judul besar) + kode & pasien di bawahnya,
     · kartu kiri berjudul **Detail Transaksi** dengan KEPALA HIJAU TUA penuh
       (teks putih) + pil putih **Total Item: N**,
     · kolom tabel persis contoh: NO · Produk & Layanan · Qty · Satuan ·
       **Embalase** · Harga · SUBTOTAL (nomor & subtotal tebal),
     · isian kanan **DUA kolom**: Tanggal Bayar / Jenis Pembayaran lalu
       Akun Bank · Akun Kas / Jumlah Diterima (kotak hijau, angka tebal),
     · kartu **Bukti Pembayaran** berbingkai AMBER + pil biru **Opsional**,
     · kaki kartu rata kanan dengan tombol lembut (Bayar Penuh / Batal) dan
       tombol utama hijau (Terima Pembayaran).
   ══════════════════════════════════════════════════════════════════════════ */

/* ── Kepala kartu ─────────────────────────────────────────────────────── */
.pay-head{gap:12px}
.pay-head-icon{
  width:44px;height:44px;flex:0 0 auto;border-radius:12px;display:grid;place-items:center;
  background:rgba(14,124,107,.12);color:var(--brand,#0E7C6B);
}
html[data-theme="dark"] .pay-head-icon{background:rgba(45,212,167,.16);color:#2DD4A7}
.pay-head-icon svg{width:24px;height:24px;fill:currentColor}
.pay-title{
  margin:0;line-height:1.2;font-size:1.4rem;font-weight:800;color:var(--head-ink);
  display:flex;align-items:baseline;gap:8px;flex-wrap:wrap;
}
.pay-crumb{color:var(--brand,#0E7C6B)}
html[data-theme="dark"] .pay-crumb{color:#2DD4A7}
.pay-crumb-sep{color:var(--ink-3);font-weight:700}
.pay-sub{display:block;margin-top:4px;font-size:.92rem;font-weight:750;color:var(--ink-strong)}

/* ── Kartu kiri: Detail Transaksi ─────────────────────────────────────── */
.pay-items-card{padding:0;overflow:hidden;border-radius:var(--radius)}
.pay-items-head{
  display:flex;align-items:center;gap:11px;flex-wrap:nowrap;
  padding:13px 16px;margin:0;
  background:linear-gradient(180deg,#128A78,#0C6A5B);
  border-bottom:0;
}
html[data-theme="dark"] .pay-items-head{background:linear-gradient(180deg,#0F7A6A,#0A5A4E)}
.pay-items-head h3{
  margin:0;font-size:1.1rem;font-weight:800;color:#fff;letter-spacing:.01em;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0;
}
.pay-items-icon{
  width:30px;height:30px;flex:0 0 auto;border-radius:9px;display:grid;place-items:center;
  background:rgba(255,255,255,.16);color:#fff;
}
.pay-items-icon svg{width:18px;height:18px;fill:currentColor}
.pay-item-count{
  margin-left:auto;flex:0 0 auto;
  display:inline-flex;align-items:center;
  background:#fff;color:#0C4A3E;border:0;
  font-size:.8rem;font-weight:750;padding:6px 12px;border-radius:999px;white-space:nowrap;
}
html[data-theme="dark"] .pay-item-count{background:#F3FFFB;color:#0A3F35}

/* ── Tabel rincian ────────────────────────────────────────────────────── */
.pay-items-wrap{
  margin:14px 16px 0;border:1px solid var(--line);border-radius:12px;overflow:auto;max-height:46vh;
}
table.data.pay-items-table thead th{
  font-size:.72rem;letter-spacing:.05em;text-transform:uppercase;font-weight:800;
  color:var(--ink-2);background:var(--foot-bg);padding:10px 9px;
  border-bottom:1px solid var(--line-strong);
}
table.data.pay-items-table thead th.col-no,
table.data.pay-items-table thead th.col-sub{color:var(--ink-strong)}
table.data.pay-items-table td{padding:10px 9px;vertical-align:top}
table.data.pay-items-table .col-no{width:44px;text-align:center;font-weight:750}
table.data.pay-items-table .col-prod{width:auto;min-width:0}
table.data.pay-items-table .col-qty{width:56px;text-align:center}
table.data.pay-items-table .col-unit{width:76px}
table.data.pay-items-table .col-price{width:104px;text-align:right;white-space:nowrap}
table.data.pay-items-table .col-sub{width:118px;text-align:right;white-space:nowrap;font-weight:800}
.pay-emb-none{color:var(--ink-3)}
.pay-item-name strong{font-weight:800;font-size:.92rem}
.pay-item-sub{color:var(--ink-3);font-size:.76rem;margin-top:1px}

/* ── Batang Total Tagihan ─────────────────────────────────────────────── */
.pay-total-row{
  margin:14px 16px 16px;padding:14px 18px;border-radius:12px;
  background:rgba(14,124,107,.10);border:1px solid rgba(14,124,107,.20);
}
.pay-total-row span{font-size:1.16rem;font-weight:850;color:var(--ink-strong)}
.pay-total-row strong{font-size:1.55rem;font-weight:900;color:var(--brand,#0E7C6B)}
html[data-theme="dark"] .pay-total-row{background:rgba(45,212,167,.12);border-color:rgba(45,212,167,.26)}
html[data-theme="dark"] .pay-total-row strong{color:#2DD4A7}

/* ── Isian kanan: DUA kolom seperti contoh ────────────────────────────── */
.pay-fields{grid-template-columns:repeat(2,minmax(0,1fr));gap:14px 16px}
/* Label isian memakai skala TEMA aplikasi (`.field` = .8rem, label .8rem/600
   redup) — sebelumnya .86rem/750 sehingga label "Jenis Pembayaran" terasa
   terlalu besar & tebal dibanding modul lain (permintaan pemilik). */
.pay-fields .field > span{font-size:.78rem;font-weight:650;color:var(--ink-2);letter-spacing:.02em}
.pay-account-field{grid-column:1}
.pay-amount-field{grid-column:2}
/* Kotak Jumlah Diterima: latar hijau lembut + border hijau + angka tebal */
.pay-amount-field .money-wrap{
  background:rgba(14,124,107,.08);border:1.5px solid rgba(14,124,107,.55);
  border-radius:11px;overflow:hidden;
}
.pay-amount-field .money-wrap > input{
  border:0;background:transparent;box-shadow:none;font-weight:850;font-size:1.06rem;
  color:#0B4A3E;height:44px;
}
html[data-theme="dark"] .pay-amount-field .money-wrap{background:rgba(45,212,167,.10);border-color:rgba(45,212,167,.55)}
html[data-theme="dark"] .pay-amount-field .money-wrap > input{color:#B8FFE8}
/* Prefix "Rp" mengikuti UKURAN & BOBOT angka nominal di sebelahnya
   (permintaan pemilik) — dulu memakai .8em sehingga tampak lebih kecil. */
.pay-amount-field .money-prefix{
  color:var(--ink-2);font-weight:850;font-size:1.06rem;letter-spacing:0;
}
html[data-theme="dark"] .pay-amount-field .money-prefix{color:#B8FFE8;opacity:.85}
.pay-note textarea{min-height:88px;resize:vertical}

/* ── Kartu Bukti Pembayaran: bingkai amber + pil biru "Opsional" ──────── */
.pay-proof-card{
  border:1.5px solid rgba(217,119,6,.55);border-radius:12px;background:var(--panel);
  padding:14px 16px;
}
.pay-proof-card .pay-proof-head{align-items:center;gap:10px;margin-bottom:10px}
.pay-proof-card .pay-proof-head h3{font-size:1.06rem;font-weight:800}
.pay-proof-icon{width:30px;height:30px;border-radius:9px;background:rgba(14,124,107,.12)}
.pay-proof-icon svg{width:17px;height:17px}
.pay-opt-pill{
  margin-left:auto;display:inline-flex;align-items:center;
  background:rgba(37,99,235,.12);color:#1D4ED8;border:1px solid rgba(37,99,235,.28);
  font-size:.78rem;font-weight:750;padding:5px 13px;border-radius:999px;white-space:nowrap;
}
html[data-theme="dark"] .pay-opt-pill{background:rgba(96,165,250,.16);color:#BFDBFE;border-color:rgba(96,165,250,.35)}
.pay-proof-card .pay-proof-body{align-items:center;gap:10px;flex-wrap:wrap}
.pay-proof-card .attach-actions{gap:10px}
.pay-proof-card .btn-attach{
  background:var(--tint-3);border:1px solid var(--line);border-radius:11px;
  min-height:44px;padding:8px 16px;font-weight:700;
}
.pay-proof-card .pay-proof-hint{flex:1 1 180px;min-width:0;margin:0}
.pay-proof-card.is-warn{border-color:rgba(220,38,38,.55)}

/* ── Kaki kartu: rata kanan, tombol lembut + tombol utama hijau ───────── */
.pay-foot{justify-content:flex-end;gap:10px;padding-top:12px}
.pay-foot .foot-note{flex:1 1 100%;margin:0 0 2px;text-align:left}
.pay-btn-soft{
  background:var(--tint-3);border:1px solid var(--line);color:var(--ink-strong);
  min-height:46px;padding:0 22px;font-weight:700;border-radius:11px;
}
.pay-btn-soft:hover{background:var(--tint-2,#eef)}
.pay-btn-main{
  min-height:46px;padding:0 26px;font-weight:800;border-radius:11px;
  background:#0E7C6B;border:1px solid #0B6A5C;color:#fff;
  display:inline-flex;align-items:center;gap:9px;
}
.pay-btn-main svg{width:18px;height:18px;fill:currentColor}
.pay-btn-main:hover{background:#0B6A5C}
html[data-theme="dark"] .pay-btn-main{background:#12A38D;border-color:#0E7C6B;color:#04231D}
html[data-theme="dark"] .pay-btn-main:hover{background:#2DD4A7}

/* ── Responsif ────────────────────────────────────────────────────────── */
@media (max-width:1180px){
  .pay-items-wrap{max-height:none}
}
@media (max-width:900px){
  .pay-title{font-size:1.2rem}
  .pay-items-head{padding:11px 13px;gap:8px}
  .pay-items-head h3{font-size:1rem}
  .pay-items-wrap{margin:12px 12px 0}
  .pay-total-row{margin:12px 12px 12px;padding:12px 14px}
  .pay-total-row span{font-size:1rem}
  .pay-total-row strong{font-size:1.3rem}
  .pay-fields{grid-template-columns:repeat(2,minmax(0,1fr))}
  .pay-foot .btn{flex:0 1 auto}
}
@media (max-width:640px){
  .pay-head-icon{width:38px;height:38px;border-radius:11px}
  .pay-head-icon svg{width:20px;height:20px}
  .pay-title{font-size:1.06rem;gap:6px}
  .pay-sub{font-size:.86rem}
  .pay-fields{grid-template-columns:minmax(0,1fr)}
  .pay-account-field,.pay-amount-field{grid-column:auto}
  .pay-foot{flex-wrap:wrap}
  .pay-foot .foot-note{flex:1 1 100%}
  .pay-foot .btn{flex:1 1 100%;justify-content:center}
  .pay-proof-card{padding:12px 13px}
  .pay-items-head h3{font-size:.95rem}
  .pay-item-count{font-size:.74rem;padding:5px 10px}
  /* tabel ringkas: sembunyikan No, Satuan, Harga (lihat blok tabel HP di atas) */
  table.data.pay-items-table .col-sub{width:96px;font-size:.82rem}
  table.data.pay-items-table .col-qty{width:40px}
}

/* Pil status kartu Bukti Pembayaran (kartu tagihan): opsional / sudah / wajib */
.pay-opt-pill.is-ok{background:rgba(22,163,74,.14);color:#15803D;border-color:rgba(22,163,74,.32)}
.pay-opt-pill.is-warn{background:rgba(220,38,38,.12);color:#B91C1C;border-color:rgba(220,38,38,.32)}
html[data-theme="dark"] .pay-opt-pill.is-ok{background:rgba(74,222,128,.16);color:#BBF7D0;border-color:rgba(74,222,128,.34)}
html[data-theme="dark"] .pay-opt-pill.is-warn{background:rgba(248,113,113,.16);color:#FECACA;border-color:rgba(248,113,113,.34)}

/* ≤400px: kepala "Detail Transaksi" — pil Total Item turun ke baris kedua supaya
   judul tidak terpotong (di 320px ruangnya hanya 88px untuk judul 118px). */
@media (max-width:400px){
  .pay-items-head{flex-wrap:wrap;row-gap:8px}
  .pay-items-head h3{white-space:normal;overflow:visible;text-overflow:clip}
  .pay-item-count{margin-left:0}
}

/* ══════════════════════════════════════════════════════════════════════════
   KARTU PEMBAYARAN TAGIHAN — KEMBALI KE DESAIN CONTOH PEMILIK
   (lampiran "Kasir › Pembayaran Tagihan")
   ──────────────────────────────────────────────────────────────────────────
   Ronde sebelumnya mengubah empat hal yang membuat tampilan TIDAK lagi sama
   dengan contoh (judul rata kanan, tabel dipaksa satu baris ber-elipsis,
   huruf tabel & Total Tagihan dikecilkan). Semua dikembalikan di sini:
     A. Kepala: ikon toko lalu judul + kode/pasien RATA KIRI di sampingnya.
     B. Tabel Detail Transaksi: nama produk tebal, keterangan (zat aktif /
        kategori layanan) TURUN DI BAWAHNYA dengan warna BIRU.
     C. Huruf tabel & baris Total Tagihan kembali nyaman dibaca.
     D. Ikon bank di kiri DALAM kotak "Akun Bank / Akun Kas".
     E. Kartu kiri mengisi tinggi baris; Total Tagihan menempel di dasarnya.
   ══════════════════════════════════════════════════════════════════════════ */

/* Kartu hampir selebar layar (contoh desain memakai seluruh ruang) */
.sheet-card.wide.pay-sheet{width:min(1660px,100%)}

/* A ── kepala: rata kiri menempel di samping ikon (tombol tetap di kanan) */
.pay-head{gap:14px;align-items:flex-start;justify-content:flex-start}
.pay-head .row-actions{margin-left:auto;flex:0 0 auto}
.pay-head-text{display:flex;flex-direction:column;align-items:flex-start;text-align:left;min-width:0}
.pay-head-text .pay-title{justify-content:flex-start;text-align:left;font-size:1.55rem}
.pay-head-text .pay-sub{text-align:left;font-size:.95rem;font-weight:700}

/* B + C ── tabel rincian: dua baris per item, keterangan biru */
table.data.pay-items-table{font-size:.88rem}
/* ⚠️ `.col-no` (750) & `.col-sub` (800) punya aturan sendiri dengan spesifisitas
   LEBIH TINGGI (0,3,1) daripada `… thead th` (0,2,3), sehingga judul kolom itu
   tampil lebih berat. Keduanya dinormalkan agar SEMUA judul kolom sama. */
table.data.pay-items-table thead th,
table.data.pay-items-table thead th.col-no,
table.data.pay-items-table thead th.col-sub,
table.data.pay-items-table thead th.col-qty,
table.data.pay-items-table thead th.col-price,
table.data.pay-items-table thead th.col-unit{
  font-size:.74rem;padding:9px 9px;white-space:nowrap;letter-spacing:.07em;font-weight:650;
}
table.data.pay-items-table td{
  padding:10px 9px;line-height:1.3;white-space:normal;overflow:visible;text-overflow:clip;
}
table.data.pay-items-table td.col-no,
table.data.pay-items-table td.col-qty,
table.data.pay-items-table td.col-unit,
table.data.pay-items-table td.col-price,
table.data.pay-items-table td.col-sub{white-space:nowrap}
.pay-item-name{min-width:0}
.pay-item-name strong{display:block;font-size:.92rem;font-weight:800;line-height:1.25}
.pay-item-name .pay-item-sub{
  display:block;margin-top:2px;font-size:.78rem;font-weight:600;line-height:1.25;
  color:#2563EB;white-space:normal;
}
html[data-theme="dark"] .pay-item-name .pay-item-sub{color:#93C5FD}
/* ⚠️ HANYA sel BODY (`td`) yang diperbesar. Dulu selektornya tanpa `td`
   sehingga juga mengenai `<th>` dan membuat judul kolom lebih besar daripada
   kolom lain (keluhan pemilik). Ukuran judul kolom kini seragam dari `thead th`. */
table.data.pay-items-table td.col-price,
table.data.pay-items-table td.col-sub{font-size:.86rem}

/* E ── kartu kiri setinggi kolom kanan; Total Tagihan menempel di dasar */
.pay-grid{align-items:stretch}
.pay-items-card{display:flex;flex-direction:column}
.pay-items-wrap{flex:1 1 auto;max-height:none;min-height:0}
.pay-total-row{margin:14px 16px 16px;padding:13px 18px}
.pay-total-row span{font-size:1.06rem;font-weight:850}
.pay-total-row strong{font-size:1.5rem;font-weight:900}

/* Petak ringkasan: label + nominal lebih tegas seperti contoh */
.pay-stat{padding:13px 14px;gap:11px}
.pay-stat-icon{width:36px;height:36px;border-radius:11px}
.pay-stat-icon svg{width:21px;height:21px}
.pay-stat-label{font-size:.82rem}
.pay-stat-value{font-size:1.4rem}

/* D ── ikon bank di dalam kotak akun */
.pay-fields .field > .pay-acct-wrap{
  position:relative;display:block;min-width:0;
  font-size:inherit;font-weight:inherit;color:inherit;letter-spacing:0;
}
.pay-acct-icon{
  position:absolute;left:12px;top:50%;transform:translateY(-50%);
  width:19px;height:19px;fill:var(--ink-2);pointer-events:none;z-index:2;
}
.pay-acct-wrap > select,
.pay-acct-wrap > .cs-btn{padding-left:40px}
.pay-fields .pay-account-field select,
.pay-fields .pay-account-field .cs-btn .cs-label{font-weight:700}

/* ══════════════════════════════════════════════════════════════════════════
   RACIKAN (baris ringkas yang bisa DIKLIK) & BARIS EMBALASE
   ──────────────────────────────────────────────────────────────────────────
   Permintaan pemilik:
     · obat racikan tampil sebagai SATU baris ringkas
       `Racikan <Sediaan> · qty · sediaan · subtotal` yang **default TERTUTUP**;
       diklik → menampilkan nama obat, qty, satuan, dan harga tiap bahan;
     · kolom Embalase DIHAPUS → totalnya menjadi satu baris pada Produk & Layanan.
   Baris turunan hanya disembunyikan bila JavaScript aktif (`.pay-cmp-js`),
   sehingga tanpa JavaScript semua rincian tetap terbaca (tidak ada data hilang).
   ══════════════════════════════════════════════════════════════════════════ */
.pay-cmp-toggle{
  display:inline-flex;align-items:center;gap:6px;max-width:100%;
  padding:0;border:0;background:none;color:inherit;font:inherit;
  font-size:.92rem;font-weight:800;line-height:1.25;text-align:left;cursor:pointer;
}
.pay-cmp-toggle:hover .pay-cmp-title{text-decoration:underline}
.pay-cmp-toggle:focus-visible{outline:2px solid var(--focus-border);outline-offset:2px;border-radius:4px}
.pay-cmp-caret{
  width:14px;height:14px;flex:0 0 14px;fill:var(--brand,#0E7C6B);
  transition:transform .15s ease;
}
.pay-cmp-parent.is-open .pay-cmp-caret{transform:rotate(90deg)}
html[data-theme="dark"] .pay-cmp-caret{fill:#2DD4A7}
.pay-cmp-title{min-width:0}

/* Baris turunan racikan */
tr.pay-cmp-detail > td{padding:0 9px 10px!important;border-bottom:1px solid var(--row-border)}
.pay-cmp-js tr.pay-cmp-detail{display:none}
.pay-cmp-js tr.pay-cmp-detail.is-open{display:table-row}
.pay-cmp-box{
  margin:2px 0 0 20px;padding:8px 10px;border-radius:10px;
  border:1px dashed var(--line-strong);background:var(--tint-3);
}
.pay-cmp-table{width:100%;border-collapse:collapse;font-size:.8rem}
/* ⚠️ Selektor WAJIB `.pay-items-table .pay-cmp-table …` (spesifisitas sama dengan
   aturan judul tabel utama, tetapi ditulis lebih akhir) — kalau hanya
   `.pay-cmp-table thead th`, aturan utama menang dan judul tabel racikan ikut
   berukuran penuh. */
.pay-items-table .pay-cmp-table thead th{
  padding:4px 8px;text-align:left;font-size:.7rem;font-weight:650;
  letter-spacing:.06em;text-transform:uppercase;color:var(--ink-2);
  background:transparent;border-bottom:1px solid var(--line);white-space:nowrap;
}
.pay-cmp-table td{padding:6px 8px;border-bottom:1px dashed var(--line);vertical-align:top;line-height:1.3}
.pay-cmp-table tbody tr:last-child td{border-bottom:0}
.pay-cmp-table .cmp-qty{width:56px;text-align:center;white-space:nowrap;font-variant-numeric:tabular-nums}
.pay-cmp-table .cmp-unit{width:78px;white-space:nowrap}
.pay-cmp-table .cmp-price{width:104px;text-align:right;white-space:nowrap;font-variant-numeric:tabular-nums}
.pay-cmp-table .cmp-sub{width:112px;text-align:right;white-space:nowrap;font-weight:700;font-variant-numeric:tabular-nums}
.pay-cmp-table .pay-item-sub{display:block;margin-top:1px;font-size:.72rem}

/* Baris EMBALASE (satu baris pada Produk & Layanan) */
tr.pay-emb-row td{background:rgba(217,119,6,.05)}
html[data-theme="dark"] tr.pay-emb-row td{background:rgba(251,191,36,.07)}

/* Kaki kartu: tombol lembut hampir putih seperti contoh */
.pay-btn-soft{background:var(--panel);border-color:var(--line)}
.pay-btn-soft:hover{background:var(--tint-3)}

/* ── JENIS PEMBAYARAN: huruf pilihannya DITEBALKAN setelah dipilih (permintaan
   pemilik). Berlaku untuk `<select>` asli maupun tombol combobox pencarian
   (`.cs-btn .cs-label`) yang menggantikannya. Akun ikut tebal supaya seragam. */
/* Teks pilihan dropdown: setelah dipilih cukup TEBAL SEDANG (650) senada tema;
   saat masih placeholder tetap redup. Jangan 750/800 — terlalu berat. */
.pay-fields .field select,
.pay-fields .field .cs-btn .cs-label{font-weight:650;color:var(--ink)}
.pay-fields .field .cs-btn.is-empty .cs-label{font-weight:500;color:var(--ink-3)}

/* Nomor Rekam Medis setelah nama pasien di kepala kartu (DATA → tetap tampil
   walau tombol Info dimatikan karena memakai warna teks biasa, bukan `.muted`). */
.pay-sub .pay-rme-sep{color:var(--ink-3);margin:0 2px}
.pay-sub .pay-rme{font-weight:800}

/* Jendela 1181–1400px: dua kolom masih dipakai, petak ringkasan menyempit →
   ukuran dirapatkan supaya nominal TIDAK terpotong elipsis. */
@media (min-width:1181px) and (max-width:1400px){
  .pay-stat{padding:12px;gap:9px}
  .pay-stat-icon{width:30px;height:30px;border-radius:9px}
  .pay-stat-icon svg{width:17px;height:17px}
  .pay-stat-value{font-size:1.12rem}
  .pay-stat-label{font-size:.76rem}
}

@media (max-width:1180px){
  .pay-items-wrap{max-height:none}
}
@media (max-width:900px){
  .pay-head-text .pay-title{font-size:1.28rem}
  .pay-stat-value{font-size:1.18rem}
  .pay-stat-icon{width:32px;height:32px}
  .pay-stat-icon svg{width:19px;height:19px}
}
@media (max-width:640px){
  .pay-head-text .pay-title{font-size:1.1rem}
  .pay-head-text .pay-sub{font-size:.86rem}
  table.data.pay-items-table{font-size:.8rem}
  table.data.pay-items-table td{padding:8px 6px}
  .pay-item-name strong{font-size:.84rem}
  .pay-item-name .pay-item-sub{font-size:.74rem}
  table.data.pay-items-table .col-qty{width:34px}
  table.data.pay-items-table .col-sub{width:88px}
  .pay-total-row span{font-size:.98rem}
  .pay-total-row strong{font-size:1.26rem}
  .pay-acct-icon{left:11px;width:17px;height:17px}
  .pay-acct-wrap > select,
  .pay-acct-wrap > .cs-btn{padding-left:36px}
}

/* Token warna khusus kartu "Penjualan Apotek" (dipakai blok .apx-* di bawah).
   Nilai mengikuti contoh desain pemilik: hijau lembut untuk latar petak, biru
   untuk keterangan stok/rak, hijau muda untuk kotak subtotal, merah lembut untuk
   tombol hapus. Tema gelap punya nilai sendiri supaya kontras tetap aman. */
:root{
  --apx-tint:rgba(45,212,167,.07);
  /* Biru untuk "Stok & Rak" dan nama kasir. Di tema gelap dipakai biru terang
     (#7EA6FF) karena #0000ff di atas latar gelap nyaris tak terbaca — nilai
     persis #0000ff dipakai di tema terang sesuai permintaan pemilik. */
  --apx-link:#7EA6FF;
  --apx-blue:#7EA6FF;
  --apx-sub-bg:rgba(45,212,167,.16);
  --apx-sub-ink:#B8FFE8;
  --apx-del-bg:rgba(248,113,113,.16);
  --apx-del-bg2:rgba(248,113,113,.26);
  --apx-del-bd:rgba(248,113,113,.34);
  --apx-del-ink:#FCA5A5;
  --apx-total-bg:rgba(45,212,167,.14);
  --apx-total-bd:rgba(45,212,167,.30);
  /* ⚠️ Blok ini = TEMA GELAP (`:root`). Nilai TERANG ada di `html[data-theme="light"]`.
     Jangan menaruh warna terang di sini (header tabel & tombol pintasan akan menyala). */
  --apx-th-bg:rgba(148,163,184,.13);
  --apx-line:rgba(148,163,184,.22);
  --apx-line-strong:rgba(148,163,184,.34);
  --apx-quick-bg:rgba(148,163,184,.13);
  --apx-quick-bg2:rgba(148,163,184,.22);
  --apx-recv-bg:rgba(45,212,167,.10);
  --apx-recv-bd:rgba(45,212,167,.55);
}
html[data-theme="light"]{
  --apx-tint:#F1F7F4;
  --apx-link:#0000ff;
  --apx-blue:#0000ff;
  --apx-sub-bg:#E8F6EF;
  --apx-sub-ink:#0B6A5C;
  --apx-del-bg:#FEE9E9;
  --apx-del-bg2:#FDD8D8;
  --apx-del-bd:#FBC7C7;
  --apx-del-ink:#DC2626;
  --apx-total-bg:#EAF7F0;
  --apx-total-bd:#CFEBDD;
  --apx-th-bg:#F3F5F7;
  --apx-line:#E4E9EE;
  --apx-line-strong:#D6DEE6;
  --apx-quick-bg:#F3F5F7;
  --apx-quick-bg2:#E8EDF1;
  --apx-recv-bg:#F4FBF7;
  --apx-recv-bd:#5FBF9F;
}

/* ══════════════════════════════════════════════════════════════════════════
   KASIR APOTEK — KARTU "PENJUALAN APOTEK" SATU LAYAR (desain contoh pemilik)
   ──────────────────────────────────────────────────────────────────────────
   Susunan: kepala (ikon + judul) · baris ringkas (tanggal/jam + Kasir | Pasien +
   Penjualan Resep + Detail Resep) · kartu **Produk** (kepala hijau, tabel 8
   kolom + kolom cari/pindai) · kartu **Ringkasan Tagihan & Pembayaran**
   (kepala hijau, 4 kolom) · kaki [Batal] [Simpan Penjualan].
   Warna memakai token tema (--brand/--panel/--line) supaya ikut tema gelap &
   terang. TIDAK memakai backdrop-filter (aturan performa global).
   ══════════════════════════════════════════════════════════════════════════ */
.apx-sheet{width:min(1560px,100%)}
.apx-head{gap:12px;align-items:center}
.apx-head-icon{
  width:46px;height:46px;flex:0 0 auto;border-radius:13px;display:grid;place-items:center;
  background:rgba(14,124,107,.13);color:var(--brand,#0E7C6B);
}
.apx-head-icon svg{width:27px;height:27px;fill:currentColor}
html[data-theme="dark"] .apx-head-icon{background:rgba(45,212,167,.16);color:#2DD4A7}
.apx-head-text{min-width:0;margin-right:auto}
.apx-head-text h2{margin:0;font-size:1.65rem;line-height:1.2;color:var(--head-ink)}
/* Tombol kepala kartu: putih + garis tipis (sesuai contoh desain pemilik). */
.apx-head .row-actions{gap:14px}
.apx-head .row-actions .btn{
  min-height:46px;padding-inline:22px;border-radius:11px;font-weight:700;
  background:var(--panel);border:1px solid var(--line-strong);color:var(--ink);
}
.apx-head .row-actions .btn:hover{background:var(--tint-3)}
.apx-head .row-actions .btn svg{width:17px;height:17px;fill:currentColor}
.apx-body{padding-top:16px}
/* ⚠️ `.sheet-body` adalah flex-column: tanpa `flex:0 0 auto` setiap kartu ikut
   MENYUSUT saat isi kartu melebihi tinggi layar, sehingga kartu Produk memotong
   tabel & kartu Ringkasan menimpanya (bug nyata saat kartu ini dirancang ulang). */
.apx-body > *{flex:0 0 auto}

/* ── baris ringkas: tanggal/jam + kasir | pasien + resep ───────────────── */
.apx-top{display:grid;grid-template-columns:minmax(0,.72fr) minmax(0,1.9fr);gap:16px;margin-bottom:16px}
.apx-meta,.apx-patient{
  display:flex;gap:9px;min-width:0;padding:10px 13px;border-radius:15px;
  border:1px solid var(--line-strong);background:var(--apx-tint);
}
.apx-meta{flex-direction:column;justify-content:center}
.apx-patient{align-items:center;flex-wrap:nowrap}
.apx-date{display:flex;align-items:center;gap:9px;flex:0 0 auto;font-size:1rem;font-weight:750;color:var(--ink-strong)}
.apx-ico{display:grid;place-items:center;width:27px;height:27px;border-radius:8px;flex:0 0 27px;
  background:rgba(14,124,107,.14);color:var(--brand,#0E7C6B)}
.apx-ico svg{width:16px;height:16px;fill:currentColor}
html[data-theme="dark"] .apx-ico{background:rgba(45,212,167,.16);color:#2DD4A7}
.apx-sep{color:var(--ink-3);font-weight:400}
.apx-clock{font-family:var(--mono);font-size:1.05rem;letter-spacing:.02em;color:var(--ink)}
/* "Kasir" + dropdown dalam satu kotak putih */
.apx-kasir-row{
  display:flex;align-items:center;gap:12px;min-width:0;padding:3px 5px 3px 13px;
  border-radius:11px;border:1px solid var(--line-strong);background:var(--panel);
}
.apx-kasir-lbl{font-size:.92rem;font-weight:800;color:var(--ink-strong);flex:0 0 auto}
.apx-kasir{flex:1 1 auto;min-width:0;margin:0;gap:0}
.apx-kasir > select{min-height:37px}
/* Nama kasir terpilih dibuat BIRU (permintaan pemilik). Combobox menampilkan
   teks lewat `.cs-label`, jadi keduanya diwarnai. */
.apx-kasir .cs-btn,.apx-kasir .cs-btn .cs-label,.apx-kasir > select{color:var(--apx-blue)}
.apx-kasir .cs-btn .cs-label{font-weight:750}
.apx-patient{background:var(--apx-tint)}
.apx-pat-field{
  display:grid;grid-template-columns:auto minmax(0,1fr);align-items:start;gap:10px;
  flex:1 1 300px;min-width:0;
}
.apx-pat-field > .apx-ico{margin-top:2px}
.apx-patient .apx-wide{flex:1 1 auto;min-width:0;margin:0}
/* Label "Pasien" & "Kasir" pada kartu ini lebih besar dari label isian biasa. */
.apx-patient .apx-wide > span:not(.money-prefix),
.apx-kasir > span:not(.money-prefix){font-size:.92rem;font-weight:800;color:var(--ink-strong)}
/* garis pemisah tipis antar blok di kartu pasien (contoh desain pemilik) */
.apx-vr{width:1px;align-self:stretch;background:var(--line-strong);flex:0 0 1px;margin-block:6px}
.apx-rx-toggle{display:flex;align-items:center;gap:9px;flex:0 0 auto}
.apx-rx-badge{display:grid;place-items:center;width:30px;height:30px;border-radius:9px;flex:0 0 30px;
  background:rgba(14,124,107,.14);color:var(--brand,#0E7C6B)}
.apx-rx-badge svg{width:18px;height:18px;fill:currentColor}
html[data-theme="dark"] .apx-rx-badge{background:rgba(45,212,167,.16);color:#2DD4A7}
.apx-rx-label{font-size:.9rem;font-weight:700;color:var(--ink-strong);white-space:nowrap}
.apx-switch{width:auto!important;max-width:none;min-height:0;padding:0;gap:0;border:0;background:none}
.apx-switch .ps-knob{flex:0 0 46px;width:46px;height:26px}
.apx-switch .ps-knob::after{width:20px;height:20px}
.apx-switch:has(input:checked) .ps-knob::after{transform:translateX(20px)}
/* Tombol Detail Resep: putih + garis & tulisan HIJAU (bukan abu-abu). */
.apx-rx-open{
  flex:1 1 260px;max-width:440px;min-height:46px;padding-inline:18px;font-weight:750;border-radius:11px;
  display:inline-flex;align-items:center;justify-content:center;gap:9px;
  background:var(--panel);border:1.5px solid var(--brand,#0E7C6B);
  color:var(--brand,#0E7C6B);
}
html[data-theme="dark"] .apx-rx-open{border-color:#2DD4A7;color:#2DD4A7;background:rgba(45,212,167,.08)}
.apx-rx-open svg{width:18px;height:18px;fill:currentColor}
.apx-rx-open:hover{background:rgba(14,124,107,.08)}
.apx-rx-open.is-active{background:var(--brand,#0E7C6B);border-color:var(--brand,#0E7C6B);color:#fff}
.apx-rx-panel{
  margin-bottom:16px;padding:14px;border-radius:14px;border:1px dashed var(--line-strong);
  background:var(--tint-3);
}
.apx-rx-panel .form-section-head{margin-bottom:10px}

/* ── kartu (Produk & Ringkasan): kepala hijau tua ──────────────────────── */
/* `overflow:visible` WAJIB: daftar autocomplete pencarian obat menempel di
   bawah kolom cari dan akan TERPOTONG bila kartu memakai overflow:hidden. */
.apx-card{border:1px solid var(--line);border-radius:15px;background:var(--panel);overflow:visible;margin-bottom:16px}
.apx-card-head{
  display:flex;align-items:center;gap:11px;padding:11px 17px;
  background:var(--brand,#0E7C6B);color:#fff;
  border-radius:14px 14px 0 0;
}
html[data-theme="dark"] .apx-card-head{background:#0F7A6A}
.apx-card-ico{display:grid;place-items:center;width:30px;height:30px;border-radius:9px;
  background:rgba(255,255,255,.16);color:#fff;flex:0 0 30px}
.apx-card-ico svg{width:18px;height:18px;fill:currentColor}
.apx-card-head h3{margin:0;font-size:1.14rem;font-weight:800;color:#fff;letter-spacing:.01em}
.apx-count{margin-left:auto;display:inline-flex;align-items:center;background:rgba(255,255,255,.92);color:#0C4A3E;
  font-size:.78rem;font-weight:750;padding:5px 12px;border-radius:999px;white-space:nowrap}
html[data-theme="dark"] .apx-count{background:#F3FFFB;color:#0A3F35}

/* ── tabel produk ──────────────────────────────────────────────────────── */
.apx-table-wrap{margin:14px 16px 0;border:1px solid var(--line);border-radius:13px;overflow:auto;max-height:none}
/* ⚠️ `.sheet-body .table-wrap` memakai `content-visibility:auto` (tinggi wadah
   "dikira-kira" 300px) sehingga kartu Produk menghitung tinggi yang salah dan
   kartu Ringkasan di bawahnya MENIMPA tabel. Wadah tabel kartu ini harus selalu
   dirender utuh. */
.sheet-body .apx-table-wrap{content-visibility:visible;contain:none}
table.data.apx-table{width:100%;min-width:0;margin:0;table-layout:fixed}
/* Judul kolom: Title Case (bukan KAPITAL), tebal & gelap seperti contoh desain. */
table.data.apx-table thead th{
  font-size:.84rem;letter-spacing:0;text-transform:none;font-weight:750;
  color:var(--ink-strong);background:var(--apx-th-bg);padding:12px 13px;white-space:nowrap;
  border-bottom:1px solid var(--apx-line);
}
table.data.apx-table td{padding:11px 12px;vertical-align:middle;white-space:normal}
table.data.apx-table tbody tr + tr td{border-top:1px solid var(--apx-line)}
.apx-col-no{width:44px;text-align:center;font-weight:750}
.apx-col-item{width:auto;min-width:0}
.apx-col-qty{width:96px}
.apx-col-unit{width:128px}
.apx-col-price{width:132px}
.apx-col-emb{width:150px}
.apx-col-sub{width:148px;text-align:right}
.apx-col-act{width:66px;text-align:center}
/* Nama obat tebal; keterangan stok & rak BIRU (contoh desain pemilik). */
table.data.apx-table .apx-col-item .cs-btn{
  font-weight:750;color:var(--ink-strong);background:var(--panel);
  border:1px solid var(--line-strong);border-radius:9px;min-height:40px;
}
.apx-hint{display:block;margin-top:5px;font-size:.76rem;font-weight:650;color:var(--apx-link);line-height:1.25}
.apx-hint.is-stock{color:var(--apx-link)}
table.data.apx-table .apx-col-sub .apx-sub{
  display:block;padding:10px 14px;border-radius:9px;font-weight:800;white-space:nowrap;text-align:right;
  background:var(--apx-sub-bg);color:var(--apx-sub-ink);font-variant-numeric:tabular-nums;font-size:1rem;
}
table.data.apx-table input[type=number]{text-align:center}
table.data.apx-table input[data-money]{text-align:right;font-variant-numeric:tabular-nums}
table.data.apx-table input[type=number],
table.data.apx-table input[data-money]{min-height:40px;border-radius:9px;background:var(--panel)}
/* Kolom Harga di tabel kartu ini ramping → batas `min-width:96px` milik
   `.money-wrap` (aturan tabel umum) menjepit nominalnya. Dilepas di sini. */
table.data.apx-table td .money-wrap{min-width:0}
/* Sel pemutus baris (dibuat assets/kasir-apotek.js) hanya dipakai di HP. */
table.data.apx-table td.apx-col-gap{display:none}
/* Tombol hapus: kotak merah lembut (bukan tombol teks). */
.apx-del{width:40px;height:40px;padding:0;display:inline-grid;place-items:center;border-radius:10px;
  background:var(--apx-del-bg);border:1px solid var(--apx-del-bd);color:var(--apx-del-ink)}
.apx-del:hover{background:var(--apx-del-bg2)}
.apx-del svg{width:18px;height:18px;fill:currentColor}

/* Centang embalase (kotak + nominal) */
.apx-emb{display:flex;align-items:center;gap:9px;cursor:pointer;font-size:.86rem;font-weight:700;color:var(--ink-strong)}
.apx-emb input{position:absolute;width:1px;height:1px;opacity:0;margin:0}
.apx-emb-box{width:20px;height:20px;flex:0 0 20px;border-radius:5px;border:1.5px solid var(--line-strong);
  background:var(--input-bg);display:grid;place-items:center;line-height:0}
/* ⚠️ Tanda centang memakai MASK SVG (bukan border yang diputar): hasilnya tepat
   di tengah kotak pada semua ukuran & zoom (dulu tampak miring ke kiri-atas). */
.apx-emb-box::after{
  content:'';display:block;width:14px;height:14px;background:#fff;transform:scale(0);
  transition:transform .12s ease;
  -webkit-mask:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M9.55 17.6 4.4 12.45l1.4-1.4 3.75 3.74 8.65-8.64 1.4 1.41z'/%3E%3C/svg%3E") center/contain no-repeat;
  mask:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M9.55 17.6 4.4 12.45l1.4-1.4 3.75 3.74 8.65-8.64 1.4 1.41z'/%3E%3C/svg%3E") center/contain no-repeat;
}
.apx-emb:has(input:checked) .apx-emb-box{background:var(--brand,#0E7C6B);border-color:var(--brand,#0E7C6B)}
.apx-emb:has(input:checked) .apx-emb-box::after{transform:scale(1)}
.apx-emb:has(input:disabled){opacity:.5;cursor:not-allowed}
.apx-emb-amt{font-variant-numeric:tabular-nums;white-space:nowrap;color:var(--ink-3)}
.apx-emb:has(input:checked) .apx-emb-amt{color:var(--ink-strong)}

/* kolom cari / pindai — SATU baris putih, ikon pindai & tambah di kanan DALAM baris */
.apx-search{
  position:relative;display:flex;align-items:center;gap:2px;margin:14px 16px 16px;padding:2px 6px 2px 12px;
  border:1px solid var(--line-strong);border-radius:12px;background:var(--panel);flex-wrap:nowrap;
}
.apx-search-ico{display:grid;place-items:center;width:26px;height:26px;flex:0 0 26px;color:var(--ink-2)}
.apx-search-ico svg{width:18px;height:18px;fill:currentColor}
.apx-search-field{flex:1 1 auto;min-width:0;margin:0;gap:0}
.apx-search-field input{
  width:100%;min-height:46px;padding:9px 12px;border:0!important;background:transparent!important;
  color:var(--ink);font-size:.95rem;box-shadow:none!important;
}
.apx-search-field input:focus{outline:none;box-shadow:none!important}
.apx-search-msg{font-size:.78rem;font-weight:700;color:var(--err-fg);flex:0 0 auto;padding-inline:6px}
.apx-scan,.apx-addrow{
  flex:0 0 auto;width:40px;height:40px;padding:0;display:inline-grid;place-items:center;
  border-radius:9px;border:0;background:transparent;color:var(--ink-2);
}
.apx-scan:hover,.apx-addrow:hover{background:var(--tint-3);color:var(--ink-strong)}
.apx-scan svg,.apx-addrow svg{width:20px;height:20px;fill:currentColor}

/* ── daftar autocomplete pencarian obat (live search ≥2 huruf) ─────────── */
.apx-ac{
  position:absolute;left:0;right:0;top:calc(100% + 6px);z-index:60;
  max-height:322px;overflow:auto;padding:6px;
  background:var(--pop-bg,var(--panel));border:1px solid var(--line-strong);border-radius:12px;
  box-shadow:0 16px 34px -16px rgba(6,20,40,.42);
}
.apx-ac[hidden]{display:none}
.apx-ac-item{
  display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:center;
  gap:1px 10px;padding:7px 9px;border-radius:8px;cursor:pointer;
}
.apx-ac-item.is-active{background:var(--tint-3)}
.apx-ac-name{font-size:.82rem;font-weight:750;color:var(--ink-strong);line-height:1.2}
.apx-ac-meta{font-size:.7rem;font-weight:650;color:var(--apx-link);line-height:1.25;grid-column:1}
.apx-ac-price{
  grid-row:1 / span 2;grid-column:2;align-self:center;white-space:nowrap;
  font-size:.78rem;font-weight:800;color:var(--ink-strong);font-variant-numeric:tabular-nums;
}
.apx-ac-empty{padding:10px 9px;font-size:.8rem;color:var(--ink-3)}

/* ── ringkasan tagihan & pembayaran ────────────────────────────────────── */
.apx-sum-grid{
  display:grid;grid-template-columns:minmax(0,1.12fr) minmax(0,1fr) minmax(0,1fr) minmax(0,1.02fr);
  gap:20px;padding:16px 18px 18px;align-items:start;
}
.apx-sum-left,.apx-sum-mid,.apx-sum-pay,.apx-sum-side{display:flex;flex-direction:column;gap:11px;min-width:0}
/* Garis pemisah kolom tipis (contoh desain pemilik). */
.apx-sum-mid,.apx-sum-side{border-left:1px solid var(--apx-line);padding-left:20px}
.apx-sum-line{
  display:grid;grid-template-columns:30px minmax(0,1fr) auto;align-items:center;gap:11px;
  padding:4px 2px;border:0;background:none;
}
.apx-sum-ico{display:grid;place-items:center;width:30px;height:30px;color:var(--brand,#0E7C6B)}
.apx-sum-ico svg{width:20px;height:20px;fill:currentColor}
html[data-theme="dark"] .apx-sum-ico{color:#2DD4A7}
.apx-sum-lbl{font-size:.9rem;font-weight:700;color:var(--ink-strong);min-width:0}
.apx-sum-lbl small{font-size:.76rem;font-weight:600;color:var(--ink-3)}
.apx-sum-line strong{font-size:1rem;font-weight:800;font-variant-numeric:tabular-nums;white-space:nowrap;color:var(--ink-strong)}
/* Baris Total Tagihan: latar hijau lembut, nominal dalam kotak hijau tua. */
.apx-total{
  display:grid;grid-template-columns:30px minmax(0,1fr) auto;align-items:center;gap:11px;
  margin-top:4px;padding:10px 12px;border-radius:12px;
  background:var(--apx-total-bg);border:1px solid var(--apx-total-bd);
}
.apx-total-ico{display:grid;place-items:center;width:30px;height:30px;color:var(--brand,#0E7C6B)}
.apx-total-ico svg{width:21px;height:21px;fill:currentColor}
html[data-theme="dark"] .apx-total-ico{color:#2DD4A7}
.apx-total-lbl{font-size:1.02rem;font-weight:850;color:var(--ink-strong)}
.apx-total-val{
  padding:9px 18px;border-radius:10px;background:var(--brand,#0E7C6B);color:#fff;
  font-size:1.26rem;font-weight:900;font-variant-numeric:tabular-nums;white-space:nowrap;
}
html[data-theme="dark"] .apx-total-val{background:#12A38D;color:#04231D}
.apx-sum-mid .field,.apx-sum-pay .field,.apx-sum-side .field{margin:0}
/* Label isian ringkasan: kecil, tegas (pola yang sama dengan tema aplikasi). */
.apx-sum-grid .field > span:not(.money-prefix){
  font-size:.8rem;font-weight:750;letter-spacing:.01em;color:var(--ink-strong);
}
.apx-sum-grid .field select,.apx-sum-grid .field input,.apx-sum-grid .field textarea,
.apx-sum-grid .field .cs-btn{min-height:42px;border-radius:10px;background:var(--panel)}
.apx-recv input{
  font-weight:850;font-size:1.08rem;height:46px;border-radius:9px;
  background:var(--apx-recv-bg)!important;border:1.5px solid var(--apx-recv-bd)!important;
  color:var(--apx-sub-ink);text-align:right;padding-right:14px;
}
html[data-theme="dark"] .apx-recv input{border-color:rgba(45,212,167,.55)!important;color:#B8FFE8}
.apx-change{
  display:flex;align-items:center;gap:8px;min-height:46px;padding:0 14px;
  border-radius:9px;border:1px solid var(--apx-line-strong);background:var(--panel);
}
.apx-change-cur{font-size:.9rem;font-weight:700;color:var(--ink-3);flex:0 0 auto}
.apx-change-val{
  margin-left:auto;font-size:1.06rem;font-weight:800;font-variant-numeric:tabular-nums;
  white-space:nowrap;color:var(--ink-strong);
}
.apx-change.is-zero .apx-change-val{color:var(--ink-3)}
.apx-quick{display:flex;gap:9px;flex-wrap:nowrap}
.apx-quick .btn{
  flex:1 1 0;min-width:0;justify-content:center;font-variant-numeric:tabular-nums;
  min-height:42px;border-radius:9px;background:var(--apx-quick-bg);border:1px solid var(--apx-line-strong);
  font-weight:750;color:var(--ink-strong);font-size:.88rem;
}
.apx-quick .btn:hover{background:var(--apx-quick-bg2)}
.apx-disc{max-width:200px}
.apx-sum-side textarea{min-height:62px;resize:vertical;font-size:.9rem}
.apx-proof{border:1px dashed var(--line-strong);border-radius:11px;padding:8px 11px;background:var(--tint-3)}
.apx-proof summary{cursor:pointer;font-size:.84rem;font-weight:750;color:var(--ink-2);
  display:flex;align-items:center;gap:8px}
.apx-proof[open] summary{margin-bottom:8px}
.apx-proof .attach-widget{margin-top:4px}

/* ── kaki kartu ────────────────────────────────────────────────────────── */
.apx-foot{gap:14px;justify-content:flex-end;padding-top:12px}
.apx-foot .apx-save{
  min-height:50px;padding-inline:26px;font-weight:800;border-radius:11px;
  display:inline-flex;align-items:center;gap:9px;
  background:#0E7C6B;border:1px solid #0B6A5C;color:#fff;
}
.apx-save-ico{
  display:grid;place-items:center;width:26px;height:26px;border-radius:7px;flex:0 0 26px;
  background:rgba(255,255,255,.20);
}
html[data-theme="dark"] .apx-save-ico{background:rgba(4,35,29,.16)}
.apx-foot .apx-save svg{width:16px;height:16px;fill:currentColor}
.apx-foot .apx-save:hover{background:#0B6A5C}
html[data-theme="dark"] .apx-foot .apx-save{background:#12A38D;border-color:#0E7C6B;color:#04231D}
html[data-theme="dark"] .apx-foot .apx-save:hover{background:#2DD4A7}
.apx-foot .apx-cancel{min-height:50px;padding-inline:26px;font-weight:700;border-radius:11px;
  display:inline-flex;align-items:center;border:1px solid var(--line);background:var(--panel)}

/* ══════════════════════════════════════════════════════════════════════════
   SKALA HURUF KARTU "PENJUALAN APOTEK" — DIPERKECIL (permintaan pemilik)
   ──────────────────────────────────────────────────────────────────────────
   Semua ukuran di blok ini SENGAJA ditulis ulang (bukan mengubah skala global
   `.content`/`html{font-size}`) supaya hanya kartu ini yang lebih ringkas:
   teks isi ~13–14px, label ~12px, judul kartu ~16px, nominal total ~18px.
   Baris tabel ikut lebih pendek sehingga 3 obat muat tanpa menggulir.
   ══════════════════════════════════════════════════════════════════════════ */
.apx-head-text h2{font-size:1.32rem}
.apx-card-head h3{font-size:.98rem}
.apx-count{font-size:.68rem;padding:4px 10px}
.apx-card-head{padding:10px 15px}
.apx-card-ico{width:27px;height:27px;flex:0 0 27px}
.apx-card-ico svg{width:16px;height:16px}
.apx-head-icon{width:42px;height:42px;border-radius:12px}
.apx-head-icon svg{width:23px;height:23px}
.apx-head .row-actions .btn{min-height:42px;padding-inline:18px;font-size:.82rem}
.apx-head .row-actions .btn svg{width:15px;height:15px}

.apx-meta,.apx-patient{padding:9px 12px;gap:8px}
.apx-date{font-size:.86rem}
.apx-clock{font-size:.9rem}
.apx-ico{width:25px;height:25px;flex:0 0 25px;border-radius:8px}
.apx-ico svg{width:15px;height:15px}
.apx-kasir-lbl{font-size:.82rem}
.apx-patient .apx-wide > span:not(.money-prefix),
.apx-kasir > span:not(.money-prefix){font-size:.82rem}
.apx-kasir-row{padding:2px 4px 2px 11px}
.apx-kasir > select{min-height:34px;font-size:.86rem}
.apx-kasir .cs-btn{min-height:34px;font-size:.86rem}
.apx-rx-badge{width:26px;height:26px;flex:0 0 26px}
.apx-rx-badge svg{width:16px;height:16px}
.apx-rx-label{font-size:.8rem}
.apx-rx-open{min-height:40px;font-size:.82rem;max-width:340px;flex:1 1 210px}
.apx-rx-open svg{width:16px;height:16px}
.apx-head .apx-rx-panel .form-section-head h3{font-size:.9rem}

/* tabel produk */
table.data.apx-table{font-size:.8rem}
table.data.apx-table thead th{font-size:.74rem;padding:8px 10px}
table.data.apx-table td{padding:7px 10px}
table.data.apx-table .apx-col-item .cs-btn{min-height:34px;font-size:.82rem}
.apx-hint{margin-top:3px;font-size:.68rem}
table.data.apx-table input[type=number],
table.data.apx-table input[data-money]{min-height:34px;font-size:.82rem}
table.data.apx-table .apx-col-sub .apx-sub{padding:7px 11px;font-size:.88rem;border-radius:8px}
.apx-emb{font-size:.76rem;gap:7px}
.apx-emb-box{width:18px;height:18px;flex:0 0 18px}
.apx-emb-box::after{width:13px;height:13px}
.apx-del{width:34px;height:34px;border-radius:9px}
.apx-del svg{width:16px;height:16px}
.apx-col-no{font-size:.78rem}
.apx-search{padding:1px 4px 1px 10px;margin:12px 15px 15px}
.apx-search-field input{min-height:40px;font-size:.84rem}
.apx-search-ico{width:22px;height:22px;flex:0 0 22px}
.apx-search-ico svg{width:16px;height:16px}
.apx-scan,.apx-addrow{width:36px;height:36px;border-radius:8px}
.apx-scan svg,.apx-addrow svg{width:19px;height:19px}
.apx-search-msg{font-size:.72rem}

/* ringkasan */
.apx-sum-grid{gap:16px;padding:13px 15px 15px}
.apx-sum-left,.apx-sum-mid,.apx-sum-pay,.apx-sum-side{gap:9px}
.apx-sum-mid,.apx-sum-side{padding-left:16px}
.apx-sum-line{grid-template-columns:25px minmax(0,1fr) auto;gap:9px;padding:2px 1px}
.apx-sum-ico{width:25px;height:25px}
.apx-sum-ico svg{width:17px;height:17px}
.apx-sum-lbl{font-size:.8rem}
.apx-sum-lbl small{font-size:.7rem}
.apx-sum-line strong{font-size:.86rem}
.apx-total{padding:8px 10px;gap:9px;grid-template-columns:25px minmax(0,1fr) auto}
.apx-total-ico{width:25px;height:25px}
.apx-total-ico svg{width:18px;height:18px}
.apx-total-lbl{font-size:.88rem}
.apx-total-val{font-size:1.02rem;padding:7px 13px;border-radius:9px}
.apx-sum-grid .field > span:not(.money-prefix){font-size:.72rem}
.apx-sum-grid .field select,.apx-sum-grid .field input,.apx-sum-grid .field textarea,
.apx-sum-grid .field .cs-btn{min-height:38px;font-size:.82rem}
.apx-recv input{height:40px;font-size:.92rem}
.apx-change{min-height:40px;padding:0 11px}
.apx-change-cur{font-size:.78rem}
.apx-change-val{font-size:.92rem}
.apx-quick{gap:7px}
.apx-quick .btn{min-height:36px;font-size:.74rem;border-radius:8px}
.apx-sum-side textarea{min-height:54px;font-size:.8rem}
.apx-proof summary{font-size:.76rem}
.apx-proof{padding:6px 9px}

/* kaki kartu */
.apx-foot{gap:12px}
.apx-foot .apx-save{min-height:44px;padding-inline:20px;font-size:.86rem}
.apx-save-ico{width:23px;height:23px;flex:0 0 23px;border-radius:6px}
.apx-foot .apx-save svg{width:14px;height:14px}
.apx-foot .apx-cancel{min-height:44px;padding-inline:20px;font-size:.86rem}

/* Ikon pindai: bingkai pemindai + garis barcode (versi lebih tegas). */
.apx-scan{color:var(--brand,#0E7C6B)}
html[data-theme="dark"] .apx-scan{color:#2DD4A7}
.apx-scan:hover{background:rgba(14,124,107,.10);color:var(--brand,#0E7C6B)}
html[data-theme="dark"] .apx-scan:hover{background:rgba(45,212,167,.14);color:#2DD4A7}
.apx-scan-svg{width:20px;height:20px}

/* ══════════════════════════════════════════════════════════════════════════
   PENYEMPURNAAN RONDE BERIKUT (permintaan pemilik)
   ══════════════════════════════════════════════════════════════════════════ */

/* (3) Prefix "Rp" pada [Jumlah Diterima]: DIPERBESAR, tetap HIJAU, dan ukuran
   hurufnya SAMA dengan nilai [Kembalian] (`.apx-change-val`). */
.apx-recv .money-wrap > .money-prefix{
  font-family:inherit;font-size:.92rem;font-weight:800;letter-spacing:0;
  color:var(--apx-sub-ink);opacity:1;
}
html[data-theme="dark"] .apx-recv .money-wrap > .money-prefix{color:#B8FFE8}
.apx-recv .money-wrap > input[data-money]{padding-left:34px!important}

/* (4) [Total Tagihan] diperkecil (label & nominal). */
.apx-total-lbl{font-size:.8rem;font-weight:800}
.apx-total-val{font-size:.92rem;padding:6px 11px;border-radius:8px}
.apx-total{padding:7px 9px;gap:8px;grid-template-columns:22px minmax(0,1fr) auto}
.apx-total-ico{width:22px;height:22px}
.apx-total-ico svg{width:16px;height:16px}

/* (6) Judul kartu [Produk] & [Ringkasan Tagihan & Pembayaran] diperkecil. */
.apx-prod .apx-card-head h3,
.apx-sum .apx-card-head h3{font-size:.82rem;font-weight:750;letter-spacing:.01em}
.apx-prod .apx-card-head,
.apx-sum .apx-card-head{padding:8px 14px;gap:9px}
.apx-prod .apx-card-ico,
.apx-sum .apx-card-ico{width:23px;height:23px;flex:0 0 23px;border-radius:7px}
.apx-prod .apx-card-ico svg,
.apx-sum .apx-card-ico svg{width:14px;height:14px}
.apx-count{font-size:.64rem;padding:3px 9px}

/* (8) Kolom Harga READ-ONLY: tampak seperti teks (bukan kolom isian) tapi tetap
   berada di dalam kotak agar sejajar dengan kolom lain. */
table.data.apx-table input[data-money][readonly],
table.data.apx-table input[data-money][readonly]:focus{
  background:var(--tint-3)!important;color:var(--ink-strong);cursor:default;
  border-style:dashed!important;box-shadow:none!important;
}
table.data.apx-table input[data-money][readonly]:hover{background:var(--tint-3)!important}
/* Kolom Jumlah kosong: placeholder samar supaya jelas harus diisi. */
table.data.apx-table input[type=number]::placeholder{color:var(--ink-3);font-weight:600}

/* (2) Tombol IKON [Simpan Antrian] di kaki kartu + TOOLTIP saat hover.
   ⚠️ Tooltip global `.act-tip` sudah DIHAPUS dari aplikasi (permintaan pemilik
   sebelumnya), jadi tooltip di sini dibuat lokal dengan pseudo-element pada
   tombolnya. `overflow` kaki kartu dibiarkan terlihat supaya balon tooltip tidak
   terpotong. */
.apx-foot{overflow:visible}
.apx-foot .apx-queue-save{
  position:relative;
  width:44px;min-width:44px;height:44px;padding:0;display:inline-grid;place-items:center;
  border-radius:10px;background:var(--panel);border:1px solid var(--line-strong);
  color:var(--brand,#0E7C6B);
}
.apx-foot .apx-queue-save::after{
  content:attr(data-tip);
  position:absolute;bottom:calc(100% + 10px);left:50%;transform:translate(-50%,4px);
  padding:6px 11px;border-radius:8px;white-space:nowrap;
  background:#0B1B2B;color:#fff;font-size:.72rem;font-weight:700;letter-spacing:.01em;
  opacity:0;pointer-events:none;transition:opacity .14s ease,transform .14s ease;z-index:5;
}
.apx-foot .apx-queue-save::before{
  content:'';position:absolute;bottom:calc(100% + 4px);left:50%;transform:translateX(-50%);
  border:5px solid transparent;border-top-color:#0B1B2B;
  opacity:0;pointer-events:none;transition:opacity .14s ease;z-index:5;
}
.apx-foot .apx-queue-save:hover::after,
.apx-foot .apx-queue-save:focus-visible::after,
.apx-foot .apx-queue-save:hover::before,
.apx-foot .apx-queue-save:focus-visible::before{opacity:1;transform:translate(-50%,0)}
html[data-theme="dark"] .apx-foot .apx-queue-save{color:#2DD4A7}
.apx-foot .apx-queue-save:hover{background:rgba(14,124,107,.10)}
html[data-theme="dark"] .apx-foot .apx-queue-save:hover{background:rgba(45,212,167,.14)}
.apx-foot .apx-queue-save svg{width:19px;height:19px;fill:currentColor}

/* Kartu "Daftar Antrian Transaksi" (menggantikan "Pembayaran apotek terakhir"). */
.apx-queue-card .table-wrap{border-radius:0}
.apx-queue-table td{vertical-align:middle}
.apx-queue-table .col-act{white-space:nowrap}
.apx-queue-table .col-act .btn + form{margin-left:6px}

/* ══════════════════════════════════════════════════════════════════════════
   (4b) KOLOM DOKTER: combobox pencarian + tombol [+] MENEMPEL di kanannya
   ──────────────────────────────────────────────────────────────────────────
   Tombol menempel (tanpa jarak) menyerupai input-group: sudut kanan combobox
   dan sudut kiri tombol dibuat rata supaya terlihat satu kontrol.
   ══════════════════════════════════════════════════════════════════════════ */
.apx-doctor-row{display:flex;align-items:stretch;gap:0;min-width:0}
.apx-doctor-row > select,
.apx-doctor-row > .cs-btn{
  flex:1 1 auto;min-width:0;border-top-right-radius:0!important;border-bottom-right-radius:0!important;
}
.apx-doctor-add{
  flex:0 0 auto;width:42px;min-width:42px;height:auto;min-height:42px;padding:0;
  display:inline-grid;place-items:center;border-radius:0 9px 9px 0;
  border:1px solid var(--line-strong);border-left:0;
  background:var(--tint-3);color:var(--brand,#0E7C6B);
}
html[data-theme="dark"] .apx-doctor-add{color:#2DD4A7}
.apx-doctor-add:hover{background:rgba(14,124,107,.14)}
html[data-theme="dark"] .apx-doctor-add:hover{background:rgba(45,212,167,.18)}
.apx-doctor-add svg{width:17px;height:17px;fill:currentColor}

/* ══════════════════════════════════════════════════════════════════════════
   RONDE: PENGAMAN & LAMPIRAN RESEP pada kartu Penjualan Apotek
   ══════════════════════════════════════════════════════════════════════════ */

/* (4) Tombol [Lampiran Resep] di samping [+ Racikan] — ikon saja + tooltip hover. */
.apx-rx-attach{
  position:relative;flex:0 0 auto;width:42px;min-width:42px;height:42px;padding:0;
  display:inline-grid;place-items:center;border-radius:11px;
  background:var(--panel);border:1px solid var(--line-strong);color:var(--ink-2);cursor:pointer;
}
.apx-rx-attach:hover{background:var(--tint-3);color:var(--brand,#0E7C6B)}
html[data-theme="dark"] .apx-rx-attach:hover{color:#2DD4A7}
.apx-rx-attach svg{width:18px;height:18px;fill:currentColor}
.apx-rx-attach.has-file{border-color:var(--brand,#0E7C6B);color:var(--brand,#0E7C6B)}
html[data-theme="dark"] .apx-rx-attach.has-file{border-color:#2DD4A7;color:#2DD4A7}
/* jumlah berkas terpilih (pojok kanan atas) */
.apx-rx-attach-count{
  position:absolute;top:-6px;right:-6px;min-width:18px;height:18px;padding:0 4px;
  display:grid;place-items:center;border-radius:999px;background:var(--brand,#0E7C6B);color:#fff;
  font-size:.62rem;font-weight:800;line-height:1;
}
/* tooltip saat hover (pseudo-element, pola sama dengan tombol Simpan Antrian) */
.apx-rx-attach::after{
  content:attr(data-tip);position:absolute;bottom:calc(100% + 10px);left:50%;
  transform:translate(-50%,4px);padding:6px 11px;border-radius:8px;white-space:nowrap;
  background:#0B1B2B;color:#fff;font-size:.72rem;font-weight:700;
  opacity:0;pointer-events:none;transition:opacity .14s ease,transform .14s ease;z-index:6;
}
.apx-rx-attach::before{
  content:'';position:absolute;bottom:calc(100% + 4px);left:50%;transform:translateX(-50%);
  border:5px solid transparent;border-top-color:#0B1B2B;
  opacity:0;pointer-events:none;transition:opacity .14s ease;z-index:6;
}
.apx-rx-attach:hover::after,.apx-rx-attach:focus-within::after,
.apx-rx-attach:hover::before,.apx-rx-attach:focus-within::before{opacity:1;transform:translate(-50%,0)}
.apx-rx-thumb{display:inline-flex;flex:0 0 auto}
.apx-rx-thumb .photo-thumb{width:42px;height:42px;border-radius:10px}

/* (7) Kotak centang "Ditebus Oleh Pasien Dalam Resep" */
.apx-check-field{margin:0}
.apx-check-row{display:flex;align-items:center;gap:10px;min-height:42px;
  padding:8px 12px;border-radius:10px;border:1px solid var(--line-strong);background:var(--panel);
  font-size:.84rem;font-weight:700;color:var(--ink-strong);cursor:pointer}
.apx-check-row input{width:18px;height:18px;flex:0 0 18px;margin:0;accent-color:var(--brand,#0E7C6B)}
.apx-pickup-fields{margin-top:2px}
/* ⚠️ `[hidden]` harus menang atas `display:grid` — tanpa ini kolom "Ditebus Oleh"
   tetap tampil walau atribut hidden dipasang. */
.apx-pickup-fields[hidden],.apx-rx-attach-count[hidden]{display:none!important}
.apx-pickup-head{margin:14px 0 8px}

/* (2)(5) Sorot baris yang perlu diperhatikan (tanpa pop-up) */
@keyframes apxFlash{0%,100%{background:transparent}20%,60%{background:rgba(220,38,38,.16)}}
table.data.apx-table tr.is-flash > td{animation:apxFlash 1.2s ease 1}
html[data-theme="dark"] table.data.apx-table tr.is-flash > td{animation-name:apxFlashDark}
@keyframes apxFlashDark{0%,100%{background:transparent}20%,60%{background:rgba(248,113,113,.22)}}

/* (3) Kotak konfirmasi tutup kartu */
.apx-confirm{
  position:fixed;inset:0;z-index:130;display:grid;place-items:center;padding:16px;
  background:rgba(6,14,26,.62);
}
html[data-theme="light"] .apx-confirm{background:rgba(15,23,42,.42)}
.apx-confirm-card{
  width:min(460px,100%);border-radius:16px;border:1px solid var(--line-strong);
  background:var(--pop-bg,var(--panel));box-shadow:0 24px 60px -24px rgba(4,12,26,.6);
  overflow:hidden;
}
.apx-confirm-head{display:flex;align-items:center;gap:10px;padding:14px 16px;border-bottom:1px solid var(--line)}
.apx-confirm-head h3{margin:0;font-size:.98rem;font-weight:800;color:var(--head-ink)}
.apx-confirm-head .btn{margin-left:auto;width:32px;height:32px;padding:0;display:grid;place-items:center}
.apx-confirm-body{margin:0;padding:16px;font-size:.86rem;line-height:1.5;color:var(--ink)}
.apx-confirm-foot{display:flex;gap:10px;justify-content:flex-end;flex-wrap:wrap;padding:0 16px 16px}
.apx-confirm-foot .btn{min-height:40px;padding-inline:16px;font-size:.82rem;border-radius:10px}

/* ── responsif ─────────────────────────────────────────────────────────── */
@media (max-width:1400px){
  .apx-sum-grid{grid-template-columns:minmax(0,1fr) minmax(0,1fr)}
}
@media (max-width:1180px){
  .apx-top{grid-template-columns:minmax(0,1fr)}
  .apx-table-wrap{max-height:none}
}
@media (max-width:1180px){
  /* Kartu pasien: "Detail Resep" turun ke barisnya sendiri supaya kolom pasien
     tidak terhimpit. */
  .apx-patient{flex-wrap:wrap;row-gap:10px}
  .apx-vr{display:none}
  .apx-rx-open{flex:1 1 100%}
}
@media (max-width:900px){
  .apx-head-text h2{font-size:1.2rem}
  .apx-sum-grid{grid-template-columns:minmax(0,1fr)}
  .apx-sum-mid,.apx-sum-pay,.apx-sum-side{border-left:0;padding-left:0}
  .apx-sum-grid{gap:16px}
  .apx-rx-open{flex:1 1 100%;justify-content:center}
  /* Kolom cari tetap SATU baris dengan ikon pindai/tambah di kanan. */
  .apx-search{flex-wrap:nowrap}
  .apx-search-field{flex:1 1 auto}
}
/* Jendela 641–1100px: tabel masih tabel (bukan kartu bertingkat) → kolom
   dirampingkan supaya TIDAK perlu digeser ke samping. */
@media (min-width:721px) and (max-width:1100px){
  /* Kolom ramping: dulu totalnya 578px sehingga kolom Item tersisa ~67px saja
     (nama obat terpotong). Sekarang Item mendapat ruang yang layak. */
  .apx-col-no{width:30px}
  .apx-col-qty{width:60px}
  .apx-col-unit{width:84px}
  .apx-col-price{width:92px}
  .apx-col-emb{width:96px}
  .apx-col-sub{width:104px}
  .apx-col-act{width:64px}
  /* Kolom hapus tetap sel tabel (bukan grid) supaya tombolnya tidak melebar
     keluar wadah kartu pada rentang ini. */
  table.data.apx-table td.apx-col-act{display:table-cell!important;padding-left:6px;padding-right:6px}
  table.data.apx-table thead th{padding:9px 8px;font-size:.78rem}
  table.data.apx-table td{padding:9px 8px}
  .apx-search{margin:12px 12px 14px}
  .apx-table-wrap{margin:12px 12px 0}
}
@media (max-width:720px){
  .apx-head-icon{width:38px;height:38px;border-radius:11px}
  .apx-head-icon svg{width:21px;height:21px}
  .apx-date{font-size:.88rem}
  .apx-total-val{font-size:1.08rem;padding:7px 12px}
  .apx-sum-line strong{font-size:.86rem}
  .apx-foot .btn{flex:1 1 100%;justify-content:center}
  /* Tabel produk di HP: kartu bertingkat 2 kolom (label | nilai) — tetap terbaca
     tanpa perlu menggeser ke samping. */
  table.data.apx-table{display:table;width:100%;min-width:0;table-layout:fixed}
  table.data.apx-table thead{display:none}
  table.data.apx-table tbody{display:table-row-group}
  table.data.apx-table tr{
    display:grid;grid-template-columns:1fr 1fr;gap:6px 10px;
    padding:10px;border-bottom:1px solid var(--row-border);background:none;
  }
  table.data.apx-table td{display:block;padding:0;border:0;text-align:left;width:auto!important}
  table.data.apx-table td.apx-col-no{display:none}
  table.data.apx-table td.apx-col-item{grid-column:1 / -1}
  table.data.apx-table td.apx-col-act{grid-column:2;justify-self:end}
  table.data.apx-table td.apx-col-sub{grid-column:1;text-align:left}
  table.data.apx-table td[data-apx-label]::before{
    content:attr(data-apx-label);display:block;font-size:.68rem;font-weight:750;
    text-transform:uppercase;letter-spacing:.05em;color:var(--ink-3);margin-bottom:3px;
  }
  table.data.apx-table .apx-del{width:42px;height:42px}
  /* Layar sangat sempit (320px): rapatkan padding wadah & sel supaya tabel
     bertingkat tidak memunculkan gulir horizontal 4px (artefak pembulatan). */
  .apx-table-wrap{margin:12px 10px 0}
  table.data.apx-table tr{padding:9px 8px;gap:6px 8px}
}


/* ══════════════════════════════════════════════════════════════════════════
   PENJUALAN APOTEK — PENYEMPURNAAN (permintaan pemilik, ronde terakhir)
   ──────────────────────────────────────────────────────────────────────────
   1. Tabel Produk TERSEMBUNYI selama belum ada baris (default kartu hanya
      menampilkan kolom cari / pindai).
   2. [Racikan] & [Lampiran Resep] hanya tampil bila toggle "Penjualan Resep"
      menyala.
   3. Penerima Obat: centang + Nama + Nomor Telp SEJAJAR dalam satu baris grid.
   4. Tombol Antrian berlabel teks (tanpa tooltip pseudo karena labelnya sudah
      ada); [Batal] dihapus dari kaki kartu.
   ══════════════════════════════════════════════════════════════════════════ */
.apx-table-wrap[hidden],
.apx-rx-tools[hidden],
.apx-pickup-fields[hidden]{display:none!important}

/* Wadah tombol resep (pemisah ikut di dalam supaya tidak menyisakan garis). */
.apx-rx-tools{display:flex;align-items:center;gap:12px;flex:0 0 auto;min-width:0}
@media (max-width:1180px){
  .apx-rx-tools{flex:1 1 100%;gap:10px}
  .apx-rx-tools .apx-rx-open{flex:1 1 auto}
}

/* Penerima Obat: TIGA kolom sejajar (centang · nama · nomor telp). */
.apx-pickup-grid{grid-template-columns:repeat(3,minmax(0,1fr));align-items:start}
.apx-pickup-grid .apx-check-field{align-self:end}
.apx-pickup-grid .apx-check-row{height:42px}
@media (max-width:1180px){
  .apx-pickup-grid{grid-template-columns:repeat(2,minmax(0,1fr))}
  .apx-pickup-grid .apx-check-field{grid-column:1 / -1}
}
@media (max-width:640px){
  .apx-pickup-grid{grid-template-columns:minmax(0,1fr)}
}

/* Tombol [Antrian]: ikon + TEKS (dulu ikon saja + tooltip). */
.apx-foot .apx-queue-save{
  width:auto;min-width:0;height:44px;padding:0 20px;gap:9px;
  display:inline-flex;align-items:center;justify-content:center;
  font-size:.86rem;font-weight:750;
}
.apx-queue-lbl{font-size:.86rem;font-weight:750;letter-spacing:.01em}
/* Tooltip pseudo tidak dipakai lagi (labelnya sudah terlihat). */
.apx-foot .apx-queue-save::after,
.apx-foot .apx-queue-save::before{content:none;display:none}
@media (max-width:720px){
  .apx-foot .apx-queue-save{height:46px;padding-inline:18px}
}

/* ══════════════════════════════════════════════════════════════════════════
   PENJUALAN APOTEK — RONDE PENYEMPURNAAN (permintaan pemilik)
   ──────────────────────────────────────────────────────────────────────────
   1. Judul kepala kartu dibuat IDEAL (tidak terlalu besar/kecil).
   2. Dropdown Kasir: TIDAK lagi bersarang (kotak di dalam kotak) — satu kolom
      dropdown dengan BORDER TUNGGAL.
   3. Tombol [+] Pasien menempel di kanan combobox (satu kolom).
   4. HP: ikon Kembali/Tutup pada kepala kartu benar-benar tampil (dulu SVG
      menyusut jadi 2px karena `width:40px` + `padding-inline:18px`), dan
      tombol [Antrian] & [BAYAR] SEJAJAR KIRI–KANAN.
   ══════════════════════════════════════════════════════════════════════════ */

/* (1) Judul kepala: 1.32rem (22,7px) → 1.15rem (±19,8px) = ideal. */
.apx-head-text h2{font-size:1.15rem;line-height:1.25;letter-spacing:.005em}

/* (2) BORDER TUNGGAL pada kolom Kasir.
   Dulu `.apx-kasir-row` (border + latar) MEMBUNGKUS combobox yang juga punya
   border sendiri → terlihat seperti input bersarang. Sekarang pembungkusnya
   tanpa border/latar, jadi yang terlihat hanya SATU border milik dropdown. */
.apx-kasir-row{
  display:flex;align-items:center;gap:10px;min-width:0;
  padding:0;border:0;background:none;border-radius:0;
}
.apx-kasir > select,
.apx-kasir .cs-btn{min-height:38px}

/* (3) Tombol [+] Pasien: combobox + tombol menyatu (meniru pola Dokter resep).
   `.apx-patient .apx-wide` adalah label bertumpuk → barisannya memakai lebar penuh. */
.apx-patient .apx-wide > .apx-doctor-row{width:100%}
.apx-wide .apx-doctor-add{width:38px;min-width:38px;min-height:38px}
.apx-wide .apx-doctor-add svg{width:16px;height:16px}

/* (4a) HP — ikon Kembali/Tutup kepala kartu benar-benar tampil.
   ⚠️ Aturan ini WAJIB di paling akhir: `.apx-head .row-actions .btn` (0,3,0) di
   atas menulis `padding-inline:18px`, sedangkan aturan global `.sheet-head
   .row-actions .btn` menulis `width:40px`. Kombinasi keduanya memeras ikon
   menjadi 40 − 36 = 4px (terukur SVG 2px) — tombol tampak kosong/rusak. */
@media (max-width:900px){
  .apx-head{gap:10px}
  .apx-head .row-actions{gap:6px}
  .apx-head .row-actions .btn{
    width:40px;min-width:40px;height:40px;min-height:40px;
    padding:0;border-radius:11px;justify-content:center;
  }
  .apx-head .row-actions .btn svg{width:18px;height:18px;flex:0 0 18px;margin:0}
  .apx-head .row-actions .btn .lbl{display:none}
}
@media (max-width:400px){
  .apx-head .row-actions .btn{width:38px;min-width:38px;height:38px;min-height:38px}
  .apx-head-text h2{font-size:1.06rem}
}

/* (4b) HP — [Antrian] & [BAYAR] SEJAJAR KIRI–KANAN (bukan bertumpuk penuh). */
@media (max-width:720px){
  .apx-foot{
    flex-wrap:nowrap;gap:10px;justify-content:space-between;align-items:stretch;
  }
  .apx-foot .apx-queue-save,
  .apx-foot .apx-save{
    flex:1 1 0;min-width:0;width:auto;padding-inline:12px;
    justify-content:center;min-height:46px;height:46px;
  }
  .apx-foot .apx-save{font-size:.88rem;letter-spacing:.01em}
  .apx-queue-lbl{font-size:.84rem}
  .apx-foot .apx-queue-save svg{width:17px;height:17px;flex:0 0 17px}
  .apx-foot .apx-save-ico{width:22px;height:22px;flex:0 0 22px}
}
@media (max-width:360px){
  .apx-foot{gap:8px}
  .apx-foot .apx-save{font-size:.82rem}
  .apx-queue-lbl{font-size:.8rem}
}

/* ── (5e) KARTU HIJAU HASIL PEMINDAIAN: nama produk (TANPA lokasi rak) ──────
   Permintaan pemilik: hasil pindai menampilkan NAMA PRODUK yang dikenali,
   bukan kode/rak. Nama ditulis besar & tebal, kode tetap ada sebagai bukti. */
.scan-result .sr-name{
  display:block;margin:2px 0 10px;font-size:1.02rem;font-weight:800;line-height:1.25;
  color:var(--ok-fg);overflow-wrap:anywhere;
}
.scan-result .sr-name.is-unknown{font-weight:650;color:var(--ink-2)}
.scan-result .sr-code{margin:4px 0 8px;font-size:.92rem;font-weight:700;color:var(--ink-2)}
html[data-theme="dark"] .scan-result .sr-name{color:#7CF0C4}
html[data-theme="dark"] .scan-result .sr-code{color:var(--ink-2)}

/* ══════════════════════════════════════════════════════════════════════════
   (5c) PEMINDAI BARCODE — kartu pop-up: teks panduan dirapikan
   Tulisan "Arahkan kamera …" & catatan dukungan peramban DIHAPUS (permintaan
   pemilik) sehingga pop-up langsung fokus ke kamera + hasil. Kelas `.scan-sub`
   / `.scan-foot` disembunyikan bila markup lama masih memuatnya.
   ══════════════════════════════════════════════════════════════════════════ */
.scan-head small.scan-sub,
.scan-foot:empty,
.scan-foot[hidden]{display:none!important}
.scan-stage .scan-tip{opacity:.85}

/* ══════════════════════════════════════════════════════════════════════════
   PENJUALAN APOTEK — RONDE: LATAR KARTU HIJAU MUDA, IKON PINDAI, GERBANG KASIR
   ══════════════════════════════════════════════════════════════════════════ */

/* (3) Kartu **Data Resep**, **Produk**, dan **Ringkasan Tagihan & Pembayaran**
   memakai LATAR HIJAU MUDA yang SAMA PERSIS dengan kartu Tanggal & Pasien
   (`--apx-tint`, dipakai `.apx-meta`/`.apx-patient`). Warna hijau tua pada
   kepala kartu TIDAK diubah (itu identitas kartu, bukan latar). */
.apx-card.apx-prod,
.apx-card.apx-sum,
.apx-rx-panel{
  background:var(--apx-tint);
  border-color:var(--line-strong);
}
/* Isi tabel tetap memakai panel terang agar angka & isian tetap kontras. */
.apx-prod .apx-table-wrap,
.apx-sum .apx-sum-grid{background:transparent}

/* (2) Ikon tombol pindai: garis pindai di tengah harus terlihat tegas. */
.apx-scan .apx-scan-svg{width:20px;height:20px;fill:currentColor;display:block}
.apx-scan:disabled,
.apx-scan.is-locked{opacity:.45;cursor:not-allowed}
.apx-scan:disabled:hover,
.apx-scan.is-locked:hover{background:var(--panel);color:var(--ink-3)}

/* (1) GERBANG KASIR — kolom Kasir wajib dipilih lebih dulu.
   ⚠️ Warna peringatan = MERAH (permintaan pemilik), bukan kuning/amber:
   keadaan "Kasir belum dipilih" adalah kesalahan yang menghalangi transaksi. */
.apx-kasir-row.is-required{border:1px solid var(--err-bd,rgba(220,38,38,.65));
  background:rgba(220,38,38,.09);border-radius:11px;padding:3px 5px 3px 13px}
html[data-theme="dark"] .apx-kasir-row.is-required{background:rgba(220,38,38,.17);
  border-color:rgba(248,113,113,.6)}
@keyframes apxKasirFlash{0%,100%{box-shadow:none}
  25%,65%{box-shadow:0 0 0 3px rgba(220,38,38,.38)}}
.apx-kasir-row.is-flash{animation:apxKasirFlash 1.2s ease 1}
/* Kolom cari nonaktif: jelas terlihat "belum bisa dipakai" (bukan rusak).
   ⚠️ Aturan dasar `.apx-search-field input` memakai `background:transparent!important`
   sehingga keadaan nonaktif WAJIB memakai `!important` juga, kalau tidak latarnya
   tidak pernah berubah. */
.apx-search .apx-search-field input:disabled{
  background:var(--tint-3)!important;color:var(--ink-3)!important;cursor:not-allowed;
  border-radius:9px;
}
.apx-search .apx-search-field input:disabled::placeholder{color:var(--ink-3);font-weight:700;opacity:1}

/* ══════════════════════════════════════════════════════════════════════════
   PENJUALAN APOTEK — RONDE: TEKS GERBANG, CARA BAYAR, JUMLAH DITERIMA,
   KEMBALIAN TANPA PREFIX "Rp" KIRI
   ══════════════════════════════════════════════════════════════════════════ */

/* (4) JUMLAH DITERIMA: angka dibuat TEBAL dan SEUKURAN dengan prefix "Rp".
   Prefix "Rp" (`.money-prefix`) = 1rem / 900, jadi angkanya disamakan persis:
   ukuran sama + bobot sama → terlihat satu kesatuan, bukan angka kecil di
   samping "Rp" besar. */
.apx-recv .money-wrap > .money-prefix{
  font-size:1rem;font-weight:900;line-height:1;letter-spacing:0;
}
.apx-recv .money-wrap > input[data-money],
.apx-recv .money-wrap > input[data-money]:focus{
  font-size:1rem!important;font-weight:900!important;letter-spacing:.005em;
  font-variant-numeric:tabular-nums;
}
.apx-recv .money-wrap > input[data-money]{padding-left:36px!important}

/* (5) KEMBALIAN: prefix "Rp" di kiri sudah dihapus dari markup. Nominal "Rp 0"
   di kanan tetap; dibuat rata kanan penuh di dalam kotaknya. */
.apx-change{justify-content:flex-end}
.apx-change-val{margin-left:0;text-align:right}
/* Bentuk lama (bila markup lama muncul) tetap disembunyikan. */
.apx-change .apx-change-cur{display:none!important}

/* (2) CARA BAYAR wajib dipilih: tanda merah saat masih placeholder. */
.apx-sum-grid select.is-invalid,
.apx-sum-grid .field select.is-invalid + .cs-btn,
.apx-sum-grid .field:has(select.is-invalid) .cs-btn{
  border-color:var(--err-bd)!important;box-shadow:0 0 0 3px rgba(220,38,38,.12);
}

/* (6) POP-UP "modul dalam pengembangan" — varian INFO pada kartu notifikasi.
   Dulu `appNotice()` hanya punya varian err/warn dengan subjudul "Penyimpanan
   belum berhasil", yang menyesatkan untuk kabar informasi seperti ini. */
#app-notice[data-kind="info"] .notice-card{border-color:var(--info-bd,var(--line-strong))}
#app-notice[data-kind="info"] .notice-list li::marker{color:var(--info-fg,var(--brand,#0E7C6B))}

/* ══════════════════════════════════════════════════════════════════════════
   LACI KASIR (Buka · Setoran · Tutup) + tombol IKON tanpa teks di kaki kartu
   ──────────────────────────────────────────────────────────────────────────
   Permintaan pemilik: SATU tombol ikon tanpa teks di samping KIRI tombol
   [Antrian] pada kartu Penjualan Apotek, berfungsi [Buka Kasir]/[Tutup Kasir].
   Ukuran & bentuknya disamakan dengan tombol [Antrian] supaya sebaris rapi.
   ══════════════════════════════════════════════════════════════════════════ */
.apx-foot .apx-drawer,
.topbar .btn-ico.btn-ico{
  position:relative;
  width:44px;min-width:44px;height:44px;padding:0;display:inline-grid;place-items:center;
  border-radius:10px;background:var(--panel);border:1px solid var(--line-strong);
  color:var(--brand,#0E7C6B);
}
.apx-foot .apx-drawer svg{width:20px;height:20px;fill:currentColor}
.apx-foot .apx-drawer:hover{background:rgba(14,124,107,.10)}
html[data-theme="dark"] .apx-foot .apx-drawer{color:#2DD4A7}
html[data-theme="dark"] .apx-foot .apx-drawer:hover{background:rgba(45,212,167,.14)}
/* Keadaan laci: terbuka = aksen hijau penuh, tertutup = netral. */
.apx-foot .apx-drawer[data-cd-open="1"]{
  background:var(--brand,#0E7C6B);border-color:var(--brand-dark,#0B6A5C);color:#fff;
}
html[data-theme="dark"] .apx-foot .apx-drawer[data-cd-open="1"]{
  background:#12A38D;border-color:#0E7C6B;color:#04231D;
}
/* Tooltip lokal (pola sama dengan [Antrian]) — global `.act-tip` sudah dihapus. */
.apx-foot .apx-drawer::after{
  content:attr(title);
  position:absolute;bottom:calc(100% + 10px);left:50%;transform:translate(-50%,4px);
  padding:6px 11px;border-radius:8px;white-space:nowrap;
  background:#0B1B2B;color:#fff;font-size:.72rem;font-weight:700;
  opacity:0;pointer-events:none;transition:opacity .14s ease,transform .14s ease;z-index:5;
}
.apx-foot .apx-drawer:hover::after,
.apx-foot .apx-drawer:focus-visible::after{opacity:1;transform:translate(-50%,0)}
/* Di HP tombol ikon laci tetap sejajar tinggi dengan tombol lain. */
@media (max-width:640px){
  .apx-foot .apx-drawer{width:44px;min-width:44px;height:44px}
}

/* Tombol ikon di kepala halaman (Kasir Layanan) — tanpa teks, ukuran tombol biasa. */
.topbar .btn-ico{display:inline-grid;place-items:center;width:40px;min-width:40px;padding:0}
.topbar .btn-ico svg{width:19px;height:19px;fill:currentColor}

/* Kartu laci: jarak antar bagian & angka ringkasan. */
.cash-drawer-card .form-section + .form-section{margin-top:18px}
.cash-drawer-card .cd-metrics{margin:0}
.cash-drawer-card .sheet-body > .form-section:first-child{margin-top:0}
.cash-drawer-card .sheet-foot{gap:10px}
.cash-drawer-card .foot-note{margin:10px 0 0}
.cash-drawer-card .metric-row.wide > div{min-width:0}

/* ══════════════════════════════════════════════════════════════════════════
   KARTU RACIKAN (+ Racikan) pada KASIR APOTEK
   ──────────────────────────────────────────────────────────────────────────
   Susunan mengikuti tabel Obat Racikan di menu Pemeriksaan Dokter (`.cmp-card`
   + `.cmp-head`), tetapi tabelnya 5 kolom (tanpa kolom harga) karena harga &
   stok dihitung otomatis saat bahan dipindahkan ke keranjang.
   ══════════════════════════════════════════════════════════════════════════ */
.apx-cmp-sheet .cmp-card{background:var(--panel);border-color:var(--line-strong)}
.apx-cmp-sheet .apx-cmp-table{table-layout:fixed;width:100%;min-width:0}
.apx-cmp-sheet .apx-cmp-table thead th{font-size:.74rem;font-weight:700;color:var(--ink-2)}
/* Kolom (permintaan pemilik): Bahan Obat · Kekuatan · Jumlah Dosis ·
   Jumlah Diperlukan · ✕ — kolom Catatan dihapus. */
.apx-cmp-sheet .apx-cmp-table .apx-cmp-drug{width:34%}
.apx-cmp-sheet .apx-cmp-table .apx-cmp-strength{width:16%}
.apx-cmp-sheet .apx-cmp-table .apx-cmp-dose{width:21%}
.apx-cmp-sheet .apx-cmp-table .apx-cmp-qty{width:21%}
.apx-cmp-sheet .apx-cmp-table .apx-cmp-x{width:8%}
.apx-cmp-sheet .apx-cmp-table td{padding:6px 6px;vertical-align:middle}
.apx-cmp-sheet .apx-cmp-table .cs-btn{min-width:0}
.apx-cmp-sheet .apx-cmp-table input[type=number],
.apx-cmp-sheet .apx-cmp-table input[type=text]{min-width:0;width:100%}
.apx-cmp-sheet .apx-cmp-x .btn{width:32px;min-width:32px;height:32px;padding:0;display:inline-grid;place-items:center}
/* Chip KEKUATAN (dari master) — teks saja, tidak bisa diubah. */
.apx-strength-tag{
  display:inline-block;padding:4px 9px;border-radius:8px;white-space:nowrap;
  background:rgba(14,124,107,.10);border:1px solid rgba(14,124,107,.26);
  color:var(--ink);font-size:.8rem;font-weight:700;
}
html[data-theme="dark"] .apx-strength-tag{background:rgba(45,212,167,.14);border-color:rgba(45,212,167,.3)}
/* INPUT + SUFFIX SATUAN STATIS (mg / tablet) dalam satu kotak — kasir hanya
   mengetik angka; satuan berasal dari Master Obat sehingga tidak bisa salah. */
.apx-suffix-wrap{
  display:flex;align-items:stretch;gap:0;min-width:0;width:100%;
  border:1px solid var(--line-strong);border-radius:10px;background:var(--panel);
  overflow:hidden;
}
.apx-suffix-wrap > input[type=number]{
  flex:1 1 auto;min-width:0;border:0!important;border-radius:0!important;
  background:transparent!important;text-align:right;padding-right:6px;
  font-variant-numeric:tabular-nums;font-weight:700;
}
.apx-suffix-wrap > input[type=number]:focus{outline:2px solid var(--brand,#0E7C6B);outline-offset:-2px}
.apx-suffix-wrap > input[type=number].is-off{opacity:.5;cursor:not-allowed}
.apx-suffix{
  flex:0 0 auto;display:inline-flex;align-items:center;padding:0 9px;
  border-left:1px solid var(--line);background:var(--tint-3);
  font-size:.78rem;font-weight:700;color:var(--ink-2);white-space:nowrap;
  max-width:56%;overflow:hidden;text-overflow:ellipsis;
}
/* Sembunyikan spinbutton bawaan di dalam kotak bersuffix. */
.apx-suffix-wrap > input[type=number]{appearance:textfield;-moz-appearance:textfield}
.apx-suffix-wrap > input[type=number]::-webkit-outer-spin-button,
.apx-suffix-wrap > input[type=number]::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}
/* Di HP tabel racikan menjadi kartu bertingkat — kolomnya jangan dipaksa 5 kolom. */
@media (max-width:900px){
  .apx-cmp-sheet .apx-cmp-table{table-layout:auto}
  .apx-cmp-sheet .apx-cmp-table .apx-cmp-drug,
  .apx-cmp-sheet .apx-cmp-table .apx-cmp-strength,
  .apx-cmp-sheet .apx-cmp-table .apx-cmp-dose,
  .apx-cmp-sheet .apx-cmp-table .apx-cmp-qty,
  .apx-cmp-sheet .apx-cmp-table .apx-cmp-x{width:auto}
}
/* Baris keranjang hasil racikan diberi penanda tipis supaya kasir tahu asalnya. */
.apx-table tr.is-racikan .apx-col-item{box-shadow:inset 3px 0 0 var(--brand,#0E7C6B)}

/* ══════════════════════════════════════════════════════════════════════════
   RACIKAN PADA KERANJANG PENJUALAN APOTEK
   ──────────────────────────────────────────────────────────────────────────
   Permintaan pemilik: baris hasil racikan menampilkan TEKS
   "Racikan Puyer • 10 Bungkus" (bukan dropdown obat) dan punya tombol **Edit**
   di kolom Aksi di samping tombol hapus.
   ══════════════════════════════════════════════════════════════════════════ */
/* ⚠️ `.apx-rac-chip` SUDAH DIHAPUS dari markup (permintaan pemilik): kolom Item
   hanya menampilkan nama obat. Label racikan ("Racikan Puyer • 10 Bungkus")
   ditampilkan sebagai TOOLTIP baris (`title`) + gaya baris `.is-racikan`.
   Aturan di bawah sengaja dipertahankan agar kelas lama (jika masih muncul dari
   cache/antrian lama) tidak merusak tata letak — tetapi tidak dipakai lagi. */
.apx-rac-chip{display:none!important}
/* ⚠️ Baris hasil racikan kini menampilkan PRODUK BIASA di kolom Item (dropdown
   obat + tombol combobox + info stok TETAP TAMPIL). Dulu ketiganya disembunyikan
   karena digantikan chip; setelah chip dihapus, menyembunyikannya membuat kolom
   Item KOSONG. Baris racikan cukup ditandai garis aksen tipis (`.is-racikan`). */
.apx-table tr.is-racikan .apx-col-item{box-shadow:inset 3px 0 0 var(--brand,#0E7C6B)}
/* Dua tombol aksi (Edit + Hapus) tetap SATU BARIS & sejajar. */
.apx-table td.apx-col-act{white-space:nowrap}
.apx-table td.apx-col-act .btn{margin:0 0 0 4px;vertical-align:middle}
.apx-table td.apx-col-act .btn:first-child{margin-left:0}
.apx-table .apx-rac-edit{color:var(--brand,#0E7C6B);border-color:var(--line-strong)}
html[data-theme="dark"] .apx-table .apx-rac-edit{color:#2DD4A7}
.apx-table .apx-rac-edit[hidden]{display:none!important}

/* KARTU LACI KASIR — dilebarkan sedikit (dulu `narrow` 620px). */
.sheet-card.cash-drawer-card{width:min(780px,100%)}
/* Tombol [Edit] racikan: ukuran SAMA dengan tombol hapus (40×40) supaya kolom
   Aksi tetap rapi & target sentuh cukup. */
.apx-table .apx-del{width:40px;height:40px}
.apx-table .apx-rac-edit{
  width:40px;height:40px;min-width:40px;padding:0;display:inline-grid;place-items:center;
  border-radius:10px;background:var(--tint-3);border:1px solid var(--line-strong);
  color:var(--brand,#0E7C6B);
}
.apx-table .apx-rac-edit svg{width:17px;height:17px;fill:currentColor}
.apx-table .apx-rac-edit:hover{background:rgba(14,124,107,.12)}
html[data-theme="dark"] .apx-table .apx-rac-edit{color:#2DD4A7;background:rgba(45,212,167,.12)}
@media (max-width:900px){
  .apx-table .apx-rac-edit,.apx-table .apx-del{width:42px;height:42px;min-width:42px}
}

/* ══════════════════════════════════════════════════════════════════════════
   TOOLTIP TOMBOL AKSI (ikon) — SATU elemen `.act-tip` ber-position:fixed
   ──────────────────────────────────────────────────────────────────────────
   ⚠️ Dibuat `position:fixed` (bukan ::after di dalam tombol) supaya tidak
   menambah area gulir `.table-wrap` — pernah menyebabkan scrollbar horizontal
   palsu pada tabel yang sebenarnya sudah muat.
   ══════════════════════════════════════════════════════════════════════════ */
.act-tip{
  position:fixed;top:0;left:0;z-index:210;pointer-events:none;
  max-width:min(260px,80vw);padding:6px 10px;border-radius:8px;
  background:#0B1B2B;color:#fff;font-size:.74rem;font-weight:700;line-height:1.3;
  letter-spacing:.01em;text-align:center;white-space:normal;
  box-shadow:0 6px 18px -8px rgba(4,12,24,.75);
  opacity:0;transform:translateY(3px);
  transition:opacity .12s ease,transform .12s ease;
}
.act-tip.is-on{opacity:1;transform:translateY(0)}
/* Tema terang tetap memakai latar gelap + huruf putih: kontrasnya paling tinggi
   dan tidak mungkin tertukar dengan warna permukaan kartu. */
html[data-theme="light"] .act-tip{background:#10233A;color:#FFFFFF}
@media (prefers-reduced-motion: reduce){.act-tip{transition:none}}

/* Chip "Cara Bayar" pada tabel Daftar Transaksi Kasir Apotek. */
.pay-chip{
  display:inline-block;padding:3px 9px;border-radius:999px;white-space:nowrap;
  background:var(--tint-3);border:1px solid var(--line-strong);
  color:var(--ink);font-size:.78rem;font-weight:700;
}

/* ══════════════════════════════════════════════════════════════════════════
   KOLOM AKSI KERANJANG APOTEK — DUA TOMBOL (Edit racikan + Hapus) SATU BARIS
   ──────────────────────────────────────────────────────────────────────────
   `.apx-col-act` asli selebar 66px (hanya cukup untuk satu tombol 40px), jadi
   baris racikan yang punya tombol Edit + Hapus membuat tombol kedua TURUN BARIS
   (terukur tinggi sel 95px). Kolom dilebarkan & tombol dirapatkan ke 38px
   sehingga keduanya selalu sejajar. `white-space:nowrap` WAJIB `!important`
   karena aturan `.apx-table td` lain menimpanya.
   ══════════════════════════════════════════════════════════════════════════ */
table.data.apx-table .apx-col-act{width:88px}
.apx-table td.apx-col-act{white-space:nowrap!important;text-align:center}
.apx-table td.apx-col-act .btn,
.apx-table .apx-del,
.apx-table .apx-rac-edit{width:38px;height:38px;min-width:38px;padding:0;display:inline-grid;place-items:center;
  vertical-align:middle}
.apx-table td.apx-col-act .btn + .btn{margin-left:4px}
@media (max-width:1100px){
  table.data.apx-table .apx-col-act{width:82px}
  .apx-table td.apx-col-act .btn,
  .apx-table .apx-del,
  .apx-table .apx-rac-edit{width:36px;height:36px;min-width:36px}
}
@media (max-width:900px){
  /* Di HP tabel menjadi kartu bertingkat — dua tombol tetap satu baris di kanan. */
  .apx-table td.apx-col-act{display:grid!important;grid-template-columns:1fr auto;gap:6px}
  .apx-table td.apx-col-act .btn,
  .apx-table .apx-del,
  .apx-table .apx-rac-edit{width:42px;height:42px;min-width:42px}
}

/* ══════════════════════════════════════════════════════════════════════════
   KEKUATAN SEDIAAN — input ANGKA + dropdown SATUAN dalam satu baris
   (kartu item: "5 mg", "0,5 gram", "100 ml").
   ══════════════════════════════════════════════════════════════════════════ */
.strength-row{display:flex;align-items:stretch;gap:8px;min-width:0;width:100%}
.strength-row > input{flex:0 0 96px;min-width:0;text-align:right}
.strength-row > select,
.strength-row > .cs-btn{flex:1 1 auto;min-width:0}
@media (max-width:640px){
  .strength-row > input{flex:0 0 80px}
}
/* Chip kekuatan pada kartu/daftar obat. */
.chip-strength{background:rgba(14,124,107,.12);border-color:rgba(14,124,107,.28);font-weight:700}
html[data-theme="dark"] .chip-strength{background:rgba(45,212,167,.14);border-color:rgba(45,212,167,.3)}

/* Tabel Daftar Transaksi Kasir Apotek (9 kolom): kolom pendukung disembunyikan
   pada layar ≤1180px supaya tabel TIDAK perlu digeser ke samping. */
@media (max-width:1180px){
  .apx-trx-table .col-opt{display:none!important}
}

/* ══════════════════════════════════════════════════════════════════════════
   GERBANG KASIR — PLACEHOLDER kolom cari menjadi penanda "Pilih Kasir dulu"
   ──────────────────────────────────────────────────────────────────────────
   Permintaan pemilik (revisi): sebelum Kasir dipilih, kolom cari menampilkan
   placeholder **"Pilih Kasir terlebih dahulu.."** (bukan lagi petunjuk produk,
   dan bukan teks terpisah di sampingnya). Warnanya dibuat jelas (merah lembut)
   supaya terbaca sebagai peringatan, bukan sekadar placeholder biasa.
   ══════════════════════════════════════════════════════════════════════════ */
.apx-search .apx-search-field input:disabled::placeholder{
  color:var(--err-fg,#B91C1C);font-weight:800;opacity:1;
}
html[data-theme="light"] .apx-search .apx-search-field input:disabled::placeholder{color:#B91C1C}
/* `.apx-search-msg` tidak dipakai lagi untuk gerbang kasir (penanda sudah di
   placeholder). Pesan pencarian lain (mis. "Tidak ditemukan: x") tetap tampil. */
.apx-search-msg:empty{display:none}

/* ══════════════════════════════════════════════════════════════════════════
   KAKI KARTU PENJUALAN APOTEK — PERBAIKAN TOMBOL (bug nyata)
   ──────────────────────────────────────────────────────────────────────────
   Penyebab: aturan HP `.apx-foot .btn{flex:1 1 100%}` juga mengenai tombol
   **ikon laci kasir** (`.btn.apx-drawer`) sehingga `flex-basis` menjadi 100%.
   Dengan `flex-wrap:nowrap` tombol itu MEMBELAH baris (terukur 202–598px),
   sementara [Antrian] & [BAYAR] diperas menjadi **26px** dan teksnya hilang.
   Perbaikan: tombol ikon selalu `flex:0 0 auto` dengan lebar tetap, dan dua
   tombol aksi berbagi sisa ruang secara adil. Berlaku juga bila tombol laci
   TIDAK dirender (role tanpa izin) — dua tombol tetap sejajar.
   ══════════════════════════════════════════════════════════════════════════ */
.apx-foot{flex-wrap:wrap}
.apx-foot .apx-drawer,
.apx-foot .apx-queue-save,
.apx-foot .apx-save{flex:0 0 auto}
.apx-foot .apx-queue-save{min-width:132px}
.apx-foot .apx-save{min-width:132px}
@media (max-width:720px){
  /* Tiga tombol sebaris: ikon laci (44px) + dua tombol aksi yang membagi sisa. */
  .apx-foot{
    flex-wrap:nowrap;gap:8px;align-items:stretch;justify-content:space-between;
  }
  .apx-foot .apx-drawer{
    flex:0 0 44px!important;width:44px!important;min-width:44px!important;
    height:46px;min-height:46px;align-self:stretch;
  }
  .apx-foot .apx-queue-save,
  .apx-foot .apx-save{
    flex:1 1 0!important;min-width:0!important;width:auto!important;
    padding-inline:10px;justify-content:center;min-height:46px;height:46px;
  }
  .apx-foot .apx-queue-lbl{display:inline}
}
@media (max-width:400px){
  .apx-foot{gap:6px}
  .apx-foot .apx-drawer{flex-basis:42px!important;width:42px!important;min-width:42px!important}
  .apx-foot .apx-queue-save,
  .apx-foot .apx-save{padding-inline:8px}
  .apx-foot .apx-save{font-size:.8rem}
  .apx-queue-lbl{font-size:.76rem}
  .apx-foot .apx-save-ico{width:18px;height:18px;flex:0 0 18px}
  .apx-foot .apx-queue-save svg{width:15px;height:15px;flex:0 0 15px}
}

/* ══════════════════════════════════════════════════════════════════════════
   TOMBOL **KELUAR** DI MENU SAMPING — SELALU TAMPIL (perbaikan bug)
   ──────────────────────────────────────────────────────────────────────────
   Tiga penyebab "tombol Keluar tidak muncul" pada sebagian pengguna:
   1. `.sidebar{height:100vh}` — di iOS Safari & Android `100vh` LEBIH TINGGI dari
      area yang terlihat (bilah URL/bawah), sehingga KAKI menu (avatar + Keluar)
      berada di bawah layar. → dipakai `100dvh` (dynamic viewport) + padding aman.
   2. `.sidebar-foot` tidak `flex:0 0 auto` → bisa TERPERAS/terdorong keluar saat
      daftar menu panjang (pengguna dengan banyak izin).
   3. Saat menu DILIPAT, tombol menjadi ikon lewat `::before` ber-`mask` CSS;
      peramban tanpa dukungan `mask` menampilkannya sebagai kotak KOSONG.
      → sekarang ikonnya SVG asli di dalam markup.
   ══════════════════════════════════════════════════════════════════════════ */
.sidebar{height:100vh;height:100dvh;min-height:0}
.sidebar-foot{flex:0 0 auto}
/* Ikon Keluar hanya dipakai pada mode terlipat (desktop) — di desktop lebar
   tombol menampilkan teks seperti sebelumnya. */
.btn-logout .logout-ico{display:none;width:18px;height:18px;flex:0 0 18px;fill:currentColor}
@media (min-width:901px){
  html[data-sidebar="min"] .btn-logout{
    width:38px;height:38px;min-width:38px;padding:0;margin-inline:auto;
    display:inline-flex;align-items:center;justify-content:center;
  }
  html[data-sidebar="min"] .btn-logout .logout-lbl{display:none}
  html[data-sidebar="min"] .btn-logout .logout-ico{display:block}
  /* `::before` ber-mask dari aturan lama tidak diperlukan lagi (bisa dobel ikon). */
  html[data-sidebar="min"] .btn-logout::before{content:none!important;display:none!important}
}
/* HP: menu samping = laci yang menggulir sendiri; kaki menu dibuat MENEMPEL di
   dasar laci sehingga Keluar selalu terjangkau walau daftar menu panjang dan
   walau tinggi layar menyusut karena bilah peramban/papan tombol. */
@media (max-width:900px){
  .sidebar{height:100dvh;max-height:100dvh;padding-bottom:calc(14px + env(safe-area-inset-bottom,0px))}
  .sidebar-foot{
    position:sticky;bottom:0;z-index:2;
    background:var(--sidebar-bg);
    padding-bottom:calc(4px + env(safe-area-inset-bottom,0px));
    box-shadow:0 -10px 18px -16px rgba(4,12,24,.6);
  }
}

/* ══════════════════════════════════════════════════════════════════════════
   MOBILE — RUANG AMAN UNTUK PAPAN TOMBOL (keyboard)
   ──────────────────────────────────────────────────────────────────────────
   Dipakai bersama blok "MOBILE: KEYBOARD-AWARE AUTO SCROLL" di assets/app.js.
   · `scroll-margin` pada kontrol membuat `scrollIntoView()` (dipakai app.js &
     fokus keyboard) menyisakan ruang di bawah, jadi kolom aktif TIDAK pernah
     menempel di tepi area yang tertutup keyboard.
   · `scroll-padding-bottom` pada wadah gulir (isi halaman & badan kartu
     mengambang) memberi ruang yang sama saat digulir.
   Hanya ≤900px — DESKTOP TIDAK BERUBAH.
   ══════════════════════════════════════════════════════════════════════════ */
@media (max-width:900px){
  input:not([type=checkbox]):not([type=radio]),
  select, textarea, .cs-btn, .num-stepper,
  .perm-item, .vis-chip{
    scroll-margin-block: 96px 200px;
  }
  .content, .sheet-body, .main{
    scroll-padding-bottom: 200px;
  }
  /* Badan kartu mengambang butuh ruang ekstra karena kepala/kaki tetap di tempat. */
  .sheet-body{scroll-padding-top:12px}
}

/* ══════════════════════════════════════════════════════════════════════════
   BIAYA RACIK + RACIKAN SEBAGAI SATU BARIS (permintaan pemilik)
   ──────────────────────────────────────────────────────────────────────────
   1. Kartu Racikan (Penjualan Apotek): kolom "Catatan racikan" DIGANTI info
      **Biaya Racik** yang terisi otomatis dari Master Kategori → Biaya Racik
      (sediaan + rentang jumlah kemasan).
   2. Hasil racikan masuk keranjang sebagai **SATU BARIS**:
      "Racikan Puyer · 10 Bungkus" dengan SATU harga = nilai bahan obat +
      biaya racik. Dropdown obat/satuan & centang embalase disembunyikan untuk
      baris itu (`.is-compound`), jumlah dikunci 1.
   ══════════════════════════════════════════════════════════════════════════ */
.apx-cmp-fee{gap:4px}
.apx-cmp-fee > .apx-fee-line{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap}
.apx-fee-amt{
  font-family:var(--mono,ui-monospace,SFMono-Regular,Menlo,monospace);
  font-size:1.02rem;font-weight:800;color:var(--ink-strong);
  font-variant-numeric:tabular-nums;
}
/* `.apx-fee-tag` (chip "Rentang 1–30") sudah TIDAK dipakai lagi — chip itu
   dihapus atas permintaan pemilik. Aturan lama sengaja dibuang supaya tidak ada
   gaya yatim yang membingungkan saat membaca CSS. */
.apx-cmp-fee .apx-fee-note{font-size:.74rem;color:var(--ink-2);line-height:1.35}
.apx-cmp-fee.is-missing .apx-fee-amt{color:var(--err-fg,#B91C1C)}
.apx-cmp-fee.is-missing .apx-fee-note{color:var(--err-fg,#B91C1C);font-weight:650}

/* Baris keranjang hasil racikan */
.apx-table tr.is-compound .apx-col-item > .apx-rac-name:not([hidden]){
  display:block;font-weight:750;color:var(--ink-strong);line-height:1.35;
}
.apx-table tr.is-compound .apx-col-item > select,
.apx-table tr.is-compound .apx-col-item > .cs-btn,
.apx-table tr.is-compound .apx-col-item > .apx-hint{display:none}
.apx-table tr.is-compound .apx-col-unit > *{display:none}
.apx-table tr.is-compound .apx-col-unit::after{
  content:'Racikan';font-size:.8rem;color:var(--ink-2);font-weight:650;
}
/* EMBALASE BARIS RACIKAN (permintaan pemilik): nilai ditampilkan & TIDAK dapat
   diketik/dicentang. Nominalnya mengikuti JUMLAH OBAT di dalam racikan (server:
   `compound_sale_quote()`), jadi kotak centang disembunyikan dan angkanya
   ditegaskan. Aturan lama `::after{content:'—'}` dibuang (sel kosong). */
.apx-table tr.is-compound .apx-col-emb .apx-emb{cursor:default;gap:0}
.apx-table tr.is-compound .apx-col-emb .apx-emb-box{display:none}
.apx-table tr.is-compound .apx-col-emb .apx-emb-amt{
  color:var(--ink-strong);font-weight:750;font-variant-numeric:tabular-nums;
}
.apx-table tr.is-compound .apx-col-qty input{
  background:transparent;border-color:transparent;text-align:center;font-weight:750;
  box-shadow:none;
}
.apx-table tr.is-compound{box-shadow:inset 3px 0 0 var(--brand,#0E7C6B)}

/* ══════════════════════════════════════════════════════════════════════════
   DOSIS PER KALI MINUM pada kartu RACIKAN (permintaan pemilik)
   ──────────────────────────────────────────────────────────────────────────
   Kolom **Dosis** di samping "Aturan pakai": angka + dropdown satuan
   (Master Kategori → Satuan Dosis). Pasangan kontrol dibuat satu baris dan
   tetap rapi di HP; dropdown satuan tidak boleh memotong angka.
   Chip rentang biaya racik ("Rentang 1–30") sudah DIHAPUS dari markup.
   ══════════════════════════════════════════════════════════════════════════ */
.apx-cmp-dose-per > .apx-dose-pair{
  display:flex;align-items:stretch;gap:6px;width:100%;min-width:0;
}
.apx-cmp-dose-per > .apx-dose-pair > input{
  flex:0 0 68px;min-width:0;text-align:center;font-weight:700;
}
.apx-cmp-dose-per > .apx-dose-pair > select{
  flex:1 1 auto;min-width:0;
}
/* Dropdown pencarian (`.cs-btn`) menggantikan <select> secara visual —
   di dalam pasangan Dosis ia WAJIB mengisi sisa lebar, bukan selebar teksnya. */
.apx-cmp-dose-per > .apx-dose-pair > .cs-btn{
  flex:1 1 auto;min-width:0;width:auto;
}
/* Label "Dosis" tetap sejajar dengan label kolom lain (grid cmp-head). */
.apx-cmp-dose-per > span{white-space:nowrap}
@media (max-width:640px){
  .apx-cmp-dose-per > .apx-dose-pair > input{flex:0 0 58px}
}
/* Layar sangat sempit: pasangan Dosis memakai SATU BARIS PENUH supaya nama
   satuan ("Tablet", "Sendok teh") tidak terpotong di dalam dropdown. */
@media (max-width:420px){
  .apx-cmp-dose-per{grid-column:1 / -1}
  .apx-cmp-dose-per > .apx-dose-pair > input{flex:0 0 64px}
}

/* ══════════════════════════════════════════════════════════════════════════
   RONDE KASIR APOTEK: PENDING PAYMENT · PEMBULATAN · PENJAGA LACI
   ──────────────────────────────────────────────────────────────────────────
   1. Tombol **[Pending Payment]** di kaki kartu = IKON SAJA dengan tooltip saat
      hover (permintaan pemilik). Menyimpan transaksi langsung ke Daftar Tagihan
      sebagai tagihan BELUM dibayar (barang keluar, stok terpotong).
   2. Baris **Pembulatan** di ringkasan (tepat di bawah Embalase) — nilainya
      dihitung otomatis, tidak dapat diketik.
   3. Catatan laci TERTUTUP di dalam kartu penjualan.
   Tombol LACI KASIR sendiri dipindah ke kepala halaman (kelas `.btn-ico`,
   aturannya sudah ada di blok LACI KASIR di atas).
   ══════════════════════════════════════════════════════════════════════════ */

/* (1) Tombol ikon Pending Payment — ukuran sama dengan tombol [Antrian]. */
.apx-foot .apx-pending{
  position:relative;
  width:44px;min-width:44px;height:44px;padding:0;display:inline-grid;place-items:center;
  border-radius:10px;background:var(--panel);border:1px solid var(--line-strong);
  color:var(--brand,#0E7C6B);
}
.apx-foot .apx-pending svg{width:20px;height:20px;fill:currentColor}
.apx-foot .apx-pending:hover{background:rgba(14,124,107,.10)}
.apx-foot .apx-pending:focus-visible{outline:2px solid var(--brand,#0E7C6B);outline-offset:2px}
html[data-theme="dark"] .apx-foot .apx-pending{color:#2DD4A7}
html[data-theme="dark"] .apx-foot .apx-pending:hover{background:rgba(45,212,167,.14)}
/* Tooltip lokal memakai `data-tip` (bukan `title`) supaya teks balon konsisten
   dengan label tombol; `title` tetap ada untuk pembaca layar/peramban lama. */
.apx-foot .apx-pending::after{
  content:attr(data-tip);
  position:absolute;bottom:calc(100% + 10px);left:50%;transform:translate(-50%,4px);
  padding:6px 11px;border-radius:8px;white-space:nowrap;
  background:#0B1B2B;color:#fff;font-size:.72rem;font-weight:700;letter-spacing:.01em;
  opacity:0;pointer-events:none;transition:opacity .14s ease,transform .14s ease;z-index:6;
}
.apx-foot .apx-pending::before{
  content:'';position:absolute;bottom:calc(100% + 4px);left:50%;transform:translateX(-50%);
  border:5px solid transparent;border-top-color:#0B1B2B;
  opacity:0;pointer-events:none;transition:opacity .14s ease;z-index:6;
}
.apx-foot .apx-pending:hover::after,
.apx-foot .apx-pending:focus-visible::after,
.apx-foot .apx-pending:hover::before,
.apx-foot .apx-pending:focus-visible::before{opacity:1;transform:translate(-50%,0)}

/* Kaki kartu: tiga tombol sebaris rapi (ikon pending + Antrian + BAYAR). */
.apx-foot .apx-pending{flex:0 0 auto}
@media (max-width:720px){
  /* Tombol ikon TIDAK boleh ikut `flex:1 1 100%` (aturan umum tombol kaki kartu
     di HP) — kalau ikut, ia membelah baris dan dua tombol aksi terperas. */
  .apx-foot .apx-pending{
    flex:0 0 44px!important;width:44px!important;min-width:44px!important;
    height:46px;min-height:46px;align-self:stretch;
  }
}
@media (max-width:400px){
  .apx-foot .apx-pending{flex:0 0 42px!important;width:42px!important;min-width:42px!important}
  .apx-foot .apx-pending svg{width:18px;height:18px}
}

/* (2) Baris Pembulatan: nominal SAMA PERSIS dengan nominal Embalase
   (permintaan pemilik). Dulu ada `font-weight:750` khusus baris ini sehingga
   angkanya terlihat lebih tipis/kecil daripada Embalase — aturan itu DIHAPUS
   supaya keduanya memakai gaya `.apx-sum-line strong` yang sama. */
.apx-sum-left .apx-round-line[hidden]{display:none!important}

/* (3) Catatan laci tertutup di dalam kartu penjualan (bukan pop-up). */
.apx-body > .apx-lock-note{margin:0 12px 4px}
@media (max-width:720px){
  .apx-body > .apx-lock-note{margin:0 10px 4px}
}

/* ══════════════════════════════════════════════════════════════════════════
   AKUN PEMBAYARAN (kartu Penjualan Apotek) — label baru + autofill
   ──────────────────────────────────────────────────────────────────────────
   Permintaan pemilik: kolom "Sumber Dana" menjadi **"Akun Pembayaran"** dan
   nilainya terisi OTOMATIS dari cara bayar (Tunai → akun kas, non-tunai → bank).
   Tiga keadaan yang perlu gaya:
     · `.apx-acc-note`  — keterangan kecil (ikut tombol Info, jadi `small.muted`)
     · `.apx-acc-empty` — peringatan TIDAK ADA akun sejenis (WAJIB selalu terlihat,
       ditandai `data-live-hint` di PHP sehingga tidak ikut disembunyikan)
     · `.apx-acc-field.is-auto` — penanda halus bahwa nilai terisi otomatis
   ══════════════════════════════════════════════════════════════════════════ */
.apx-sum-pay .apx-acc-note{margin-top:-2px;line-height:1.3}
.apx-sum-pay .apx-acc-empty{
  display:block;margin-top:2px;padding:7px 9px;border-radius:9px;
  background:var(--tint-2);border:1px solid var(--line);
  color:var(--ink-2);font-size:.78rem;font-weight:650;line-height:1.4;
}
.apx-sum-pay .apx-acc-empty[hidden]{display:none!important}
.apx-sum-pay .apx-acc-empty strong{color:var(--ink-strong)}
.apx-sum-pay .apx-acc-empty a{color:var(--cyan);font-weight:800;text-decoration:underline}
/* Penanda autofill: kelas `.is-auto` HANYA penanda keadaan (dipakai JS & uji) —
   select sengaja TIDAK diwarnai agar tidak tertukar dengan kotak "Jumlah Diterima"
   yang memang beraksen hijau. Tidak ada aturan visual tambahan di sini. */
@media (max-width:640px){
  .apx-sum-pay .apx-acc-empty{font-size:.76rem;padding:6px 8px}
}

/* ══════════════════════════════════════════════════════════════════════════
   KARTU PEMBAYARAN TAGIHAN — DESAIN ULANG DENGAN TEMA "PENJUALAN APOTEK"
   ──────────────────────────────────────────────────────────────────────────
   Permintaan pemilik: UI/UX kartu Pembayaran Tagihan (Kasir) disamakan tema-nya
   dengan kartu **Penjualan Apotek**; SELURUH isian & perilakunya TIDAK berubah
   (semua `data-pay-*`, tabel racikan, bukti pembayaran, riwayat, kaki kartu).

   Padanan komponen yang dipakai (sumber kebenaran tema ada di blok `.apx-*`):
     · kepala kartu      → `.apx-card-head`  : hijau merek DATAR + ikon putih + pil putih
     · kartu             → `.apx-card`       : radius 15, garis `--line`, latar `--panel`
     · tabel             → `table.data.apx-table` : judul Title Case, kepala `--apx-th-bg`
     · kolom SUBTOTAL    → `.apx-sub`        : kotak hijau lembut
     · batang total      → `.apx-total`      : latar hijau lembut + nominal KOTAK hijau tua
     · isian ringkasan   → `.apx-sum-grid`   : label kecil tegas, kontrol 42px radius 10
     · kotak nominal     → `.apx-recv`       : latar hijau lembut, angka kanan & tebal
     · kartu bukti       → `.apx-proof`      : bingkai PUTUS-PUTUS di atas `--tint-3`
     · kaki kartu        → `.apx-foot`       : tombol utama hijau, tombol lain lembut
   ⚠️ Aturan di blok ini ditulis dengan selektor ber-prefix `.pay-sheet` supaya
   menang atas blok `.pay-*` lama (yang tetap dipertahankan agar rollback mudah:
   cukup HAPUS blok ini + kelas `apx-*` tambahan di `_pay_sheet.php`).
   ══════════════════════════════════════════════════════════════════════════ */

/* ── 1. Kepala kartu: ikon merek + remah judul ─────────────────────────── */
.pay-sheet .pay-head{gap:14px;align-items:flex-start}
.pay-sheet .pay-head-icon{
  width:46px;height:46px;border-radius:13px;
  background:rgba(14,124,107,.13);color:var(--brand,#0E7C6B);
}
html[data-theme="dark"] .pay-sheet .pay-head-icon{background:rgba(45,212,167,.16);color:#2DD4A7}
.pay-sheet .pay-head-icon svg{width:27px;height:27px;fill:currentColor}
.pay-sheet .pay-title{font-size:1.5rem;font-weight:800}
.pay-sheet .pay-crumb{color:var(--brand,#0E7C6B);font-weight:800}
html[data-theme="dark"] .pay-sheet .pay-crumb{color:#2DD4A7}
.pay-sheet .pay-sub{font-size:.92rem;font-weight:700;color:var(--ink-2)}
.pay-sheet .pay-head .row-actions{gap:10px;margin-left:auto;flex:0 0 auto}
.pay-sheet .pay-head .row-actions .btn{
  min-height:42px;padding-inline:16px;border-radius:11px;font-weight:700;
  background:var(--panel);border:1px solid var(--line-strong);color:var(--ink);
}
.pay-sheet .pay-head .row-actions .btn:hover{background:var(--tint-3)}

/* ── 2. Kartu (kiri & kanan): garis, radius, dan KEPALA HIJAU DATAR ────── */
.pay-sheet .pay-items-card{
  border:1px solid var(--line);border-radius:15px;background:var(--panel);
  padding:0;overflow:visible;
}
.pay-sheet .pay-items-head{
  padding:11px 17px;gap:11px;flex-wrap:nowrap;
  background:var(--brand,#0E7C6B);                     /* DATAR — bukan gradien */
  border-radius:14px 14px 0 0;
}
html[data-theme="dark"] .pay-sheet .pay-items-head{background:#0F7A6A}
.pay-sheet .pay-items-head h3{
  font-size:1.12rem;font-weight:800;color:#fff;letter-spacing:.01em;text-transform:none;
}
.pay-sheet .pay-items-icon{
  width:30px;height:30px;border-radius:9px;background:rgba(255,255,255,.16);color:#fff;
}
.pay-sheet .pay-items-icon svg{width:18px;height:18px;fill:currentColor}
.pay-sheet .pay-item-count{
  margin-left:auto;flex:0 0 auto;display:inline-flex;align-items:center;
  background:rgba(255,255,255,.92);color:#0C4A3E;border:0;
  font-size:.8rem;font-weight:750;padding:6px 12px;border-radius:999px;white-space:nowrap;
}
html[data-theme="dark"] .pay-sheet .pay-item-count{background:#F3FFFB;color:#0A3F35}
/* Kartu kanan = satu kartu bertema (kepala + isi) */
/* ⚠️ TANPA `overflow:hidden`: kartu hanya perlu SUDUT membulat pada kepalanya
   (`.pay-side-head`), sedangkan `overflow:hidden` akan MEMOTONG isi yang lebih
   lebar (mis. riwayat pembayaran / label akun panjang) pada layar sempit. */
.pay-sheet .pay-side-card{display:flex;flex-direction:column;border-radius:15px}
.pay-sheet .pay-side-head{padding:11px 17px;background:var(--brand,#0E7C6B);border-radius:14px 14px 0 0}
html[data-theme="dark"] .pay-sheet .pay-side-head{background:#0F7A6A}
.pay-sheet .pay-side-head h3{font-size:1.12rem;font-weight:800;color:#fff;text-transform:none}
.pay-sheet .pay-side-head .apx-card-ico{width:30px;height:30px;flex:0 0 30px;border-radius:9px;
  background:rgba(255,255,255,.16);color:#fff}
.pay-sheet .pay-side-head .apx-card-ico svg{width:18px;height:18px}
.pay-sheet .pay-side-count{background:rgba(255,255,255,.92);color:#0C4A3E;font-size:.78rem;font-weight:750;
  padding:6px 12px;border-radius:999px}
html[data-theme="dark"] .pay-sheet .pay-side-count{background:#F3FFFB;color:#0A3F35}
.pay-sheet .pay-side-card-body{padding:14px 16px 16px}
.pay-sheet .pay-side{gap:14px}

/* ── 3. Tabel rincian: judul Title Case + kepala bertint + garis apx ───── */
.pay-sheet .pay-items-wrap{
  margin:14px 16px 0;border:1px solid var(--line);border-radius:13px;
  overflow:auto;max-height:46vh;
}
.pay-sheet table.data.pay-items-table{font-size:.88rem;table-layout:fixed}
.pay-sheet table.data.pay-items-table thead th,
.pay-sheet table.data.pay-items-table thead th.col-no,
.pay-sheet table.data.pay-items-table thead th.col-sub,
.pay-sheet table.data.pay-items-table thead th.col-qty,
.pay-sheet table.data.pay-items-table thead th.col-price,
.pay-sheet table.data.pay-items-table thead th.col-unit{
  font-size:.84rem;letter-spacing:0;text-transform:none;font-weight:750;
  color:var(--ink-strong);background:var(--apx-th-bg);
  padding:12px 13px;white-space:nowrap;border-bottom:1px solid var(--apx-line);
}
.pay-sheet table.data.pay-items-table td{
  padding:11px 12px;vertical-align:middle;border-top:1px solid var(--apx-line);
}
.pay-sheet table.data.pay-items-table tbody tr:first-child td{border-top:0}
.pay-sheet table.data.pay-items-table td.col-price,
.pay-sheet table.data.pay-items-table td.col-sub{font-size:.86rem}
.pay-sheet .pay-item-name strong{font-size:.92rem;font-weight:800;color:var(--ink-strong)}
.pay-sheet .pay-item-name .pay-item-sub{font-size:.76rem;font-weight:650;color:var(--apx-link)}
html[data-theme="dark"] .pay-sheet .pay-item-name .pay-item-sub{color:var(--apx-link)}
/* Kotak SUBTOTAL hijau lembut (sama seperti kolom Subtotal pada kartu apotek) */
.pay-sheet .pay-items-table .apx-sub{
  display:block;padding:8px 12px;border-radius:9px;text-align:right;white-space:nowrap;
  background:var(--apx-sub-bg);color:var(--apx-sub-ink);
  font-weight:800;font-variant-numeric:tabular-nums;
}
/* Tombol buka/tutup racikan tetap terbaca di atas latar baru */
.pay-sheet .pay-cmp-toggle{color:var(--ink-strong);font-weight:800}
.pay-sheet .pay-cmp-caret{fill:var(--brand,#0E7C6B)}
html[data-theme="dark"] .pay-sheet .pay-cmp-caret{fill:#2DD4A7}
.pay-sheet .pay-cmp-box{border-color:var(--apx-line-strong);background:var(--tint-3)}

/* ── 4. Batang Total Tagihan = `.apx-total` ────────────────────────────── */
.pay-sheet .pay-total-row{
  display:flex;align-items:center;justify-content:space-between;gap:12px;
  margin:14px 16px 16px;padding:10px 12px;border-radius:12px;
  background:var(--apx-total-bg);border:1px solid var(--apx-total-bd);
}
.pay-sheet .pay-total-row .apx-total-lbl{
  display:inline-flex;align-items:center;gap:11px;
  font-size:1.02rem;font-weight:850;color:var(--ink-strong);
}
.pay-sheet .pay-total-row .apx-total-ico{
  display:grid;place-items:center;width:30px;height:30px;flex:0 0 30px;
  color:var(--brand,#0E7C6B);
}
html[data-theme="dark"] .pay-sheet .pay-total-row .apx-total-ico{color:#2DD4A7}
.pay-sheet .pay-total-row .apx-total-ico svg{width:21px;height:21px;fill:currentColor}
.pay-sheet .pay-total-row strong{
  padding:9px 18px;border-radius:10px;background:var(--brand,#0E7C6B);color:#fff;
  font-size:1.24rem;font-weight:900;font-variant-numeric:tabular-nums;white-space:nowrap;
}
html[data-theme="dark"] .pay-sheet .pay-total-row strong{background:#12A38D;color:#04231D}

/* ── 5. Petak ringkasan: tile lembut bertema (bukan blok warna pekat) ──── */
.pay-sheet .pay-stats{gap:10px}
.pay-sheet .pay-stat{
  padding:12px 13px;gap:11px;border-radius:12px;
  background:var(--tint-3);border:1px solid var(--line);
}
.pay-sheet .pay-stat-icon{width:34px;height:34px;border-radius:10px}
.pay-sheet .pay-stat-icon svg{width:19px;height:19px}
.pay-sheet .pay-stat-label{font-size:.8rem;font-weight:750;color:var(--ink-2);letter-spacing:.01em}
/* Nominal petak ringkasan memakai CONTAINER QUERY: huruf menyesuaikan lebar
   petak sehingga "Rp 1.234.567" tidak pernah terpotong/ber-elipsis (pola yang
   sama dengan kartu KPI aplikasi). */
.pay-sheet .pay-stat{container-type:inline-size}
.pay-sheet .pay-stat-value{
  font-size:clamp(.95rem, 13.2cqi, 1.24rem);font-weight:900;letter-spacing:-.01em;
  white-space:nowrap;overflow:visible;text-overflow:clip;
}
.pay-sheet .pay-stat.is-paid{background:var(--ok-bg);border-color:var(--ok-bd)}
.pay-sheet .pay-stat.is-paid .pay-stat-icon{background:rgba(255,255,255,.35);color:var(--ok-fg)}
.pay-sheet .pay-stat.is-paid .pay-stat-value{color:var(--ok-fg)}
.pay-sheet .pay-stat.is-due{background:var(--err-bg);border-color:var(--err-bd)}
.pay-sheet .pay-stat.is-due .pay-stat-icon{background:rgba(255,255,255,.35);color:var(--err-fg)}
.pay-sheet .pay-stat.is-due .pay-stat-value{color:var(--err-fg)}
.pay-sheet .pay-stat.is-change{background:var(--apx-sub-bg);border-color:var(--apx-total-bd)}
.pay-sheet .pay-stat.is-change .pay-stat-icon{background:rgba(255,255,255,.35);color:var(--apx-sub-ink)}
.pay-sheet .pay-stat.is-change .pay-stat-value{color:var(--apx-sub-ink)}
.pay-sheet .pay-stat.is-change.is-zero{opacity:.72}

/* ── 6. Isian: label & kontrol mengikuti `.apx-sum-grid` ───────────────── */
.pay-sheet .pay-fields{gap:14px 16px}
.pay-sheet .pay-fields .field > span{
  font-size:.8rem;font-weight:750;letter-spacing:.01em;color:var(--ink-strong);
}
.pay-sheet .pay-fields .field select,
.pay-sheet .pay-fields .field input,
.pay-sheet .pay-fields .field .cs-btn{min-height:42px;border-radius:10px;background:var(--panel)}
.pay-sheet .pay-fields .req-mark{color:var(--err-fg);font-style:normal;font-weight:800}
/* Kotak nominal (Jumlah Diterima) = gaya `.apx-recv`: hijau lembut, angka kanan tebal */
.pay-sheet .pay-amount-field .money-wrap{
  background:var(--apx-recv-bg);border:1.5px solid var(--apx-recv-bd);border-radius:10px;
}
.pay-sheet .pay-amount-field .money-wrap > input{
  height:44px;font-weight:850;font-size:1.06rem;text-align:right;
  color:var(--apx-sub-ink);background:transparent;border:0;box-shadow:none;
}
.pay-sheet .pay-amount-field .money-prefix{font-weight:850;font-size:1.06rem;color:var(--apx-sub-ink);opacity:.85}
.pay-sheet .pay-note textarea{min-height:74px;border-radius:10px;background:var(--panel)}
.pay-sheet .pay-fields small.muted,
.pay-sheet .pay-amount-field small.muted,
.pay-sheet .pay-account-field small.muted{font-size:.76rem;line-height:1.3}

/* Catatan hasil (piutang / kembalian) — versi lembut bertema */
.pay-sheet .pay-due-note{background:var(--warn-bg);border:1px solid var(--warn-bd);color:var(--ink)}
.pay-sheet .pay-due-note svg{color:var(--warn-fg)}
.pay-sheet .pay-change-note{background:var(--ok-bg);border:1px solid var(--ok-bd);color:var(--ink)}
.pay-sheet .pay-change-note svg{color:var(--ok-fg)}
.pay-sheet .pay-due-note a{color:var(--brand,#0E7C6B);font-weight:800}
html[data-theme="dark"] .pay-sheet .pay-due-note a{color:#2DD4A7}

/* ── 7. Kartu Bukti Pembayaran = `.apx-proof` (bingkai putus-putus) ────── */
.pay-sheet .pay-proof-card{
  border:1px dashed var(--line-strong);border-radius:12px;
  background:var(--tint-3);padding:12px 14px;
}
.pay-sheet .pay-proof-card .pay-proof-head{margin-bottom:8px;gap:9px}
.pay-sheet .pay-proof-card .pay-proof-head h3{font-size:.98rem;font-weight:800;color:var(--ink-strong)}
.pay-sheet .pay-proof-card .pay-proof-icon{
  width:28px;height:28px;border-radius:9px;background:rgba(14,124,107,.12);color:var(--brand,#0E7C6B);
}
html[data-theme="dark"] .pay-sheet .pay-proof-card .pay-proof-icon{background:rgba(45,212,167,.16);color:#2DD4A7}
.pay-sheet .pay-proof-card .pay-proof-icon svg{width:16px;height:16px}
.pay-sheet .pay-opt-pill{
  background:var(--tint-2);color:var(--ink-2);border:1px solid var(--line-strong);
  font-size:.76rem;font-weight:750;padding:5px 12px;
}
.pay-sheet .pay-opt-pill.is-ok{background:var(--ok-bg);color:var(--ok-fg);border-color:var(--ok-bd)}
.pay-sheet .pay-opt-pill.is-warn{background:var(--err-bg);color:var(--err-fg);border-color:var(--err-bd)}
.pay-sheet .pay-proof-card .btn-attach{
  background:var(--panel);border:1px solid var(--line-strong);border-radius:10px;
  min-height:42px;padding:8px 14px;font-weight:700;color:var(--ink-strong);
}
.pay-sheet .pay-proof-card .btn-attach:hover{background:var(--tint-3)}
.pay-sheet .pay-proof-card .pay-proof-hint{font-size:.76rem;line-height:1.3}

/* Riwayat pembayaran sebelumnya: kartu kecil bertema */
.pay-sheet .pay-history{
  border:1px dashed var(--line-strong);border-radius:12px;background:var(--tint-3);padding:10px 12px;
}
.pay-sheet .pay-history-title{font-size:.72rem;font-weight:800;letter-spacing:.03em;text-transform:uppercase;color:var(--ink-2)}

/* ── 8. Kaki kartu: tombol utama hijau + tombol lembut (`.apx-foot`) ───── */
.pay-sheet .pay-foot{gap:12px;justify-content:flex-end;padding-top:12px}
.pay-sheet .pay-foot .foot-note{flex:1 1 100%;margin:0 0 2px;text-align:left;font-size:.76rem}
.pay-sheet .pay-btn-soft{
  min-height:46px;padding:0 20px;border-radius:11px;font-weight:750;
  background:var(--tint-3);border:1px solid var(--line-strong);color:var(--ink-strong);
}
.pay-sheet .pay-btn-soft:hover{background:var(--tint-2)}
.pay-sheet .pay-btn-main{
  min-height:48px;padding-inline:24px;border-radius:11px;font-weight:800;
  background:var(--brand,#0E7C6B);border:1px solid #0B6A5C;color:#fff;
}
.pay-sheet .pay-btn-main:hover{background:#0B6A5C}
html[data-theme="dark"] .pay-sheet .pay-btn-main{background:#12A38D;border-color:#0E7C6B;color:#04231D}
html[data-theme="dark"] .pay-sheet .pay-btn-main:hover{background:#2DD4A7}
.pay-sheet .pay-btn-main svg{width:18px;height:18px;fill:currentColor}

/* ── 9. Responsif (tata letak tetap dua kolom → satu kolom seperti semula) ─ */
@media (max-width:1180px){
  .pay-sheet .pay-items-wrap{max-height:none}
}
@media (max-width:900px){
  .pay-sheet .pay-items-head{padding:10px 13px;gap:9px}
  .pay-sheet .pay-items-head h3{font-size:1rem}
  .pay-sheet .pay-side-head{padding:10px 13px}
  .pay-sheet .pay-items-wrap{margin:12px 12px 0}
  .pay-sheet .pay-total-row{margin:12px 12px 12px;padding:10px 12px}
  .pay-sheet .pay-total-row strong{font-size:1.1rem;padding:8px 14px}
  .pay-sheet .pay-side-card-body{padding:12px 13px 14px}
  .pay-sheet .pay-stat-value{font-size:1.1rem}
  /* tabel ringkas di HP (No/Satuan/Harga disembunyikan blok lama) — kotak subtotal
     dibuat lebih rapat supaya 3 kolom tetap muat tanpa geser */
  .pay-sheet .pay-items-table .apx-sub{padding:6px 9px;font-size:.82rem}
}
@media (max-width:640px){
  .pay-sheet .pay-side-card-body{padding:10px 11px 12px}
  .pay-sheet .pay-account-field .cs-btn,
  .pay-sheet .pay-account-field select{font-size:.86rem}
  .pay-sheet .pay-head-icon{width:40px;height:40px;border-radius:12px}
  .pay-sheet .pay-head-icon svg{width:22px;height:22px}
  .pay-sheet .pay-title{font-size:1.12rem}
  .pay-sheet .pay-total-row{flex-wrap:wrap;row-gap:8px}
  .pay-sheet .pay-total-row .apx-total-lbl{flex:1 1 auto}
  .pay-sheet .pay-total-row strong{font-size:1.16rem}
  .pay-sheet .pay-side-count{font-size:.72rem;padding:5px 10px}
  .pay-sheet .pay-item-count{font-size:.72rem;padding:5px 10px}
}
/* ≤400px: kepala kartu kiri — pil "Total Item" turun baris agar judul utuh */
@media (max-width:400px){
  .pay-sheet .pay-items-head{flex-wrap:wrap;row-gap:8px}
  .pay-sheet .pay-items-head h3{white-space:normal}
  .pay-sheet .pay-item-count{margin-left:0}
}

/* ≤400px: label kombinasi dropdown (`.cs-label`) pada kartu pembayaran BOLEH
   MEMBUNGKUS dua baris. Nama akun panjang ("Bank BCA 1234567890") sebelumnya
   dipotong elipsis di 320px sehingga kasir tidak bisa membedakan akun —
   ini juga yang membuat audit tata letak menandai "teks terpotong". */
@media (max-width:400px){
  /* Semua dropdown kartu pembayaran (Jenis Pembayaran & Akun) — label boleh dua
     baris. Placeholder "-- Pilih Jenis Pembayaran --" butuh ±166px sedangkan
     ruangnya 158px di 320px, dan nama akun panjang juga terpotong.
     ⚠️ Sejak isian pindah ke grid ringkasan, selektornya `.pay-sum-grid`
     (bukan `.pay-fields` lagi) — tanpa ini label kembali terpotong elipsis. */
  .pay-sheet .pay-sum-grid .cs-btn{height:auto;min-height:42px;padding-block:6px}
  .pay-sheet .pay-sum-grid .cs-btn .cs-label{
    white-space:normal;overflow:visible;text-overflow:clip;line-height:1.22;
  }
}

/* ══════════════════════════════════════════════════════════════════════════
   KARTU PEMBAYARAN — PENEGASAN SPESIFISITAS & LATAR KARTU (tema apotek)
   ──────────────────────────────────────────────────────────────────────────
   Dua hal yang HARUS ditulis terpisah:
   1. **Latar kartu hijau muda** — kartu Produk & Ringkasan pada Penjualan
      Apotek memakai `--apx-tint` + `--line-strong` (blok `.apx-card.apx-prod`).
      Supaya kedua kartu benar-benar serupa, kartu kiri & kanan di sini ikut.
   2. **Aturan `html[data-theme="dark"] .pay-…` LAMA** (dari desain sebelumnya)
      berbobot (0,2,1)–(0,3,1) sehingga MENGALAHKAN selektor `.pay-sheet …`
      (0,2,0)/(0,3,0) di blok sebelumnya — akibatnya di tema gelap warna petak
      ringkasan & batang total masih memakai nilai lama. Semua nilai tema di
      bawah ditulis dengan prefix `html[data-theme="dark"] .pay-sheet …` agar
      menang, dan TIDAK mengubah tema terang.
   ══════════════════════════════════════════════════════════════════════════ */
.pay-sheet .pay-items-card,
.pay-sheet .pay-side-card{
  background:var(--apx-tint);
  border-color:var(--line-strong);
}
/* Isi tabel & isian tetap memakai panel terang/pekat agar kontras terjaga. */
.pay-sheet .pay-items-table,
.pay-sheet .pay-side-card-body{background:transparent}

/* Tema gelap: samakan dengan nilai tema apotek (yang juga dipakai .apx-*). */
html[data-theme="dark"] .pay-sheet .pay-total-row{
  background:var(--apx-total-bg);border-color:var(--apx-total-bd);
}
html[data-theme="dark"] .pay-sheet .pay-total-row strong{background:#12A38D;color:#04231D}
html[data-theme="dark"] .pay-sheet .pay-total-row .apx-total-ico{color:#2DD4A7}
html[data-theme="dark"] .pay-sheet .pay-stat.is-paid{background:var(--ok-bg);border-color:var(--ok-bd)}
html[data-theme="dark"] .pay-sheet .pay-stat.is-paid .pay-stat-value{color:var(--ok-fg)}
html[data-theme="dark"] .pay-sheet .pay-stat.is-paid .pay-stat-icon{background:rgba(255,255,255,.16);color:var(--ok-fg)}
html[data-theme="dark"] .pay-sheet .pay-stat.is-due{background:var(--err-bg);border-color:var(--err-bd)}
html[data-theme="dark"] .pay-sheet .pay-stat.is-due .pay-stat-value{color:var(--err-fg)}
html[data-theme="dark"] .pay-sheet .pay-stat.is-due .pay-stat-icon{background:rgba(255,255,255,.16);color:var(--err-fg)}
html[data-theme="dark"] .pay-sheet .pay-stat.is-change{background:var(--apx-sub-bg);border-color:var(--apx-total-bd)}
html[data-theme="dark"] .pay-sheet .pay-stat.is-change .pay-stat-value{color:var(--apx-sub-ink)}
html[data-theme="dark"] .pay-sheet .pay-stat.is-change .pay-stat-icon{background:rgba(255,255,255,.16);color:var(--apx-sub-ink)}
html[data-theme="dark"] .pay-sheet .pay-item-name .pay-item-sub{color:var(--apx-link)}
html[data-theme="dark"] .pay-sheet .pay-opt-pill{background:var(--tint-2);color:var(--ink-2);border-color:var(--line-strong)}
html[data-theme="dark"] .pay-sheet .pay-opt-pill.is-ok{background:var(--ok-bg);color:var(--ok-fg);border-color:var(--ok-bd)}
html[data-theme="dark"] .pay-sheet .pay-opt-pill.is-warn{background:var(--err-bg);color:var(--err-fg);border-color:var(--err-bd)}
html[data-theme="dark"] .pay-sheet .pay-proof-card .pay-proof-icon{background:rgba(45,212,167,.16);color:#2DD4A7}
html[data-theme="dark"] .pay-sheet .pay-due-note a{color:#2DD4A7}
/* Isian ringkasan di dalam kartu berlatar hijau muda: kontrol tetap panel. */
.pay-sheet .pay-fields .field select,
.pay-sheet .pay-fields .field input,
.pay-sheet .pay-fields .field textarea,
.pay-sheet .pay-fields .field .cs-btn,
.pay-sheet .pay-history{background:var(--panel)}

/* ══════════════════════════════════════════════════════════════════════════
   KARTU PEMBAYARAN TAGIHAN — LAYOUT & SKALA HURUF DISAMAKAN DENGAN
   KARTU "PENJUALAN APOTEK" (permintaan pemilik)
   ──────────────────────────────────────────────────────────────────────────
   Bukan hanya warna: SUSUNAN & UKURAN HURUF ikut disamakan.
     · kepala kartu   : ikon 42px · judul 1.32rem · tombol 42px/.82rem
                        (`.apx-head-icon` / `.apx-head-text h2` / `.apx-head .row-actions .btn`)
     · baris ringkas  : `.apx-top` (kotak tint) berisi tanggal+kode & pasien+RME+status
     · kartu          : DITUMPUK LEBAR PENUH (bukan dua kolom) — persis kartu apotek
     · kepala kartu   : padding 10px 15px · judul .98rem · pil .68rem
     · tabel          : judul .84rem · sel .88rem · padding 12/13 → 9/8 di ≤1100px
     · ringkasan      : grid 4 kolom `.apx-sum-grid` (2 kolom ≤1400px, 1 kolom ≤900px)
     · kaki kartu     : tombol utama 50px radius 11 · tombol lembut 50px
   ⚠️ `.pay-body` adalah `.sheet-body` (flex kolom) → anak WAJIB `flex:0 0 auto`,
   kalau tidak kartu menyusut dan isinya saling menimpa (bug yang pernah terjadi
   pada kartu Penjualan Apotek).
   ══════════════════════════════════════════════════════════════════════════ */
.pay-sheet{width:min(1560px,100%)}
.pay-sheet .pay-body{padding-top:16px}
.pay-sheet .pay-body > *{flex:0 0 auto}

/* ── 1. Kepala kartu (ukuran = kepala kartu Penjualan Apotek) ──────────── */
.pay-sheet .pay-head{gap:12px;align-items:center}
.pay-sheet .pay-head-icon{width:42px;height:42px;border-radius:12px}
.pay-sheet .pay-head-icon svg{width:23px;height:23px}
.pay-sheet .pay-head-text h2{font-size:1.32rem;line-height:1.2}
.pay-sheet .pay-crumb{font-weight:800}
.pay-sheet .pay-head .row-actions{gap:10px;margin-left:auto}
.pay-sheet .pay-head .row-actions .btn{
  min-height:42px;padding-inline:18px;font-size:.82rem;border-radius:11px;font-weight:700;
  background:var(--panel);border:1px solid var(--line-strong);color:var(--ink);
}
.pay-sheet .pay-head .row-actions .btn svg{width:15px;height:15px}
.pay-sheet .pay-head .row-actions .btn:hover{background:var(--tint-3)}

/* ── 2. Baris ringkas (.apx-top sudah mengatur grid & jarak) ───────────── */
.pay-top{margin-bottom:16px}
.pay-top .apx-wide strong{display:block;font-size:.92rem;font-weight:750;color:var(--ink-strong);line-height:1.2}
.pay-top .apx-wide .muted.small{font-size:.74rem}
.pay-top .apx-wide .mono{font-size:.9rem}
.pay-top-pill{margin-left:auto;flex:0 0 auto;align-self:center}

/* ── 3. Kartu ditumpuk lebar penuh (dua kolom lama dinetralkan) ────────── */
.pay-sheet .pay-grid{display:flex;flex-direction:column;gap:16px;align-items:stretch}
.pay-sheet .pay-items-card,
.pay-sheet .pay-side-card{margin:0}

/* ── 4. Kepala kartu: skala apotek ─────────────────────────────────────── */
.pay-sheet .pay-items-head,
.pay-sheet .pay-side-head{padding:10px 15px;gap:9px;border-radius:14px 14px 0 0}
.pay-sheet .pay-items-head h3,
.pay-sheet .pay-side-head h3{font-size:.98rem;font-weight:800;letter-spacing:.01em}
.pay-sheet .pay-items-icon,
.pay-sheet .pay-side-head .apx-card-ico{width:27px;height:27px;flex:0 0 27px;border-radius:8px}
.pay-sheet .pay-items-icon svg,
.pay-sheet .pay-side-head .apx-card-ico svg{width:16px;height:16px}
.pay-sheet .pay-item-count,
.pay-sheet .pay-side-count{font-size:.68rem;font-weight:750;padding:4px 10px}

/* ── 5. Tabel rincian: skala apotek ────────────────────────────────────── */
.pay-sheet .pay-items-wrap{margin:14px 15px 0;max-height:none}
.pay-sheet table.data.pay-items-table{font-size:.88rem}
.pay-sheet table.data.pay-items-table thead th,
.pay-sheet table.data.pay-items-table thead th.col-no,
.pay-sheet table.data.pay-items-table thead th.col-sub,
.pay-sheet table.data.pay-items-table thead th.col-qty,
.pay-sheet table.data.pay-items-table thead th.col-price,
.pay-sheet table.data.pay-items-table thead th.col-unit{
  font-size:.84rem;font-weight:750;letter-spacing:0;text-transform:none;
  padding:12px 13px;color:var(--ink-strong);
}
.pay-sheet table.data.pay-items-table td{padding:11px 12px}
.pay-sheet .pay-item-name strong{font-size:.92rem}
.pay-sheet .pay-item-name .pay-item-sub{font-size:.76rem}

/* ── 6. Grid ringkasan = `.apx-sum-grid` (padding & jarak dari kelas apx) ─ */
.pay-sheet .pay-sum-grid{padding:16px 18px 18px}
.pay-sheet .pay-sum-mid,
.pay-sheet .pay-sum-pay,
.pay-sheet .pay-sum-side{border-left:1px solid var(--apx-line);padding-left:20px}
.pay-sheet .pay-sum-mid .field,
.pay-sheet .pay-sum-pay .field,
.pay-sheet .pay-sum-side .field{margin:0}
/* Kotak nominal "Jumlah Diterima": gaya `.apx-recv` (hijau lembut, angka kanan).
   Wrapper `money-wrap` global dinetralkan agar tidak ada bingkai ganda. */
.pay-sheet .pay-amount-field .money-wrap{background:transparent;border:0;border-radius:0}
.pay-sheet .pay-amount-field .money-wrap > input{
  background:var(--apx-recv-bg)!important;border:1.5px solid var(--apx-recv-bd)!important;
  border-radius:9px!important;color:var(--apx-sub-ink);font-weight:850;font-size:1.06rem;
  text-align:right;height:46px;
}
html[data-theme="dark"] .pay-sheet .pay-amount-field .money-wrap > input{color:#B8FFE8}
.pay-sheet .pay-amount-field .money-prefix{color:var(--apx-sub-ink);opacity:.85;font-weight:850;font-size:1.06rem}
/* Kotak "Sisa Tagihan" = kotak aksen seperti `.apx-total` */
.pay-sheet .pay-due-total{margin-top:4px}
/* Kolom 4: catatan + bukti pembayaran (details `.apx-proof`) */
.pay-sheet .pay-sum-side .pay-note textarea{min-height:56px;font-size:.9rem}
.pay-sheet .pay-proof-card{border:1px dashed var(--line-strong);border-radius:11px;padding:8px 11px;background:var(--tint-3)}
.pay-sheet .pay-proof-card summary{
  display:flex;align-items:center;gap:8px;cursor:pointer;
  font-size:.84rem;font-weight:750;color:var(--ink-2);
}
.pay-sheet .pay-proof-card[open] summary{margin-bottom:8px}
.pay-sheet .pay-proof-card .pay-opt-pill{margin-left:auto;font-size:.72rem;padding:3px 10px}
.pay-sheet .pay-proof-card .pay-proof-body{display:block;padding:0}
.pay-sheet .pay-proof-card .btn-attach{min-height:40px;padding:7px 13px;font-size:.82rem;border-radius:10px}
.pay-sheet .pay-proof-card .pay-proof-hint{font-size:.74rem;margin:8px 0 0}

/* Catatan hasil & riwayat: padding di dalam kartu (bukan menempel tepi) */
.pay-sheet .pay-side-card-body > .pay-due-note,
.pay-sheet .pay-side-card-body > .pay-change-note{margin:0 18px 12px}
.pay-sheet .pay-side-card-body > .pay-history{margin:0 18px 16px}

/* ── 7. Kaki kartu = skala `.apx-foot` ─────────────────────────────────── */
.pay-sheet .pay-foot{gap:14px;justify-content:flex-end;padding-top:12px}
.pay-sheet .pay-foot .foot-note{flex:1 1 100%;margin:0 0 2px;font-size:.76rem;text-align:left}
.pay-sheet .pay-btn-soft{
  min-height:50px;padding-inline:22px;border-radius:11px;font-weight:700;font-size:.9rem;
  background:var(--panel);border:1px solid var(--line-strong);color:var(--ink-strong);
}
.pay-sheet .pay-btn-soft:hover{background:var(--tint-3)}
.pay-sheet .pay-btn-main{min-height:50px;padding-inline:26px;border-radius:11px;font-weight:800;font-size:.95rem}

/* ── 8. Responsif mengikuti kartu apotek ───────────────────────────────── */
@media (max-width:1400px){
  .pay-sheet .pay-sum-grid{grid-template-columns:minmax(0,1fr) minmax(0,1fr)}
}
@media (max-width:1180px){
  .pay-top{grid-template-columns:minmax(0,1fr)}
  .pay-sheet .pay-items-wrap{max-height:none}
}
@media (min-width:721px) and (max-width:1100px){
  /* Tabel masih tabel → judul & sel dirampingkan supaya tidak perlu digeser */
  .pay-sheet table.data.pay-items-table thead th,
  .pay-sheet table.data.pay-items-table thead th.col-no,
  .pay-sheet table.data.pay-items-table thead th.col-sub{font-size:.78rem;padding:9px 8px}
  .pay-sheet table.data.pay-items-table td{padding:9px 8px}
  .pay-sheet .pay-items-wrap{margin:12px 12px 0}
}
@media (max-width:900px){
  .pay-sheet .pay-head-text h2{font-size:1.2rem}
  .pay-sheet .pay-sum-grid{grid-template-columns:minmax(0,1fr);padding:13px 15px 15px}
  .pay-sheet .pay-sum-mid,
  .pay-sheet .pay-sum-pay,
  .pay-sheet .pay-sum-side{border-left:0;padding-left:0}
  .pay-sheet .pay-side-card-body > .pay-due-note,
  .pay-sheet .pay-side-card-body > .pay-change-note,
  .pay-sheet .pay-side-card-body > .pay-history{margin-inline:15px}
  .pay-sheet .pay-foot .btn{flex:0 1 auto}
}
@media (max-width:640px){
  .pay-sheet .pay-head-icon{width:38px;height:38px;border-radius:11px}
  .pay-sheet .pay-head-icon svg{width:20px;height:20px}
  .pay-sheet .pay-head-text h2{font-size:1.12rem}
  .pay-sheet .pay-items-head,
  .pay-sheet .pay-side-head{padding:9px 12px}
  .pay-sheet .pay-items-head h3,
  .pay-sheet .pay-side-head h3{font-size:.92rem}
  .pay-sheet .pay-items-wrap{margin:12px 12px 0}
  .pay-sheet .pay-foot{flex-wrap:wrap}
  .pay-sheet .pay-foot .btn{flex:1 1 100%;justify-content:center}
  .pay-top-pill{margin-left:0}
}
/* Jenis Pembayaran: huruf agak tebal SETELAH dipilih (permintaan pemilik ronde
   sebelumnya — placeholder tetap ringan). Aturan lama hilang saat isian pindah
   ke grid ringkasan `.apx-sum-grid`, jadi ditegaskan lagi di sini. */
.pay-sheet .pay-method-field select,
.pay-sheet .pay-method-field .cs-btn{font-weight:650}
.pay-sheet .pay-method-field .cs-btn.is-empty{font-weight:500}

/* ══════════════════════════════════════════════════════════════════════════
   PARITAS AKHIR: SKALA HURUF & KEPALA KARTU PEMBAYARAN = KARTU APOTEK
   ──────────────────────────────────────────────────────────────────────────
   Nilai di bawah disalin dari aturan TERAKHIR kartu Penjualan Apotek (yang
   menang atas blok awalnya), karena diukur langsung di browser:
     judul kepala 1.15rem · kepala kartu padding 8px 14px / h3 .82rem /
     ikon 23px · pil .64rem · tabel .8rem / th .74rem (8px 10px) /
     td 7px 10px · tombol utama kaki 44px .86rem · HP: tombol kepala 40px
     (38px di ≤400px, label teks disembunyikan) & judul 1.06rem.
   Semua selektor memakai prefix `.pay-sheet` supaya menang atas blok tema
   sebelumnya tanpa `!important`.
   ══════════════════════════════════════════════════════════════════════════ */
.pay-sheet .pay-head-text h2{font-size:1.15rem;line-height:1.25;letter-spacing:.005em}
.pay-sheet .pay-head-icon{width:42px;height:42px;border-radius:12px}
.pay-sheet .pay-items-head,
.pay-sheet .pay-side-head{padding:8px 14px;gap:9px}
.pay-sheet .pay-items-head h3,
.pay-sheet .pay-side-head h3{font-size:.82rem;font-weight:750;letter-spacing:.01em}
.pay-sheet .pay-items-icon,
.pay-sheet .pay-side-head .apx-card-ico{width:23px;height:23px;flex:0 0 23px;border-radius:7px}
.pay-sheet .pay-items-icon svg,
.pay-sheet .pay-side-head .apx-card-ico svg{width:14px;height:14px}
.pay-sheet .pay-item-count,
.pay-sheet .pay-side-count{font-size:.64rem;padding:3px 9px}
.pay-sheet table.data.pay-items-table{font-size:.8rem}
.pay-sheet table.data.pay-items-table thead th,
.pay-sheet table.data.pay-items-table thead th.col-no,
.pay-sheet table.data.pay-items-table thead th.col-sub,
.pay-sheet table.data.pay-items-table thead th.col-qty,
.pay-sheet table.data.pay-items-table thead th.col-price,
.pay-sheet table.data.pay-items-table thead th.col-unit{font-size:.74rem;padding:8px 10px}
.pay-sheet table.data.pay-items-table td{padding:7px 10px}
.pay-sheet .pay-btn-main{min-height:44px;padding-inline:20px;font-size:.86rem}
.pay-sheet .pay-btn-soft{min-height:44px;padding-inline:18px;font-size:.86rem}
/* Tabel rincian: font nama & keterangan ikut skala kartu apotek */
.pay-sheet .pay-item-name strong{font-size:.86rem}
.pay-sheet .pay-item-name .pay-item-sub{font-size:.72rem}
.pay-sheet .pay-items-wrap .apx-sub{font-size:.88rem;padding:7px 11px;border-radius:8px}

@media (max-width:900px){
  .pay-sheet .pay-head{gap:10px}
  .pay-sheet .pay-head .row-actions{gap:6px}
  .pay-sheet .pay-head .row-actions .btn{
    width:40px;min-width:40px;height:40px;min-height:40px;
    padding:0;border-radius:11px;justify-content:center;
  }
  .pay-sheet .pay-head .row-actions .btn svg{width:18px;height:18px;flex:0 0 18px;margin:0}
  .pay-sheet .pay-head .row-actions .btn .lbl{display:none}
  .pay-sheet .pay-head-text h2{font-size:1.06rem}
}
@media (max-width:400px){
  .pay-sheet .pay-head .row-actions .btn{width:38px;min-width:38px;height:38px;min-height:38px}
  .pay-sheet .pay-head-text h2{font-size:1.06rem}
}

/* ── PARITAS RESPONSIF TAMBAHAN (kartu pembayaran vs kartu apotek) ────────
   Ditulis PALING AKHIR karena aturan dasar di atas (tanpa media query) akan
   menimpa media query yang ditulis lebih dulu (spesifisitas sama).
   · ≤900px : ikon kepala kartu 38px (sama seperti kartu apotek di HP).
   · 721–1100px : judul & sel tabel dirampingkan jadi 9px 8px (kartu apotek).
   · ≤640px : tombol kaki kartu 46px, tombol utama .8rem (kartu apotek).
   ⚠️ Padding SEL tabel di ≤900px TIDAK dibandingkan dengan kartu apotek: di
   sana tabel apotek berubah menjadi kartu bertingkat (`data-stack`) sehingga
   padding selnya 0 — sedangkan tabel pembayaran sengaja tetap tabel ringkas
   (`data-no-stack`, lihat blok HP-nya). Bentuknya memang beda peran. */
@media (max-width:900px){
  .pay-sheet .pay-head-icon{width:38px;height:38px;border-radius:11px}
  .pay-sheet .pay-head-icon svg{width:21px;height:21px}
}
@media (min-width:721px) and (max-width:1100px){
  .pay-sheet table.data.pay-items-table thead th,
  .pay-sheet table.data.pay-items-table thead th.col-no,
  .pay-sheet table.data.pay-items-table thead th.col-sub,
  .pay-sheet table.data.pay-items-table thead th.col-qty,
  .pay-sheet table.data.pay-items-table thead th.col-price,
  .pay-sheet table.data.pay-items-table thead th.col-unit{font-size:.74rem;padding:9px 8px}
  .pay-sheet table.data.pay-items-table td{padding:9px 8px}
}
@media (max-width:640px){
  .pay-sheet .pay-foot .btn{min-height:46px}
  .pay-sheet .pay-btn-main{font-size:.8rem}
  .pay-sheet .pay-btn-soft{font-size:.88rem}
}
@media (max-width:360px){
  .pay-sheet .pay-btn-main{font-size:.82rem}
  .pay-sheet .pay-btn-soft{font-size:.82rem}
}

/* ══════════════════════════════════════════════════════════════════════════
   KARTU PEMBAYARAN TAGIHAN — TOTAL TAGIHAN DIPERKECIL (permintaan pemilik)
   ──────────────────────────────────────────────────────────────────────────
   Batang "Total Tagihan" di dasar kartu Detail Transaksi masih memakai ukuran
   dari blok tema Penjualan Apotek (label 1.02rem, nominal 1.24rem). Pemilik
   meminta fontnya diperkecil supaya kartu lebih ringkas dan tidak "berteriak"
   dibanding isi tabel di atasnya — nominal tetap tegas (kotak hijau, tebal).
   Ditulis di PALING AKHIR agar menang atas aturan 10715 (spesifisitas sama).
   ══════════════════════════════════════════════════════════════════════════ */
.pay-sheet .pay-total-row{padding:8px 11px;gap:10px;margin:12px 16px 14px}
.pay-sheet .pay-total-row .apx-total-lbl{font-size:.82rem;font-weight:800;gap:8px}
.pay-sheet .pay-total-row .apx-total-ico{width:24px;height:24px;flex:0 0 24px}
.pay-sheet .pay-total-row .apx-total-ico svg{width:17px;height:17px}
.pay-sheet .pay-total-row strong{font-size:1.02rem;padding:6px 13px;border-radius:9px}
@media (max-width:640px){
  .pay-sheet .pay-total-row{padding:7px 10px;margin:10px 12px 12px}
  .pay-sheet .pay-total-row .apx-total-lbl{font-size:.8rem}
  .pay-sheet .pay-total-row strong{font-size:.98rem;padding:6px 11px}
}

/* ══════════════════════════════════════════════════════════════════════════
   KARTU PEMBAYARAN TAGIHAN — SERAGAMKAN FONT 4 SECTION + TANPA IKON TOTAL
   ──────────────────────────────────────────────────────────────────────────
   Permintaan pemilik: **Sudah Dibayar · Kembalian · Total Tagihan · Sisa Tagihan**
   harus memakai UKURAN HURUF YANG SAMA untuk label maupun nominalnya.

   Sebelum blok ini ukurannya berbeda-beda (terukur pada bill INV-261027-04):
     · Total Tagihan   label 14,10px/800 · nominal 17,54px/900
     · Sudah Dibayar   label 13,76px/700 · nominal 14,79px/800
     · Kembalian       label 13,76px/700 · nominal 14,79px/800
     · Sisa Tagihan    label 13,76px/800 · nominal 15,82px/900

   Target yang dipakai sekarang (satu nilai untuk keempatnya):
     · LABEL   `.8rem` (13,76px) / 800
     · NOMINAL `.92rem` (15,82px) / 900, angka tabular

   ⚠️ Ditulis di PALING AKHIR berkas supaya menang atas aturan tema apotek
   (`.apx-sum-lbl`, `.apx-total-lbl`, `.pay-total-row strong`) yang spesifisitasnya
   sama tetapi ditulis lebih dulu. Jangan menurunkan selektornya ke satu kelas saja.
   ══════════════════════════════════════════════════════════════════════════ */
.pay-sheet .pay-total-row .apx-total-lbl,
.pay-sheet .pay-sum-grid .apx-sum-lbl,
.pay-sheet .pay-sum-grid .apx-total-lbl{
  font-size:.8rem;font-weight:800;
}
.pay-sheet .pay-total-row > strong,
.pay-sheet .pay-sum-grid .apx-sum-line > strong,
.pay-sheet .pay-sum-grid .apx-total-val{
  font-size:.92rem;font-weight:900;font-variant-numeric:tabular-nums;
}
/* Tanpa ikon: label tidak lagi memakai flex ber-`gap` (sisa ruang ikon dihapus). */
.pay-sheet .pay-total-row .apx-total-lbl{gap:0}
@media (max-width:640px){
  .pay-sheet .pay-total-row .apx-total-lbl,
  .pay-sheet .pay-sum-grid .apx-sum-lbl,
  .pay-sheet .pay-sum-grid .apx-total-lbl{font-size:.79rem}
  .pay-sheet .pay-total-row > strong,
  .pay-sheet .pay-sum-grid .apx-sum-line > strong,
  .pay-sheet .pay-sum-grid .apx-total-val{font-size:.9rem}
}

/* ══════════════════════════════════════════════════════════════════════════
   KARTU PENJUALAN APOTEK — SUSUNAN MOBILE, FONT NORMAL, RACIKAN HIJAU
   ══════════════════════════════════════════════════════════════════════════
   Permintaan pemilik:
     1. [Pembulatan] kembali ke bawah [Embalase]  → dikerjakan di MARKUP
        (`pages/kasir_apotek.php`, `.apx-sum-left`), bukan di CSS.
     2. Layout DESKTOP DIPERTAHANKAN; hanya tampilan HP yang disusun ulang
        menjadi satu kolom dengan urutan:
          Subtotal · Embalase · Pembulatan · Total Tagihan ·
          Metode Pembayaran · Akun Pembayaran · Opsi Harga · Jumlah Diterima ·
          Kembalian · Catatan · Bukti Pembayaran
     3. Font [Kasir], [Pasien], dan nilai [-- Pasien Umum --] dibuat NORMAL
        (tidak tebal).
     4. Sub-kartu Racikan (kartu [Racikan]) berlatar HIJAU.

   ⚠️ Cara menyusun ulang (penting): keempat kolom `.apx-sum-*` adalah wadah
   flex; `order` TIDAK bisa menyelipkan isi satu wadah di antara isi wadah lain.
   Karena itu pada layar HP wadahnya dibuat `display:contents` sehingga SEMUA
   baris menjadi anak langsung `.apx-sum-grid` (flex kolom) — barulah `order`
   per baris bisa menghasilkan urutan campuran di atas. Desktop tidak tersentuh
   karena seluruh blok ini berada di dalam `@media (max-width:900px)` (titik
   yang sama dengan saat grid ringkasan menjadi satu kolom).
   ══════════════════════════════════════════════════════════════════════════ */
/* ⚠️ SEMUA selektor di sini WAJIB diawali `.apx-sum` (kartu Ringkasan milik
   Penjualan Apotek). Kelas `.apx-sum-grid` / `.apx-sum-left` JUGA dipakai kartu
   Pembayaran Tagihan (`_pay_sheet.php`, `.pay-sum-*`) — tanpa awalan ini tata
   letak kartu pembayaran ikut berubah. */
@media (max-width:900px){
  .apx-sum > .apx-sum-grid{display:flex;flex-direction:column;gap:14px}
  /* Wadah kolom "dibubarkan" supaya isinya ikut antre di kolom tunggal. */
  .apx-sum .apx-sum-left,
  .apx-sum .apx-sum-mid,
  .apx-sum .apx-sum-pay,
  .apx-sum .apx-sum-side{display:contents}
  /* Baris yang disembunyikan (mis. Pembulatan saat langkah = 0) tetap hilang. */
  .apx-sum > .apx-sum-grid [hidden]{display:none!important}

  /* ── URUTAN 1–4: kolom kiri ─────────────────────────────────────────── */
  .apx-sum .apx-sum-left > .apx-sum-line:nth-child(1){order:1}   /* Subtotal */
  .apx-sum .apx-sum-left > .apx-sum-line:nth-child(2){order:2}   /* Embalase */
  .apx-sum .apx-sum-left > .apx-round-line{order:3}              /* Pembulatan */
  .apx-sum .apx-sum-left > .apx-total{order:4}                   /* Total Tagihan */
  /* ── 5: Metode Pembayaran · 8: Jumlah Diterima ──────────────────────── */
  .apx-sum .apx-sum-mid > .field:nth-child(1){order:5}
  .apx-sum .apx-sum-mid > .apx-recv{order:8}
  /* ── 6: Akun Pembayaran · 9: Kembalian ─────────────────────────────── */
  .apx-sum .apx-sum-pay > .apx-acc-field{order:6}
  .apx-sum .apx-sum-pay > .field:not(.apx-acc-field){order:9}
  /* ── 7: Opsi Harga · 10: Catatan · 11: Bukti Pembayaran ────────────── */
  .apx-sum .apx-sum-side > .field:nth-child(1){order:7}
  .apx-sum .apx-sum-side > .field:nth-child(2){order:10}
  .apx-sum .apx-sum-side > .apx-proof{order:11}
}

/* ── Font NORMAL untuk Kasir / Pasien / nilai pasien (permintaan pemilik) ──
   Sebelumnya: label "Kasir" & "Pasien" 800, nilai kasir 750, dan nilai pasien
   800 (`.cs-btn{font:inherit}` mewarisi bobot dari `.apx-doctor-row`). Semua
   diturunkan ke 400; UKURAN huruf tidak diubah. */
.apx-top .apx-kasir-lbl,
.apx-top .apx-kasir > span:not(.money-prefix),
.apx-top .apx-patient .apx-wide > span:not(.money-prefix),
.apx-top .apx-patient .apx-doctor-row,
.apx-top .apx-kasir .cs-btn,
.apx-top .apx-kasir .cs-btn .cs-label,
.apx-top .apx-kasir > select,
.apx-top .apx-patient .cs-btn,
.apx-top .apx-patient .cs-btn .cs-label,
.apx-top .apx-patient select{font-weight:400}

/* ── Sub-kartu RACIKAN berlatar HIJAU LEMBUT (permintaan pemilik) ─────────
   Memakai token tint hijau yang sama dengan baris penerimaan barang
   (`--grn-tint` / `--grn-bd`) sehingga warnanya otomatis menyesuaikan tema
   terang & gelap. Tabel di dalamnya tetap berlatar panel agar angka terbaca. */
.apx-cmp-sheet .cmp-card,
.apx-cmp-sheet .apx-cmp-card{
  background:var(--grn-tint);
  border-color:var(--grn-bd);
}


/* ══════════════════════════════════════════════════════════════════════════
   PENJUALAN APOTEK — HP: RINGKASAN RAPAT & TABEL PRODUK KOMPAK (permintaan pemilik)
   ──────────────────────────────────────────────────────────────────────────
   DESKTOP TIDAK DIUBAH: seluruh blok di bawah hanya berlaku ≤720px (tabel) dan
   ≤900px (ringkasan) — titik yang sama dengan saat kartu menjadi satu kolom.

   (a) RINGKASAN: baris "Subtotal / Embalase / Pembulatan / Total" harus selebar
       KARTU, label rapat KIRI dan angka rapat KANAN, dengan jarak di antaranya.
       ⚠️ Akar masalahnya: `.apx-sum-grid` memakai `align-items:start` (benar untuk
       grid desktop). Di HP wadah kolom dijadikan `display:contents`, sehingga
       `align-items:start` membuat SETIAP baris hanya selebar isinya — angka tiap
       baris jadi tidak sejajar di kanan (terukur: Subtotal 182px, Total 207px di
       kartu 323px). Di HP `align-items` WAJIB `stretch`.
   (b) RINGKASAN: seluruh isian (Metode, Akun, Opsi Harga, Jumlah Diterima,
       Kembalian, Catatan, Bukti Pembayaran) ikut melebar SATU BARIS penuh di
       dalam kartu — efek samping yang sama dari `stretch`.
   (c) TABEL PRODUK: kolom Jumlah/Satuan/Harga/Embalase mengikuti UKURAN KONTEN
       (dulu masing-masing dipaksa 50% lebar → banyak ruang kosong), dan
       **SUBTOTAL melebar serta satu baris dengan tombol hapus**.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── (a)+(b) ringkasan HP ─────────────────────────────────────────────── */
@media (max-width:900px){
  /* Wadah kolom sudah `display:contents` (lihat blok urutan mobile di atas) —
     baris & isian adalah anak langsung grid, jadi harus `stretch`. */
  .apx-sum > .apx-sum-grid{align-items:stretch}
  /* Baris angka: label menempel KIRI, nominal menempel KANAN, ada jarak. */
  .apx-sum .apx-sum-left > .apx-sum-line,
  .apx-sum .apx-sum-left > .apx-total{width:100%}
  .apx-sum .apx-sum-left > .apx-sum-line > strong,
  .apx-sum .apx-sum-left > .apx-total > .apx-total-val{justify-self:end;text-align:right}
  /* Isian satu baris penuh di dalam kartu. */
  .apx-sum .apx-sum-mid > .field,
  .apx-sum .apx-sum-pay > .field,
  .apx-sum .apx-sum-side > .field,
  .apx-sum .apx-sum-side > .apx-proof{width:100%;max-width:none}
}

/* ── (c) tabel produk HP: SUSUNAN 2 KOLOM TETAP (permintaan pemilik) ─────
   Urutan yang diminta (tampilan HP):
       [OBAT / ALKES]
       [JUMLAH] [SATUAN]
       [HARGA]  [EMBALASE]
       [SUBTOTAL] [AKSI]
   Dipakai GRID dua kolom sama lebar sehingga tepi kiri & kanan kolom rata
   dengan tepi kartu, label tiap kontrol muncul di atas isiannya (dari
   `data-apx-label` yang dipasang `renumber()`), dan SUBTOTAL selalu sebaris
   dengan tombol hapus.

   ⚠️ Jangan kembali ke `flex-wrap`: hasilnya baris tidak konsisten
   (Embalase kadang sendirian, SUBTOTAL jadi sempit) — itu bug yang dilaporkan
   pemilik sebelum ini.
   ══════════════════════════════════════════════════════════════════════════ */
@media (max-width:720px){
  /* Kontrol dirampingkan: padding bawaan (10px 12px) membuat kolom sempit
     tidak cukup untuk angka + prefix "Rp". */
  table.data.apx-table td input,
  table.data.apx-table td select,
  table.data.apx-table td .cs-btn{font-size:.78rem;min-height:34px}
  table.data.apx-table td input[type=number]{padding:5px 6px;text-align:center}
  /* Prefix "Rp" DIPERTAHANKAN tetapi dirapatkan. `!important` wajib: aturan global
     `.money-wrap>input[data-money]{padding-left:38px!important}` (dan 40px di
     ≤640px) mengalahkan aturan biasa sehingga "22.138" terpotong. */
  table.data.apx-table td .money-wrap > input[data-money]{padding-left:21px!important;padding-right:4px}
  table.data.apx-table td .money-wrap > .money-prefix{left:4px;font-size:.66rem}
  table.data.apx-table td .cs-btn{padding:6px 24px 6px 7px}
  table.data.apx-table td .cs-btn .cs-caret{right:5px;width:13px;height:13px}
  table.data.apx-table td[data-apx-label]::before{
    font-size:.62rem;margin-bottom:2px;letter-spacing:.04em;white-space:nowrap;
  }
  /* Embalase = LABEL (bukan input) sehingga tidak kena aturan 16px anti-zoom iOS. */
  table.data.apx-table td.apx-col-emb .apx-emb{font-size:.74rem;gap:7px}
  table.data.apx-table td.apx-col-emb .apx-emb-box{width:18px;height:18px;flex:0 0 18px}

  /* ── BARIS = GRID 2 KOLOM (urutan tetap, rata kiri & kanan) ─────────── */
  table.data.apx-table tr{
    display:grid;
    grid-template-columns:minmax(0,1fr) minmax(0,1fr);
    grid-template-areas:
      "item  item"
      "qty   unit"
      "price emb"
      "sub   act";
    align-items:end;
    gap:8px 8px;
    padding:10px 9px;
  }
  table.data.apx-table td{
    display:block;padding:0;border:0;
    width:auto!important;min-width:0;
  }
  table.data.apx-table td.apx-col-no{display:none}
  /* Sisa sel pemutus baris dari ronde sebelumnya tidak dipakai lagi di sini. */
  table.data.apx-table td.apx-col-gap{display:none!important}
  table.data.apx-table td.apx-col-item{grid-area:item}
  table.data.apx-table td.apx-col-qty{grid-area:qty}
  table.data.apx-table td.apx-col-unit{grid-area:unit}
  table.data.apx-table td.apx-col-price{grid-area:price}
  table.data.apx-table td.apx-col-emb{grid-area:emb}
  table.data.apx-table td.apx-col-sub{grid-area:sub}
  /* AKSI: sel MENGISI kolomnya (dua kolom tetap sama lebar = rata kiri/kanan),
     tombolnya didorong ke KANAN. `justify-self:stretch` wajib — aturan ≤900px
     lain (`justify-self:end`) membuat sel ini hanya selebar tombolnya.
     Label "Aksi" DIPINDAH KE ATAS tombol hapus (permintaan pemilik): karena sel
     ini flex ROW, label `::before` tidak bisa menjadi baris sendiri — karena itu
     label diposisikan ABSOLUT di kanan-atas dan sel diberi `padding-top`. */
  table.data.apx-table td.apx-col-act{
    grid-area:act;
    display:flex!important;
    align-items:flex-end;
    justify-content:flex-end;
    justify-self:stretch;
    gap:6px;
    position:relative;
    padding-top:15px!important;
  }
  table.data.apx-table td.apx-col-act[data-apx-label]::before{
    position:absolute;top:0;right:0;
    margin:0;text-align:right;line-height:1;
  }

  /* Isian mengisi kolomnya, tetapi tidak melar tanpa batas di layar lebar
     (mis. 600–720px) supaya tetap "sesuai konten". */
  table.data.apx-table td input,
  table.data.apx-table td select,
  table.data.apx-table td .cs-btn{width:100%;max-width:220px;min-width:0}
  /* ⚠️ PENGECUALIAN: dropdown pencarian **OBAT / ALKES** menempati SATU BARIS
     PENUH (rata kiri & rata kanan kartu) — jadi batas 220px di atas DILEPAS
     untuk sel itu. Tanpa ini dropdown hanya 220px di tengah baris yang lebarnya
     283–613px (terlihat "menggantung"). */
  table.data.apx-table td.apx-col-item .cs-btn,
  table.data.apx-table td.apx-col-item select,
  table.data.apx-table td.apx-col-item .cs-btn .cs-label{width:100%;max-width:none}
  /* ⚠️ `.money-wrap` punya `min-width:96px` (aturan tabel desktop) yang menjepit
     kolom ramping — dilepas, dan pembungkusnya ikut mengikuti lebar kolom. */
  table.data.apx-table td .money-wrap{width:100%;max-width:220px;min-width:0}
  table.data.apx-table td .apx-emb{min-width:0}
  /* SUBTOTAL: kotak selebar kolom, angkanya rata KANAN. */
  table.data.apx-table td.apx-col-sub .apx-sub{width:100%;text-align:right}
  /* Tombol hapus/ubah racikan tetap 34px (target sentuh nyaman) & rapat kanan. */
  table.data.apx-table td.apx-col-act .btn{
    width:34px;height:34px;min-width:34px;margin:0;
  }
}

/* ══════════════════════════════════════════════════════════════════════════
   PENJUALAN APOTEK — TABEL PRODUK PADA LAYAR 721–1100px (TABLET / JENDELA SEMPIT)
   ──────────────────────────────────────────────────────────────────────────
   Di rentang ini tabel MASIH berupa tabel (bukan kartu bertingkat), tetapi aturan
   lama memberi kolom hapus `width:82px` + `display:grid` sehingga kolom Item
   hanya tersisa ~67px (nama obat terpotong) dan sel tombol hapus melebar keluar
   wadah kartu.

   ⚠️ Lebar kolom `table-layout:fixed` ditentukan oleh sel BARIS PERTAMA (yaitu
   `<th>` di thead). Karena itu selektornya memakai KELAS KOLOM (`.apx-col-*`)
   yang mengenai th DAN td — kalau hanya `td.`, aturan lama (`width:88px/82px`
   pada `<th>`) tetap menang. Blok ini juga mengembalikan kolom hapus menjadi
   `table-cell` supaya tombolnya tidak melebar keluar kartu.
   ══════════════════════════════════════════════════════════════════════════ */
@media (min-width:721px) and (max-width:1100px){
  table.data.apx-table .apx-col-no{width:30px}
  table.data.apx-table .apx-col-qty{width:58px}
  table.data.apx-table .apx-col-unit{width:96px}
  table.data.apx-table .apx-col-price{width:112px}
  table.data.apx-table .apx-col-emb{width:96px}
  table.data.apx-table .apx-col-sub{width:112px}
  table.data.apx-table .apx-col-act{width:60px}
  table.data.apx-table .apx-col-item{width:auto;min-width:110px}
  table.data.apx-table td.apx-col-act{
    display:table-cell!important;text-align:center;padding:8px 6px;
  }
  table.data.apx-table td.apx-col-act .btn{
    width:34px;height:34px;min-width:34px;margin:0 0 0 3px;
  }
  table.data.apx-table td.apx-col-act .btn:first-child{margin-left:0}
  /* Nominal Harga: pembungkus "Rp" dilepas dari `min-width:96px` & prefix dirapatkan
     (aturan dasar memakai 38px sehingga "22.138" terpotong di kolom 112px). */
  table.data.apx-table td.apx-col-price .money-wrap{min-width:0;width:100%}
  table.data.apx-table td.apx-col-price .money-wrap > input[data-money]{
    width:100%;min-width:0;padding-left:24px!important;padding-right:3px;
  }
  table.data.apx-table td.apx-col-price .money-wrap > .money-prefix{left:6px;font-size:.72rem}
}

/* ══════════════════════════════════════════════════════════════════════════
   PENJUALAN APOTEK — HP: KOLOM [SATUAN] SEJAJAR [JUMLAH] & [EMBALASE]
   SEBAGAI KOTAK GAYA INPUT (permintaan pemilik)
   ──────────────────────────────────────────────────────────────────────────
   DESKTOP TIDAK DIUBAH — seluruh aturan ada di `@media (max-width:720px)`.

   (a) SATUAN sejajar Jumlah.
       Terukur sebelumnya: `<select>` Satuan tinggi **43,6px** sedangkan input
       Jumlah **34px** (select memakai padding global 10px 12px; input angka
       memakai padding ramping 5px 6px). Walau `align-items:end` membuat alasnya
       rata, kotaknya terlihat tidak sejajar. Sekarang select diberi padding &
       tinggi yang SAMA dengan input Jumlah (34px).

   (b) EMBALASE = satu kotak bergaya INPUT: kotak centang di KIRI (untuk
       mengaktifkan/mematikan), nominal STATIS dari master embalase produk di
       KANAN (rata kanan, angka tabular), tinggi sejajar kolom Harga (44px).
       Sebelumnya hanya label tanpa kotak (checkbox + teks), sehingga tidak
       terlihat sebagai kontrol dan tingginya cuma 18px.
   ══════════════════════════════════════════════════════════════════════════ */
@media (max-width:720px){
  /* ── (a) Satuan = tinggi & padding sama dengan Jumlah ─────────────────── */
  table.data.apx-table td.apx-col-unit select{
    min-height:34px;height:34px;
    padding:5px 26px 5px 6px;      /* panah sendiri: sisakan ruang di kanan */
    line-height:1.15;
  }
  /* Input Jumlah & Harga disamakan tinggi kotaknya agar satu baris rapi. */
  table.data.apx-table td.apx-col-qty input[type=number]{
    min-height:34px;height:34px;padding:5px 6px;line-height:1.15;
  }
  table.data.apx-table td.apx-col-price input[data-money]{
    min-height:44px;height:44px;
  }

  /* ── (b) Embalase = kotak gaya input ─────────────────────────────────── */
  table.data.apx-table td.apx-col-emb .apx-emb{
    display:flex;align-items:center;gap:8px;
    width:100%;max-width:220px;
    height:44px;min-height:44px;
    padding:0 9px;
    border:1px solid var(--line-strong);
    border-radius:9px;
    background:var(--panel);
    font-size:.74rem;font-weight:650;
  }
  /* Nominal STATIS dari master: menempel KANAN, angka tabular (tidak "melompat"). */
  table.data.apx-table td.apx-col-emb .apx-emb-amt{
    margin-left:auto;text-align:right;
    font-variant-numeric:tabular-nums;font-weight:750;
    white-space:nowrap;
  }
  /* Kotak centang di kiri sedikit lebih besar agar mudah ditekan di HP. */
  table.data.apx-table td.apx-col-emb .apx-emb-box{width:20px;height:20px;flex:0 0 20px}
  table.data.apx-table td.apx-col-emb .apx-emb-box::after{width:14px;height:14px}
  /* Baris RACIKAN: nominal otomatis, kotak centang tersembunyi → tetap kotak input. */
  table.data.apx-table tr.is-compound td.apx-col-emb .apx-emb{padding:0 10px}
}
/* Layar sangat sempit: rapatkan padding kotak embalase supaya "Rp 1.000" utuh. */
@media (max-width:384px){
  table.data.apx-table td.apx-col-emb .apx-emb{gap:6px;padding:0 7px}
  table.data.apx-table td.apx-col-emb .apx-emb-amt{font-size:.7rem}
  table.data.apx-table td.apx-col-emb .apx-emb-box{width:18px;height:18px;flex:0 0 18px}
}

/* ══════════════════════════════════════════════════════════════════════════
   MENU OBAT & ALKES — KARTU MASTER + BARIS PENCARIAN SELALU TAMPIL
   ──────────────────────────────────────────────────────────────────────────
   Permintaan pemilik: kartu [Filter & Pencarian] dipindah KE DALAM kartu
   Master Obat/Alkes, selalu tampil (tanpa tombol sembunyikan), dan kotak
   pencarian sejajar dengan pilihan [Kolom] serta tombol [Terapkan],
   [Unduh CSV], dan [Stok Rendah].
   MARKUP: `.lab-card.master-card > .card-head + form.global-search.master-tools`
   ══════════════════════════════════════════════════════════════════════════ */
.master-card{padding-bottom:14px}
.master-card > .card-head{margin-bottom:0}
.master-card .card-head h2{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.master-card .master-tools{
  margin:12px 0 0;padding:0;border:0;background:none;
  display:flex;flex-wrap:wrap;align-items:center;gap:10px;
}
.master-card .master-tools .master-q{flex:1 1 320px;min-width:0}
.master-card .master-tools .master-kind{flex:0 0 auto;margin:0}
.master-card .master-tools .master-kind select{min-width:150px}
/* [Kolom] menempel pada deretan tombol (slot diisi assets/app.js) */
.master-card .master-tools .master-cols{flex:0 0 auto;display:flex;align-items:center}
.master-card .master-tools .master-cols:empty{display:none}
.master-card .master-tools .table-tools.is-inline{margin:0;justify-content:flex-start}
/* Tinggi kontrol disamakan dengan kotak pencarian (46px) supaya sejajar rapi. */
.master-card .master-tools .btn,
.master-card .master-tools .btn-cols{flex:0 0 auto;min-height:46px;padding:0 16px}
.master-card .master-tools .btn-cols{padding:0 13px}
.master-card .master-tools .master-kind select{min-height:46px}

/* Warna ZAT AKTIF di bawah nama produk: #0000ff (permintaan pemilik).
   Di tema gelap dipakai biru terang (#7C8CFF) supaya tetap terbaca —
   #0000ff di latar gelap kontrasnya hanya ~2:1. */
.item-ing{
  margin-top:2px;font-size:.75rem;font-weight:650;line-height:1.3;
  color:#0000ff;white-space:normal;overflow-wrap:anywhere;
}
html[data-theme="dark"] .item-ing{color:#7C8CFF}

/* HP: pencarian satu baris penuh, tombol 2 kolom rapi (tetap ≥44px). */
@media (max-width:640px){
  .master-card{padding-left:12px;padding-right:12px}
  .master-card .master-tools{gap:8px}
  .master-card .master-tools .master-q{flex:1 1 100%}
  .master-card .master-tools .master-kind{flex:1 1 100%}
  .master-card .master-tools .master-kind select{width:100%}
  .master-card .master-tools > .btn,
  .master-card .master-tools > .master-cols{flex:1 1 calc(50% - 4px)}
  .master-card .master-tools .master-cols .table-tools{width:100%}
  .master-card .master-tools .master-cols .btn-cols{width:100%;justify-content:center}
  .master-card .master-tools .btn{min-height:44px;padding:0 10px;justify-content:center}
}

/* ══════════════════════════════════════════════════════════════════════════
   1. BUG [Kolom]: panel tertutup kartu tabel
   ──────────────────────────────────────────────────────────────────────────
   `.lab-card{isolation:isolate}` membuat SETIAP kartu menjadi konteks
   penumpukan sendiri dengan `z-index:auto`. Panel `.cols-panel` berada di dalam
   kartu Master (kartu lebih dulu di DOM), sehingga kartu TABEL yang datang
   sesudahnya dilukis DI ATAS panel — walau panelnya `z-index:55`.
   Perbaikan: kartu Master diberi `z-index` (di atas kartu daftar) selama panel
   terbuka / saat kartu itu memuat slot [Kolom]. Ditulis spesifik `.master-card`
   supaya urutan kartu lain tidak berubah.
   ══════════════════════════════════════════════════════════════════════════ */
.lab-card.master-card{position:relative;z-index:6}
/* Kartu daftar di bawahnya tetap di lapisan dasar. */
.master-card + .lab-card,
.master-card ~ .lab-card{position:relative;z-index:1}

/* ══════════════════════════════════════════════════════════════════════════
   2. AREA GULIR DAFTAR — hanya daftar yang bergulir
   ──────────────────────────────────────────────────────────────────────────
   `--list-h` dihitung assets/app.js (sisa ruang di layar). Bila layar terlalu
   pendek, kelas `.is-scroller` TIDAK dipasang dan halaman memakai gulir biasa.
   TAB, KPI, dan baris pencarian otomatis tetap diam karena halaman tidak lagi
   perlu digulir.
   ══════════════════════════════════════════════════════════════════════════ */
[data-list-scroll].is-scroller{
  max-height:var(--list-h,70vh);
  overflow:auto;
  overscroll-behavior:contain;
  /* ruang untuk bayangan tepi agar tidak menempel ke kartu di bawahnya */
  padding-bottom:4px;
}
/* Judul kolom tabel menempel di atas saat daftar digulir. */
[data-list-scroll].is-scroller table.data thead th{
  position:sticky;top:0;z-index:3;
  background:var(--apx-th-bg,var(--foot-bg,var(--panel-2)));
  box-shadow:inset 0 -1px 0 var(--line-strong);
}
/* Gulir halus di dalam area daftar (bukan halaman). */
[data-list-scroll].is-scroller{scrollbar-gutter:stable}
@media (max-width:900px){
  /* Di HP tinggi --list-h dihitung dari sisa layar; pastikan minimal nyaman. */
  [data-list-scroll].is-scroller{max-height:var(--list-h,64vh)}
}

/* ══════════════════════════════════════════════════════════════════════════
   3. KOLOM PENCARIAN KEDUA (Zat Aktif) pada kartu Master
   ══════════════════════════════════════════════════════════════════════════ */
.master-card .master-tools .master-qa{flex:1 1 260px;min-width:0}
@media (max-width:640px){
  .master-card .master-tools .master-q,
  .master-card .master-tools .master-qa{flex:1 1 100%}
}

/* ══════════════════════════════════════════════════════════════════════════
   KEPALA HALAMAN STICKY — TAB + KPI + BARIS PENCARIAN DIAM SAAT DAFTAR DIGULIR
   ──────────────────────────────────────────────────────────────────────────
   Permintaan pemilik (Obat & Alkes, juga Master Tindakan): saat menggulir
   daftar, TAB, kartu KPI, dan baris pencarian tetap di atas.

   ⚠️ `position:sticky` hanya menempel SELAMA kotak induknya masih terlihat.
   Karena itu ketiga blok ini **tidak dibungkus** — mereka tetap anak langsung
   `.content` (setinggi halaman) dan menempel dengan offset BERTUMPUK:
     TAB        top = --topbar-h
     KPI        top = --topbar-h + --tabbar-h   (desktop saja)
     pencarian  top = --topbar-h + --tabbar-h + --kpi-h
   Tinggi diukur assets/app.js (stickyHeads()).
   Latar WAJIB pekat: isi daftar bergerak DI BAWAH blok yang menempel.
   Di HP kartu KPI sengaja tidak menempel supaya daftar tetap lapang.
   ══════════════════════════════════════════════════════════════════════════ */
@media (min-width:901px){
  .content > .tab-bar.sticky-head{
    position:sticky;top:var(--topbar-h,49px);z-index:14;
    background:var(--topbar-bg);border-radius:0 0 var(--radius-sm) var(--radius-sm);
    padding-block:5px;margin-block:-5px;
  }
  .content > .kpi-grid.sticky-head{
    position:sticky;
    top:calc(var(--topbar-h,49px) + var(--tabbar-h,0px));
    z-index:13;margin:0;
    background:var(--topbar-bg);
    padding-block:6px;border-radius:0 0 var(--radius-sm) var(--radius-sm);
  }
  .content > .lab-card.master-card{
    position:sticky;
    top:calc(var(--topbar-h,49px) + var(--tabbar-h,0px) + var(--kpi-h,0px));
    z-index:12;
    box-shadow:0 12px 26px -20px rgba(0,0,0,.6);
  }
}
@media (max-width:900px){
  /* HP: TAB + baris pencarian menempel; KPI ikut tergulir (hemat layar). */
  .content > .tab-bar.sticky-head{
    position:sticky;top:var(--topbar-h,59px);z-index:14;
    background:var(--topbar-bg);padding-block:4px;margin-block:-4px;
  }
  .content > .lab-card.master-card{
    position:sticky;
    top:calc(var(--topbar-h,59px) + var(--tabbar-h,0px));
    z-index:12;
    box-shadow:0 12px 24px -20px rgba(0,0,0,.6);
  }
}

/* ══════════════════════════════════════════════════════════════════════════
   KARTU MUTASI STOK — RANCANGAN TIGA BARIS (permintaan pemilik, tab
   Stok & Batch → Mutasi stok)

   Susunan tiap kartu:
     ① #nomor · 📅 tanggal jam ···································· [Stok Keluar]
     ② KODE • NAMA OBAT • BN : … • ED : …
     ③ [ 📄 rujukan │ 👤 dicatat oleh │ 🏷 keterangan ]  │  JUMLAH + satuan
        (panel hijau lembut, segmen dipisah garis tipis)   (angka besar, merah/hijau)

   Angka jumlah TANPA tanda +/−: warna sudah menunjukkan arah stok (hijau masuk,
   merah keluar, biru penyesuaian) — sama seperti gambar acuan pemilik.
   Blok ini berada PALING AKHIR berkas supaya menimpa aturan `.smv-*` lama
   (padanan spesifisitas, jadi urutan yang menentukan).
   ══════════════════════════════════════════════════════════════════════════ */
.stock-move-list{display:flex;flex-direction:column;gap:14px}

.stock-move-list .smv-card{
  display:flex;flex-direction:column;gap:10px;
  padding:13px 15px 14px;
  border:1px solid var(--line-strong);
  border-radius:16px;
  background:var(--panel);
  box-shadow:0 14px 28px -26px rgba(15,23,42,.55);
  font-size:.78rem;
}
html[data-theme="dark"] .stock-move-list .smv-card{box-shadow:0 14px 28px -24px rgba(0,0,0,.85)}

/* ① kepala kartu */
.stock-move-list .smv-head{display:flex;align-items:center;gap:12px;flex-wrap:wrap}
.stock-move-list .smv-id{
  font-family:var(--mono);font-size:.72rem;font-weight:700;letter-spacing:.01em;
  padding:2px 10px;border-radius:999px;white-space:nowrap;
  border:1px solid var(--line-strong);background:var(--tint-3);color:var(--code-ink);
}
.stock-move-list .smv-time{
  display:inline-flex;align-items:center;gap:9px;
  font-size:.84rem;font-weight:700;color:var(--head-ink);
  font-variant-numeric:tabular-nums;letter-spacing:.01em;
}
.stock-move-list .smv-time svg{width:16px;height:16px;fill:var(--ink-2);flex:0 0 auto}
.stock-move-list .smv-kind{
  margin-left:auto;text-transform:none;letter-spacing:0;
  font-size:.7rem;font-weight:700;padding:3px 11px;
}
.stock-move-list .smv-kind.is-out{background:var(--warn-bg);color:var(--warn-fg);border-color:var(--warn-bd)}
.stock-move-list .smv-kind.is-in{background:var(--ok-bg);color:var(--ok-fg);border-color:var(--ok-bd)}
.stock-move-list .smv-kind.is-adj{background:var(--info-bg);color:var(--info-fg);border-color:var(--info-bd)}

/* ② nama barang */
.stock-move-list .smv-title{
  font-size:.86rem;font-weight:700;line-height:1.5;
  color:var(--head-ink);overflow-wrap:anywhere;
}
.stock-move-list .smv-title .smv-code{font-family:var(--mono);color:var(--code-ink);font-weight:700}
.stock-move-list .smv-title .smv-sep{color:var(--ink-3);margin:0 3px;font-weight:600}
.stock-move-list .smv-title .smv-bn{font-weight:700}

/* ③ panel informasi + jumlah */
.stock-move-list .smv-bottom{display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:stretch}
.stock-move-list .smv-info{
  display:flex;align-items:center;flex-wrap:wrap;gap:5px 0;min-width:0;
  background:var(--grn-tint);border:1px solid var(--grn-bd);
  border-radius:10px;padding:6px 4px;
  font-size:.78rem;font-weight:600;color:var(--ink);
}
.stock-move-list .smv-seg{
  display:inline-flex;align-items:center;gap:8px;min-width:0;
  padding:2px 12px;line-height:1.45;text-align:left;
  border:0;border-left:1px solid var(--grn-bd);background:none;
  font:inherit;color:inherit;
}
.stock-move-list .smv-seg:first-child{border-left:0;padding-left:11px}
.stock-move-list .smv-seg svg{width:15px;height:15px;fill:var(--brand);flex:0 0 auto}
.stock-move-list .smv-seg strong{color:var(--head-ink);font-weight:700}
.stock-move-list button.smv-seg{cursor:pointer;border-radius:8px}
.stock-move-list button.smv-seg:hover,
.stock-move-list button.smv-seg:focus-visible{background:var(--grn-tint-2);text-decoration:underline}
/* Catatan panjang (mis. rincian racikan) dibatasi 2 baris supaya tinggi kartu
   tetap seragam; teks utuh tersedia sebagai tooltip (title). */
.stock-move-list .smv-seg-note > span{
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;
  overflow:hidden;overflow-wrap:anywhere;
}

/* kolom jumlah: angka besar + satuan, dipisah garis tegak dari panel info */
.stock-move-list .smv-qty-col{
  display:flex;flex-direction:column;align-items:flex-end;justify-content:center;gap:3px;
  min-width:84px;margin-left:12px;padding:0 4px 0 16px;
  border-left:1px solid var(--line-strong);text-align:right;
}
.stock-move-list .smv-qty{
  font-family:var(--mono);font-size:1.4rem;font-weight:800;line-height:1.06;
  white-space:nowrap;color:var(--red);
}
.stock-move-list .smv-qty.pos{color:var(--green)}
.stock-move-list .smv-unit{
  font-size:.74rem;font-weight:700;white-space:nowrap;color:var(--red);
}
.stock-move-list .smv-qty.pos + .smv-unit{color:var(--green)}

/* kaki (hanya bila baris boleh dikoreksi/dihapus) */
.stock-move-list .smv-actions{
  display:flex;align-items:center;gap:12px;flex-wrap:wrap;
  border-top:1px dashed var(--line);padding-top:10px;
}
.stock-move-list .smv-actions form{margin:0}
.stock-move-list .smv-actions .btn{min-height:32px}

@media (max-width:900px){
  .stock-move-list{gap:12px}
  .stock-move-list .smv-card{padding:12px 13px;gap:10px;border-radius:14px}
  .stock-move-list .smv-time{font-size:.8rem}
  .stock-move-list .smv-title{font-size:.82rem}
  /* Panel info: segmen DITUMPUK (bukan dibungkus) supaya garis pemisah tidak
     muncul menggantung di awal baris saat teksnya panjang. */
  .stock-move-list .smv-info{
    flex-direction:column;align-items:stretch;gap:7px;
    padding:9px 11px;font-size:.75rem;
  }
  .stock-move-list .smv-seg{
    width:100%;padding:0;border-left:0;align-items:flex-start;
  }
  .stock-move-list .smv-seg svg{width:14px;height:14px;margin-top:2px}
}

/* HP: panel info selebar kartu, jumlah pindah ke bawah (tetap rata kanan) agar
   teks rujukan/keterangan tidak terhimpit. */
@media (max-width:640px){
  .stock-move-list .smv-bottom{grid-template-columns:minmax(0,1fr)}
  .stock-move-list .smv-qty-col{
    flex-direction:row;align-items:baseline;justify-content:flex-end;gap:8px;
    min-width:0;margin:9px 0 0;padding:9px 2px 0;
    border-left:0;border-top:1px solid var(--line);
  }
  .stock-move-list .smv-qty{font-size:1.2rem}
  .stock-move-list .smv-unit{font-size:.72rem}
  .stock-move-list .smv-actions .btn{flex:1 1 auto;justify-content:center}
}

/* ══════════════════════════════════════════════════════════════════════════
   TAB "DATA STOK" — KERANGKA KOSONG (menu Stok & Batch)
   Tab ini sengaja belum berisi data (permintaan pemilik: disiapkan dulu, diisi
   pada pengembangan berikutnya). Tampil sebagai satu kartu terpusat dengan ikon
   dan satu kalimat status — tanpa filter, KPI, atau tombol apa pun supaya
   tidak ada kontrol yang terlihat bisa dipakai padahal belum berfungsi.
   ══════════════════════════════════════════════════════════════════════════ */
.lab-card.data-stock-empty{
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:10px;padding:46px 24px;text-align:center;
}
.data-stock-empty .dse-icon{
  display:inline-flex;align-items:center;justify-content:center;
  width:56px;height:56px;border-radius:16px;
  background:var(--grn-tint);border:1px solid var(--grn-bd);
}
.data-stock-empty .dse-icon svg{width:28px;height:28px;fill:var(--brand)}
.data-stock-empty .empty{padding:0;font-size:.85rem;line-height:1.65;max-width:46ch}
@media (max-width:640px){
  .lab-card.data-stock-empty{padding:34px 18px;gap:9px}
  .data-stock-empty .dse-icon{width:48px;height:48px;border-radius:14px}
  .data-stock-empty .dse-icon svg{width:24px;height:24px}
  .data-stock-empty .empty{font-size:.8rem}
}

/* Ikon kartu "Data Stok": di tema gelap `--brand` (#0E7C6B) terlalu redup di atas
   lingkaran hijau gelap (kontras ikon 2,75:1 — di bawah 3:1 untuk grafis).
   Tema gelap memakai `--brand-light` (#2DD4A7) → terukur 6,3:1. */
html[data-theme="dark"] .data-stock-empty .dse-icon svg{fill:var(--brand-light)}

/* ══════════════════════════════════════════════════════════════════════════
   PAGER KUSTOM (Mutasi Stok, Defecta) — "Menampilkan a–b dari n" + pilihan
   per halaman 10/50/100/200/semua.
   Berbeda dari `.pager` biasa (tombol 12/24/48/96): di sini ukuran halaman
   dipilih lewat SATU dropdown supaya kontrolnya ringkas walau di HP.
   ══════════════════════════════════════════════════════════════════════════ */
.pager.pager-custom{gap:10px 14px}
.pager-custom .pager-info{
  font-size:.8rem;color:var(--ink-2);font-weight:600;
  font-variant-numeric:tabular-nums;
}
.pager-custom .pager-info strong{color:var(--head-ink);font-weight:700}
.pager-per-form{margin:0}
.pager-per-pick{display:inline-flex;align-items:center;gap:8px;font-size:.8rem;color:var(--ink-2);font-weight:600}
.pager-per-pick select{
  min-height:34px;padding:4px 30px 4px 10px;font-size:.82rem;font-weight:700;
  width:auto;min-width:96px;
}
@media (max-width:640px){
  .pager.pager-custom{align-items:stretch;gap:10px}
  .pager-custom .pager-info{text-align:center}
  .pager-custom .pager-actions{justify-content:center}
  .pager-per-pick{justify-content:center;width:100%}
  .pager-per-pick select{min-height:40px;font-size:16px;flex:0 0 auto}
}

/* ══════════════════════════════════════════════════════════════════════════
   DEFECTA — daftar pesanan ulang (menu Pengadaan → Defecta)
   Rancangan mengikuti acuan pemilik:
     · SATU baris filter di atas daftar (cari · periode · satuan · status ·
       [Filter] · [muat ulang]) yang SELALU terlihat;
     · SATU kartu tabel dengan kepala BERTINGKAT (STOK REAL · Penjualan
       terakhir · Average penjualan) + footer "Menampilkan … / N per halaman".

   ⚠️ Tabel ini LEBAR (15 kolom). Permintaan pemilik: bila tidak muat, tabel
   BOLEH DIGESER KE SAMPING di dalam kartunya (scrollbar terlihat & bisa
   disentuh) — HALAMAN tidak ikut bergeser. Di ≤900px tabel tetap menjadi
   KARTU BERTINGKAT (aturan global, TIDAK diubah di sini).
   ⚠️ Tabel memakai `data-no-cols` (pemilih kolom dimatikan) dan
   `data-no-proportion` (penandaan kolom otomatis dimatikan) karena lebarnya
   ditetapkan sendiri lewat <colgroup>.
   ══════════════════════════════════════════════════════════════════════════ */

/* Tombol utama di kepala halaman = IKON KERANJANG hijau dengan LENCANA jumlah
   (permintaan pemilik; menggantikan tombol teks "+ Rencana Pembelian (defecta)").
   Ukuran & bentuknya sengaja sama dengan tombol tema/Info di topbar supaya
   sejajar; lencana menempel di pojok kanan-atas ikon. */
.defecta-cart-btn{
  position:relative;min-height:46px;height:46px;padding:0 14px;gap:8px;
  background:var(--primary-grad);border-color:transparent;color:#fff;
  box-shadow:var(--primary-shadow);border-radius:10px;
}
.defecta-cart-btn:hover{filter:brightness(1.08);background:var(--primary-grad);border-color:transparent}
.defecta-cart-btn svg{width:20px;height:20px;fill:currentColor}
.defecta-cart-btn .dcart-badge{
  display:none;position:absolute;top:-6px;right:-6px;min-width:20px;height:20px;padding:0 5px;
  border-radius:999px;background:#fff;color:var(--brand,#0b6a5c);
  font-size:.68rem;font-weight:800;line-height:20px;text-align:center;
  box-shadow:0 2px 6px -2px rgba(0,0,0,.5);border:1px solid rgba(0,0,0,.06);
  font-variant-numeric:tabular-nums;
}
.defecta-cart-btn.has-items .dcart-badge{display:block}
html[data-theme="dark"] .defecta-cart-btn .dcart-badge{background:#fff;color:#0b3b33}
@media (max-width:900px){
  /* Di HP tombol aksi halaman ikon saja (label teks tidak ada) → 42×42. */
  .defecta-cart-btn{width:42px;min-width:42px;padding:0;justify-content:center}
}

/* ─────────────────────────── 1. BARIS FILTER ─────────────────────────── */
.defecta-tools{padding:14px 16px}
form.defecta-filter{
  display:flex;flex-wrap:wrap;align-items:center;gap:12px;
  margin:0;padding:0;border:0;background:none;border-radius:0;width:100%;
}
form.defecta-filter .gs-field{flex:1 1 240px;min-width:150px}
form.defecta-filter input[type=search]{
  width:100%;min-height:46px;height:46px;font-size:.88rem;
  padding:0 14px 0 44px;border:1px solid var(--line-strong);
  border-radius:10px;background:var(--input-bg);color:var(--ink);
}
/* Rentang tanggal: SATU kotak bergaris berisi ikon kalender + 2 isian tanggal. */
form.defecta-filter .df-range{
  display:flex;align-items:center;gap:2px;flex:0 1 auto;
  height:46px;padding:0 10px;border:1px solid var(--line-strong);
  border-radius:10px;background:var(--input-bg);
}
form.defecta-filter .df-cal{width:17px;height:17px;fill:var(--ink-2);flex:0 0 auto;margin-right:6px}
form.defecta-filter .df-dash{color:var(--ink-2);font-weight:700;padding:0 3px}
/* ⚠️ Kelas `.defecta-filter` DITULIS DUA KALI dengan sengaja: aturan umum
   `.search input:not([type=checkbox]):not([type=radio]):not([type=search])`
   memakai tiga `:not()` (spesifisitas 0,4,1) sehingga `width:auto;min-width:130px`
   miliknya MENANG atas aturan biasa dan kedua isian tanggal membengkak 140px
   (baris filter jadi dua baris). Mengulang kelas menaikkan spesifisitas menjadi
   0,4,2 tanpa `!important`. */
.defecta-filter.defecta-filter .df-range input[type=date]{
  width:108px;min-width:0;height:34px;min-height:34px;padding:0 2px;
  border:0;background:transparent;box-shadow:none;border-radius:0;
  font-size:.82rem;font-weight:650;color:var(--ink);
}
form.defecta-filter .df-range input[type=date]::-webkit-calendar-picker-indicator{opacity:.5;cursor:pointer}
/* Combobox (select yang sudah ditingkatkan jadi `.cs-btn`) — kotak tersendiri. */
form.defecta-filter select{flex:0 1 152px}
form.defecta-filter .cs-btn{
  flex:0 1 152px;width:auto;min-width:128px;min-height:46px;height:46px;
  padding:0 32px 0 13px;border-radius:10px;border-color:var(--line-strong);
  background:var(--input-bg);font-size:.85rem;font-weight:600;
}
form.defecta-filter .btn-filter{min-height:46px;height:46px;padding:0 20px;gap:8px;font-size:.88rem;font-weight:750}
form.defecta-filter .btn-filter svg{width:17px;height:17px;fill:currentColor}
form.defecta-filter .btn-reset{
  width:46px;min-width:46px;height:46px;padding:0;border-radius:10px;
  display:inline-flex;align-items:center;justify-content:center;
  background:var(--panel-2);border:1px solid var(--line-strong);
}
form.defecta-filter .btn-reset svg{width:17px;height:17px;fill:var(--ink)}
form.defecta-filter .btn-reset:hover{border-color:var(--btn-border-hover);background:var(--btn-bg-hover)}

/* ─────────────────────────── 2. KARTU TABEL ──────────────────────────── */
.defecta-card{padding:0;overflow:hidden}
/* Wadah GULIR MENDATAR: satu-satunya yang boleh bergeser ke samping. */
.defecta-wrap{
  border:0;border-radius:0;max-width:100%;position:relative;
  overflow-x:auto;overflow-y:hidden;
  scrollbar-width:thin;scrollbar-color:var(--line-strong) transparent;
  overscroll-behavior-x:contain;-webkit-overflow-scrolling:touch;
}
.defecta-wrap:focus-visible{outline:2px solid var(--focus-border);outline-offset:-2px}
/* Isyarat "masih ada kolom di kanan" (dipasang assets/app.js saat masih bisa
   digeser). Bayangan dibuat INSET pada wadah gulir supaya tidak ikut bergeser
   bersama isi dan tidak menutupi footer pager. */
.defecta-wrap.has-hscroll{box-shadow:inset -22px 0 22px -20px var(--line-strong)}
.defecta-wrap::-webkit-scrollbar{height:11px}
.defecta-wrap::-webkit-scrollbar-track{background:var(--tint-2)}
.defecta-wrap::-webkit-scrollbar-thumb{background:var(--line-strong);border-radius:999px}
.defecta-wrap::-webkit-scrollbar-thumb:hover{background:var(--ink-3)}

/* `table-layout:fixed` WAJIB: tanpa itu lebar kolom mengikuti isi
   ("INV-261027-05 • 4 botol", "20/10/2026 18:53") sehingga tabel melar tak
   terkendali. Lebar pasti datang dari <colgroup> di halaman. */
table.data.defecta-table{
  font-size:.82rem;table-layout:fixed;min-width:1560px;width:100%;
  border-collapse:collapse;background:transparent;
}
/* Lebar kolom (kolom tanpa aturan = membagi sisa ruang → Produk).
   ⚠️ RONDE 2: "Tanggal" & "Tanggal / Invoice • Jumlah" DIGABUNG menjadi SATU
   kolom `Penjualan Terakhir` (c-sale); kolom baru `Status Stok` (c-stokstat)
   masuk tepat setelah "Stok System"; `c-time` menggantikan `c-date` pada
   kelompok STOK REAL (judulnya kini "Waktu"). */
table.data.defecta-table col.c-no{width:42px}
table.data.defecta-table col.c-qty{width:114px}
table.data.defecta-table col.c-time{width:138px}
table.data.defecta-table col.c-unit{width:72px}
table.data.defecta-table col.c-sale{width:204px}
table.data.defecta-table col.c-num{width:86px}
table.data.defecta-table col.c-perhari{width:82px}
table.data.defecta-table col.c-min{width:82px}
table.data.defecta-table col.c-sys{width:86px}
table.data.defecta-table col.c-stokstat{width:104px}
table.data.defecta-table col.c-order{width:92px}
table.data.defecta-table col.c-last{width:134px}
/* ⚠️ "Status" WAJIB cukup lebar untuk label TERPANJANG "Tidak Cocok".
   Terukur (font .74rem/750 + padding chip 10px): chip "Tidak Cocok" = 88px,
   + padding sel 2×10px = 108px. Lebar lama 92px membuat chip 96–102px meluber
   20px menimpa ikon keranjang di kolom Aksi (keluhan pemilik). */
table.data.defecta-table col.c-stat{width:108px}
table.data.defecta-table col.c-act{width:58px}

/* ── Kepala tabel bertingkat ── */
table.data.defecta-table thead th{
  /* Latar kepala memakai `--th-bg` (tint hijau merek) supaya nuansanya sama
     dengan acuan pemilik — bukan abu netral `--tint-2`. */
  background:var(--th-bg);color:var(--ink);
  font-size:.74rem;font-weight:700;text-transform:none;letter-spacing:0;
  text-align:center;white-space:normal;line-height:1.35;
  padding:13px 8px;border-bottom:1px solid var(--line-strong);vertical-align:middle;
}
table.data.defecta-table thead tr.defecta-group th{font-size:.78rem;font-weight:750;padding-bottom:7px}
table.data.defecta-table thead tr.defecta-sub th{
  font-size:.75rem;font-weight:650;padding-top:7px;padding-bottom:14px;
  border-bottom:1px solid var(--line-strong);
}
/* Garis pemisah ANTARKELOMPOK (hanya di kepala tabel, tidak memotong baris).
   `.grp`      = judul kelompok ber-colspan (STOK REAL, Average penjualan)
   `.th-split` = kolom tunggal pemisah kelompok — dipakai "Penjualan Terakhir"
                 dan untuk garis pembatas antara "Average penjualan" dan
                 "Stok Min." (permintaan pemilik: poin d).
   Sub-kepala: th ke-1 (Jumlah) & ke-4 (Per Bulan) memulai kelompoknya. */
table.data.defecta-table thead tr.defecta-group th.grp{border-left:1px solid var(--line-strong)}
table.data.defecta-table thead tr.defecta-group th.th-split{border-left:1px solid var(--line-strong)}
table.data.defecta-table thead tr.defecta-sub th:nth-child(1),
table.data.defecta-table thead tr.defecta-sub th:nth-child(4){border-left:1px solid var(--line-strong)}
table.data.defecta-table thead th.col-no{text-align:center}
table.data.defecta-table thead th.col-prod{text-align:left;padding-left:14px}

/* ── Baris data ── */
table.data.defecta-table tbody td{
  padding:14px 10px;font-size:.82rem;color:var(--ink);
  border-bottom:1px solid var(--row-border);vertical-align:middle;
}
table.data.defecta-table tbody tr:last-child td{border-bottom:0}
table.data.defecta-table tbody tr:hover td{background:var(--tint-2)}
table.data.defecta-table tbody tr:target td{background:var(--warn-bg)}
table.data.defecta-table tbody td.col-no{text-align:center;color:var(--ink-2);font-weight:650}
table.data.defecta-table tbody td.col-prod{text-align:left;padding-left:14px}
table.data.defecta-table tbody td.col-time,
table.data.defecta-table tbody td.col-num{white-space:nowrap}
table.data.defecta-table tbody td.col-num{text-align:right;font-variant-numeric:tabular-nums}
table.data.defecta-table tbody td.col-time{font-variant-numeric:tabular-nums}
/* (a) Kolom "Satuan" pada kelompok STOK REAL = RATA TENGAH (permintaan pemilik). */
table.data.defecta-table tbody td.col-unit{
  text-align:center;font-variant-numeric:tabular-nums;white-space:nowrap;
}
table.data.defecta-table tbody td.col-stokstat,
table.data.defecta-table tbody td.col-stat,
table.data.defecta-table tbody td.col-act{text-align:center}
table.data.defecta-table tbody td.col-qty{padding-left:9px;padding-right:9px}
table.data.defecta-table tbody td.col-order strong{font-weight:750}

/* (c) SATU kolom "Penjualan Terakhir": baris 1 tanggal + jam, baris 2
   nomor invoice • jumlah (lengkap dengan satuannya). */
.defecta-table .col-sale{vertical-align:middle}
.defecta-table .sale-date{font-weight:700;color:var(--ink);font-variant-numeric:tabular-nums;white-space:nowrap}
.defecta-table .sale-sub{
  display:flex;align-items:baseline;gap:6px;flex-wrap:wrap;margin-top:2px;
}
.defecta-table .sale-inv{font-size:.74rem;font-weight:700;color:var(--ink-2);white-space:nowrap}
.defecta-table .sale-qty{font-size:.74rem;font-weight:650;color:var(--ink-2);white-space:nowrap}

/* Teks di dalam sel. */
.defecta-table .def-code{font-size:.73rem;color:var(--ink-2);font-weight:600;line-height:1.25}
.defecta-table .def-name{font-size:.82rem;font-weight:700;color:var(--head-ink);line-height:1.4;white-space:normal;overflow-wrap:anywhere}
.defecta-table .def-t{color:var(--ink-2);font-weight:650}
.defecta-table .def-inv{font-weight:700;color:var(--ink);white-space:nowrap}
.defecta-table .def-qty{color:var(--ink-2);font-weight:650;white-space:nowrap}
.defecta-table .def-sup{font-weight:700;color:var(--ink);line-height:1.35;white-space:normal;overflow-wrap:anywhere}
.defecta-table .def-date{font-size:.75rem;color:var(--ink-2);font-variant-numeric:tabular-nums}
.defecta-table td .muted{font-size:.78rem}

/* ── Status (pill) — dipakai kolom "Status" DAN "Status Stok" ── */
table.data.defecta-table td.col-stat .pill,
table.data.defecta-table td.col-stokstat .pill{
  margin:0;padding:6px 10px;border-radius:8px;font-size:.74rem;font-weight:750;
  text-transform:capitalize;letter-spacing:0;line-height:1.25;
  /* Chip TIDAK boleh melebar melebihi selnya — dulu "Tidak Cocok" (102px)
     meluber 20px dan menimpa ikon keranjang di kolom Aksi (keluhan pemilik).
     Lebar kolom sudah dinaikkan; pembungkusan ini jaring pengaman bila kelak
     ada label status yang lebih panjang. */
  max-width:100%;white-space:normal;text-align:center;
}

/* ── Isian hitung fisik + tombol simpan ── */
.def-count{display:flex;align-items:center;gap:6px;margin:0;justify-content:flex-start;flex-wrap:nowrap}
.def-count-input{
  width:66px;min-height:38px;height:38px;padding:0 8px;text-align:left;
  font-size:.84rem;font-weight:700;font-variant-numeric:tabular-nums;
  border-radius:8px;border:1px solid var(--line-strong);
  background:var(--panel-2);color:var(--ink);
}
.def-count-input:focus{border-color:var(--focus-border);box-shadow:0 0 0 3px var(--focus-ring)}
.def-count-input.is-mismatch{border-color:var(--err-bd);background:var(--err-bg);color:var(--err-fg)}
.def-count-go{
  display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;
  width:30px;height:30px;padding:0;border:0;border-radius:7px;cursor:pointer;
  background:var(--primary-grad);color:#fff;box-shadow:var(--primary-shadow);
}
.def-count-go svg{width:16px;height:16px;fill:currentColor}
.def-count-go:hover{filter:brightness(1.08)}
/* (Tombol [✕] hapus hitung fisik SUDAH DIHAPUS atas permintaan pemilik —
   jumlah hanya diubah lewat kolom angka di atas. Aturan `.def-count-reset`
   ikut dibuang agar tidak ada sisa gaya untuk tombol yang tak pernah dirender.) */

/* ── Tombol aksi (keranjang / kartu stok) ── */
table.data.defecta-table td.col-act .act-row{justify-content:center;gap:0}
table.data.defecta-table td.col-act .btn.def-cart{
  width:42px;height:42px;min-width:42px;min-height:42px;padding:0;border-radius:10px;
  display:inline-flex;align-items:center;justify-content:center;
  background:var(--panel-2);border:1px solid var(--line-strong);color:var(--ink);
}
table.data.defecta-table td.col-act .btn.def-cart:hover{border-color:var(--focus-border);background:var(--btn-bg-hover)}
table.data.defecta-table td.col-act .btn.def-cart svg{width:19px;height:19px;min-width:19px;fill:currentColor}
/* Tombol keranjang per baris dalam <form> (pengaman double: barang yang sudah
   masuk keranjang ditandai TERISI — latar hijau + ikon centang). */
table.data.defecta-table td.col-act .def-cart-form{margin:0;display:flex;justify-content:center}
table.data.defecta-table td.col-act .btn.def-cart.is-in{
  background:var(--primary-grad);border-color:transparent;color:#fff;
}
table.data.defecta-table td.col-act .btn.def-cart.is-in svg{fill:currentColor}

/* ══════════════ KARTU KERANJANG DEFECTA (rancang ulang sesuai acuan pemilik) ══════════════
   Susunan (persis seperti gambar acuan):
     kepala   : judul besar "Keranjang Defecta" + keterangan jumlah barang + [✕ Tutup]
     isi      : satu kartu per barang → baris identitas (No · kode · nama · chip status),
                baris fakta (Stok · Min · Saran Pembelian · Harga) dengan garis pemisah,
                blok "Pembelian terakhir" (supplier · tanggal · chip nomor nota), [Hapus]
     ringkasan: pita hijau "Perkiraan nilai belanja" + nominal
     kaki     : [Kosongkan keranjang]  …  [+ Buat Rencana Pembelian] [Batal]
   Semua warna memakai token tema (bukan warna tetap) supaya tetap benar di tema
   gelap & terang. */
.dcart-sheet{width:min(1180px,100%)}
.dcart-head{align-items:center;padding:18px 22px;gap:14px;border-bottom:1px solid var(--line-strong)}
.dcart-head-text{min-width:0}
.dcart-head h2{font-size:1.28rem;font-weight:650;letter-spacing:-.01em;line-height:1.25;color:var(--head-ink)}
.dcart-sub{display:block;margin-top:5px;font-size:.88rem;font-weight:500;color:var(--ink-2)}
.dcart-close{
  display:inline-flex;align-items:center;justify-content:center;gap:8px;
  min-height:44px;padding:0 18px;border-radius:12px;
  border:1px solid var(--line-strong);background:var(--panel-2);color:var(--ink);
  font-size:.9rem;font-weight:600;
}
.dcart-close svg{width:16px;height:16px;min-width:16px;fill:currentColor}
.dcart-close:hover{background:var(--btn-bg-hover);border-color:var(--focus-border)}
.dcart-body{padding:20px 22px;gap:16px}

/* ── satu kartu per barang ── */
.dcart-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:14px}
.dcart-item{
  display:grid;grid-template-columns:minmax(0,1fr) 250px auto;
  align-items:center;gap:18px;
  padding:16px 18px;border:1px solid var(--line-strong);border-radius:14px;
  background:var(--panel-2);
}
.dcart-main{min-width:0;display:flex;flex-direction:column;gap:14px}
.dcart-title{display:flex;align-items:center;gap:12px;flex-wrap:wrap;min-width:0}
.dcart-no{
  flex:0 0 auto;width:28px;height:28px;border-radius:50%;
  background:var(--tint);border:1px solid var(--line-strong);color:var(--ink-2);
  font-size:.8rem;font-weight:650;font-variant-numeric:tabular-nums;
  display:inline-flex;align-items:center;justify-content:center;
}
.dcart-code{flex:0 0 auto;font-size:.84rem;font-weight:600;color:var(--ink-2);font-variant-numeric:tabular-nums}
.dcart-name{font-size:1rem;font-weight:650;color:var(--head-ink);line-height:1.3;overflow-wrap:anywhere}
.dcart-title .pill{margin:0}
.dcart-facts{display:flex;align-items:stretch;flex-wrap:wrap;min-width:0}
.dcart-fact{display:flex;flex-direction:column;gap:3px;min-width:0;padding:0 18px;border-left:1px solid var(--line-strong)}
.dcart-fact:first-child{padding-left:0;border-left:0}
.dcart-k{font-size:.75rem;font-weight:500;color:var(--ink-2);line-height:1.3}
.dcart-v{font-size:.92rem;font-weight:650;color:var(--ink);font-variant-numeric:tabular-nums;white-space:nowrap;line-height:1.35}

/* ── blok pembelian terakhir (dipisah garis tegak) ── */
.dcart-buy{
  display:flex;flex-direction:column;gap:3px;min-width:0;
  padding-left:18px;border-left:1px solid var(--line-strong);
}
.dcart-buy-sup{font-size:.9rem;font-weight:650;color:var(--ink);line-height:1.35;overflow-wrap:anywhere}
.dcart-buy-date{font-size:.83rem;font-weight:500;color:var(--ink-2);font-variant-numeric:tabular-nums}
.dcart-buy-none{font-size:.82rem;font-weight:500;color:var(--ink-3)}
.dcart-inv{
  display:inline-flex;align-items:center;gap:8px;max-width:100%;margin-top:8px;
  padding:8px 12px;border-radius:10px;align-self:flex-start;
  border:1px solid var(--ok-bd);background:var(--ok-bg);color:var(--ok-fg);
  font-size:.82rem;font-weight:600;text-decoration:none;
}
.dcart-inv svg{width:15px;height:15px;min-width:15px;fill:currentColor}
.dcart-inv .mono{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
a.dcart-inv:hover{filter:brightness(1.07)}
.dcart-inv.is-plain{cursor:default}

/* ── tombol hapus per barang ── */
.dcart-del{margin:0;align-self:center}
.dcart-del-btn{
  display:inline-flex;align-items:center;justify-content:center;gap:9px;
  min-height:46px;padding:0 20px;border-radius:12px;
  font-size:.9rem;font-weight:600;white-space:nowrap;
}
.dcart-del-btn svg{width:16px;height:16px;min-width:16px;fill:currentColor}

/* ── pita ringkasan nilai belanja ── */
.dcart-sum{
  display:flex;align-items:center;justify-content:space-between;gap:16px;
  margin:0;padding:16px 20px;border-radius:12px;
  border:1px solid var(--ok-bd);background:var(--ok-bg);
}
.dcart-sum span{font-size:.92rem;font-weight:500;color:var(--ink-2)}
.dcart-sum strong{font-size:1.38rem;font-weight:650;color:var(--ok-fg);font-variant-numeric:tabular-nums;white-space:nowrap}

/* ── keadaan kosong ── */
.dcart-empty{
  display:flex;flex-direction:column;align-items:center;gap:8px;
  padding:34px 20px;text-align:center;
  border:1px dashed var(--line-strong);border-radius:14px;background:var(--tint-3);
}
.dcart-empty svg{width:38px;height:38px;fill:var(--ink-3)}
.dcart-empty p{margin:0;font-size:.92rem;font-weight:600;color:var(--ink)}

/* ── kaki kartu ── */
.dcart-foot{justify-content:space-between;gap:12px;padding:16px 22px;border-top:1px solid var(--line-strong)}
.dcart-clear{margin:0}
.dcart-foot-actions{display:flex;align-items:center;gap:12px;margin-left:auto}
.dcart-ghost{
  display:inline-flex;align-items:center;justify-content:center;
  min-height:46px;padding:0 20px;border-radius:12px;
  border:1px solid var(--line-strong);background:transparent;color:var(--ink);
  font-size:.9rem;font-weight:600;
}
.dcart-ghost:hover{background:var(--btn-bg-hover)}
.dcart-primary{
  display:inline-flex;align-items:center;justify-content:center;gap:9px;
  min-height:46px;padding:0 22px;border-radius:12px;
  border-color:transparent;background:var(--brand-bg);color:#fff;
  font-size:.92rem;font-weight:650;box-shadow:var(--brand-shadow);
}
.dcart-primary svg{width:17px;height:17px;min-width:17px;fill:currentColor}
.dcart-primary:hover{filter:brightness(1.06)}
@media (min-width:901px) and (max-width:1100px){
  .dcart-item{grid-template-columns:minmax(0,1fr) 210px auto;gap:14px}
}
@media (max-width:900px){
  .dcart-item{grid-template-columns:minmax(0,1fr) auto;align-items:start}
  .dcart-buy{
    grid-column:1 / -1;padding:13px 0 0;border-left:0;
    border-top:1px solid var(--line-strong);
  }
  .dcart-del{align-self:center}
}
@media (max-width:640px){
  .dcart-head{padding:14px}
  .dcart-head h2{font-size:1.06rem}
  /* Subjudul panjang di layar sempit dibatasi 2 baris supaya kepala kartu
     tidak menjorok (target ≤ ~85px seperti kartu lain). */
  .dcart-sub{
    font-size:.8rem;line-height:1.35;margin-top:3px;
    display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
  }
  .dcart-body{padding:14px}
  .dcart-item{grid-template-columns:minmax(0,1fr);gap:14px;padding:14px}
  .dcart-title{gap:9px}
  .dcart-name{flex:1 1 100%;font-size:1rem}
  .dcart-facts{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px}
  .dcart-fact{padding:0 12px 0 0;border-left:0;border-right:1px solid var(--line-strong)}
  .dcart-fact:nth-child(2n){padding-right:0;border-right:0}
  .dcart-del{width:100%}
  .dcart-del-btn{width:100%}
  .dcart-sum{flex-direction:column;align-items:flex-start;gap:4px}
  .dcart-sum strong{font-size:1.28rem}
  .dcart-foot{flex-direction:column;align-items:stretch}
  .dcart-foot .btn{width:100%}
  .dcart-foot-actions{flex-direction:column;align-items:stretch;margin-left:0}
}

/* ─────────────────────────── 3. FOOTER PAGER ─────────────────────────── */
.defecta-foot{border-top:1px solid var(--line);background:var(--tint-3)}
.defecta-foot .pager{
  margin:0;padding:12px 16px;border:0;border-radius:0;background:none;
  align-items:center;gap:12px;
}
.defecta-foot .pager-info{font-size:.8rem;color:var(--ink-2)}
.defecta-foot .pager-info strong{color:var(--ink);font-weight:750}
.defecta-foot .pager-per-pick{gap:7px;font-size:.8rem;color:var(--ink-2);font-weight:600}
.defecta-foot .pager-per-word .cs-btn{
  width:auto;min-width:96px;min-height:38px;padding:0 30px 0 11px;
  font-size:.8rem;font-weight:650;border-radius:9px;
}
.defecta-foot .pager .btn-sm{
  min-width:36px;min-height:36px;padding:0 10px;border-radius:9px;
  display:inline-flex;align-items:center;justify-content:center;font-weight:700;
}
.defecta-foot .pager .btn-primary{color:#fff}

/* ───────────────────────── 4. RESPONSIF FILTER ───────────────────────── */
/* Rentang 901–1620px (mis. 1366/1440/1600): biarkan kolom pencarian mengambil
   SATU baris penuh, lalu kontrol filter tersusun rapi di baris kedua — lebih
   enak dibaca daripada pembungkusan acak. Di ≥1621px semuanya kembali satu baris
   (seperti acuan pemilik). */
@media (min-width:901px) and (max-width:1620px){
  form.defecta-filter .gs-field{flex:1 1 100%}
}
@media (max-width:900px){
  form.defecta-filter{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}
  form.defecta-filter .gs-field{grid-column:1 / -1}
  form.defecta-filter .df-range{grid-column:1 / -1;justify-content:flex-start;width:100%}
  form.defecta-filter select,
  form.defecta-filter .cs-btn{flex:1 1 auto;width:100%;min-width:0}
  form.defecta-filter .btn-filter{grid-column:1 / 2;width:100%}
  form.defecta-filter .btn-reset{grid-column:2 / 3;justify-self:end}
  /* Mode KARTU BERTINGKAT: tidak ada gulir mendatar di dalam kartu. */
  .defecta-card{overflow:visible}
  .defecta-wrap{overflow:visible}
  table.data.defecta-table tbody td{white-space:normal;text-align:left}
  table.data.defecta-table tbody td.col-stokstat,
  table.data.defecta-table tbody td.col-stat,
  table.data.defecta-table tbody td.col-act{text-align:left}
  table.data.defecta-table td.col-stokstat .pill{margin:0}
  table.data.defecta-table tbody td.col-prod{padding-left:0}
  table.data.defecta-table td.col-act .act-row{justify-content:flex-start}
  .def-count{flex-wrap:wrap}
  .def-count-input{width:100%;max-width:140px}
}
@media (max-width:640px){
  .defecta-tools{padding:12px}
  form.defecta-filter .df-range{padding:0 8px}
  .defecta-filter.defecta-filter .df-range input[type=date]{flex:1 1 0;width:auto;min-width:0;padding:0;font-size:16px;height:36px}
  form.defecta-filter input[type=search]{font-size:16px}
  form.defecta-filter .cs-btn{font-size:16px;min-height:46px}
  .defecta-foot .pager{flex-direction:column;align-items:stretch;gap:10px}
  .defecta-foot .pager-actions{justify-content:center}
}
@media (max-width:420px){
  form.defecta-filter{grid-template-columns:1fr}
  form.defecta-filter .btn-filter{grid-column:1 / -1}
  form.defecta-filter .btn-reset{grid-column:1 / -1;justify-self:stretch;width:100%}
}

/* ══════════════════════════════════════════════════════════════════════════
   DEFECTA — RONDE TERAKHIR (permintaan pemilik)
   1) Rata tengah untuk 7 kolom data tertentu.
   2) Status stok 3 kategori: Overstok (hijau) · Defecta (kuning) · Stokout (merah).
   3) Tombol keranjang per baris: dua ikon (tambah ⇄ terisi) tanpa memuat ulang.
   4) Baris CONTOH (semua kolom terisi) yang bisa dihapus.
   5) Toast kecil untuk hasil aksi keranjang (bukan pita pesan halaman).
   ══════════════════════════════════════════════════════════════════════════ */

/* ── 1) KOLOM RATA TENGAH ────────────────────────────────────────────────
   Kolom: Penjualan Terakhir · Per Bulan · Per Hari · Stok Min. · Stok System ·
   Saran Pembelian · Pembelian Terakhir.
   ⚠️ Aturan `.col-num` (rata kanan) punya spesifisitas sama, jadi selektor di
   sini digandakan (`.col-c.col-c`) agar PASTI menang tanpa `!important`. */
table.data.defecta-table thead th.col-c.col-c,
table.data.defecta-table tbody td.col-c.col-c{text-align:center}
/* Blok multi-baris di dalam sel ikut rata tengah (flex tidak terpengaruh
   text-align, jadi justify-content-nya diatur terpisah). */
table.data.defecta-table tbody td.col-c .sale-sub{justify-content:center}
table.data.defecta-table tbody td.col-c .sale-date,
table.data.defecta-table tbody td.col-c .sale-qty,
table.data.defecta-table tbody td.col-c .sale-inv{text-align:center}
table.data.defecta-table tbody td.col-c .def-sup{white-space:nowrap;overflow-wrap:normal}
/* "Stok System" & "Saran Pembelian" memang dua baris — jaga agar tetap rapat. */
table.data.defecta-table thead th.col-order{line-height:1.25}

/* ── 2) CHIP STATUS STOK (hijau · kuning · merah) ─────────────────────────
   Permintaan pemilik: Overstok = HIJAU · Defecta = KUNING · Stokout = MERAH.
   Warnanya memakai token khusus (`--stok-*`) supaya tetap benar di dua tema dan
   TIDAK mengubah warna chip kolom "Status" (Cocok / Tidak Cocok) di tabel yang sama.
   Nilai token: lihat blok `:root` / `html[data-theme="dark"]` di bawah. */
:root{
  --stok-over-bg:rgba(52,211,153,.18); --stok-over-fg:#A7F3D0; --stok-over-bd:rgba(52,211,153,.42);
  --stok-def-bg:rgba(250,204,21,.20);  --stok-def-fg:#FDE68A;  --stok-def-bd:rgba(250,204,21,.45);
  --stok-out-bg:rgba(248,113,113,.18); --stok-out-fg:#FECACA;  --stok-out-bd:rgba(248,113,113,.42);
}
html[data-theme="light"]{
  --stok-over-bg:#DCFCE7; --stok-over-fg:#14532D; --stok-over-bd:#86EFAC;
  --stok-def-bg:#FEF3C0;  --stok-def-fg:#6B4A00; --stok-def-bd:#EBCB5E;
  --stok-out-bg:#FEE2E2;  --stok-out-fg:#7F1D1D; --stok-out-bd:#FCA5A5;
}
table.data.defecta-table td.col-stokstat .pill.pill-ok{
  background:var(--stok-over-bg);color:var(--stok-over-fg);border:1px solid var(--stok-over-bd);
}
table.data.defecta-table td.col-stokstat .pill.pill-warn{
  background:var(--stok-def-bg);color:var(--stok-def-fg);border:1px solid var(--stok-def-bd);
}
table.data.defecta-table td.col-stokstat .pill.pill-err{
  background:var(--stok-out-bg);color:var(--stok-out-fg);border:1px solid var(--stok-out-bd);
}

/* ── 3) TOMBOL KERANJANG PER BARIS — dua ikon ────────────────────────────
   `assets/defecta.js` hanya menukar kelas `.is-in`; ikon yang tampil dipilih CSS
   supaya tidak perlu menyalin markup SVG di JavaScript. */
.def-cart-form .btn.def-cart .ico-in{display:none}
.def-cart-form .btn.def-cart.is-in .ico-add{display:none}
.def-cart-form .btn.def-cart.is-in .ico-in{display:block}
.def-cart-form .btn.def-cart.is-busy{opacity:.62;cursor:progress}
.def-cart-form .btn.def-sample-del{
  width:42px;height:42px;min-width:42px;min-height:42px;padding:0;border-radius:10px;
  display:inline-flex;align-items:center;justify-content:center;
  background:var(--err-bg);border:1px solid var(--err-bd);color:var(--err-fg);
}
.def-cart-form .btn.def-sample-del svg{width:19px;height:19px;min-width:19px;fill:currentColor}
.def-cart-form .btn.def-sample-del:hover{background:var(--err-bg-hover)}

/* ── 4) BARIS CONTOH ─────────────────────────────────────────────────────
   Ditandai jelas (chip CONTOH + garis putus-putus) supaya tidak pernah dikira
   data nyata. Aksi hitung fisik & keranjang diganti penanda/hapus contoh. */
table.data.defecta-table tbody tr.def-row-sample > td{
  background:var(--info-bg);
  border-bottom:1px dashed var(--info-bd);
}
html[data-theme="dark"] table.data.defecta-table tbody tr.def-row-sample > td{
  background:rgba(20,163,139,.10);
}
table.data.defecta-table tbody tr.def-row-sample .def-sample-chip{
  display:inline-block;margin-left:7px;padding:1px 7px;border-radius:999px;
  font-size:.62rem;font-weight:700;letter-spacing:.05em;
  background:var(--info-bg);color:var(--info-fg);border:1px solid var(--info-bd);
  vertical-align:middle;
}
/* Nilai "Stok Real" baris contoh (tanpa form) dibuat mirip kolom isian. */
.def-count-static{
  display:inline-flex;align-items:center;justify-content:flex-start;
  min-width:66px;min-height:38px;padding:0 9px;border-radius:8px;
  border:1px dashed var(--line-strong);background:var(--tint-2);color:var(--ink);
  font-size:.84rem;font-weight:650;font-variant-numeric:tabular-nums;
}
/* Tautan "Tampilkan baris contoh" pada footer tabel. */
.defecta-foot{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap}
.def-sample-restore{margin:0 0 0 auto;padding:12px 16px 12px 0}
.def-sample-link{
  padding:0;border:0;background:none;cursor:pointer;
  font:inherit;font-size:.78rem;font-weight:600;color:var(--ink-2);
  text-decoration:underline;text-underline-offset:3px;
}
.def-sample-link:hover{color:var(--ink)}

/* ── 5) TOAST hasil aksi keranjang (menggantikan pita pesan penuh halaman) ── */
.defecta-toast{
  position:fixed;left:50%;bottom:calc(22px + env(safe-area-inset-bottom,0px));
  transform:translate(-50%,14px);z-index:95;
  max-width:min(420px,calc(100vw - 32px));
  padding:11px 16px;border-radius:12px;
  background:var(--pop-bg);border:1px solid var(--line-strong);
  box-shadow:0 10px 26px -14px rgba(0,0,0,.7);
  font-size:.86rem;font-weight:600;color:var(--ink);text-align:center;
  opacity:0;pointer-events:none;transition:opacity .16s ease,transform .16s ease;
}
.defecta-toast.is-on{opacity:1;transform:translate(-50%,0)}
.defecta-toast[data-kind="ok"]{border-color:var(--ok-bd)}
.defecta-toast[data-kind="warn"]{border-color:var(--warn-bd)}
.defecta-toast[data-kind="err"]{border-color:var(--err-bd)}
@media (min-width:901px){
  /* Navigasi bawah hanya ada di HP; toast tetap aman di desktop. */
  .defecta-toast{bottom:24px}
}
@media (prefers-reduced-motion:reduce){
  .defecta-toast{transition:none}
}

/* ══════════════════════════════════════════════════════════════════════════
   KARTU "RENCANA PEMBELIAN BARU" — RANCANG ULANG SESUAI ACUAN PEMILIK
   ──────────────────────────────────────────────────────────────────────────
   Semua aturan di bawah DIBATASI ke `#sheet-rencana` supaya kartu lain
   (penerimaan, pembelian, kasir, …) tidak ikut berubah.
   Susunan: kepala (judul + Kembali/Tutup) → 3 kartu bagian bergaris
   (Nomor RP · Permintaan Barang · Detail Pembelian) → kaki (catatan + Simpan).
   Ukuran huruf & ketebalan mengikuti tema aplikasi (h3 650, isi 400–600,
   label kontrol .8rem/500) — bukan angka tebal berlebihan seperti versi lama.
   ══════════════════════════════════════════════════════════════════════════ */
:root{
  /* Permukaan kartu bagian + kepala tabel Detail Pembelian (tema gelap) */
  --plan-sec-bg:rgba(148,196,178,.055);
  --plan-sec-bd:rgba(150,214,197,.16);
  --plan-th-bg:rgba(45,212,167,.13);
  --plan-th-bd:rgba(45,212,167,.22);
  --plan-total-bg:rgba(45,212,167,.14);
  --plan-total-bd:rgba(45,212,167,.35);
  --plan-total-fg:#D8FFF2;
}
html[data-theme="light"]{
  --plan-sec-bg:#FFFFFF;
  --plan-sec-bd:#DEE7E4;
  --plan-th-bg:#E8F3EF;
  --plan-th-bd:#D5E7E0;
  --plan-total-bg:#E8F4F0;
  --plan-total-bd:#CBE4DB;
  --plan-total-fg:#0B5F52;
}

/* ── Kepala kartu: judul lebih tegas, tombol Kembali/Tutup bergaris ──────── */
#sheet-rencana .sheet-head{padding:18px 22px;border-bottom:1px solid var(--plan-sec-bd)}
#sheet-rencana .sheet-head h2{font-size:1.22rem;font-weight:650;letter-spacing:-.01em}
#sheet-rencana .sheet-head .row-actions{gap:10px}
#sheet-rencana .sheet-head .btn{
  min-height:44px;padding:0 18px;border-radius:12px;
  border:1px solid var(--line-strong);background:var(--panel-2);color:var(--ink);
  font-size:.9rem;font-weight:600;
}
#sheet-rencana .sheet-head .btn:hover{background:var(--btn-bg-hover);border-color:var(--focus-border)}
#sheet-rencana .sheet-head .btn svg{width:16px;height:16px;min-width:16px}

/* ── Isi: jarak antarbagian lega seperti acuan ───────────────────────────── */
#sheet-rencana .sheet-body{padding:20px 22px;gap:18px}

/* ── Kartu BAGIAN (tiga kotak bergaris) ─────────────────────────────────── */
#sheet-rencana .form-section.plan-sec{
  display:flex;flex-direction:column;gap:14px;
  padding:16px 18px;border:1px solid var(--plan-sec-bd);border-radius:14px;
  background:var(--plan-sec-bg);
}
/* Global `form-section + form-section` memberi garis atas → tidak dipakai lagi. */
#sheet-rencana .form-section.plan-sec + .form-section.plan-sec{
  margin-top:0;padding-top:16px;border-top:1px solid var(--plan-sec-bd);
}
#sheet-rencana .form-section-head{align-items:center;gap:10px}
#sheet-rencana .form-section-head h3{
  font-size:.95rem;font-weight:650;letter-spacing:0;color:var(--head-ink);
}
#sheet-rencana .form-section-head .muted{font-size:.76rem;font-weight:400;color:var(--ink-2)}

/* ── Bagian 1: 4 kolom sejajar, catatan selebar kartu ───────────────────── */
#sheet-rencana .plan-fields{grid-template-columns:repeat(4,minmax(0,1fr));gap:16px 18px}
#sheet-rencana .plan-fields .plan-span-all{grid-column:1 / -1}
#sheet-rencana .plan-fields .field > span{font-size:.82rem;font-weight:500;color:var(--ink-2)}
/* Kolom "Nomor rencana" = pratinjau kode (bukan isian) → kotak terisi, bukan
   garis putus-putus seperti input readonly biasa. */
#sheet-rencana .plan-fields input[readonly]{
  border-style:solid;background:var(--tint-2);color:var(--ink);
  font-weight:600;letter-spacing:.01em;
}
#sheet-rencana .plan-fields input[type=text],
#sheet-rencana .plan-fields input[type=date],
#sheet-rencana .plan-fields select{min-height:44px;border-radius:10px}

/* ── Bagian 2: keterangan "mandiri" seperti acuan ───────────────────────── */
#sheet-rencana #section-pb .form-hint{
  margin:0;font-size:.86rem;font-weight:400;color:var(--ink-2);line-height:1.5;
}
#sheet-rencana #section-pb .form-hint strong{font-weight:650;color:var(--ink)}

/* ── Bagian 3: TABEL Detail Pembelian ─────────────────────────────────────
   Kepala tabel = pita hijau muda, label huruf besar kecil (.72rem/600) —
   sama seperti acuan, tetapi ukuran & ketebalan mengikuti tema aplikasi. */
/* Tabel boleh bergulir DI DALAM kotaknya bila layar sempit (jangan sampai
   menggeser seluruh halaman); sudut membulat tetap terjaga. */
#sheet-rencana .plan-lines-wrap{overflow-x:auto;overflow-y:hidden;border:1px solid var(--plan-sec-bd);border-radius:12px}
table.data.plan-lines{
  min-width:0;width:100%;border-collapse:separate;border-spacing:0;table-layout:auto;
  background:transparent;
}
table.data.plan-lines thead th{
  background:var(--plan-th-bg);color:var(--ink);
  font-size:.72rem;font-weight:600;letter-spacing:.03em;text-transform:uppercase;
  padding:11px 10px;border:0;border-bottom:1px solid var(--plan-th-bd);
  white-space:nowrap;vertical-align:middle;
}
table.data.plan-lines thead th:first-child{border-radius:11px 0 0 0;padding-left:14px}
table.data.plan-lines thead th:last-child{border-radius:0 11px 0 0;padding-right:12px;text-align:center}
table.data.plan-lines tbody td{
  padding:12px 10px;border:0;border-bottom:1px solid var(--plan-th-bd);
  vertical-align:top;background:transparent;white-space:normal;
}
table.data.plan-lines tbody td:first-child{padding-left:14px}
table.data.plan-lines tbody tr:last-child td{border-bottom:0}
table.data.plan-lines tbody td.col-del{border-bottom:1px solid var(--plan-th-bd);text-align:center;vertical-align:middle}
table.data.plan-lines tbody tr:last-child td.col-del{border-bottom:0}
/* Lebar kolom: nama barang paling lebar, sisanya secukupnya. */
table.data.plan-lines col.c-item,table.data.plan-lines th:nth-child(1){min-width:230px}
table.data.plan-lines th:nth-child(2){width:96px}
table.data.plan-lines th:nth-child(3){width:170px}
table.data.plan-lines th:nth-child(4){width:96px}
table.data.plan-lines th:nth-child(5){width:190px}
table.data.plan-lines th:nth-child(6){width:170px}
table.data.plan-lines th:nth-child(7){width:160px}
table.data.plan-lines th:nth-child(8){width:56px}

/* Kontrol di dalam sel: kotak putih bergaris, sudut 10px, tinggi 42px. */
#sheet-rencana .plan-lines td input[type=text],
#sheet-rencana .plan-lines td input[type=number],
#sheet-rencana .plan-lines td select,
#sheet-rencana .plan-lines td .cs-btn{
  min-height:42px;border-radius:10px;font-size:.86rem;
}
#sheet-rencana .plan-lines td input[type=number]{text-align:center}
#sheet-rencana .plan-lines td .money-wrap{min-width:0}
/* Nama produk (dropdown pencarian) — teks boleh membungkus 2 baris. */
#sheet-rencana .plan-lines td:first-child .cs-btn{justify-content:flex-start;text-align:left;height:auto;min-height:42px;padding-top:8px;padding-bottom:8px;line-height:1.35}

/* Baris keterangan di bawah nama produk: chip asal baris + stok terkini. */
#sheet-rencana .plan-lines .row-src{margin-top:8px;gap:6px}
#sheet-rencana .plan-lines .src-chip{
  font-size:.7rem;font-weight:500;padding:3px 9px;border-radius:999px;
}
#sheet-rencana .plan-lines td:first-child small[data-row-stock]{
  display:block;margin-top:6px;font-size:.76rem;font-weight:400;color:var(--ink-2);
}
#sheet-rencana .plan-lines td:first-child small[data-row-stock].neg{color:var(--err-fg);font-weight:600}

/* Tombol hapus baris = ikon tempat sampah bulat (acuan). */
#sheet-rencana .plan-del{
  width:38px;height:38px;min-width:38px;padding:0;border-radius:10px;
  display:inline-flex;align-items:center;justify-content:center;
  background:var(--err-bg);border:1px solid var(--err-bd);color:var(--err-fg);
}
#sheet-rencana .plan-del svg{width:17px;height:17px;min-width:17px;fill:currentColor}
#sheet-rencana .plan-del:hover{background:var(--err-bg-hover)}

/* Saran harga (terakhir/termurah) kini berdiri sebagai kolom sendiri
   "Saran pembelian" dengan gaya KARTU (lihat blok terakhir berkas). */
#sheet-rencana .plan-lines .plan-sug{margin-top:0}

/* ── Kaki bagian Detail: [+ Tambah Baris] kiri · total kanan ────────────── */
#sheet-rencana .plan-lines-foot{
  margin-top:14px;padding-top:0;border-top:0;align-items:center;gap:12px;
}
#sheet-rencana .plan-add-line{
  display:inline-flex;align-items:center;gap:8px;
  min-height:44px;padding:0 16px;border-radius:10px;
  border:1px solid var(--plan-th-bd);background:transparent;color:var(--ink);
  font-size:.88rem;font-weight:600;
}
#sheet-rencana .plan-add-line svg{width:16px;height:16px;min-width:16px;fill:currentColor;color:var(--plan-total-fg)}
#sheet-rencana .plan-add-line:hover{background:var(--tint-2);border-color:var(--focus-border)}
#sheet-rencana .plan-total-chip{
  margin-left:auto;display:inline-flex;align-items:center;gap:8px;
  min-height:44px;padding:0 18px;border-radius:10px;
  background:var(--plan-total-bg);border:1px solid var(--plan-total-bd);
  font-size:.9rem;font-weight:400;color:var(--ink-2);white-space:nowrap;
}
#sheet-rencana .plan-total-chip strong{
  font-size:1.06rem;font-weight:650;color:var(--plan-total-fg);
  font-variant-numeric:tabular-nums;
}

/* ── Kaki kartu (catatan + Simpan/Batal) ────────────────────────────────── */
#sheet-rencana .sheet-foot{padding:16px 22px;border-top:1px solid var(--plan-sec-bd)}
#sheet-rencana .sheet-foot .foot-note{font-size:.84rem;font-weight:400;color:var(--ink-2)}
#sheet-rencana .sheet-foot .btn{
  min-height:46px;padding:0 22px;border-radius:12px;font-size:.92rem;font-weight:650;
}
#sheet-rencana .sheet-foot .btn-primary svg{width:17px;height:17px;min-width:17px}

/* ── Responsif: 4 kolom → 2 kolom → 1 kolom ─────────────────────────────── */
@media (max-width:1100px){
  #sheet-rencana .plan-fields{grid-template-columns:repeat(2,minmax(0,1fr))}
  #sheet-rencana .plan-fields .plan-span-all{grid-column:1 / -1}
}
/* 901–1200px: kolom tabel dibuat lentur supaya TIDAK perlu digeser ke samping
   (kedelapan kolom masih terbaca; teks panjang membungkus). */
@media (min-width:901px) and (max-width:1200px){
  table.data.plan-lines{table-layout:fixed}
  table.data.plan-lines th:nth-child(1){width:22%;min-width:0}
  table.data.plan-lines th:nth-child(2){width:8%;min-width:0}
  table.data.plan-lines th:nth-child(3){width:14%;min-width:0}
  table.data.plan-lines th:nth-child(4){width:8%;min-width:0}
  table.data.plan-lines th:nth-child(5){width:16%;min-width:0}
  table.data.plan-lines th:nth-child(6){width:14%;min-width:0}
  table.data.plan-lines th:nth-child(7){width:12%;min-width:0}
  table.data.plan-lines th:nth-child(8){width:44px;min-width:0}
  #sheet-rencana .plan-lines td input[type=text],
  #sheet-rencana .plan-lines td input[type=number],
  #sheet-rencana .plan-lines td select,
  #sheet-rencana .plan-lines td .cs-btn{min-width:0;width:100%;font-size:.8rem}
  #sheet-rencana .plan-lines thead th{padding:10px 7px;font-size:.68rem;letter-spacing:.02em;white-space:normal;line-height:1.25}
  #sheet-rencana .plan-lines tbody td{padding:10px 7px}
}
@media (max-width:900px){
  /* Di HP tabel tetap menjadi KARTU BERTINGKAT (aturan global), jadi gaya
     tabel di atas dinetralkan agar tidak mengganggu susunan kartu. */
  #sheet-rencana .plan-lines-wrap{border:0;border-radius:0}
  table.data.plan-lines thead th{border-radius:0}
  table.data.plan-lines tbody td{border-bottom:0}
  #sheet-rencana .plan-lines td:first-child small[data-row-stock]{margin-top:4px}
  #sheet-rencana .plan-add-line,
  #sheet-rencana .plan-total-chip{width:100%;justify-content:center}
  #sheet-rencana .plan-total-chip{margin-left:0}
}
@media (max-width:640px){
  #sheet-rencana .sheet-head{padding:14px}
  #sheet-rencana .sheet-head h2{font-size:1.04rem}
  #sheet-rencana .sheet-body{padding:14px;gap:14px}
  #sheet-rencana .form-section.plan-sec{padding:14px;border-radius:12px}
  #sheet-rencana .plan-fields{grid-template-columns:minmax(0,1fr)}
  #sheet-rencana .plan-lines-foot{flex-direction:column;align-items:stretch}
  #sheet-rencana .sheet-foot{flex-direction:column;align-items:stretch;padding:14px}
  #sheet-rencana .sheet-foot .btn{width:100%}
}

/* ══════════════════════════════════════════════════════════════════════════
   RONDE: KARTU "RENCANA PEMBELIAN BARU" — CATATAN RINGKAS, SEL OBAT/ALKES
   BARU, KOLOM "SARAN PEMBELIAN", DAN LEBAR TABEL DINAMIS
   ──────────────────────────────────────────────────────────────────────────
   Semua aturan di blok ini SENGAJA ditaruh paling akhir berkas supaya menang
   dari blok `#sheet-rencana` sebelumnya (spesifisitas sama, urutan menentukan).
   ══════════════════════════════════════════════════════════════════════════ */

/* ── (1) CATATAN PRE-FILL: satu kotak ringkas, bukan dua alert penuh ────── */
.plan-notes{
  display:flex;flex-direction:column;gap:8px;
  padding:10px 12px;border-radius:12px;border:1px solid var(--line-strong);
  background:var(--tint-3);
}
.plan-notes-head{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.plan-notes-head .pn-title{
  font-size:.78rem;font-weight:700;letter-spacing:.02em;text-transform:uppercase;
  color:var(--ink-2);
}
.plan-notes-head .pn-count{
  font-size:.72rem;font-weight:700;padding:2px 8px;border-radius:999px;
  background:var(--panel);border:1px solid var(--line-strong);color:var(--ink);
}
.pn-list{display:flex;flex-direction:column;gap:6px;margin:0;padding:0;list-style:none}
.pn-item{display:flex;align-items:flex-start;gap:8px;line-height:1.45}
.pn-dot{
  flex:0 0 auto;width:9px;height:9px;margin-top:5px;border-radius:999px;
  background:var(--warn-fg,#B45309);
}
.pn-item.is-ok .pn-dot{background:var(--ok-fg,#0E7C6B)}
.pn-body{display:flex;align-items:baseline;gap:6px;flex-wrap:wrap;min-width:0}
.pn-lbl{font-size:.8rem;font-weight:700;color:var(--ink)}
.pn-txt{font-size:.8rem;color:var(--ink-2)}
.pn-code{
  font-size:.72rem;font-weight:650;padding:1px 7px;border-radius:999px;
  background:var(--panel);border:1px solid var(--line-strong);
}
@media (max-width:640px){
  .pn-body{gap:4px}
  .pn-lbl,.pn-txt{font-size:.78rem}
}

/* ── (2) SEL OBAT/ALKES: dropdown master + nama produk baru + TOMBOL IKON ──
   Urutan visual memakai `order` supaya tombol ikon [Tambah Produk Baru]
   SELALU berdiri tepat di samping kolom "Nama produk baru" ketika kolom itu
   tampil (baris produk baru), dan tetap terlihat di baris biasa. */
.plan-item-main{display:flex;flex-wrap:wrap;align-items:center;gap:8px;min-width:0}
.plan-item-main > select,.plan-item-main > .cs-btn{order:1;flex:1 1 170px;min-width:0}
.plan-item-main > .pb-new-fields{order:2;flex:1 1 150px;min-width:0;margin:0}
.plan-item-main > .plan-newitem{order:3;flex:0 0 auto}
.pb-new-fields{display:none;gap:6px;align-items:center;margin-top:0}
.pb-new-fields.is-on{display:flex;flex-wrap:wrap}
.pb-new-fields input[type=text]{flex:1 1 auto;min-width:0;width:100%}
/* Tombol ikon (dulu tombol teks "Formulir lengkap…") — ukuran & warna seragam
   dengan tombol ikon lain di aplikasi. */
.plan-newitem{
  width:42px;min-width:42px;height:42px;padding:0;display:inline-grid;place-items:center;
  border-radius:10px;border:1px solid var(--line-strong);
  background:var(--panel-2);color:var(--brand,#0E7C6B);
  position:relative;
}
.plan-newitem:hover{background:var(--tint-2);border-color:var(--focus-border)}
.plan-newitem svg{width:18px;height:18px;min-width:18px;fill:currentColor}
html[data-theme="dark"] .plan-newitem{color:#2DD4A7}

/* ── (3) KOLOM "SARAN PEMBELIAN": kartu supplier terakhir / nominal / tanggal ── */
#sheet-rencana .plan-lines td.col-sug{min-width:186px}
.plan-sug{display:flex;flex-direction:column;gap:6px;margin:0}
.sug-btn{
  display:flex;flex-direction:column;gap:1px;align-items:stretch;
  text-align:left;font:inherit;color:var(--ink);cursor:pointer;
  padding:8px 10px;border-radius:12px;
  border:1px solid var(--line-strong);
  background:var(--panel-2);
  box-shadow:0 2px 6px -3px rgba(8,26,22,.28),0 6px 16px -12px rgba(8,26,22,.5);
}
html:not([data-theme]) .sug-btn,
html[data-theme="light"] .sug-btn{
  background:#FFFFFF;border-color:#DCE7E3;
  box-shadow:0 1px 2px rgba(12,32,26,.06),0 6px 14px -10px rgba(12,32,26,.35);
}
.sug-btn:hover,.sug-btn:focus-visible{
  border-color:var(--brand,#0E7C6B);
  background:var(--tint-2);
}
html:not([data-theme]) .sug-btn:hover,
html[data-theme="light"] .sug-btn:hover{background:#F4FAF7}
.sug-btn.is-best{border-color:rgba(34,160,110,.55)}
.sug-btn .sug-k{
  font-size:.62rem;font-weight:700;letter-spacing:.05em;text-transform:uppercase;
  color:var(--ink-3);
}
.sug-btn .sug-m{
  font-size:.78rem;font-weight:650;color:var(--ink);line-height:1.3;
  overflow-wrap:anywhere;
}
.sug-btn .sug-v{
  font-size:.92rem;font-weight:750;color:var(--ink-strong);
  font-variant-numeric:tabular-nums;line-height:1.3;
}
.sug-btn .sug-v em{font-style:normal;font-size:.72rem;font-weight:600;color:var(--ink-2)}
.sug-btn .sug-d{
  font-size:.72rem;font-weight:600;color:var(--ink-2);font-variant-numeric:tabular-nums;
}
.sug-btn.is-best .sug-k{color:var(--ok-fg,#0E7C6B)}
/* Tema gelap: latar kartu saran dibuat PEKAT (solid) supaya bayangan & garis
   tepinya terbaca jelas di atas sel tabel yang gelap. */
html[data-theme="dark"] .sug-btn{
  background:#131E2E;border-color:rgba(150,214,197,.24);
  box-shadow:0 2px 6px -3px rgba(0,0,0,.45),0 8px 18px -12px rgba(0,0,0,.75);
}
.sug-empty{
  display:block;padding:8px 10px;border-radius:12px;
  border:1px dashed var(--line-strong);background:transparent;
  font-size:.74rem;font-weight:600;color:var(--ink-2);line-height:1.35;
}
/* ⚠️ Penegasan spesifisitas: di dalam tabel Rencana Pembelian ada aturan lama
   `#sheet-rencana .plan-lines .sug-btn{padding:4px 8px;border-radius:8px}`
   (1,2,0) yang MENANG atas `.sug-btn` (0,1,0) — tanpa aturan ini kartu saran
   kembali ringkas & tidak berbentuk kartu. */
#sheet-rencana .plan-lines td.col-sug .sug-btn{padding:8px 10px;border-radius:12px}
#sheet-rencana .plan-lines td.col-sug .sug-k{font-size:.62rem;font-weight:700}
#sheet-rencana .plan-lines td.col-sug .sug-m{font-size:.78rem;font-weight:650}
#sheet-rencana .plan-lines td.col-sug .sug-v{font-size:.92rem;font-weight:750}
#sheet-rencana .plan-lines td.col-sug .sug-d{font-size:.72rem}

/* ── (4) LEBAR TABEL DINAMIS & KARTU MELEBAR ─────────────────────────────
   Kolom teks (obat/alkes) mengambil sisa ruang, kolom angka/aksi hanya
   selebar isinya; tabel boleh bergulir DI DALAM kotaknya pada layar sempit
   (tidak pernah menggeser halaman). */
#sheet-rencana .plan-lines-wrap{width:100%;max-width:100%}
/* ⚠️ `table-layout:auto` + `min-width` per kolom membuat total lebar melebihi
   wadah → tabel bergulir ke samping walau layar masih lebar. Karena itu lebar
   kolom dipatok PERSENTASE murni dengan `table-layout:fixed` (pola yang sama
   dipakai tabel e-Resep) sehingga tabel SELALU muat dan kolom obat/alkes
   otomatis melebar mengikuti lebar kartu. */
table.data.plan-lines{width:100%;max-width:100%;table-layout:fixed}
table.data.plan-lines th:nth-child(1){width:20%}
table.data.plan-lines th:nth-child(2){width:7.5%}
table.data.plan-lines th:nth-child(3){width:11%}
table.data.plan-lines th:nth-child(4){width:7.5%}
table.data.plan-lines th:nth-child(5){width:12.5%}
table.data.plan-lines th:nth-child(6){width:11%}
table.data.plan-lines th:nth-child(7){width:10.5%}
table.data.plan-lines th:nth-child(8){width:15%}
table.data.plan-lines th:nth-child(9){width:5%}
#sheet-rencana .plan-lines td.col-del{padding-left:4px;padding-right:8px}
#sheet-rencana .plan-lines td.col-sug{padding-left:8px;padding-right:10px}
table.data.plan-lines tbody td{overflow-wrap:anywhere}
/* Di layar lebar kartu ikut melebar (auto-expanding) sampai batas nyaman. */
@media (min-width:1000px){
  #sheet-rencana .sheet-card.wide{width:min(1400px,100%)}
}
/* ≤1180px (masih desktop/tablet): kolom "Keterangan" ditiadakan dari baris dan
   dipindah ke baris kecil di bawah sel Obat/Alkes? — TIDAK. Supaya tetap satu
   baris & tidak terhimpit, tabel dipersempit dengan mengecilkan kolom saran. */
@media (max-width:1180px) and (min-width:901px){
  table.data.plan-lines th:nth-child(1){width:19%}
  table.data.plan-lines th:nth-child(8){width:16%}
  table.data.plan-lines th:nth-child(7){width:9.5%}
}

/* ══════════════════════════════════════════════════════════════════════════
   RICH TOOLTIP BERBENTUK KARTU (permintaan pemilik — GLOBAL)
   ──────────────────────────────────────────────────────────────────────────
   Menggantikan balon teks kecil/hitam DAN tooltip pseudo-element lokal
   (`.act-tip`, `.apx-queue-save::after`, `.apx-rx-attach::after`,
   `.apx-drawer::after`, `.apx-pending::after`). Satu elemen `.rich-tip`
   dibuat `assets/app.js` dan dipakai SEMUA elemen ber-`data-tip` / `title`.
   ══════════════════════════════════════════════════════════════════════════ */
.rich-tip{
  position:fixed;top:0;left:0;z-index:260;pointer-events:none;
  display:flex;flex-direction:column;gap:2px;
  max-width:min(280px,86vw);padding:10px 13px;
  border-radius:12px;border:1px solid var(--line-strong);
  background:var(--panel-2);color:var(--ink-strong);
  font-size:.78rem;font-weight:650;line-height:1.35;letter-spacing:.01em;
  box-shadow:0 2px 4px rgba(6,24,20,.10),0 12px 28px -12px rgba(6,24,20,.55);
  opacity:0;transform:translateY(3px);
  transition:opacity .13s ease,transform .13s ease;
}
html:not([data-theme]) .rich-tip,
html[data-theme="light"] .rich-tip{
  background:#FFFFFF;border-color:#D7E4E0;color:#0C1630;
  box-shadow:0 2px 5px rgba(10,36,30,.10),0 14px 30px -14px rgba(10,36,30,.45);
}
html[data-theme="dark"] .rich-tip{
  background:#12312B;border-color:rgba(150,214,197,.30);color:#EAF7F2;
  box-shadow:0 2px 5px rgba(0,0,0,.35),0 14px 30px -12px rgba(0,0,0,.7);
}
.rich-tip.is-on{opacity:1;transform:translateY(0)}
.rich-tip .rt-title{display:block}
.rich-tip .rt-sub{display:block;font-size:.72rem;font-weight:500;color:var(--ink-2)}
html:not([data-theme]) .rich-tip .rt-sub,
html[data-theme="light"] .rich-tip .rt-sub{color:#4B5F6B}
html[data-theme="dark"] .rich-tip .rt-sub{color:#AFCEBF}
@media (prefers-reduced-motion: reduce){.rich-tip{transition:none}}

/* ⚠️ Tooltip PSEUDO-ELEMENT lokal DIMATIKAN: semuanya sekarang memakai
   `.rich-tip` supaya tidak muncul dua balon sekaligus. */
.act-tip{display:none!important}
.apx-foot .apx-queue-save::after,.apx-foot .apx-queue-save::before,
.apx-rx-attach::after,.apx-rx-attach::before,
.apx-foot .apx-drawer::after,
.apx-foot .apx-pending::after,.apx-foot .apx-pending::before{content:none!important}

/* ══════════════════════════════════════════════════════════════════════════
   RONDE: DETAIL PEMBELIAN — DUA MODE SEL OBAT/ALKES, KOLOM AUTO-FIT + RESIZE
   ──────────────────────────────────────────────────────────────────────────
   Semua aturan di blok ini SENGAJA di paling akhir berkas supaya menang dari
   blok `#sheet-rencana` sebelumnya (spesifisitas sama → urutan menentukan).
   ══════════════════════════════════════════════════════════════════════════ */

/* ── (1) SEL OBAT/ALKES: dua mode (item ⇄ produk baru) ──────────────────── */
/* ⚠️ `align-items:stretch` WAJIB. Aturan lama (saat sel ini masih satu BARIS
   flex) memakai `align-items:center`; pada flex-kolom, `center` membuat anak
   menyusut ke lebar KONTEN-nya — combobox dengan NAMA PRODUK PANJANG lalu
   melebar keluar sel dan MENUTUPI kolom "Jumlah" (keluhan pemilik, foto
   "contoh yang salah"). Dengan `stretch` anak selalu mengikuti lebar sel dan
   teksnya memotong rapi (elipsis) di dalam kolom Obat/Alkes. */
.plan-item-main{
  display:flex;flex-direction:column;align-items:stretch;gap:6px;
  min-width:0;max-width:100%;
}
.plan-pick{min-width:0;max-width:100%}
/* Combobox/select WAJIB tidak pernah melebihi kotaknya, berapa pun panjang
   nama produknya. */
.plan-pick > select,.plan-pick > .cs-btn{width:100%;max-width:100%;min-width:0}
.plan-newbox{display:flex;align-items:center;gap:6px;min-width:0;max-width:100%}
.plan-newbox > input[type=text]{flex:1 1 auto;min-width:0;max-width:100%}
/* Mode `item` (produk persediaan): dropdown tampil, kolom nama + tombol ikon
   + tautan balik disembunyikan. */
.plan-item-main[data-mode="item"] .plan-newbox,
.plan-item-main[data-mode="item"] .plan-mode-back{display:none}
/* Mode `new` (belum ada di persediaan): HANYA kolom nama + tombol ikon. */
.plan-item-main[data-mode="new"] .plan-pick{display:none}
/* Tombol ikon [Tambah Produk Baru] — ukuran & warna seragam tombol ikon lain. */
.plan-newitem{
  flex:0 0 auto;width:42px;min-width:42px;height:42px;padding:0;
  display:inline-grid;place-items:center;position:relative;
  border-radius:10px;border:1px solid var(--line-strong);
  background:var(--panel-2);color:var(--brand,#0E7C6B);
}
html[data-theme="dark"] .plan-newitem{color:#2DD4A7}
.plan-newitem:hover{background:var(--tint-2);border-color:var(--focus-border)}
.plan-newitem svg{width:18px;height:18px;min-width:18px;fill:currentColor}
/* Jalan keluar dari mode produk baru (baris dibuat tidak sengaja). */
/* Tautan balik "Pilih dari persediaan" (jalan keluar dari mode produk baru).
   Dibuat sebagai kontrol kecil yang rapi — bukan teks bergaris bawah yang
   tampak seperti sisa/artefak di dalam sel (keluhan pada foto "contoh salah"). */
.plan-mode-back{
  align-self:flex-start;margin-top:-2px;padding:3px 9px;
  border:1px solid var(--line-strong);border-radius:999px;background:var(--tint-3);
  font-size:.71rem;font-weight:600;color:var(--ink-2);
  text-decoration:none;cursor:pointer;line-height:1.3;white-space:nowrap;
  max-width:100%;overflow:hidden;text-overflow:ellipsis;
}
.plan-mode-back:hover{border-color:var(--focus-border);background:var(--tint-2);color:var(--brand,#0E7C6B)}
.plan-mode-back:hover{color:var(--brand,#0E7C6B)}
html[data-theme="dark"] .plan-mode-back:hover{color:#2DD4A7}

/* ── (2) KOLOM: lebar dari JS (`colgroup` px) + pegangan drag di header ─── */
#sheet-rencana .plan-lines.plan-fitted{table-layout:fixed;table-layout:fixed}
/* Saat auto-fit aktif, lebar kolom persentase bawaan tidak dipakai lagi. */
#sheet-rencana .plan-lines.plan-fitted th{width:auto!important;min-width:0!important}
#sheet-rencana .plan-lines thead th{position:relative;white-space:normal;overflow-wrap:anywhere}
/* Kontrol WAJIB mengikuti lebar sel (tidak ada yang meluber keluar kolom). */
#sheet-rencana .plan-lines td > input[type=text],
#sheet-rencana .plan-lines td > input[type=number],
#sheet-rencana .plan-lines td select,
#sheet-rencana .plan-lines td .cs-btn,
#sheet-rencana .plan-lines td .money-wrap{width:100%;min-width:0;max-width:100%}
#sheet-rencana .plan-lines td{overflow-wrap:anywhere}
/* Pegangan resize: garis tipis di batas kanan header. */
#sheet-rencana .plan-lines .col-resize{
  position:absolute;top:0;right:-3px;width:9px;height:100%;
  display:block;cursor:col-resize;z-index:3;touch-action:none;
}
#sheet-rencana .plan-lines .col-resize::after{
  content:'';position:absolute;left:4px;top:18%;bottom:18%;width:1px;
  background:var(--line-strong);
}
#sheet-rencana .plan-lines .col-resize:hover::after,
#sheet-rencana .plan-lines .col-resize:active::after{
  top:8%;bottom:8%;width:2px;left:3px;background:var(--brand,#0E7C6B);
}
html[data-theme="dark"] #sheet-rencana .plan-lines .col-resize:hover::after,
html[data-theme="dark"] #sheet-rencana .plan-lines .col-resize:active::after{background:#2DD4A7}
/* Gulir mendatar HANYA saat tabel memang lebih lebar dari kartu. */
#sheet-rencana .plan-lines-wrap{overflow-x:auto;overflow-y:hidden}
#sheet-rencana .plan-lines-wrap.is-scrollable{
  scrollbar-width:thin;
  background-image:linear-gradient(to right,rgba(14,124,107,.06),transparent 24px,transparent calc(100% - 24px),rgba(14,124,107,.06));
}
/* Di HP/tablet (tabel = kartu bertingkat) pegangan resize tidak berguna. */
@media (max-width:900px){
  #sheet-rencana .plan-lines .col-resize{display:none}
  #sheet-rencana .plan-lines td > input[type=text],
  #sheet-rencana .plan-lines td > input[type=number],
  #sheet-rencana .plan-lines td select,
  #sheet-rencana .plan-lines td .cs-btn{max-width:none}
}
/* Tombol "Baris Produk Baru" di kaki tabel = gaya sekunder yang sama. */
#sheet-rencana .plan-add-new{
  background:var(--tint-2);border-color:var(--line-strong);color:var(--ink);
}
#sheet-rencana .plan-add-new svg{width:15px;height:15px;fill:currentColor}

/* ── (3) HP: sel Obat/Alkes & Saran pembelian menjadi BLOK PENUH ──────────
   `app.js` memakai grid 2 kolom (label 100px + nilai) untuk tabel bertingkat.
   Sel Obat/Alkes berisi beberapa kontrol bertumpuk (dropdown / kolom nama +
   tombol ikon) sehingga kolom nilai menjadi terlalu sempit dan tombolnya
   melewati wadah → wadah tabel ikut bergulir di layar 320px. Kedua sel ini
   dibuat BLOK penuh (label di ATAS isi) supaya tidak ada yang terpotong. */
@media (max-width:900px){
  #sheet-rencana .plan-lines td.col-item,
  #sheet-rencana .plan-lines td.col-sug{display:block;width:auto}
  #sheet-rencana .plan-lines td.col-item::before,
  #sheet-rencana .plan-lines td.col-sug::before{
    display:block;margin-bottom:5px;padding-top:0;
  }
  #sheet-rencana .plan-lines td.col-item > *,
  #sheet-rencana .plan-lines td.col-sug > *{max-width:100%}
}

/* ══════════════════════════════════════════════════════════════════════════
   RONDE: KAKI TABEL DETAIL PEMBELIAN → DUA TOMBOL IKON BER-TOOLTIP
   ──────────────────────────────────────────────────────────────────────────
   [+ Tambah Baris] & [+ Baris Produk Baru] kini TOMBOL IKON (permintaan
   pemilik) dengan tooltip kartu (`.rich-tip`) berisi nama tombolnya.
   Label teks tetap ada di `<span class="lbl">` (pembaca layar + tanpa CSS).
   ══════════════════════════════════════════════════════════════════════════ */
#sheet-rencana .plan-add-actions{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
#sheet-rencana .plan-icon-btn{
  position:relative;width:44px;min-width:44px;height:44px;padding:0;
  display:inline-grid;place-items:center;border-radius:10px;
  border:1px solid var(--plan-th-bd);background:transparent;color:var(--ink);
}
#sheet-rencana .plan-icon-btn svg{width:18px;height:18px;min-width:18px;fill:currentColor}
#sheet-rencana .plan-add-line.plan-icon-btn svg{color:var(--plan-total-fg)}
#sheet-rencana .plan-icon-btn:hover{background:var(--tint-2);border-color:var(--focus-border)}
#sheet-rencana .plan-icon-btn:focus-visible{outline:2px solid var(--focus-border);outline-offset:2px}
#sheet-rencana .plan-add-new.plan-icon-btn{background:var(--tint-2);border-color:var(--line-strong)}
/* Label hanya untuk pembaca layar (tooltip kartu yang tampil untuk pengguna). */
#sheet-rencana .plan-icon-btn > .lbl{
  position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip-path:inset(50%);white-space:nowrap;border:0;
}
/* Tanpa JavaScript tooltip kartu tidak muncul → tampilkan label teks agar
   tombolnya tetap bisa dipahami. */
html.no-js #sheet-rencana .plan-icon-btn > .lbl{
  position:static;width:auto;height:auto;margin:0 0 0 8px;clip-path:none;
}
@media (max-width:640px){
  #sheet-rencana .plan-icon-btn{width:46px;min-width:46px;height:46px}
}

/* ══════════════════════════════════════════════════════════════════════════
   PENGAMAN KELUAR KARTU ("isian belum disimpan") — dipakai assets/klinik.js
   ──────────────────────────────────────────────────────────────────────────
   Konfirmasi 3 pilihan: [Kembali] · [Hapus] · [Simpan sbg Draft].
   z-index 140 → di ATAS kartu mengambang (70) & bar navigasi HP (30), di bawah
   pop-up kamera (120)… justru harus di atas semuanya kecuali pop-up kamera:
   dipilih 140 agar tetap terlihat walau kartu induk terbuka.
   ══════════════════════════════════════════════════════════════════════════ */
.guard-confirm{
  position:fixed;inset:0;z-index:140;display:grid;place-items:center;padding:16px;
  background:rgba(6,14,26,.62);
}
html[data-theme="light"] .guard-confirm,
html:not([data-theme]) .guard-confirm{background:rgba(15,23,42,.42)}
body.guard-locked{overflow:hidden}
.guard-card{
  width:min(480px,100%);border-radius:16px;border:1px solid var(--line-strong);
  background:var(--pop-bg,var(--panel));box-shadow:0 24px 60px -24px rgba(4,12,26,.65);
  overflow:hidden;
}
.guard-head{padding:16px 18px 0}
.guard-head h3{margin:0;font-size:1rem;font-weight:700;color:var(--head-ink)}
.guard-body{margin:0;padding:10px 18px 18px;font-size:.88rem;line-height:1.55;color:var(--ink)}
.guard-body strong{color:var(--head-ink)}
.guard-foot{
  display:flex;gap:10px;justify-content:flex-end;flex-wrap:wrap;
  padding:0 18px 16px;
}
.guard-foot .btn{min-height:42px;padding-inline:16px;font-size:.84rem;border-radius:10px}
@media (max-width:520px){
  .guard-foot{flex-direction:column-reverse}
  .guard-foot .btn{width:100%}
}

/* ══════════════════════════════════════════════════════════════════════════
   RONDE: BARIS TOTAL DAFTAR NOTA · TABEL "BARANG YANG DIPESAN" · CASHBACK
   ══════════════════════════════════════════════════════════════════════════ */

/* ── (1) BARIS TOTAL pada tabel Daftar Nota Pembelian (tampilan Tabel) ───
   Satu baris rapi: label + jumlah nota di kiri, nominal tebal di kolom Total,
   keterangan lunas/belum lunas di kanan. Tidak ada teks yang membungkus. */
table.data tfoot tr.list-total > td{
  background:var(--plan-total-bg,var(--foot-bg));
  border-top:2px solid var(--plan-total-bd,var(--line-strong));
  padding:13px 12px;vertical-align:middle;white-space:nowrap;
}
table.data tfoot tr.list-total .lt-label{display:flex;align-items:baseline;gap:10px;flex-wrap:nowrap}
table.data tfoot tr.list-total .lt-title{
  font-family:inherit;font-size:.78rem;font-weight:800;letter-spacing:.08em;
  text-transform:uppercase;color:var(--ink-2);
}
table.data tfoot tr.list-total .lt-meta{
  font-family:inherit;font-size:.74rem;font-weight:500;color:var(--ink-3);
  overflow:hidden;text-overflow:ellipsis;
}
table.data tfoot tr.list-total .lt-value{
  font-family:var(--mono);font-size:1.02rem;font-weight:800;
  color:var(--plan-total-fg,var(--ink-strong));font-variant-numeric:tabular-nums;
}
table.data tfoot tr.list-total .lt-side{text-align:right;font-family:inherit;font-size:.74rem;font-weight:600}
table.data tfoot tr.list-total .lt-unpaid{color:var(--warn-fg);background:var(--warn-bg);
  border:1px solid var(--warn-bd);border-radius:999px;padding:3px 10px;display:inline-block}
table.data tfoot tr.list-total .lt-paid{color:var(--ok-fg);background:var(--ok-bg);
  border:1px solid var(--ok-bd);border-radius:999px;padding:3px 10px;display:inline-block}

/* ── (2) TABEL "BARANG YANG DIPESAN" pada kartu Ubah Draft / Koreksi Nota ─ */
table.data.nota-lines{min-width:0}
table.data.nota-lines thead th{
  font-size:.7rem;font-weight:700;letter-spacing:.04em;text-transform:uppercase;
  white-space:nowrap;
}
table.data.nota-lines th.nl-no,table.data.nota-lines td.nl-no{width:44px;text-align:center}
table.data.nota-lines th.nl-qty,table.data.nota-lines td.nl-qty{width:112px}
table.data.nota-lines th.nl-price,table.data.nota-lines td.nl-price{width:132px}
table.data.nota-lines th.nl-disc,table.data.nota-lines td.nl-disc{width:184px}
table.data.nota-lines td.nl-num{text-align:right;font-variant-numeric:tabular-nums;white-space:nowrap}
table.data.nota-lines td.nl-num small{display:block;font-size:.66rem;font-weight:600;color:var(--ink-3)}
table.data.nota-lines td.nl-qty small{display:block;margin-top:3px;font-size:.66rem;font-weight:600;color:var(--ink-3)}
table.data.nota-lines td.nl-no .nl-idx{
  display:inline-grid;place-items:center;min-width:24px;height:24px;padding:0 6px;
  border-radius:8px;background:var(--tint-3);border:1px solid var(--line-strong);
  font-family:var(--mono);font-size:.74rem;font-weight:700;color:var(--ink-2);
}
/* TOTAL sejajar kolom Diskon · HNA · HPP · Subtotal */
table.data.nota-lines tfoot tr.nota-foot > td{
  background:var(--plan-total-bg,var(--foot-bg));
  border-top:2px solid var(--plan-total-bd,var(--line-strong));
  padding:12px;font-family:var(--mono);font-size:.86rem;font-weight:700;
  color:var(--plan-total-fg,var(--ink-strong));white-space:nowrap;
}
table.data.nota-lines tfoot tr.nota-foot > td.nf-label{
  font-family:inherit;font-size:.78rem;font-weight:800;letter-spacing:.08em;
  text-transform:uppercase;color:var(--ink-2);text-align:right;
}
table.data.nota-lines tfoot tr.nota-foot > td.nl-num{text-align:right}
table.data.nota-lines tfoot tr.nota-foot > td[data-nl-total-sub]{font-size:.95rem;font-weight:800}
/* Nilai Diskon pada kaki tabel diberi warna aksen bila memang ada diskon. */
table.data.nota-lines tfoot tr.nota-foot.has-disc > td[data-nl-total-disc]{color:var(--warn-fg)}

/* Sel Diskon: TOMBOL TOGGLE Rp/% DIHAPUS (permintaan pemilik) — sekarang DUA
   kolom isian berdampingan (Rp & %) yang saling menghitung otomatis.
   Gaya pasangan isian ada di blok `.rp-pct-pair` paling akhir berkas ini.
   ⚠️ Jangan kembalikan aturan yang MENYEMBUNYIKAN salah satu kolom
   (`[data-mode=...] .disc-pct{display:none}`) — pengguna butuh keduanya. */

/* ── (3) CASHBACK + ringkasan nilai dokumen ─────────────────────────────── */
.nota-sum{
  display:grid;grid-template-columns:repeat(6,minmax(0,1fr));gap:10px;
  margin-top:14px;padding:12px 14px;border-radius:12px;
  border:1px solid var(--plan-sec-bd,var(--line-strong));background:var(--tint-3);
}
.nota-sum > div{display:flex;flex-direction:column;gap:2px;min-width:0}
.nota-sum span{font-size:.7rem;font-weight:600;letter-spacing:.02em;color:var(--ink-3);white-space:nowrap}
.nota-sum strong{font-family:var(--mono);font-size:.86rem;font-weight:700;color:var(--ink);
  font-variant-numeric:tabular-nums;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.nota-sum .ns-total{
  grid-column:auto;padding-left:12px;border-left:1px solid var(--line-strong);
}
.nota-sum .ns-total strong{font-size:1rem;font-weight:800;color:var(--plan-total-fg,var(--ink-strong))}
@media (max-width:1100px){ .nota-sum{grid-template-columns:repeat(3,minmax(0,1fr))} .nota-sum .ns-total{border-left:0;padding-left:0} }
@media (max-width:640px){ .nota-sum{grid-template-columns:repeat(2,minmax(0,1fr))} }

/* ── (4) GLOBAL: pegangan ubah lebar kolom untuk SEMUA tabel ─────────────
   Sama seperti pegangan pada tabel Rencana Pembelian (garis tipis di batas
   kanan judul kolom). Disembunyikan di HP (tabel = kartu bertingkat). */
table.data thead th{position:relative}
table.data .col-resize{
  position:absolute;top:0;right:-3px;width:9px;height:100%;
  display:block;cursor:col-resize;z-index:3;touch-action:none;
}
table.data .col-resize::after{
  content:'';position:absolute;left:4px;top:18%;bottom:18%;width:1px;
  background:var(--line-strong);
}
table.data .col-resize:hover::after,
table.data .col-resize:active::after{
  top:8%;bottom:8%;width:2px;left:3px;background:var(--brand,#0E7C6B);
}
html[data-theme="dark"] table.data .col-resize:hover::after,
html[data-theme="dark"] table.data .col-resize:active::after{background:#2DD4A7}
/* Tabel yang lebarnya diatur manual: wadah menggulir mendatar bila perlu. */
table.data.cols-manual{table-layout:fixed}
table.data.cols-manual thead th{white-space:normal;overflow-wrap:anywhere}
table.data.cols-manual td{overflow-wrap:anywhere}
@media (max-width:900px){
  table.data .col-resize{display:none}
  table.data.cols-manual{table-layout:auto;width:auto!important;min-width:0!important}
}

/* ══════════════════════════════════════════════════════════════════════════
   TABEL "PRODUK YANG DIPESAN" (KARTU UBAH DRAFT / KOREKSI NOTA)
   ──────────────────────────────────────────────────────────────────────────
   Permintaan pemilik:
     · kolom No. dihapus; "Dipesan" dipecah jadi **Jumlah** + **Satuan** produk;
     · **LEBAR KOLOM MENGIKUTI KEBUTUHAN KONTEN**, bukan dibagi rata:
         – Obat/alkes  : mengambil SISA ruang kartu (proporsional);
         – Jumlah/Satuan: ringkas sesuai isinya;
         – Diskon      : DIPERLEBAR agar dua isian (Rp & %) nyaman dipakai;
         – Harga satuan/HNA/HPP/Subtotal: ringkas, selebar angka terpanjang
           di kolomnya (dihitung `notaFit()` di assets/app.js);
     · tidak boleh ada kolom yang saling menimpa: SEMUA isian dipaksa
       `width:100%;min-width:0` sehingga tidak pernah melebihi selnya;
     · prefix "Rp" & suffix "%" STATIS di dalam kotak isian.
   Angka di bawah adalah NILAI AWAL (juga dipakai bila JavaScript mati);
   `notaFit()` menyesuaikannya dengan lebar kartu & panjang angka sebenarnya.
   Di ≤900px tabel tetap menjadi kartu bertingkat (aturan global).
   ══════════════════════════════════════════════════════════════════════════ */
table.data.nota-lines{table-layout:fixed;width:100%;min-width:0}
table.data.nota-lines col.nl-c-item{width:auto}
table.data.nota-lines col.nl-c-qty{width:78px}
table.data.nota-lines col.nl-c-unit{width:100px}
table.data.nota-lines col.nl-c-price{width:120px}
table.data.nota-lines col.nl-c-disc{width:210px}
table.data.nota-lines col.nl-c-hna{width:118px}
table.data.nota-lines col.nl-c-hpp{width:118px}
table.data.nota-lines col.nl-c-sub{width:122px}
/* ⚠️ Isian TIDAK BOLEH melebihi selnya: aturan global memberi `min-width:96px`
   pada input[data-money] & .money-wrap (dulu input harga 96px di kolom 86px →
   menimpa kolom sebelah). Di tabel ini semuanya `min-width:0`. */
table.data.nota-lines :is(input, select, .money-wrap, .pct-field){min-width:0;max-width:100%}
table.data.nota-lines td.nl-price .money-wrap > input[data-money]{
  padding-left:27px!important;font-size:.78rem;
}
table.data.nota-lines td.nl-price .money-prefix{left:8px;font-size:.7em}
table.data.nota-lines thead th{padding:9px 8px}
table.data.nota-lines td{padding:9px 8px;vertical-align:top}
/* Kaki tabel (TOTAL) ikut aturan pemotongan yang sama supaya angka bold tidak
   meluber ke kolom sebelah; huruf sedikit dikecilkan agar muat sejajar. */
table.data.nota-lines tfoot tr.nota-foot > td{
  overflow:hidden;text-overflow:ellipsis;font-size:.8rem;padding:10px 8px;
}
table.data.nota-lines tfoot tr.nota-foot > td[data-nl-total-sub]{font-size:.86rem}
table.data.nota-lines tfoot tr.nota-foot > td.nf-label{font-size:.74rem}

/* Angka jumlah tetap di tengah; teks pilihan satuan rata KIRI supaya sejalan
   dengan judul kolom yang kini semuanya rata kiri. */
table.data.nota-lines td.nl-qty{text-align:center}
table.data.nota-lines td.nl-unit{text-align:left}
table.data.nota-lines td.nl-qty input,
table.data.nota-lines td.nl-unit select{width:100%;min-width:0;text-align:center}
table.data.nota-lines td.nl-num{font-size:.78rem;line-height:1.35}
/* Isian baris: tinggi & posisinya SERAGAM (permintaan pemilik) — Jumlah,
   Satuan, Harga satuan, dan dua isian Diskon (Rp & %) semuanya satu tinggi
   sehingga sejajar rapi dalam satu baris tabel. Dropdown butuh padding kanan
   ≥28px agar panah tidak menabrak teks. */
table.data.nota-lines td.nl-qty input,
table.data.nota-lines td.nl-unit select{
  height:var(--nl-ctl-h);min-height:var(--nl-ctl-h);padding:0 8px;font-size:.8rem;
}
table.data.nota-lines td.nl-unit select{padding-right:28px;background-position:right 8px center;text-align:left}
/* Sel angka: nominal TIDAK boleh menimpa kolom sebelah. Bila terpotong, teks
   diberi elipsis + tooltip (assets/app.js mengukur dan memasang `data-tip`). */
table.data.nota-lines td.nl-num,
table.data.nota-lines td.nl-num > strong{
  display:table-cell;overflow:hidden;text-overflow:ellipsis;
}
table.data.nota-lines td.nl-num > strong{display:block}
/* ── Sel "Obat / alkes": nama + kode + urutan satuan + info penerimaan ──── */
table.data.nota-lines td.nl-item{overflow-wrap:anywhere}
table.data.nota-lines .nl-name{display:block;font-size:.86rem;font-weight:700;line-height:1.3;color:var(--ink-strong)}
/* Urutan satuan (permintaan pemilik: huruf kecil saja) — "1 Box = 10 Strip = 100 Tablet" */
table.data.nota-lines .nl-conv{
  display:block;margin-top:2px;font-size:.68rem;font-weight:600;line-height:1.35;
  letter-spacing:0;text-transform:lowercase;color:var(--ink-2);
}
table.data.nota-lines .nl-ro{display:block;text-align:right;font-variant-numeric:tabular-nums}
/* ── PASANGAN ISIAN Rp & % — PREFIX & SUFFIX STATIS ──────────────────────
   Dipakai kolom Diskon per produk DAN kolom Pajak / biaya.
   Permintaan pemilik: **"Rp" selalu tampil di KIRI kolom nominal** dan
   **"%" selalu tampil di KANAN kolom persen** — keduanya statis (bukan
   placeholder), jadi tetap terlihat walau kolomnya sudah berisi angka.
   Dua isian bersebelahan tanpa tombol toggle: mengisi salah satu langsung
   menghitung yang lain (assets/app.js). */
.rp-pct-pair{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:6px;min-width:0}
.rp-pct-pair > input,
.rp-pct-pair > .money-wrap,
.rp-pct-pair > .pct-field{width:100%;min-width:0}
table.data .rp-pct-pair input[data-money],
table.data .rp-pct-pair .money-wrap,
table.data .rp-pct-pair .pct-field{min-width:0}
/* Sisi RUPIAH: prefix "Rp" di dalam kotak (dibuat wrapMoney() di app.js). */
.rp-pct-pair .money-prefix{display:block;left:8px;font-size:.7em;color:var(--ink-2)}
.rp-pct-pair .money-wrap > input[data-money]{padding-left:26px!important;text-align:right}
.rp-pct-pair input{font-size:.82rem;padding-top:7px;padding-bottom:7px}
.rp-pct-pair input::placeholder{font-weight:600;color:var(--ink-3);opacity:.75}
/* Sisi PERSEN: pembungkus relatif + suffix "%" statis di kanan. */
.pct-field{position:relative;display:block;min-width:0}
.pct-field > input{width:100%;padding-right:21px!important;text-align:right;font-family:var(--mono)}
.pct-suffix{
  position:absolute;right:8px;top:50%;transform:translateY(-50%);
  font-family:var(--mono);font-size:.72em;font-weight:700;line-height:1;
  color:var(--ink-2);pointer-events:none;user-select:none;
}
/* Di dalam kolom tabel yang sempit, dua isian butuh lebih banyak ruang:
   gap dirapatkan & huruf sedikit dikecilkan (tetap ≥ 12px agar terbaca). */
table.data.nota-lines .rp-pct-pair{gap:5px}
table.data.nota-lines .rp-pct-pair input{font-size:.78rem}
table.data.nota-lines .rp-pct-pair .money-wrap > input[data-money]{padding-left:23px!important}
table.data.nota-lines .rp-pct-pair .money-prefix{left:6px;font-size:.66em}
table.data.nota-lines .pct-field > input{padding-right:18px!important}
table.data.nota-lines .pct-suffix{right:6px;font-size:.66em}
/* Sisi "Rp" pada kartu Dokumen (Pajak / biaya) — tetap dua kolom sejajar. */
.field .rp-pct-pair{max-width:360px}
/* Nilai nominal yang disamarkan untuk role tanpa izin nominal. */
.masked-money{
  display:inline-block;font-family:var(--mono);font-weight:700;letter-spacing:.06em;
  color:var(--ink-2);
}

/* Layar sangat sempit (≤560px): pasangan isian Rp & % DITUMPUK (bukan
   dua kolom) supaya angkanya tidak terklip — di kartu bertingkat HP, dua isian
   berdampingan hanya menyisakan ~50px per kolom. */
@media (max-width:560px){
  .rp-pct-pair{grid-template-columns:minmax(0,1fr);gap:6px}
  .rp-pct-pair .money-wrap > input[data-money]{padding-left:26px!important}
  .rp-pct-pair .pct-field > input{padding-right:20px!important}
}
/* ≤400px: kolom label pada kartu bertingkat dipersempit (label tetap terbaca,
   boleh 2 baris) supaya kolom NILAI cukup lebar untuk nominal berformat ribuan
   — isian HP memakai font 16px (anti-zoom iOS) sehingga butuh ruang lebih. */
@media (max-width:400px){
  table.data.nota-lines td,
  table.data.nota-lines tbody th{grid-template-columns:minmax(0,84px) minmax(0,1fr);gap:3px 8px}
  /* Harga satuan bisa bernilai jutaan (mis. "1.250.000"): di layar ≤400px
     labelnya ditaruh di ATAS sehingga isian memakai lebar penuh dan angkanya
     tidak terpotong. */
  table.data.nota-lines td.nl-price{grid-template-columns:minmax(0,1fr)}
  table.data.nota-lines td.nl-price::before{margin-bottom:1px}
}
@media (max-width:900px){
  /* Kartu bertingkat: kolom isian memakai lebar penuh, bukan persentase. */
  table.data.nota-lines{table-layout:auto}
  table.data.nota-lines col{width:auto!important}
  /* ⚠️ `proportionTable()` menambahkan kelas `.col-num` (width:1%) pada sel
     angka. Di mode kartu bertingkat aturan itu membuat sel MENYEMPIT
     (terukur 112–184px dari 301px) sehingga isian nominal tinggal 30–40px.
     Di sini lebar sel dikembalikan penuh. */
  table.data.nota-lines td,
  table.data.nota-lines td.col-num,
  table.data.nota-lines td.col-date,
  table.data.nota-lines td.col-num-wrap,
  table.data.nota-lines tbody th{width:auto!important;white-space:normal}
  table.data.nota-lines td.nl-price .money-wrap,
  table.data.nota-lines td.nl-disc .rp-pct-pair,
  table.data.nota-lines td.nl-qty input,
  table.data.nota-lines td.nl-unit select{width:100%;max-width:none}
  table.data.nota-lines td.nl-price .money-wrap > input[data-money]{
    padding-left:27px!important;padding-right:8px!important;font-size:.78rem;
  }
  table.data.nota-lines td.nl-price .money-prefix{left:7px;font-size:.7em}
  table.data.nota-lines td.nl-qty,
  table.data.nota-lines td.nl-unit{text-align:left}
  table.data.nota-lines td.nl-qty input,
  table.data.nota-lines td.nl-unit select{text-align:left}
  /* Kartu bertingkat: sel angka kembali memakai tata letak grid global
     (label kolom di kiri, nilai di kanan) — tanpa klip/elipsis. */
  table.data.nota-lines td.nl-num{
    display:grid;overflow:visible;text-overflow:clip;white-space:normal;
  }
  table.data.nota-lines td.nl-num > strong{display:inline;overflow:visible}
  .field .rp-pct-pair{max-width:none}
}

/* ══════════════════════════════════════════════════════════════════════════
   TABEL "PRODUK YANG DIPESAN" — TINGGI ISIAN SERAGAM & JUDUL KOLOM RATA KIRI
   ──────────────────────────────────────────────────────────────────────────
   Permintaan pemilik:
     1. judul kolom Diskon cukup **"Diskon"** — label kecil "Rp / %" dihapus;
     2. kolom Obat/alkes hanya NAMA + urutan satuan (PLU & info stok dihapus);
     3. **tinggi semua isian SAMA** (Jumlah · Satuan · Harga satuan · Diskon Rp ·
        Diskon %) dan posisinya sejajar dalam satu baris tabel;
     4. **semua judul kolom rata KIRI**.
   Satu variabel `--nl-ctl-h` dipakai bersama supaya tinggi tidak pernah
   berbeda lagi bila salah satu kontrol diubah di kemudian hari.
   ══════════════════════════════════════════════════════════════════════════ */
table.data.nota-lines{--nl-ctl-h:36px}

/* (4) JUDUL KOLOM RATA KIRI SEMUA.
   ⚠️ `table.data th.col-num{text-align:right}` (dari proportionTable) membuat
   judul Jumlah/Harga/Diskon/HPP/Subtotal rata kanan — di tabel ini dipaksa kiri. */
table.data.nota-lines thead th,
table.data.nota-lines thead th.col-num,
table.data.nota-lines thead th.col-date,
table.data.nota-lines thead th.ta-r{text-align:left}

/* (3) TINGGI ISIAN SERAGAM & SEJAJAR (desktop; di HP tabel = kartu bertingkat
   dan tinggi kontrol mengikuti aturan sentuh global 44px). */
@media (min-width:901px){
  table.data.nota-lines td.nl-qty input,
  table.data.nota-lines td.nl-unit select,
  table.data.nota-lines td.nl-price input[data-money],
  table.data.nota-lines .rp-pct-pair input{
    height:var(--nl-ctl-h);min-height:var(--nl-ctl-h);box-sizing:border-box;
    padding-top:0;padding-bottom:0;font-size:.8rem;line-height:1.2;
  }
  /* Pembungkus (prefix "Rp" & suffix "%") ikut tinggi kontrol supaya tidak ada
     selisih 1–4px antara kolom nominal dan kolom persen. */
  table.data.nota-lines .rp-pct-pair > input,
  table.data.nota-lines .rp-pct-pair > .money-wrap,
  table.data.nota-lines .rp-pct-pair > .pct-field,
  table.data.nota-lines td.nl-price .money-wrap{
    height:var(--nl-ctl-h);min-height:var(--nl-ctl-h);align-self:center;
  }
  table.data.nota-lines .rp-pct-pair > .money-wrap > input,
  table.data.nota-lines .rp-pct-pair > .pct-field > input,
  table.data.nota-lines td.nl-price .money-wrap > input{height:100%}
  /* Dua isian Diskon sejajar penuh (tidak menyusut) di dalam selnya. */
  table.data.nota-lines td.nl-disc .rp-pct-pair{align-items:stretch}
  /* Sel kontrol memakai vertical-align TOP + padding sama → semua kontrol
     berada pada garis atas yang sama, apa pun panjang nama produknya. */
  table.data.nota-lines td.nl-qty,
  table.data.nota-lines td.nl-unit,
  table.data.nota-lines td.nl-price,
  table.data.nota-lines td.nl-disc{vertical-align:top;padding-top:9px;padding-bottom:9px}
  /* Placeholder/suffix tetap di tengah tinggi kontrol. */
  table.data.nota-lines .pct-suffix,
  table.data.nota-lines td.nl-price .money-prefix{top:50%;transform:translateY(-50%)}
}

/* ══════════════════════════════════════════════════════════════════════════
   STOK & BATCH → TAB "DATA STOK"  (permintaan pemilik, mengikuti desain foto)
   ──────────────────────────────────────────────────────────────────────────
   Tata letak:
     h1.ds-title          → judul halaman "Data Stok"
     form.lab-card.ds-filter → (kiri) kolom "Cari produk" dengan prefix ikon
                              kaca pembesar + suffix tombol pindai barcode;
                              (kanan) dropdown "Urutkan persediaan"
     .lab-card.ds-table-card → tabel No. · Nama Produk · Persediaan · Aksi
   ⚠️ Tabel memakai `data-no-stack` (TIDAK diubah menjadi kartu bertingkat di HP)
   karena bentuknya memang ringkas 4 kolom dan di HP tetap muat — sesuai desain
   yang diminta. Di ≤640px kolom No. disembunyikan agar nama produk lega.
   ══════════════════════════════════════════════════════════════════════════ */
.ds-title{
  /* Permintaan pemilik: judul "Daftar Harga …" tidak boleh terlalu tebal.
     Dulu 800 (extra-bold) → kini 650 (semi-bold) sehingga seimbang dengan judul
     kartu/tab. Berlaku untuk SEMUA tab (Obat · BMHP & Alkes · Tindakan) karena
     judulnya memakai elemen yang sama, dan tab "Data Stok" (halaman kembar)
     ikut konsisten. */
  margin:2px 0 12px;font-size:1.32rem;font-weight:650;letter-spacing:0;
  color:var(--head-ink);
}
.ds-filter{margin:0 0 16px;padding:14px 16px}
.ds-filter-row{display:flex;align-items:flex-end;gap:16px;flex-wrap:wrap}
.ds-f-q{flex:1 1 420px;min-width:0;display:flex;flex-direction:column;gap:6px}
.ds-f-sort{flex:0 1 300px;min-width:200px;display:flex;flex-direction:column;gap:6px}
.ds-f-q > span:first-child,
.ds-f-sort > span:first-child{
  font-size:.82rem;font-weight:700;color:var(--ink-2);letter-spacing:0;
}
/* ── KOLOM CARI = SATU KOMPONEN UTUH ──────────────────────────────────────
   Permintaan pemilik: prefix ikon TIDAK boleh tampil dua kali / menimpa teks,
   dan tombol [Scan] harus menjadi SATU bagian dengan kolom input.
   Rancangan: bingkai (border + background + radius) dipasang pada PEMBUNGKUS
   `.gs-field`, input di dalamnya dibuat TANPA border/latar sendiri, ikon
   kaca pembesar menempati padding kiri 44px, dan tombol pindai berada DI DALAM
   baris flex yang sama (bukan elemen absolut) sehingga mustahil tumpang tindih. */
.ds-filter .gs-field{
  flex:1 1 auto;display:flex;align-items:stretch;gap:0;position:relative;
  border:1px solid var(--line-strong);border-radius:var(--radius-sm);
  background:var(--input-bg);
  transition:border-color .14s ease,box-shadow .14s ease;
}
.ds-filter .gs-field:focus-within{
  border-color:var(--focus-border);box-shadow:0 0 0 3px var(--focus-ring);
}
/* Input: tanpa bingkai sendiri; 44px kiri = ruang ikon (ikon berakhir di 32px). */
.ds-filter .gs-field > input[type=search]{
  flex:1 1 auto;min-width:0;width:auto;
  border:0!important;background:transparent!important;box-shadow:none!important;
  padding:0 10px 0 44px!important;height:42px;min-height:42px;font-size:.95rem;
  border-radius:var(--radius-sm);
}
.ds-filter .gs-field > input[type=search]:focus,
.ds-filter .gs-field > input[type=search]:focus-visible{outline:none;box-shadow:none!important}
/* Ikon kaca pembesar: SATU-SATUNYA ikon di kolom ini (ikon latar dimatikan). */
.ds-filter .gs-field > input[type=search]{background-image:none!important}
.ds-filter .gs-field .gs-icon{left:14px;width:18px;height:18px;fill:var(--ink-3)}
/* Tombol pindai: menempel di dalam bingkai (satu kesatuan dengan input). */
.ds-filter .gs-field .gs-scan{
  position:static;transform:none;flex:0 0 auto;align-self:center;
  height:34px;margin:0 4px 0 0;padding:0 10px;border-radius:6px;
  border:1px solid var(--ds-btn-bd);background:var(--ds-btn-bg);color:var(--ds-btn-fg);
}
.ds-filter .gs-field .gs-scan:hover{
  background:var(--ds-head-bg);color:var(--ds-head-fg);border-color:var(--ds-head-bd);
}
.ds-filter .gs-scan-lbl{display:none}
.ds-filter .gs-field.has-scan > input[type=search]{padding-right:10px!important}
.ds-filter select{width:100%}

.ds-table-card{padding:0;overflow:hidden}
.ds-table-card .table-wrap{border:0;border-radius:0}
table.data.ds-table{min-width:0;width:100%}
/* Warna kepala tabel & tombol [Detail] memakai token KHUSUS dengan latar
   SOLID (bukan `--ok-bg` yang transparan). Dengan latar transparan, warna akhir
   bergantung lapisan di belakangnya sehingga kontrasnya berubah-ubah antar tema
   (terukur 1,3:1 di tema gelap). Token di bawah dijamin terbaca di kedua tema. */
:root,html[data-theme="dark"]{
  --ds-head-bg:#0B3B2C; --ds-head-fg:#EAFBF2; --ds-head-bd:#1E5A46;
  --ds-btn-bg:#11362B; --ds-btn-fg:#B8F5DA; --ds-btn-bd:#2A6B54;
}
html[data-theme="light"]{
  --ds-head-bg:#E1F8EC; --ds-head-fg:#04281D; --ds-head-bd:#B7E3CE;
  --ds-btn-bg:#E7F7EF; --ds-btn-fg:#0B4A34; --ds-btn-bd:#B7E3CE;
}
/* ⚠️ Spesifisitas: aturan lain seperti `table.data.ds-table th.ds-plu{...}`
   (0,3,2) MENANG atas `table.data.ds-table thead th` (0,2,2) sehingga warna judul
   kolom bisa berbeda sendiri. Karena itu warna kepala tabel dipaksa dengan
   selektor yang lebih spesifik + `!important` (dua warna token saja). */
.ds-table-card table.data.ds-table thead th,
.ds-table-card table.data.ds-table thead th.ds-plu,
.ds-table-card table.data.ds-table thead th.ds-stok,
.ds-table-card table.data.ds-table thead th.ds-act{
  background:var(--ds-head-bg)!important;color:var(--ds-head-fg)!important;
  border-bottom:1px solid var(--ds-head-bd)!important;
  font-size:.8rem;font-weight:750;letter-spacing:.02em;text-transform:none;
  padding:14px 16px;white-space:nowrap;
}
table.data.ds-table td{padding:13px 16px;border-bottom:1px solid var(--row-border);vertical-align:middle}
table.data.ds-table tbody tr:last-child td{border-bottom:0}
/* Kolom pertama = KODE PLU (dulu nomor urut). */
table.data.ds-table th.ds-plu,table.data.ds-table td.ds-plu{width:120px;text-align:left;white-space:nowrap}
table.data.ds-table td.ds-plu .mono{font-size:.8rem;font-weight:700}
table.data.ds-table td.ds-name{font-weight:600;color:var(--ink-strong)}
table.data.ds-table th.ds-stok,table.data.ds-table td.ds-stok{width:150px;white-space:nowrap}
table.data.ds-table td.ds-stok{font-weight:700;color:var(--ink-strong);font-variant-numeric:tabular-nums}
/* Stok kosong (0) ditulis MERAH supaya langsung terlihat. */
table.data.ds-table td.ds-stok.is-empty{color:var(--err-fg)}
table.data.ds-table th.ds-act,table.data.ds-table td.ds-act{width:130px;text-align:left}
/* Tombol [Detail] bergaya lembut (ikon mata + teks), bukan ikon saja. */
.ds-table-card .btn.ds-detail{
  display:inline-flex;align-items:center;gap:7px;
  background:var(--ds-btn-bg);color:var(--ds-btn-fg);border:1px solid var(--ds-btn-bd);
  padding:7px 14px;border-radius:9px;font-weight:650;
}
.ds-detail svg{width:16px;height:16px;fill:currentColor}
.ds-table-card .btn.ds-detail:hover{background:var(--ds-head-bg);color:var(--ds-head-fg);border-color:var(--ds-head-bd)}
@media (max-width:640px){
  .ds-filter{padding:12px}
  .ds-filter-row{gap:10px}
  .ds-f-q,.ds-f-sort{flex:1 1 100%;min-width:0}
  /* Di HP kolom No. disembunyikan & tombol Detail dibuat ringkas. */
  table.data.ds-table th.ds-plu,table.data.ds-table td.ds-plu{display:none}
  table.data.ds-table thead th{padding:11px 10px}
  table.data.ds-table td{padding:11px 10px}
  table.data.ds-table th.ds-stok,table.data.ds-table td.ds-stok{width:auto}
  table.data.ds-table th.ds-act,table.data.ds-table td.ds-act{width:44px}
  .ds-detail{padding:8px;border-radius:9px}
  .ds-detail .lbl{display:none}
  /* Kolom cari: input & tombol pindai tetap satu komponen, tinggi 44px. */
  .ds-filter .gs-field > input[type=search]{height:44px;min-height:44px;font-size:16px}
  .ds-filter .gs-field .gs-scan{height:36px;margin-right:4px}
}

/* ══════════════════════════════════════════════════════════════════════════
   TINDAK LANJUT BARANG MENDEKATI ED
   · `.ed-fu-facts`  = 4 fakta di kepala kartu tindak lanjut
                       (nama produk · jumlah+satuan · nomor batch · tgl expired)
   · `.ed-fu-line`   = baris ringkas keputusan yang sudah tersimpan pada kartu batch
   ══════════════════════════════════════════════════════════════════════════ */
.ed-fu-facts{
  display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;
  margin:0 0 16px;padding:14px;border-radius:12px;
  border:1px solid var(--line-strong);background:var(--tint-3);
}
.ed-fu-facts > div{display:flex;flex-direction:column;gap:2px;min-width:0}
.ed-fu-facts span{font-size:.72rem;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:var(--ink-2)}
.ed-fu-facts strong{font-size:.94rem;font-weight:750;color:var(--ink-strong);overflow-wrap:anywhere}
.ed-fu-facts strong.neg{color:var(--err-fg)}
@media (max-width:640px){ .ed-fu-facts{grid-template-columns:1fr;gap:10px} }

.ed-fu-line{
  margin:0;padding:9px 12px;border-radius:10px;
  background:var(--ok-bg);border:1px solid var(--ok-bd);
  font-size:.8rem;color:var(--ok-fg);overflow-wrap:anywhere;
}
.ed-fu-line strong{font-weight:750}
.ed-fu-line .muted{color:inherit;opacity:.8}

/* ══════════════════════════════════════════════════════════════════════════
   KARTU "DETAIL STOK PRODUK"  (tab Data Stok → tombol [Detail])
   ──────────────────────────────────────────────────────────────────────────
   Susunan sesuai desain yang diminta pemilik:
     .dsd-card      → kartu identitas (ikon kotak · nama produk · 3 jenjang
                      satuan · stok onhand dengan pemecahan kemasan)
     .dsd-sub       → sub-judul "Riwayat Stok"
     .dsd-table     → tabel riwayat (9 kolom) dengan badge Masuk/Keluar
     .dsd-note      → catatan kaki aturan tingkatan satuan
   Memakai token tema yang sudah ada (tanpa warna hardcode baru) supaya tetap
   benar pada tema gelap & terang. Tabel TIDAK menumpuk saat HP selebar ≥721px;
   di bawah itu kolom sempit disembunyikan agar tidak perlu digeser.
   ══════════════════════════════════════════════════════════════════════════ */
.dsd-card{
  border:1px solid var(--line-strong);border-radius:14px;background:var(--tint-3);
  padding:20px 22px;margin:0 0 22px;
}
.dsd-hero{display:grid;grid-template-columns:auto minmax(0,1fr) auto;gap:22px;align-items:start}
.dsd-icon{
  display:grid;place-items:center;width:88px;height:88px;border-radius:22px;
  background:var(--ds-head-bg);border:1px solid var(--ds-head-bd);flex:0 0 auto;
}
.dsd-icon svg{width:42px;height:42px;fill:var(--ds-head-fg)}
.dsd-label{
  display:block;font-size:.78rem;font-weight:650;letter-spacing:0;
  color:var(--ink-2);margin-bottom:2px;
}
.dsd-name{margin:0 0 14px;font-size:1.42rem;font-weight:800;line-height:1.2;color:var(--head-ink)}
.dsd-tiers{display:flex;align-items:flex-start;gap:34px;flex-wrap:wrap}
.dsd-tier{display:flex;flex-direction:column;gap:6px;min-width:0}
.dsd-chip{
  display:inline-block;align-self:flex-start;padding:3px 10px;border-radius:7px;
  background:var(--ds-btn-bg);border:1px solid var(--ds-btn-bd);color:var(--ds-btn-fg);
  font-size:.82rem;font-weight:750;line-height:1.35;
}
.dsd-conv{font-size:.82rem;font-weight:500;color:var(--ink-2);white-space:nowrap}
.dsd-onhand{
  display:flex;flex-direction:column;gap:5px;min-width:0;
  padding-left:22px;border-left:1px solid var(--line-strong);
}
.dsd-onhand-val{font-size:1.16rem;font-weight:800;color:var(--ds-btn-fg);line-height:1.25}
html[data-theme="light"] .dsd-onhand-val{color:var(--ds-btn-fg)}
.dsd-onhand-line{
  position:relative;padding-left:14px;font-size:.82rem;font-weight:600;color:var(--ink-2);
}
.dsd-onhand-line::before{
  content:'';position:absolute;left:2px;top:.5em;width:5px;height:5px;border-radius:50%;
  background:var(--ds-btn-fg);
}
.dsd-sub{
  margin:0 0 10px;font-size:1rem;font-weight:800;color:var(--head-ink);letter-spacing:0;
}
.dsd-table-wrap{border:1px solid var(--line-strong);border-radius:12px;overflow:auto;background:var(--panel)}
table.data.dsd-table{min-width:100%;width:100%;border-collapse:separate;border-spacing:0}
table.data.dsd-table thead th{
  background:var(--ds-head-bg)!important;color:var(--ds-head-fg)!important;
  border-bottom:1px solid var(--ds-head-bd)!important;
  font-size:.76rem;font-weight:750;letter-spacing:0;text-transform:none;
  padding:11px 12px;white-space:nowrap;
}
table.data.dsd-table td{padding:11px 12px;border-bottom:1px solid var(--row-border);vertical-align:middle;font-size:.82rem}
table.data.dsd-table tbody tr:last-child td{border-bottom:0}
table.data.dsd-table td.dsd-c-no{width:48px;text-align:center;color:var(--ink-2);font-variant-numeric:tabular-nums}
table.data.dsd-table th.dsd-c-num,table.data.dsd-table td.dsd-c-num{text-align:right;white-space:nowrap}
table.data.dsd-table td.dsd-c-num strong{font-weight:750;color:var(--ink-strong);font-variant-numeric:tabular-nums}
table.data.dsd-table td.dsd-c-num small{display:block;font-size:.7rem;font-weight:500;color:var(--ink-3);margin-top:1px}
table.data.dsd-table td.dsd-date{white-space:nowrap}
table.data.dsd-table td.dsd-date small{display:block;font-size:.72rem;margin-top:1px}
table.data.dsd-table td.dsd-empty{text-align:center;color:var(--ink-3);padding:22px}
/* Badge jenis transaksi */
.dsd-badge{
  display:inline-flex;align-items:center;gap:6px;padding:4px 10px;border-radius:999px;
  font-size:.78rem;font-weight:700;white-space:nowrap;border:1px solid transparent;
}
.dsd-badge svg{width:14px;height:14px;fill:currentColor;flex:0 0 14px}
.dsd-badge.is-in{background:var(--ok-bg);color:var(--ok-fg);border-color:var(--ok-bd)}
.dsd-badge.is-out{background:var(--err-bg);color:var(--err-fg);border-color:var(--err-bd)}
/* Angka perubahan */
.dsd-delta{font-weight:750;font-variant-numeric:tabular-nums}
.dsd-delta.pos{color:var(--ok-fg)}
.dsd-delta.neg{color:var(--err-fg)}
html[data-theme="light"] .dsd-delta.pos{color:#0B6A4F}
html[data-theme="light"] .dsd-delta.neg{color:#9B1C1C}
/* Catatan kaki */
.dsd-note{
  display:flex;align-items:flex-start;gap:8px;margin:14px 0 0;
  font-size:.82rem;font-weight:500;color:var(--ink-2);
}
.dsd-note svg{width:16px;height:16px;fill:var(--ink-3);flex:0 0 16px;margin-top:1px}
/* Lebar kartu detail: cukup lega untuk 9 kolom tanpa menggeser halaman. */
#sheet-detail-stok .sheet-card.wide{width:min(1300px,100%)}
@media (max-width:1100px){
  .dsd-hero{grid-template-columns:auto minmax(0,1fr);gap:18px}
  .dsd-onhand{grid-column:1 / -1;padding-left:0;border-left:0;border-top:1px solid var(--line-strong);padding-top:14px}
  .dsd-icon{width:72px;height:72px;border-radius:18px}
  .dsd-icon svg{width:34px;height:34px}
  .dsd-name{font-size:1.24rem}
  .dsd-tiers{gap:22px}
}
@media (max-width:720px){
  .dsd-card{padding:14px}
  .dsd-icon{width:56px;height:56px;border-radius:14px}
  .dsd-icon svg{width:26px;height:26px}
  .dsd-name{font-size:1.1rem;margin-bottom:10px}
  .dsd-tiers{gap:14px}
}
/* ⚠️ Di HP tabel riwayat memakai **KARTU BERTINGKAT** global (aturan
   `table.data[data-stack]`): semua kolom tetap terbaca tanpa menggeser layar.
   Jangan menyembunyikan kolom di sini — informasi riwayat stok harus utuh. */
@media (max-width:900px){
  table.data.dsd-table[data-stack] td,
  table.data.dsd-table[data-stack] tbody th{padding:5px 0}
  table.data.dsd-table[data-stack] td.dsd-c-num{text-align:left}
  table.data.dsd-table[data-stack] td.dsd-c-num small{display:inline;margin-left:4px}
  table.data.dsd-table[data-stack] td.dsd-c-no{text-align:left}
  .dsd-table-wrap{border-radius:10px;background:transparent;border:0}
  table.data.dsd-table[data-stack] tbody tr{background:var(--tint-3)}
}

/* ══════════════════════════════════════════════════════════════════════════
   DATA STOK → BARIS **CONTOH** (permintaan pemilik)
   ──────────────────────────────────────────────────────────────────────────
   Satu baris contoh yang SELALU berada di urutan pertama (tidak ikut tersaring,
   terurut, atau bergeser halaman) berisi satuan berjenjang Box → Strip → Tablet
   dan stok onhand 7 Box, lengkap dengan 15 pergerakan ilustrasi pada kartu
   Detail-nya. Datanya VIRTUAL (`includes/stocksample.php`) — tidak ada item,
   mutasi, atau batch nyata yang dibuat.

   Markup:
     tr.ds-row-sample            → baris contoh (chip CONTOH + garis putus-putus)
     .ds-name-main / .ds-sample-chip / .ds-sample-tiers
     .ds-stok > .ds-sample-eq    → "(= 700 Tablet)" di bawah "7 box"
     .ds-act-row                 → Detail + [Trash] sejajar satu baris
     .ds-sample-del              → tombol ikon hapus (Administrator)
     .ds-sample-foot / .ds-sample-link → tautan "Tampilkan baris contoh"
   ══════════════════════════════════════════════════════════════════════════ */
table.data.ds-table tbody tr.ds-row-sample > td{
  background:var(--info-bg);
  border-bottom:1px dashed var(--info-bd);
  vertical-align:top;
}
html[data-theme="dark"] table.data.ds-table tbody tr.ds-row-sample > td{
  background:rgba(20,163,139,.10);
}
table.data.ds-table tbody tr.ds-row-sample .ds-name-main{
  font-weight:750;color:var(--ink-strong);
}
/* Chip penanda — sama bentuknya dengan chip CONTOH di menu Defecta. */
.ds-sample-chip{
  display:inline-block;margin-left:7px;padding:1px 7px;border-radius:999px;
  font-size:.62rem;font-weight:750;letter-spacing:.05em;line-height:1.55;
  background:var(--info-bg);color:var(--info-fg);border:1px solid var(--info-bd);
  vertical-align:middle;white-space:nowrap;
}
.ds-sample-tiers{
  display:block;margin-top:3px;
  font-size:.76rem;font-weight:600;color:var(--ink-2);
}
.ds-sample-eq{
  display:block;margin-top:2px;
  font-size:.74rem;font-weight:600;color:var(--ink-2);
}
/* Kolom Aksi: Detail + [Trash] dalam SATU baris (tidak pernah tumpang tindih). */
table.data.ds-table td.ds-act .ds-act-row{
  display:inline-flex;align-items:center;gap:6px;flex-wrap:nowrap;
}
.ds-sample-del-form{display:contents}
table.data.ds-table .btn.ds-sample-del{
  width:34px;min-width:34px;height:34px;padding:0;
  display:inline-flex;align-items:center;justify-content:center;
  border-radius:9px;background:var(--err-bg);border:1px solid var(--err-bd);
  color:var(--err-fg);
}
table.data.ds-table .btn.ds-sample-del svg{width:16px;height:16px;min-width:16px;fill:currentColor}
table.data.ds-table .btn.ds-sample-del:hover{background:var(--err-bg-hover);color:var(--err-fg)}
/* Kolom Aksi butuh ruang dua tombol (dulu 130px hanya untuk satu tombol). */
table.data.ds-table th.ds-act,table.data.ds-table td.ds-act{width:186px}
/* Baris "tidak ada hasil" saat daftar kosong (tetap di bawah baris contoh). */
table.data.ds-table td.ds-empty{
  padding:18px 16px;text-align:center;font-size:.86rem;color:var(--ink-2);
}
/* Tautan "Tampilkan baris contoh" (hanya Administrator). */
.ds-sample-foot{display:flex;justify-content:flex-end;padding:10px 16px 12px}
.ds-sample-restore{margin:0}
.ds-sample-link{
  padding:0;border:0;background:none;cursor:pointer;
  font:inherit;font-size:.78rem;font-weight:600;color:var(--ink-2);
  text-decoration:underline;text-underline-offset:3px;
}
.ds-sample-link:hover{color:var(--ink)}
/* Catatan kaki tambahan pada kartu Detail baris contoh. */
.dsd-note.is-sample{color:var(--info-fg)}
.dsd-note.is-sample svg{fill:var(--info-fg)}

@media (max-width:640px){
  /* Di HP: dua tombol ikon 34px + jarak masih muat; kolom Aksi dilonggarkan
     dari 44px (hanya satu tombol) menjadi 82px agar [Trash] tidak terpotong. */
  table.data.ds-table th.ds-act,
  table.data.ds-table td.ds-act{width:86px}
  table.data.ds-table .ds-act-row{gap:4px}
  table.data.ds-table .btn.ds-sample-del{width:32px;min-width:32px;height:32px}
  .ds-sample-tiers{font-size:.72rem}
}

/* ══════════════════════════════════════════════════════════════════════════
   NOTA PEMBELIAN → "PAJAK / BIAYA" = DROPDOWN 3 PILIHAN + SUFFIX STATIS
   ──────────────────────────────────────────────────────────────────────────
   Permintaan pemilik: isian Pajak/biaya (Rp & %) diganti dropdown
     · Harga termasuk PPN · Harga belum termasuk PPN · Tidak Kena Pajak
   dan DI SAMPINGNYA (menempel) tampil dua chip statis yang TIDAK bisa diedit:
   tarif PPN dari Pengaturan → Harga & Pajak ([11%]) dan nominal PPN hasil
   hitung baris ([Rp 30.660]).
   Markup: .ppn-pick > select[data-ppn-mode] + .ppn-suffix > .ppn-chip × 2
   ══════════════════════════════════════════════════════════════════════════ */
/* Dropdown + suffix dalam SATU baris; bila ruang tidak cukup (kolom sempit /
   HP) chip pindah ke baris kedua — dropdown TIDAK pernah dipersempit sampai
   tidak terbaca (dulu sempat 60px di 768px). */
.ppn-pick{
  display:flex;align-items:stretch;flex-wrap:wrap;gap:8px;min-width:0;
}
.ppn-pick > select,
.ppn-pick > .cs-btn{
  flex:1 1 200px;min-width:0;width:auto;
}
/* Suffix MENEMPEL pada dropdown: dua chip sejajar, tidak bisa difokus/diedit. */
.ppn-suffix{
  display:inline-flex;align-items:stretch;gap:6px;flex:0 0 auto;
  pointer-events:none;user-select:none;min-width:0;
}
.ppn-chip{
  display:inline-flex;align-items:center;justify-content:center;
  min-height:42px;padding:0 12px;border-radius:10px;
  border:1px solid var(--line-strong);background:var(--tint-3);
  font-size:.86rem;font-weight:700;color:var(--ink-strong);
  font-variant-numeric:tabular-nums;white-space:nowrap;
}
/* Nominal: latar aksen lembut supaya jelas ini ANGKA HASIL HITUNG (bukan isian). */
.ppn-chip-rp{
  background:var(--ok-bg);border-color:var(--ok-bd);color:var(--ok-fg);
  min-width:96px;
}
/* "Tidak Kena Pajak" → chip diredupkan (PPN memang 0). */
.ppn-suffix.is-off{opacity:.55}
.ppn-warn{
  display:block;margin-top:6px;font-size:.78rem;font-weight:600;color:var(--err-fg);
}
.ppn-warn a{color:inherit;text-decoration:underline;text-underline-offset:3px}
/* Keterangan mode pada ringkasan nilai (mis. "PPN · termasuk harga"). */
.nota-sum .ns-mode{
  font-size:.72rem;font-weight:600;color:var(--ink-2);text-transform:none;
}
@media (max-width:720px){
  /* HP: dropdown tetap satu baris dengan kedua chip; chip sedikit dirampingkan
     agar tidak ada kontrol yang terpotong. */
  .ppn-pick{gap:6px}
  .ppn-chip{min-height:44px;padding:0 9px;font-size:.8rem}
  .ppn-chip-rp{min-width:82px}
}
@media (max-width:400px){
  /* Layar sangat sempit: kedua chip berbagi satu baris penuh di bawah dropdown. */
  .ppn-suffix{width:100%}
  .ppn-chip{flex:1 1 0;min-height:38px}
}

/* ══════════════════════════════════════════════════════════════════════════
   KARTU [Ubah Draft Nota] — SUSUNAN KOLOM DOKUMEN (permintaan pemilik)
   ──────────────────────────────────────────────────────────────────────────
   Empat baris dengan jumlah kolom yang DIMINTA:
     1) 5 kolom : Nomor Nota · Surat Pesanan (PO) · Nomor Faktur ·
                  Tanggal Faktur · Supplier
     2) 3 kolom : Cara Pembayaran · Tanggal Nota · Jatuh Tempo
     3) 3 kolom : Diskon Nota · Pajak / biaya · Cashback supplier
     4) 1 kolom : Catatan nota  → selebar kartu
   Memakai grid per baris (bukan `.field-grid` auto-fit) karena auto-fit
   membagi rata sehingga susunan 5/3/3/1 tidak pernah tercapai. Jumlah kolom
   diturunkan bertahap di layar sempit agar tidak ada kontrol terjepit.
   ══════════════════════════════════════════════════════════════════════════ */
.nota-fields{display:flex;flex-direction:column;gap:16px;min-width:0}
.nota-fields .nf-row{display:grid;gap:16px;align-items:start;min-width:0}
.nota-fields .nf-row-5{grid-template-columns:repeat(5,minmax(0,1fr))}
.nota-fields .nf-row-3{grid-template-columns:repeat(3,minmax(0,1fr))}
.nota-fields .nf-row-1{grid-template-columns:minmax(0,1fr)}
.nota-fields .field{min-width:0}
/* Isian tanggal/angka dalam baris 5 kolom butuh ruang minimum agar tidak
   memotong teksnya sendiri (mis. "31/12/2026" + ikon kalender). */
.nota-fields .nf-row-5 > .field{min-width:0}
/* Baris CATATAN: satu kartu penuh — isian mengikuti seluruh lebar kartu. */
.nota-fields .nf-row-1 > .field > input{width:100%}
/* Label kolom di dalam satu baris WAJIB setinggi sama supaya ISIAN-nya sejajar
   (label panjang bisa membungkus 2 baris sementara yang lain 1 baris). */
.nota-fields .nf-row > .field > span:first-child{
  display:flex;align-items:flex-end;min-height:2.4em;line-height:1.2;
}
@media (max-width:1200px){
  /* Cukup lebar untuk 3 kolom; baris 5 kolom melipat menjadi 3 + 2. */
  .nota-fields .nf-row-5{grid-template-columns:repeat(3,minmax(0,1fr))}
}
@media (max-width:900px){
  .nota-fields .nf-row-5,
  .nota-fields .nf-row-3{grid-template-columns:repeat(2,minmax(0,1fr))}
  .nota-fields{gap:14px}
  .nota-fields .nf-row{gap:14px}
}
@media (max-width:640px){
  .nota-fields .nf-row-5,
  .nota-fields .nf-row-3,
  .nota-fields .nf-row-1{grid-template-columns:minmax(0,1fr)}
}

/* ══════════════════════════════════════════════════════════════════════════
   DETAIL STOK PRODUK (Stok & Batch → tab Data Stok → [Detail]) — DIPADATKAN
   ──────────────────────────────────────────────────────────────────────────
   Permintaan pemilik: kartu identitas `.dsd-card` beserta seluruh huruf di
   dalamnya (ikon, nama produk, chip jenjang, angka onhand) DIPERKECIL supaya
   tidak memakan banyak baris di dalam kartu. Susunannya tetap sama — hanya
   skala & jaraknya yang dirampingkan; informasi tidak ada yang dihilangkan.
   Diletakkan DI AKHIR berkas agar menang atas blok `.dsd-*` di atasnya
   (spesifisitas sama → yang belakangan berlaku).
   ══════════════════════════════════════════════════════════════════════════ */
.dsd-card{padding:10px 12px;border-radius:12px;margin:0 0 12px}
.dsd-hero{grid-template-columns:auto minmax(0,1fr) auto;gap:12px;align-items:center}
.dsd-icon{width:44px;height:44px;border-radius:12px}
.dsd-icon svg{width:22px;height:22px}
.dsd-label{font-size:.66rem;font-weight:650;margin-bottom:0;line-height:1.2}
.dsd-name{margin:0 0 6px;font-size:.96rem;line-height:1.2}
/* Jenjang satuan dibuat SATU BARIS per jenjang ("Satuan Besar (Box) 1 Box = 10 Strip")
   — dulu label/chip/konversi bertumpuk 3 baris sehingga kartu memakan ruang.
   ⚠️ PERATAAN (perbaikan UI/UX): `align-items:baseline` membuat posisi label
   BERUBAH 3px antar jenjang — jenjang yang punya teks konversi ("1 Box = 10
   Strip") menurunkan label, sedangkan jenjang terakhir (tanpa konversi) tidak
   (terukur label y=247 vs y=244). Sekarang isi jenjang dipusatkan
   (`align-items:center`) dan SEMUA jenjang diberi tinggi minimum yang sama
   (`align-items:stretch` pada wadah) sehingga label, chip, dan konversi selalu
   sebaris rata untuk berapa pun panjang teksnya. */
.dsd-tiers{gap:4px 18px;align-items:stretch}
.dsd-tier{
  flex-direction:row;align-items:center;gap:5px;flex-wrap:wrap;
  min-height:22px;
}
.dsd-tier > .dsd-label{margin:0;line-height:1.2}   /* label jenjang selalu di tengah baris */
.dsd-tier > .dsd-chip{align-self:center}
.dsd-chip{padding:1px 7px;border-radius:5px;font-size:.72rem;line-height:1.25}
.dsd-conv{font-size:.7rem;line-height:1.3;align-self:center}
.dsd-onhand{gap:2px;padding-left:12px}
.dsd-onhand-val{font-size:.94rem;line-height:1.2}
.dsd-onhand-line{font-size:.72rem;padding-left:11px}
.dsd-onhand-line::before{width:4px;height:4px;top:.55em}
.dsd-sub{margin:0 0 8px;font-size:.92rem}
/* Chip "CONTOH" ikut mengecil agar tidak mendorong judul. */
.dsd-name .ds-sample-chip{font-size:.62rem;padding:1px 6px}
@media (max-width:1100px){
  .dsd-hero{grid-template-columns:auto minmax(0,1fr);gap:10px}
  .dsd-onhand{padding-top:8px}
  .dsd-icon{width:40px;height:40px;border-radius:11px}
  .dsd-icon svg{width:20px;height:20px}
  .dsd-name{font-size:.94rem}
  .dsd-tiers{gap:4px 14px}
}
@media (max-width:720px){
  .dsd-card{padding:9px 10px}
  .dsd-icon{width:36px;height:36px;border-radius:10px}
  .dsd-icon svg{width:18px;height:18px}
  .dsd-name{font-size:.92rem;margin-bottom:4px}
  .dsd-tiers{gap:3px 12px}
  .dsd-onhand-val{font-size:.9rem}
}

/* ══════════════════════════════════════════════════════════════════════════
   ANALISIS PENGADAAN (Pengadaan → Analisis)
   ──────────────────────────────────────────────────────────────────────────
   Halaman analisis pembelian: baris KPI berikon, lima tab, grafik tren
   (garis + area), donut proporsi kategori, dan tabel peringkat.

   Catatan teknis:
   · Grafik digambar sebagai SVG oleh `includes/charts.php`. SEMUA TEKS
     (sumbu Y, sumbu X, tooltip, pusat donut) adalah elemen HTML di sekitar
     SVG supaya ukurannya mengikuti tipografi aplikasi (SVG akan menyusutkan
     teksnya di layar HP).
   · Warna grafik memakai token `--pa-*` di bawah agar tetap kontras pada
     tema gelap & terang.
   ══════════════════════════════════════════════════════════════════════════ */
:root{
  /* Tema GELAP: warna harus lebih TERANG dari latar kartu agar cincin donut &
     garis grafik terbaca (hijau tua #0B6A5C nyaris hilang di atas panel gelap). */
  --pa-line:#2DD4A7;
  --pa-1:#34D399;
  --pa-2:#0E9F6E;
  --pa-3:#A7F3D0;
  --pa-4:#FBBF24;
  --pa-5:#94A3B8;
  --pa-ico-bg:rgba(45,212,167,.14);
  --pa-ico-fg:#2DD4A7;
  --pa-tip-bg:#0B6A5C;
  --pa-tip-fg:#FFFFFF;
}
html:not([data-theme]),
html[data-theme="light"]{
  --pa-line:#0E7C6B;
  --pa-1:#0B6A5C;
  --pa-2:#14957E;
  --pa-3:#4FCBA5;
  --pa-4:#E8A317;
  --pa-5:#9AA7B8;
  --pa-ico-bg:rgba(14,124,107,.12);
  --pa-ico-fg:#0B6A5C;
  --pa-tip-bg:#0B6A5C;
  --pa-tip-fg:#FFFFFF;
}

/* ── KPI berikon (opsional: `icon` pada kpi_cards()) ── */
.kpi-grid .kpi.has-ico{
  display:grid;grid-template-columns:44px minmax(0,1fr);column-gap:13px;row-gap:3px;
  grid-template-areas:"ico label" "ico value" "ico foot";align-items:start;
}
.kpi.has-ico .kpi-ico{
  grid-area:ico;align-self:center;width:44px;height:44px;border-radius:13px;
  display:flex;align-items:center;justify-content:center;
  background:var(--pa-ico-bg);border:1px solid var(--line);color:var(--pa-ico-fg);
}
.kpi.has-ico .kpi-ico svg{width:22px;height:22px;fill:currentColor}
.kpi.has-ico .kpi-label{grid-area:label}
.kpi.has-ico .kpi-value{grid-area:value}
.kpi.has-ico .kpi-foot{grid-area:foot;min-width:0;white-space:normal;overflow-wrap:anywhere}
/* Keterangan KPI (chip pertumbuhan + teks) WAJIB boleh membungkus: pada kartu
   sempit isinya lebih lebar dari kartu sehingga menambah 3px gulir halaman. */
.kpi.has-ico .kpi-foot .an-chg-vs,
.kpi.has-ico .kpi-foot .an-chg{white-space:normal;overflow-wrap:anywhere}

/* ── chip pertumbuhan pada KPI ── */
.an-chg{display:inline-block;font-size:.7rem;font-weight:700;padding:1px 7px;border-radius:20px;
  border:1px solid transparent;line-height:1.35;white-space:nowrap}
.an-chg.is-up{color:var(--ok-fg);background:var(--ok-bg);border-color:var(--ok-bd)}
.an-chg.is-down{color:var(--err-fg);background:var(--err-bg);border-color:var(--err-bd)}
.an-chg.is-flat{color:var(--ink-2);background:var(--tint);border-color:var(--line)}
.an-chg-vs{font-size:.7rem;color:var(--ink-2);margin-left:6px}

/* ── tab berikon ── */
.an-tabs{gap:6px;margin:2px 0 0}
.an-tabs .tab{display:inline-flex;align-items:center;gap:8px}
.an-tabs .tab svg{width:17px;height:17px;fill:currentColor;opacity:.75;flex:0 0 auto}
.an-tabs .tab.is-active svg{opacity:1}

/* ── kerangka kartu grafik ── */
.an-charts{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(430px,100%),1fr));gap:20px;margin-bottom:20px}
.an-tables{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(430px,100%),1fr));gap:20px}
.an-card{min-width:0;display:flex;flex-direction:column}
.an-charts > .lab-card, .an-tables > .lab-card{min-width:0}

/* ── GRAFIK GARIS + AREA ──
   Label sumbu Y adalah elemen HTML ABSOLUT di dalam `.an-canvas` (bukan kolom
   grid terpisah): dengan begitu posisinya selalu ikut tinggi kanvas sehingga
   tepat sejajar dengan garis bantunya di semua lebar layar. Ruang label kiri
   dibuat lewat `padding-left` pada `.an-chart`. */
.an-chart{position:relative;margin-top:4px}
.an-chart.has-y{padding-left:56px}
.an-canvas{position:relative;aspect-ratio:720/240;min-width:0}
.an-canvas svg{display:block;width:100%;height:100%;overflow:visible}
.an-ytick{position:absolute;right:calc(100% + 8px);transform:translateY(-50%);
  font-size:.66rem;color:var(--ink-2);white-space:nowrap;font-variant-numeric:tabular-nums;
  line-height:1;pointer-events:none}
.an-xaxis{display:flex;gap:2px;font-size:.66rem;color:var(--ink-2);padding-left:2px;margin-top:6px}
.an-xaxis span{flex:1 1 0;min-width:0;text-align:center;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.an-xaxis span.is-blank{color:transparent}
.an-grid-line{stroke:var(--line-strong);stroke-width:1;stroke-dasharray:3 4;opacity:.7}
.an-line{fill:none;stroke:var(--pa-line);stroke-width:2.6;stroke-linejoin:round;stroke-linecap:round}
.an-dot{fill:var(--pa-line);stroke:var(--panel);stroke-width:2.5}
.an-dot.is-last{stroke-width:3.5}
.an-tip{position:absolute;transform:translate(-50%,-125%);background:var(--pa-tip-bg);color:var(--pa-tip-fg);
  border-radius:10px;padding:5px 10px;line-height:1.3;white-space:nowrap;pointer-events:none;
  box-shadow:0 10px 22px -14px rgba(0,0,0,.75);border:1px solid rgba(255,255,255,.16)}
.an-tip span{display:block;font-size:.63rem;opacity:.9;letter-spacing:.02em}
.an-tip strong{font-size:.85rem;font-family:var(--mono);font-variant-numeric:tabular-nums}

/* ── DONUT + LEGENDA ── */
.an-donut-wrap{display:grid;grid-template-columns:minmax(150px,210px) minmax(0,1fr);
  gap:20px;align-items:center;margin-top:4px}
.an-donut{position:relative;width:100%;max-width:210px;aspect-ratio:1/1;margin-inline:auto}
.an-donut svg{display:block;width:100%;height:100%}
.an-ring{fill:none;stroke-width:26;stroke-linecap:butt}
.an-ring-bg{fill:none;stroke:var(--tint);stroke-width:26}
.an-donut-center{position:absolute;inset:0;display:flex;flex-direction:column;
  align-items:center;justify-content:center;text-align:center;gap:1px;pointer-events:none}
.an-donut-center strong{font-size:1.02rem;font-family:var(--mono);font-variant-numeric:tabular-nums;line-height:1.15}
.an-donut-center span{font-size:.66rem;color:var(--ink-2)}
.an-legend{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:9px}
.an-legend li{display:grid;grid-template-columns:11px minmax(0,1fr) 50px 104px;
  gap:10px;align-items:center;font-size:.8rem}
.an-dot-c{width:11px;height:11px;border-radius:4px;display:inline-block}
.an-legend-name{color:var(--ink-2);font-weight:600;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.an-legend-pct{text-align:right;color:var(--ink-2);font-variant-numeric:tabular-nums}
.an-legend-val{text-align:right;font-weight:700;font-variant-numeric:tabular-nums}
.an-seg-1{stroke:var(--pa-1);background:var(--pa-1)}
.an-seg-2{stroke:var(--pa-2);background:var(--pa-2)}
.an-seg-3{stroke:var(--pa-3);background:var(--pa-3)}
.an-seg-4{stroke:var(--pa-4);background:var(--pa-4)}
.an-seg-5{stroke:var(--pa-5);background:var(--pa-5)}

/* ── tabel: kolom nomor urut ringkas ── */
table.data .col-no{width:44px;text-align:center;white-space:nowrap}
.an-tables .card-head, .an-charts .card-head{gap:10px;flex-wrap:wrap}

/* ── responsif ── */
@media (max-width:900px){
  .an-donut-wrap{grid-template-columns:minmax(0,1fr);justify-items:center;gap:16px}
  .an-legend{width:100%}
  .an-chart.has-y{padding-left:46px}
  .an-ytick{font-size:.6rem}
}
@media (max-width:640px){
  .an-tabs{gap:4px}
  .an-tabs .tab{gap:6px}
  .an-tabs .tab svg{width:15px;height:15px}
  .an-legend li{grid-template-columns:11px minmax(0,1fr) 44px auto;gap:7px;font-size:.76rem}
  .kpi-grid .kpi.has-ico{grid-template-columns:38px minmax(0,1fr);column-gap:11px}
  .kpi.has-ico .kpi-ico{width:38px;height:38px;border-radius:11px}
  .kpi.has-ico .kpi-ico svg{width:19px;height:19px}
  .an-canvas{aspect-ratio:720/300}
}

/* ══════════════════════════════════════════════════════════════════════════
   MASTER HARGA (Data Master → Master Harga)
   ──────────────────────────────────────────────────────────────────────────
   Permintaan pemilik: tampilan utama = TABEL DAFTAR PRODUK dengan UI/UX yang
   SAMA PERSIS dengan tabel "Data Stok" (memakai kelas `.ds-*` yang sama), lalu
   tombol [Detail] membuka kartu **Set Harga**.

   Blok ini HANYA menambah:
     · `.ds-money`  → kolom nominal HPP/HJO pada tabel daftar (rata kanan, mono);
     · `.px2-*`     → isi kartu Set Harga (informasi HNA/HPP + tabel 5 tingkatan
                      harga × metode Rp/% × 3 jenjang satuan).
   Warna memakai token aplikasi (`--brand`, `--ok-bg`, `--line`, …) supaya ikut
   tema gelap & terang.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── kolom nominal pada tabel daftar (HPP · HJO) ── */
table.data.ds-table th.ds-money,
table.data.ds-table td.ds-money{
  width:150px;text-align:right;white-space:nowrap;
  font-family:var(--mono);font-variant-numeric:tabular-nums;
}
table.data.ds-table th.ds-money{text-align:right}
table.data.ds-table td.ds-money{font-weight:700;color:var(--ink-strong)}
/* ── kolom MARGIN pada tabel daftar ──────────────────────────────────────
   Permintaan pemilik: nominal Rupiah di ATAS, persentase margin di BAWAHNYA
   (dua baris dalam satu kolom). Warna mengikuti tanda marginnya. */
table.data.ds-table th.ds-margin,
table.data.ds-table td.ds-margin{
  width:140px;text-align:right;white-space:nowrap;
  font-family:var(--mono);font-variant-numeric:tabular-nums;
}
table.data.ds-table th.ds-margin{text-align:right}
table.data.ds-table td.ds-margin .dm-rp{
  display:block;font-size:.86rem;font-weight:750;line-height:1.25;color:var(--ok-fg);
}
table.data.ds-table td.ds-margin .dm-pct{
  display:block;margin-top:1px;font-size:.74rem;font-weight:700;line-height:1.2;color:var(--ok-fg);
}
table.data.ds-table td.ds-margin .is-neg{color:var(--err-fg)}
table.data.ds-table td.ds-margin .dm-rp:not(.is-neg){color:var(--ink-strong)}
/* kolom status pada kartu filter (tiga kontrol: cari · urutkan · status) */
.ds-filter .ds-f-status{flex:0 1 230px;min-width:180px}
@media (max-width:640px){
  table.data.ds-table th.ds-money,
  table.data.ds-table td.ds-money{width:auto;font-size:.82rem;padding-left:8px;padding-right:8px}
  .ds-filter .ds-f-status{flex:1 1 100%;min-width:0}
}
/* LAYAR SANGAT SEMPIT (≤480px): tabel 6 kolom (PLU disembunyikan) harus MUAT
   tanpa digeser. "Rp" disembunyikan (angkanya tetap), huruf & padding
   dirapatkan, tombol aksi jadi ikon 40px. */
@media (max-width:480px){
  .ds-table-card table.data.ds-table thead th{padding:10px 6px;font-size:.72rem}
  .ds-table-card table.data.ds-table td{padding:10px 6px}
  table.data.ds-table td.ds-name{font-size:.82rem;overflow-wrap:anywhere}
  table.data.ds-table .ds-cur{display:none}
  table.data.ds-table th.ds-money,table.data.ds-table td.ds-money{
    width:1%;font-size:.74rem;padding-left:4px;padding-right:4px;
  }
  table.data.ds-table th.ds-margin,table.data.ds-table td.ds-margin{
    width:1%;padding-left:4px;padding-right:4px;
  }
  table.data.ds-table td.ds-margin .dm-rp{font-size:.74rem}
  table.data.ds-table td.ds-margin .dm-pct{font-size:.64rem}
  table.data.ds-table th.ds-act,table.data.ds-table td.ds-act{
    width:38px;padding-left:2px;padding-right:2px;
  }
  .ds-table-card .btn.ds-detail{padding:6px;border-radius:8px}
}

@media (max-width:390px){
  /* ≤390px: enam kolom hanya muat bila huruf & padding dirapatkan lagi —
     nominal bisa 7 digit ("1.817.625") sehingga kolom angka ikut menyusut. */
  .ds-table-card table.data.ds-table thead th{padding:9px 4px;font-size:.68rem}
  .ds-table-card table.data.ds-table td{padding:9px 4px}
  table.data.ds-table td.ds-name{font-size:.78rem}
  table.data.ds-table th.ds-money,table.data.ds-table td.ds-money{font-size:.7rem;padding-left:2px;padding-right:2px}
  table.data.ds-table th.ds-margin,table.data.ds-table td.ds-margin{padding-left:2px;padding-right:2px}
  table.data.ds-table td.ds-margin .dm-rp{font-size:.7rem}
  table.data.ds-table td.ds-margin .dm-pct{font-size:.62rem}
  table.data.ds-table th.ds-act,table.data.ds-table td.ds-act{width:36px;padding-left:1px;padding-right:1px}
  table.data.ds-table td.ds-act .act-row,
  table.data.ds-table td.ds-act .ds-act-row{gap:0;min-width:0;width:auto}
  table.data.ds-table td.ds-act .btn,
  .ds-table-card .btn.ds-detail{
    width:34px!important;min-width:34px!important;height:34px;padding:0!important;
  }
}

/* ≤340px (HP terkecil): sisa 3px dirapatkan lagi supaya tabel tetap utuh. */
@media (max-width:340px){
  .ds-table-card table.data.ds-table thead th{padding:8px 3px;font-size:.66rem}
  .ds-table-card table.data.ds-table td{padding:8px 3px}
  table.data.ds-table td.ds-name{font-size:.74rem}
  table.data.ds-table td.ds-act,
  table.data.ds-table th.ds-act{padding-left:0;padding-right:0}
}

/* ── KARTU SET HARGA ─────────────────────────────────────────────────────── */
/* ⚠️ `.sheet-body` adalah flex-col; wadah tabel riwayat WAJIB `flex:0 0 auto`
   supaya tidak ikut menyusut (dulu `overflow:auto` + tinggi menyusut membuat
   15 baris riwayat terpotong dengan gulir internal setinggi ±900px). */
.sheet-body .dsd-table-wrap{flex:0 0 auto}
.sheet-body > .dsd-sub{flex:0 0 auto}

.px2-tier-head{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap;margin:4px 0 10px}
.px2-tier-head h3{margin:0;font-size:.98rem;font-weight:750;color:var(--head-ink)}

/* TABEL TINGKATAN HARGA JUAL: nama tingkatan + 3 jenjang satuan.
   Setiap sel jenjang memuat DUA kolom isian sejajar — [Rp] dan [%] — yang
   saling menghitung (lihat assets/klinik.js). "Rp" adalah prefix statis di
   dalam kolom (`.money-prefix`, dibuat wrapMoney()) dan "%" suffix statis
   (`.pct-suffix`), jadi keduanya tetap terlihat walau kolomnya sudah berisi. */
table.data.px2-table{min-width:0;width:100%;table-layout:fixed}
/* Kolom nama tingkatan 26%, sisanya dibagi tiga jenjang satuan. */
table.data.px2-table th.px2-c-name{width:26%}
table.data.px2-table thead th{
  background:var(--ds-head-bg);color:var(--ds-head-fg);
  font-size:.74rem;font-weight:750;letter-spacing:.02em;text-transform:none;
  padding:10px 12px;white-space:nowrap;vertical-align:bottom;
}
table.data.px2-table thead th small{display:block;font-size:.68rem;font-weight:600;opacity:.85}
table.data.px2-table td{padding:9px 12px;vertical-align:middle}
table.data.px2-table th.px2-tname,table.data.px2-table td.px2-tname{
  text-align:left;white-space:normal;width:30%;
  font-size:.82rem;color:var(--ink-strong);
}
/* ⚠️ Jarak kiri sel judul tingkatan WAJIB sama dengan jarak kanan kolom isian
   (12px). Tanpa aturan ini `th[scope]` (baris tubuh) hanya mendapat padding
   bawaan browser ±1px sehingga teks "Harga Utama" menempel di tepi kiri tabel
   sementara sisi kanan menjorok 12px — terlihat tidak seimbang. */
table.data.px2-table tbody th.px2-tname{padding:9px 12px}
table.data.px2-table th.px2-tname{background:transparent;font-weight:750}
table.data.px2-table th.px2-tname small{display:block;font-size:.7rem;font-weight:600;color:var(--ink-2);margin-top:1px}
table.data.px2-table tbody tr:nth-child(odd){background:var(--tint-3)}
table.data.px2-table tbody tr[data-tier="main"]{background:var(--ok-bg)}
table.data.px2-table tfoot td{background:transparent;border-top:1px solid var(--line-strong);padding:10px 12px}
.px2-foot{font-size:.78rem;color:var(--ink-2)}

/* Pasangan isian Rp + % (dua kolom, sejajar). */
.px2-pair{
  display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);
  gap:6px;align-items:center;min-width:0;
}
.px2-pair.is-rp-only{grid-template-columns:minmax(0,1fr)}
.px2-pair > .money-wrap,
.px2-pair > .pct-field{width:100%;min-width:0}
.px2-pair input{
  width:100%;height:36px;text-align:right;font-variant-numeric:tabular-nums;
  font-size:.82rem;
}
.px2-pair .money-wrap > input[data-money]{padding-left:26px!important}
.px2-pair .money-prefix{left:7px;font-size:.7em;font-weight:700}
.px2-pair .pct-field > input{padding-right:19px!important}
.px2-pair .pct-suffix{right:6px;font-size:.68em;font-weight:700}
/* ── WARNA ISIAN KOLOM [%] ────────────────────────────────────────────────
   ⚠️ BUG NYATA yang diperbaiki: warna sebelumnya memakai `--brand-accent`, yang
   di TEMA TERANG bernilai `#e2f7f0` (hampir putih) — jadi angka persen tidak
   terbaca di atas kolom putih (terukur kontras ≈1,05:1). Kolom % kini memakai
   token KHUSUS yang gelap/terang berlawanan dengan latarnya, ditambah latar &
   garis aksen lembut supaya jelas beda peran dengan kolom Rp:
     · gelap : teks mint terang  di latar gelap transparan  (≈11:1)
     · terang: teks hijau tua    di latar hijau sangat muda  (≈7,4:1)
   Jangan dikembalikan ke `--brand-accent`. */
:root,html[data-theme="dark"]{
  --pct-ink:#5EEAD4; --pct-bg:rgba(45,212,167,.10); --pct-bd:rgba(45,212,167,.40);
}
html[data-theme="light"]{
  --pct-ink:#0A5A4C; --pct-bg:rgba(14,124,107,.07); --pct-bd:rgba(14,124,107,.30);
}
.px2-pair [data-tier-pct]{
  color:var(--pct-ink);font-weight:750;
  background:var(--pct-bg);border-color:var(--pct-bd);
}
.px2-pair [data-tier-pct]:focus,
.px2-pair [data-tier-pct]:focus-visible{background:var(--pct-bg);border-color:var(--pct-ink)}
.px2-pair [data-tier-pct]:disabled{opacity:.55}
.px2-pair .pct-suffix{color:var(--pct-ink);opacity:.85}

/* ── HPP DI KANAN KARTU NAMA PRODUK ───────────────────────────────────────
   Permintaan pemilik: blok HPP dipindahkan dari KIRI ke KANAN kartu nama produk
   sehingga susunannya SERUPA kartu "Detail Stok Produk" (Data Stok):
     ikon │ nama produk + jenjang satuan │ HPP
   Blok HPP memakai gaya `.dsd-onhand` (garis pemisah di kiri) seperti blok
   "Stok Onhand Saat Ini" pada kartu Data Stok. Karena HPP sekarang berada di
   kolom TERAKHIR, `grid-template-columns` kembali ke susunan dasar
   `auto minmax(0,1fr) auto` — kolom tengah (nama produk) tetap paling lebar. */
.dsd-hero.dsd-hero-hpp{grid-template-columns:auto minmax(0,1fr) auto;align-items:start}
.dsd-hpp{
  padding-left:16px;padding-right:0;min-width:0;
  border-left:1px solid var(--line-strong);border-right:0;
}
/* ⚠️ PERATAAN: `align-items:center` (bawaan `.dsd-hero` versi padat) membuat
   SETIAP kolom mengambang di ketinggian berbeda — terukur label HPP y=133,
   ikon y=159, judul produk y=165, chip y=191 sehingga tulisan nama produk
   tampak "naik/turun" dibanding kolom lain. Dengan `start` ketiga kolom mulai
   pada garis yang SAMA, dan label HPP ↔ label "Nama Produk" serta nilai HPP ↔
   judul produk menjadi sejajar (diuji ≤2px). */
.dsd-hpp .dsd-label,
.dsd-hero-hpp .dsd-hero-main > .dsd-label{line-height:1.25;margin:0 0 2px}
.dsd-hpp .dsd-onhand-val{font-size:1rem;line-height:1.25}
.dsd-hero-hpp .dsd-hero-main > .dsd-label + .dsd-name{margin-top:0}
.dsd-hpp-unit{font-size:.7rem;font-weight:600;color:var(--ink-2);margin-top:-1px}
.dsd-hpp .dsd-onhand-line{font-size:.72rem}
.dsd-hpp .dsd-onhand-line strong{
  color:var(--ds-btn-fg);font-weight:750;font-variant-numeric:tabular-nums;
}
/* Nominal HPP yang disamarkan tetap terbaca sebagai penanda izin. */
.dsd-hpp .dsd-onhand-val.is-masked{letter-spacing:.06em;font-size:.86rem}

/* Ikon di tengah tinggi NAMA PRODUK (bukan di tengah seluruh blok HPP yang
   lebih tinggi) supaya sebaris dengan judul produk. */
@media (min-width:1101px){
  .dsd-hero-hpp .dsd-icon{align-self:center;margin-top:2px}
}

@media (max-width:1100px){
  /* Di layar sedang/kecil blok HPP turun menjadi baris penuh di BAWAH nama
     produk (bukan di kanan) supaya nama produk tetap lebar. */
  .dsd-hero.dsd-hero-hpp{grid-template-columns:auto minmax(0,1fr);align-items:center}
  .dsd-hpp{
    grid-column:1 / -1;min-width:0;
    padding:8px 0 0;border-left:0;border-top:1px solid var(--line-strong);
  }
  .dsd-hpp .dsd-onhand-val{font-size:.94rem}
}

@media (max-width:900px){
  table.data.px2-table thead th,table.data.px2-table td{padding:8px 9px}
  table.data.px2-table tbody th.px2-tname{padding:8px 9px}
  .px2-pair input{height:40px}
  /* Di HP tabel tingkatan disusun sebagai blok per tingkatan:
     nama tingkatan, lalu satu baris per jenjang ("Satuan Kecil  [Rp] [%]"). */
  table.data.px2-table[data-no-stack]{display:block}
  table.data.px2-table[data-no-stack] thead{display:none}
  table.data.px2-table[data-no-stack] tbody,
  table.data.px2-table[data-no-stack] tfoot{display:block}
  table.data.px2-table[data-no-stack] tbody tr{
    display:block;padding:10px 12px;margin:0 0 10px;
    border:1px solid var(--line);border-radius:var(--radius-sm);
  }
  table.data.px2-table[data-no-stack] tbody tr:last-child{margin-bottom:0}
  table.data.px2-table[data-no-stack] th.px2-tname{
    display:block;width:auto;padding:0 0 8px;border:0;
  }
  table.data.px2-table[data-no-stack] td.px2-cell{
    display:grid;grid-template-columns:minmax(0,96px) minmax(0,1fr);
    gap:4px 10px;align-items:center;
    width:auto;padding:4px 0;border:0;border-bottom:1px dashed var(--row-border);
  }
  table.data.px2-table[data-no-stack] td.px2-cell:last-child{border-bottom:0}
  table.data.px2-table[data-no-stack] td.px2-cell::before{
    content:attr(data-label);font-size:.68rem;font-weight:700;letter-spacing:.04em;
    text-transform:uppercase;color:var(--ink-2);
  }
  table.data.px2-table[data-no-stack] tfoot tr{display:block}
  table.data.px2-table[data-no-stack] tfoot td{display:block;width:auto;border-top:1px solid var(--line-strong)}
}
@media (max-width:400px){
  .px2-pair{grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:5px}
  .px2-pair input{font-size:.8rem}
  .px2-pair .money-wrap > input[data-money]{padding-left:22px!important}
  .px2-pair .money-prefix{left:5px;font-size:.64em}
  .px2-pair .pct-field > input{padding-right:16px!important}
  .px2-pair .pct-suffix{right:4px;font-size:.62em}
}

/* ══════════════════════════════════════════════════════════════════════════
   PREFIX "Rp" & SUFFIX "%" — DIPERBESAR, PROPOSIONAL, TINGGI INPUT TETAP
   ──────────────────────────────────────────────────────────────────────────
   Permintaan pemilik: semua kolom nominal ber-prefix [Rp] (dan kolom persen
   bersuffix [%]) dibuat lebih besar, TETAPI proporsional (tidak sampai
   mengalahkan angkanya) dan TIDAK boleh mengubah tinggi kolom isian.

   Sebelumnya ukuran affix beragam 10,06–11,83 px sementara huruf angkanya
   14,1–15 px (rasio 0,71–0,79) — "Rp" tampak kecil & tidak konsisten antar
   modul. Sekarang dipakai DUA token:
     ·  --affix-rp   / --affix-pct        → konteks normal (kartu/form)
     ·  --affix-rp-d / --affix-pct-d      → konteks PADAT (sel tabel sempit)
   Rasio terhadap huruf angka ±0,88 (normal) dan ±0,8 (padat) — cukup tegas
   tanpa mendominasi angka.

   ⚠️ Affix berposisi `absolute`, jadi membesarkan hurufnya TIDAK menambah
   tinggi baris/kolom isian. Yang WAJIB ikut disesuaikan hanya `padding`
   kiri/kanan supaya angka tidak tertimpa — nilai padding di bawah sudah
   dihitung dari lebar "Rp"/"%" baru (diuji: nol tumpang-tindih).
   Blok ini diletakkan PALING AKHIR agar mengalahkan aturan per-komponen.
   ══════════════════════════════════════════════════════════════════════════ */
:root,html[data-theme="dark"],html[data-theme="light"]{
  --affix-rp:.78rem;     /* ≈13,4px  (huruf angka 14,1–16px → rasio .84–.95) */
  --affix-pct:.74rem;    /* ≈12,7px */
  --affix-rp-d:.70rem;   /* ≈12,0px  — sel tabel padat */
  --affix-pct-d:.66rem;  /* ≈11,4px */
}
.money-prefix{
  font-size:var(--affix-rp)!important;
  font-weight:750;line-height:1;letter-spacing:0;
}
.pct-suffix{
  font-size:var(--affix-pct)!important;
  font-weight:750;line-height:1;letter-spacing:0;
}
/* Ruang kiri/kanan dihitung ulang untuk affix yang lebih besar. */
.money-wrap>input[data-money]{padding-left:40px!important}
.pct-field>input{padding-right:24px!important}
.rp-pct-pair .money-wrap>input[data-money]{padding-left:31px!important}
.rp-pct-pair .pct-field>input{padding-right:23px!important}
.px2-pair .money-wrap>input[data-money]{padding-left:30px!important}
.px2-pair .pct-field>input{padding-right:22px!important}
.rp-pct-pair .money-prefix,.px2-pair .money-prefix{left:8px}
.rp-pct-pair .pct-suffix,.px2-pair .pct-suffix{right:7px}

/* Konteks PADAT (SEMUA sel tabel): satu tingkat lebih kecil dari konteks form,
   tetapi tetap lebih besar dari ukuran lama (10,1–11,8px → 12,0px).
   Padding di bawah sudah dihitung dari lebar affix baru → tidak ada tabrakan. */
table.data .money-prefix{font-size:var(--affix-rp-d)!important}
table.data .pct-suffix{font-size:var(--affix-pct-d)!important}
table.data.nota-lines .money-wrap>input[data-money],
table.data.nota-lines td.nl-price .money-wrap>input[data-money]{padding-left:27px!important}
table.data.nota-lines .rp-pct-pair .money-wrap>input[data-money]{padding-left:26px!important}
table.data.nota-lines .pct-field>input,
table.data.nota-lines .rp-pct-pair .pct-field>input{padding-right:20px!important}
table.data.apx-table td .money-wrap>input[data-money]{padding-left:30px!important}
table.data.act-table .money-wrap>input[data-money]{padding-left:28px!important}

/* PENGECUALIAN yang memang sudah dirancang lebih besar (kasir & kartu
   pembayaran): ukurannya dipertahankan sama dengan huruf angka di sebelahnya
   supaya tetap terbaca sebagai satu kesatuan. */
.apx-recv .money-wrap>.money-prefix{
  font-size:1rem!important;font-weight:900;font-family:inherit;letter-spacing:0;
}
.apx-recv .money-wrap>input[data-money]{padding-left:38px!important}
.pay-amount-field .money-prefix,
.pay-sheet .pay-amount-field .money-prefix{
  font-size:1.06rem!important;font-weight:850;letter-spacing:0;
}
.pay-amount-field .money-wrap>input[data-money],
.pay-sheet .pay-amount-field .money-wrap>input[data-money]{padding-left:44px!important}

/* Di layar sangat sempit affix boleh turun satu tingkat agar tidak menabrak
   angka saat kolom menyempit (padding ikut dirapatkan). */
@media (max-width:400px){
  /* Di layar sangat sempit huruf isian naik ke 16px (anti-zoom iOS), jadi token
     padat dinaikkan satu tingkat agar rasionya tetap wajar (≈0,77/0,73). */
  :root,html[data-theme="dark"],html[data-theme="light"]{
    --affix-rp-d:.72rem; --affix-pct-d:.68rem;
  }
  .px2-pair .money-prefix{left:6px}
  .px2-pair .pct-suffix{right:5px}
  .px2-pair .money-wrap>input[data-money]{padding-left:28px!important}
  .px2-pair .pct-field>input{padding-right:21px!important}
}

/* ══════════════════════════════════════════════════════════════════════════
   PEMBELIAN → [UBAH DRAFT NOTA] = KONTEN HALAMAN PENUH (bukan kartu mengambang)
   ──────────────────────────────────────────────────────────────────────────
   Permintaan pemilik: kartu mengambang "Ubah Draft/Koreksi Nota" dipindah
   menjadi konten halaman (pola menu Pemeriksaan Dokter). ISINYA TIDAK BERUBAH
   — field, tabel, perhitungan, dan validasi tetap; hanya wadahnya:
     · `.nota-page-head` → kartu kepala halaman (nomor nota · supplier ·
       tanggal · status stok) + tombol [Kembali] + pill status di kanan;
     · `.nota-page-card` → kartu isi formulir (`#form-nota`) dengan seluruh
       `.form-section` di dalamnya persis seperti pada kartu lama;
     · `.nota-page-foot` → kaki kartu berisi [Simpan Nota]/[Simpan Koreksi] dan
       [Batal] (tombol di luar formulir → tetap `form="form-nota"`).
   ⚠️ `.form-section` di dalam kartu halaman tidak lagi memakai
   `content-visibility:auto` milik `.sheet-body` — tidak diperlukan di halaman
   biasa dan bisa "mengira-kira" tinggi sehingga tabel terpotong.
   ══════════════════════════════════════════════════════════════════════════ */
/* Jarak ke kartu isi sudah diberikan oleh `gap` pada `.content` (24px) —
   jangan menambah margin bawah lagi (dulu 42px, terlalu renggang). */
.nota-page-head{margin:0}
.nota-page-head .card-head{margin-bottom:0}
.nota-page-head h2{margin:0 0 4px;font-size:1.12rem;line-height:1.25}
.nota-page-head .doc-meta{margin-top:0}
/* Peringatan KOREKSI: jarak lega dari kepala kartu, tidak menempel tepi kartu. */
.nota-page-head > .alert{margin:14px 0 0}
.nota-page-card{padding-bottom:0}
/* Isi formulir memakai jarak antar-bagian yang SAMA dengan kartu lama. */
.nota-page-card .form-section{content-visibility:visible;contain:none}
.nota-page-card .form-section + .form-section{margin-top:18px}
/* Kaki kartu: aksi penyimpanan selalu di dasar kartu isi. */
.nota-page-card .nota-page-foot{
  margin-top:20px;padding:14px 0 16px;
  border-top:1px solid var(--line-strong);
  align-items:center;
}
.nota-page-card .nota-page-foot .row-actions{
  display:inline-flex;align-items:center;gap:10px;flex-wrap:wrap;
}
.nota-page-card .nota-page-foot .btn{min-height:42px}
.nota-page-card .nota-page-foot .btn-primary{min-height:46px;padding:0 22px}
@media (max-width:900px){
  .nota-page-head{margin-bottom:0}
  .nota-page-head h2{font-size:1.02rem}
  .nota-page-card .nota-page-foot{
    flex-direction:column;align-items:stretch;gap:10px;
    /* Ruang untuk navigasi bawah HP supaya tombol Simpan tidak tertutup. */
    padding-bottom:calc(16px + env(safe-area-inset-bottom,0px));
  }
  .nota-page-card .nota-page-foot .row-actions{width:100%;flex-direction:column;align-items:stretch}
  .nota-page-card .nota-page-foot .row-actions .btn{width:100%}
  /* Urutan HP: tombol Simpan lebih dulu (paling penting), Batal di bawahnya. */
  .nota-page-card .nota-page-foot .row-actions .btn-primary{order:-1}
}

/* ── HALAMAN NOTA (Ubah Draft / Koreksi) — GUTTER LEBIH TIPIS ───────────────
   Tabel "Produk yang dipesan" punya 8 kolom isian; sebagai konten halaman ia
   kehilangan lebar yang dulu dipakai kartu mengambang (kartu menutup seluruh
   layar, halaman dikurangi menu samping). Supaya tabel TIDAK perlu digeser di
   ≥1280px, halaman ini memakai gutter & padding kartu yang lebih tipis.
   Hanya berlaku ≥901px (di HP tabel sudah menjadi kartu bertingkat). */
@media (min-width:901px){
  body.nota-page .content{padding-left:clamp(10px,1.2vw,18px);padding-right:clamp(10px,1.2vw,18px)}
  body.nota-page .nota-page-card{padding-left:16px;padding-right:16px}
}

/* ══════════════════════════════════════════════════════════════════════════
   TABEL "PRODUK YANG DIPESAN" PADA HALAMAN NOTA: KARTU BERTINGKAT DI ≤1279px
   ──────────────────────────────────────────────────────────────────────────
   Tabel ini punya 8 kolom ISIAN (jumlah · satuan · harga · diskon Rp/% · HNA ·
   HPP · subtotal) yang butuh ±935px. Sebagai konten halaman, lebar area isi
   = lebar layar − menu samping − padding, sehingga di bawah 1280px tabel TIDAK
   akan pernah muat dan harus digeser ke samping — padahal pemilik meminta
   tabel tidak perlu digeser.
   Solusinya memakai MEKANISME YANG SUDAH ADA: susunan **kartu bertingkat**
   (sama seperti tampilan HP ≤900px) diperluas untuk tabel ini sampai 1279px.
   Setiap sel tetap diberi label kolomnya (`data-label` dipasang `assets/app.js`),
   semua field tetap sama, dan ≥1280px tabel kembali seperti semula.
   ⚠️ `min-width:0!important` wajib: `notaFit()` menulis `min-width` px pada tabel.
   ══════════════════════════════════════════════════════════════════════════ */
@media (min-width:901px) and (max-width:1279px){
  table.data.nota-lines[data-stack]{
    display:block;width:100%;min-width:0!important;
    border-collapse:separate;border-spacing:0;font-size:.84rem;
  }
  table.data.nota-lines[data-stack] thead{display:none}
  table.data.nota-lines[data-stack] tbody,
  table.data.nota-lines[data-stack] tfoot{display:block;width:auto}
  /* Baris = grid DUA kolom supaya kartu tidak terlalu tinggi: sel produk
     (`.nl-item`) selebar baris, lalu pasangan sel berikutnya berdampingan
     (Jumlah | Satuan · Harga | Diskon · HNA | HPP · Subtotal). */
  table.data.nota-lines[data-stack] tbody tr{
    display:grid;grid-template-columns:repeat(2,minmax(0,1fr));column-gap:22px;
    width:auto;margin:0 0 10px;padding:11px 12px;
    border:1px solid var(--line);border-radius:var(--radius-sm);background:var(--tint-3);
  }
  table.data.nota-lines[data-stack] tbody td.nl-item{grid-column:1 / -1}
  /* Diskon berisi DUA isian (Rp + %) — diberi satu baris penuh agar nominal
     besar ("Rp 1.156.250") tidak terklip & kedua isian tetap nyaman. */
  table.data.nota-lines[data-stack] tbody td.nl-disc{grid-column:1 / -1}
  table.data.nota-lines[data-stack] tbody tr:last-child{margin-bottom:0}
  table.data.nota-lines[data-stack] td,
  table.data.nota-lines[data-stack] tbody th{
    display:grid;grid-template-columns:minmax(0,120px) minmax(0,1fr);
    gap:3px 12px;align-items:start;width:auto;padding:5px 0;border:0;
    border-bottom:1px dashed var(--row-border);text-align:left!important;white-space:normal;
  }
  table.data.nota-lines[data-stack] tr > *:last-child{border-bottom:0}
  table.data.nota-lines[data-stack] td::before{
    content:attr(data-label);font-size:.68rem;font-weight:700;letter-spacing:.05em;
    text-transform:uppercase;color:var(--ink-2);padding-top:2px;overflow-wrap:anywhere;
  }
  table.data.nota-lines[data-stack] td:not([data-label])::before{content:none}
  table.data.nota-lines[data-stack] td > *{min-width:0}
  table.data.nota-lines[data-stack] td input,
  table.data.nota-lines[data-stack] td select,
  table.data.nota-lines[data-stack] td textarea{width:100%;max-width:none}
  table.data.nota-lines[data-stack] tfoot tr{display:block;width:auto}
  table.data.nota-lines[data-stack] tfoot td{
    display:flex;align-items:baseline;justify-content:space-between;gap:10px;
    width:auto;padding:7px 2px;border:0;
  }
  /* Kaki TOTAL: label "Total" + nominal Subtotal dalam satu baris ringkas. */
  table.data.nota-lines[data-stack] tfoot td.nf-label{font-weight:750;border-bottom:1px dashed var(--row-border)}
  table.data.nota-lines[data-stack] tfoot td:empty{display:none}
}
