/* ==========================================================================
   SAXO CELL ERP — DESIGN SYSTEM · arah "SAXO"
   Satu berkas untuk seluruh modul. Tidak ada modul yang boleh mendefinisikan
   gayanya sendiri.

   ARAHNYA DIPILIH PEMILIKNYA dari tiga calon yang digambar berdampingan pada
   layar yang sama (lihat docs/rupa.html): ketegasan lapangan pada ANGKA,
   kelapangan pada RUANG BACA.

   Tiga hal yang menentukan rupanya, dan ketiganya punya alasan:

   · SUDUT 4 PIKSEL. Bukan siku, bukan bulat. Ia menggemakan keping lambangnya
     sendiri — satu-satunya bentuk yang memang milik Saxo Cell.
   · ANGKA MEMAKAI HURUF MESIN KETIK, seluruhnya, tanpa kecuali. Rupiah yang
     berjajar rapi ke bawah membuat selisih satu digit langsung kelihatan;
     angka berhuruf biasa memaksa mata membandingkan panjang, bukan nilai.
   · SATU KELUARGA HURUF UNTUK JUDUL DAN ISI (Roboto, huruf Shopee — K-125).
     Yang membedakan judul dari isi tebal dan ukurannya, bukan keluarganya.
     Dulu dua (Archivo untuk judul, Inter untuk isi); pemiliknya membaca ERP
     ini bergantian dengan Shopee sepanjang hari, dan ia memintanya
     mengikuti Shopee.

   Palet dasarnya tetap hitam / putih / perak — warna lambangnya sendiri.
   Keadaan dokumen dibedakan WARNA, dengan bentuk penanda sebagai penegas:
   bentuknya sudah ada, tidak memakan tempat, dan tetap menolong pada layar
   redup di bawah lampu neon toko.
   ========================================================================== */

:root{
  /* SKALA HURUF SEBAGAI TOKEN (K-293). Setiap ukuran huruf di erp.css dan di
     gaya sebaris layar menunjuk salah satu token ini, jadi ukuran di layar
     telepon bisa diturunkan satu anak tangga di SATU tempat — di bawah,
     `@media (max-width:640px)` — tanpa menyentuh 600 aturannya. */
  --f10:10px; --f11:11px; --f12:12px; --f13:13px; --f14:14px; --f16:16px; --f18:18px; --f22:22px;
  --ground:#F1F2F3; --surface:#FFFFFF; --surface-2:#F7F8F8;
  --rail:#0E0F11; --rail-ink:#F4F5F6; --rail-muted:#8A9097; --rail-line:#232629;
  --ink:#101214; --ink-2:#5C6268; --ink-3:#868C93; --on-ink:#FFFFFF;
  --line:#DCDEE1; --line-strong:#B4B9BE; --focus:#101214;
  --shadow:0 1px 2px rgba(16,18,20,.05), 0 8px 24px -14px rgba(16,18,20,.16);
  /* SATU sudut untuk seluruh ERP. Yang lebih kecil dari ini (penanda status,
     kotak centang) memakai --radius-kcl; yang lebih besar tidak ada. */
  --radius:4px; --radius-kcl:3px;
  /* TINGGI BILAH "Tanya Penjual" yang muncul di bawah kartu etalase saat
     kursor mengarah ke sana (K-182). Ia berdiri DI SINI dan bukan pada
     bilahnya sendiri karena DUA benda membacanya: bilahnya, dan ruang yang
     dicadangkan baris geser di bawahnya. Dua angka yang ditulis
     sendiri-sendiri cepat atau lambat berbeda — dan K-182 sudah
     membuktikannya, lihat K-258 di prototipe/CLAUDE.md. */
  --tanya-t:38px;
  /* SATU tinggi untuk seluruh kendali: kotak isian, tombol, dan saringan.
     Sebelumnya tombol 36 dan saringan 36 kebetulan sama; begitu salah satunya
     diubah sendirian, seluruh baris saringan melipat menjadi dua. Ditulis
     sebagai satu angka supaya keadaan itu tidak bisa terjadi lagi. */
  --tinggi-kendali:38px;
  /* SKALA HURUF DELAPAN ANAK TANGGA (K-291, diminta pemiliknya: *"font-nya
     masih agak kebesaran dikit, dan variasi ukuran font-nya agak kebanyakan
     dikit"*). Sesudah K-285 masih 19 ukuran; sekarang cuma 10 · 11 · 12 · 13
     · 14 · 16 · 18 · 22 px, badan halaman 13px, dan tiap ukuran turun satu
     langkah kecil. Nama halaman di baris kepala tetap 16px. Ukuran BARU harus
     memilih salah satu anak tangga ini — ukuran di luarnya dijaga
     `uji/smoke.js`. */
  /* HURUFNYA MENGIKUTI SHOPEE (K-125, diminta pemiliknya: "untuk font tolong
     ikuti font Shopee aja"). Shopee memakai ROBOTO, dan itu pula huruf bawaan
     Android — jadi di telepon pemiliknya ia memang huruf yang sudah ia baca
     sepanjang hari, dan di sana ia bahkan tidak perlu diunduh.

     Archivo dan Inter dicabut: satu keluarga huruf untuk judul dan isi, sama
     seperti Shopee. Yang membedakan judul dari isi tinggal tebal dan
     ukurannya.

     `--f-angka` DULU MENUNJUK DIRINYA SENDIRI (`var(--f-angka)`), dan CSS
     menganggap rujukan berputar itu tidak sah — jadi SETIAP `font-family:
     var(--f-angka)` di 86 tempat gugur, dan seluruh nomor, serial, dan uang
     tampil dengan huruf badan. IBM Plex Mono tetap diunduh di 122 halaman
     tanpa pernah dipakai satu huruf pun.

     ANGKA TIDAK JADI BERHURUF MESIN KETIK (K-127). Begitu peubahnya
     dibetulkan, angka uang di seluruh ERP berubah menjadi mono — dan
     pemiliknya menolaknya begitu melihatnya: "saya tidak suka angka yang
     terlalu lebar". Ia benar untuk layar telepon: digit mono ±18% lebih
     lebar, dan pada kartu selebar setengah layar itu persis lebar yang
     dibutuhkan nama barang di sebelahnya.

     Yang dikejar aturan lama tetap didapat, lewat jalan yang tidak memakan
     lebar: `font-variant-numeric:tabular-nums` (di bawah). Yang membuat
     rupiah berjajar rapi bukan huruf mesin ketiknya, melainkan DIGIT YANG
     SAMA LEBARNYA — dan itu bisa didapat dari huruf badan yang sama. */
  --f-judul:Roboto,"Segoe UI",system-ui,-apple-system,sans-serif;
  --f-isi:Roboto,"Segoe UI",system-ui,-apple-system,sans-serif;
  --f-angka:Roboto,"Segoe UI",system-ui,-apple-system,sans-serif;
}
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]){
    --ground:#0A0B0C; --surface:#141618; --surface-2:#1A1D1F;
    --rail:#050607; --rail-ink:#E9EBEC; --rail-muted:#7E858C; --rail-line:#1D2023;
    --ink:#EDEFF1; --ink-2:#9AA0A7; --ink-3:#787F86; --on-ink:#0B0C0D;
    --line:#25292D; --line-strong:#3B4045; --focus:#EDEFF1;
    --shadow:0 1px 2px rgba(0,0,0,.5), 0 10px 30px -14px rgba(0,0,0,.8);
  }
}
:root[data-theme="dark"]{
  --ground:#0A0B0C; --surface:#141618; --surface-2:#1A1D1F;
  --rail:#050607; --rail-ink:#E9EBEC; --rail-muted:#7E858C; --rail-line:#1D2023;
  --ink:#EDEFF1; --ink-2:#9AA0A7; --ink-3:#787F86; --on-ink:#0B0C0D;
  --line:#25292D; --line-strong:#3B4045; --focus:#EDEFF1;
  --shadow:0 1px 2px rgba(0,0,0,.5), 0 10px 30px -14px rgba(0,0,0,.8);
}

*{box-sizing:border-box}
html,body{height:100%}
/* Kursor panah, bukan kursor ketik. Bawaan peramban untuk teks di dalam div
   adalah I-beam — bentuk yang di seluruh dunia berarti "di sini bisa
   mengetik". Pada layar yang sembilan puluh persen isinya angka dan label
   yang tidak bisa disunting, ia berbohong di setiap gerakan tetikus. Yang
   memang bisa diketik mengembalikannya sendiri di aturan di bawah. */
/* TEKS TIDAK BISA DIPILIH (K-65, diminta pemiliknya): tekan-tahan pada angka
   di telepon memunculkan penyorot biru dan pencarian Google, dan keduanya
   merampas kartu yang sedang dibaca. Yang bisa disalin tetap ada, lewat
   tombol salin ERP sendiri (nomor dokumen, serial); kolom isian tetap bisa
   dipilih karena di situ orang memang menyunting. */
body{user-select:none;-webkit-user-select:none;-webkit-tap-highlight-color:transparent;font-variant-numeric:tabular-nums}
input,textarea,[contenteditable]{user-select:text;-webkit-user-select:text}
body{margin:0;background:var(--ground);color:var(--ink);cursor:default;
  font-family:var(--f-isi);
  font-size:var(--f13);line-height:1.45;-webkit-font-smoothing:antialiased;
  -webkit-text-size-adjust:100%;text-size-adjust:100%}
input:not([type=checkbox]):not([type=radio]):not([type=file]),textarea,
.inp,[contenteditable="true"]{cursor:text}
input[readonly],textarea[readonly],.inp:has(input[readonly]),.inp:has(textarea[readonly]){cursor:default}
button,label,select,summary,a,[role="button"],.chipopt,.radio,.combo-btn{cursor:pointer}
button[disabled],.btn[disabled]{cursor:not-allowed}
/* Judul RAPAT: jarak antar-huruf dikurangi dan bobotnya dinaikkan, supaya ia
   menandai tempat dengan sekali lihat tanpa harus menjadi besar sekali. */
h1,h2,h3,h4{font-family:var(--f-judul);margin:0;text-wrap:balance;
  letter-spacing:-.03em;font-weight:700}
p{margin:0}
a{color:inherit}
button,input,select,textarea{font:inherit;color:inherit}
:focus-visible{outline:2px solid var(--focus);outline-offset:2px;border-radius:var(--radius)}
.mono{font-family:var(--f-angka);font-variant-numeric:tabular-nums}
.muted{color:var(--ink-2)}
.dash{color:var(--ink-3)}
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}

/* ---------- SHELL ---------- */
.app{display:grid;grid-template-columns:262px minmax(0,1fr);min-height:100vh}
.rail{background:var(--rail);color:var(--rail-ink);display:flex;flex-direction:column;gap:1px;
  padding:16px 12px;position:sticky;top:0;height:100vh;overflow:hidden}
/* DAFTAR MODULNYA YANG DIGULIR, BUKAN SELURUH MENUNYA (K-165). Dulu
   `overflow-y:auto` berdiri di `.rail` sendiri, jadi pada halaman yang
   submenunya panjang — Inventory sepuluh anak, HR sebelas — lambang, tombol
   lokasi, nama orang yang sedang masuk, dan tombol Keluar semuanya terdorong
   KELUAR LAYAR bersama daftarnya. Diukur di layar 960px: kaki menunya berdiri
   di 1.130px, seratus tujuh puluh piksel di bawah tepi bawah layar.

   `min-height:0` wajib: tanpa itu anak flex tidak pernah mau menyusut lebih
   kecil daripada isinya, dan penggulirnya tidak pernah jalan. */
.rail-list{flex:1 1 auto;min-height:0;overflow-y:auto;display:flex;flex-direction:column;gap:1px;
  margin:0 -4px;padding:0 4px}
/* Lambang dan tombol tutup berbagi satu baris; tombol lokasi berdiri di
   BARISNYA SENDIRI di bawahnya. Sebaris bertiga, ketiganya berebut 262px:
   "Saxo Cell" terpotong menjadi "Saxo Cel" dan nama lokasi berhenti di
   "Semua Lo…" — padahal nama lokasi yang terbaca utuh adalah satu-satunya
   guna tombol itu. */
.rail-hd{display:flex;align-items:center;gap:7px;padding:6px 6px 10px}
/* Lambangnya TIDAK menyusut: ia identitas, dan "Saxo Cel" bukan nama
   siapa pun. Yang mengalah tulisan tombol lokasi di sebelahnya, yang
   memang dipotong titik-titik sejak dulu. */
.brand{display:flex;align-items:center;gap:10px;flex:none;text-decoration:none}
/* Tombol lokasi: KONTEKS sesi, bukan tindakan halaman. Tempatnya di menu
   kiri, sejajar dengan lambangnya — dan sejajar pula dengan nama orang yang
   sedang masuk di kaki menu ini, karena keduanya menjawab pertanyaan yang
   sama jenisnya: "saya sedang jadi siapa, dan di mana". */
/* Selebar menunya penuh: nama lokasi adalah satu-satunya isinya, dan sebuah
   tombol yang tidak memakai lebar yang tersedia memotong namanya di sebelah
   ruang yang menganggur. */
.railpov{display:flex;align-items:center;gap:6px;width:calc(100% - 12px);min-width:0;margin:0 6px 12px;
  padding:0 10px;height:32px;border-radius:var(--radius);cursor:pointer;flex:none;
  border:1px solid var(--rail-line);background:rgba(255,255,255,.05);
  color:var(--rail-ink);font:inherit;font-size:var(--f12);text-align:left;
  transition:background .14s,border-color .14s}
.railpov:hover{background:rgba(255,255,255,.12);border-color:rgba(255,255,255,.24)}
.railpov:focus-visible{outline:2px solid var(--rail-ink);outline-offset:2px}
.railpov > svg{width:14px;height:14px;flex:none;opacity:.75}
.railpov-t{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* TIRAI DI BELAKANG LACI. Ia yang menutup lacinya saat ditekan — menggantikan
   tombol silang yang dulu berdiri di dalam laci, di sudut kiri atas: sudut yang
   paling sulit dijangkau ibu jari, untuk pekerjaan yang jauh lebih mudah
   dikerjakan dengan menekan halaman di sebelahnya.

   Warnanya yang mengatakan halaman di belakang sedang tidak bisa dipakai.
   Tanpa tirai, latar itu tetap bisa ditekan tetapi tidak ada satu pun tanda
   bahwa ia bisa — dan itulah yang dulu membuat tombol silangnya diperlukan. */
.railtirai{display:none}
/* Keping lambang: hitam, bertepi perak, dengan satu kilau di sisi kiri-atas —
   sama dengan keping aslinya. Pendar HIJAU yang dipakai sebelumnya bukan
   warna lambang ini; ia menambahkan satu warna yang tidak pernah ada pada
   mereknya sendiri, dan warna yang tidak berarti apa-apa adalah warna yang
   membuat orang mencari artinya. */
/* Jarak dalamnya 2px, bukan 5px: dengan 5px, X-nya cuma memenuhi 45% lebar
   keping sementara pada lambang aslinya ia memenuhi hampir 60% — kepingnya
   jadi terbaca sebagai kotak hitam yang kebetulan ada X kecil di tengahnya.

   Sudutnya 8px, bukan `--radius` 4px yang dipakai seluruh kendali: ini LAMBANG,
   bukan tombol, dan lambang aslinya memang berbentuk keping bersudut bulat
   lebar. Aturan radius arah "Saxo" tetap berlaku untuk semua yang lain. */
/* KOTAK PEMBUNGKUS PERAKNYA DICABUT (K-123, diminta pemiliknya). Sebabnya
   ikon di layar utama telepon: Android memotongnya menjadi LINGKARAN, jadi
   keping persegi bersudut bulat itu selalu terpotong keempat sudutnya dan
   terbaca sebagai logo yang rusak. "Tolong hilangkan sekalian aja kotak
   pembungkus yang silver itu."

   Yang tinggal X-nya sendiri, tanpa latar dan tanpa bingkai. Di menu kiri,
   halaman Masuk versi lebar, dan di mana pun permukaannya gelap, ia memang
   tidak butuh apa-apa di belakangnya. */
.brand-mark{width:40px;height:40px;display:grid;place-items:center;flex:none}
.brand-mark svg,.brand-mark img{width:100%;height:100%;display:block}
.login-art .brand-mark{width:72px;height:72px}
.login-art .brand-name{font-size:var(--f12);letter-spacing:.45em}
.login-art .brand-sub{font-size:var(--f12)}
.brand-name{display:block;font-family:var(--f-angka);font-size:var(--f10);font-weight:500;letter-spacing:.4em;
  text-transform:uppercase;color:var(--ink-3);line-height:1.2;white-space:nowrap}
/* WORDMARK "SAXO CELL" (K-66, diminta pemiliknya dari rancangan halaman
   masuknya): huruf mono kapital berjarak lebar, tenang di sebelah kepingnya —
   bukan huruf judul tebal yang bersaing dengan lambangnya sendiri. Berlaku
   di menu, halaman Masuk, dan kepala Toko Online — satu kelas. */
.brand-sub{font-size:var(--f10);color:var(--rail-muted);letter-spacing:.14em;text-transform:uppercase;line-height:1.5;display:block}
.rail-label{font-size:var(--f10);letter-spacing:.14em;text-transform:uppercase;color:var(--rail-muted);padding:14px 10px 6px}
.nav-item{display:flex;align-items:center;gap:10px;width:100%;padding:8px 10px;border-radius:var(--radius);border:0;
  background:transparent;color:var(--rail-muted);font-size:var(--f12);cursor:pointer;text-align:left;text-decoration:none}
.nav-item:hover{background:var(--rail-line);color:var(--rail-ink)}
.nav-item[aria-current="page"]{background:var(--rail-ink);color:var(--rail);font-weight:600}
.nav-item svg{width:16px;height:16px;flex:none}
/* MODUL BERSUBMENU MEMBUKA DAFTARNYA DULU (K-171). Daftarnya selalu digambar
   lalu disembunyikan di sini, jadi membukanya tidak menuntut menunya digambar
   ulang — dan simpul lain yang sedang terbuka tidak ikut terlepas. */
.nav-item--induk{text-align:left}
.nav-item-nama{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.nav-item--induk > svg:last-child{width:14px;height:14px;opacity:.6;transition:transform .18s ease}
.nav-item--induk[aria-expanded="true"] > svg:last-child{transform:rotate(90deg)}
/* Modul tempat halaman ini berdiri tetap disorot seperti dulu — yang berubah
   cuma bentuk simpulnya, dari tautan menjadi tombol. */
.nav-item--aktif{background:var(--rail-ink);color:var(--rail);font-weight:600}
.nav-item--aktif > svg:last-child{opacity:.75}
.nav-sub{display:none;flex-direction:column;gap:1px;margin:2px 0 4px 26px;padding-left:10px;border-left:1px solid var(--rail-line)}
.nav-sub--buka{display:flex}
.nav-sub a{color:var(--rail-muted);text-align:left;padding:6px 8px;border-radius:var(--radius);font-size:var(--f12);text-decoration:none;display:block}
.nav-sub a:hover{color:var(--rail-ink)}
/* Setelan yang menggeser angka SETIAP barang dipisah dari daftar harian di
   atasnya oleh satu garis tipis — bukan oleh judul kedua, yang di dalam
   submenu setinggi 26px per baris cuma menambah baris yang harus dibaca. */
.nav-sub-pisah{margin-top:7px;padding-top:7px;border-top:1px solid var(--rail-line)}
.nav-sub a[aria-current="page"]{color:var(--rail-ink);font-weight:600}
.rail-foot{margin-top:auto;border-top:1px solid var(--rail-line);padding-top:12px;display:flex;align-items:center;gap:9px}
.avatar{width:28px;height:28px;border-radius:50%;background:var(--rail-line);display:grid;place-items:center;
  font-size:var(--f11);font-weight:600;color:var(--rail-ink);flex:none}
.rail-foot .who{font-size:var(--f12);display:block}
.rail-foot .role{font-size:var(--f11);color:var(--rail-muted);display:block}

.main{min-width:0;display:flex;flex-direction:column}
.topbar{position:sticky;top:0;z-index:40;display:flex;align-items:center;gap:14px;height:56px;padding:0 24px;
  background:var(--surface);border-bottom:1px solid var(--line)}
/* Satu baris, selalu. Nama dokumen boleh sepanjang 255 karakter, dan remah
   roti yang membungkus ke baris ketiga mendorong seluruh isi halaman turun —
   yang terbaca bukan lagi jejak halaman, melainkan judul kedua. */
/* Remah roti memakai seluruh sisa lebar baris kepala sejak kolom pencarian
   global dicabut, jadi tombol lokasi tetap menempel di tepi kanan. */
/* LONCENG (K-79): tempatnya tetap di ujung kanan baris kepala, di layar
   lebar maupun telepon. Angka merah kecil menempel di bahunya — yang
   dibaca orang dari jauh cuma "ada" atau "tidak ada". */
.lonceng{position:relative;flex:none;display:flex;align-items:center;justify-content:center;
  width:34px;height:34px;border:1px solid var(--line);border-radius:9px;background:var(--surface);
  color:var(--ink-2);cursor:pointer}
.lonceng:hover{color:var(--ink);border-color:var(--line-strong)}
.lonceng svg{width:17px;height:17px}
.lonceng-n{position:absolute;top:-6px;right:-6px;min-width:17px;height:17px;padding:0 4px;
  display:flex;align-items:center;justify-content:center;border-radius:9px;
  background:var(--stop);color:#fff;font-size:var(--f10);font-weight:700;line-height:1}
.pop--pbr{width:320px;padding:4px}
.pbr{display:flex;flex-direction:column;gap:2px;width:100%;padding:9px 10px;border:0;border-radius:8px;
  background:none;text-align:left;cursor:pointer}
.pbr:hover{background:var(--surface-2)}
.pbr + .pbr{border-top:1px solid var(--line)}
.pbr-j{font-size:var(--f12);font-weight:600;color:var(--ink)}
.pbr--baru .pbr-j::before{content:"";display:inline-block;width:6px;height:6px;margin-right:6px;
  border-radius:50%;background:var(--stop);vertical-align:middle}
.pbr-i{font-size:var(--f12);color:var(--ink-2)}
.pbr-t{font-size:var(--f11);color:var(--ink-3)}
.pbrkosong{padding:14px 12px;font-size:var(--f12);color:var(--ink-3)}
/* DETAIL ITEM TIDAK PUNYA BARIS KEPALA DI LAYAR LEBAR (K-213). Diminta
   pemiliknya bersama tangkapan layarnya sendiri — baris kosong yang cuma
   berisi lonceng di ujung kanan — dengan kalimat yang sama dengan K-210:
   "remove this while we're already opening the page of the product for it to
   be more clear".

   K-210 mencabut remah rotinya, dan yang tersisa sesudah itu memang tinggal
   KOTAKNYA: di layar 961px ke atas `.navsel` dan `.topmid` keduanya
   `display:none`, jadi barisnya berdiri setinggi 56px beserta garis bawahnya
   untuk satu lonceng. Alasannya yang sama dengan K-207 §6 dan K-210 — yang
   membuka satu barang sedang memeriksa barang itu, bukan sedang mencari
   barang berikutnya — dan sekarang ia ditepati sampai habis.

   HANYA 961px KE ATAS, dan batas itu bukan kerapian: di bawahnya baris ini
   membawa TOMBOL KEMBALI beserta nama halamannya, dan di bawah 640px ia
   kepala yang mengambang di atas fotonya (K-207). Mencabutnya di sana berarti
   mencabut satu-satunya jalan pulang.

   Dua aturan K-210 tidak ditinggalkan sebagai kode mati (aturan tetap nomor
   8): remah roti sudah dicabut seluruh ERP di bawah 960px sejak K-65, jadi
   keduanya cuma pernah berlaku di lebar yang barisnya sekarang tidak digambar
   sama sekali.

   `.unitsplit` tetap penandanya — ia cuma dipakai halaman Detail Item, jadi
   tidak perlu kelas baru di `<body>`: kelas begitu harus dituliskan di
   halamannya, dan yang lupa menuliskannya tidak berbunyi seperti kerusakan. */
/* HANYA `.unitsplit` YANG BERDIRI SEBAGAI HALAMAN (K-273): sejak Detail Item
   juga digambar di panel Daftar Item, `.unitsplit` di mana pun akan ikut
   mencabut baris kepala DAFTARNYA. Penanda kerangka server berdiri langsung
   di bawah `#kerangka`, jadi ia disebut tersendiri. */
@media (min-width:961px){ body:has(.page > .unitsplit, #kerangka > .unitsplit) .topbar{display:none} }
.kbd{position:absolute;right:9px;top:8px;font-size:var(--f10);color:var(--ink-3);border:1px solid var(--line);border-radius:var(--radius);padding:1px 5px;background:var(--surface)}
/* `.outlet` DICABUT bersama tombol lokasi di pojok kanan atas — lihat
   `.railpov`. Baris kepala halaman sekarang tinggal berisi tombol menu dan
   remah rotinya saja. */

/* RUANG KOSONG DI KAKI HALAMAN DIPANGKAS (diminta pemiliknya): "begitu card
   udah habis ya itulah yang terakhir". Dulu 96px — hampir dua kartu tingginya
   — dan di layar telepon itu berarti menggulir dua kali untuk membuktikan
   memang tidak ada apa-apa lagi. Yang tersisa sama dengan jarak SISI-nya,
   supaya kartu terakhir tidak menempel ke tepi jendela. Halaman yang punya
   bilah mengambang di dasarnya menambah ruangnya sendiri (`:has(.jualbar)`). */
/* CELAH KIRI-KANAN DIPANGKAS (K-125, lalu dipangkas sekali lagi di K-127:
   "ini cardnya kok di sisi kiri dan kanannya masih ada space ya?"). Yang
   digeser SATU angka di tiga lebar; setiap benda yang menembus tepi halaman —
   daftar ubin, jejeran foto, bilah saringan yang menempel — sudah menghitung
   dirinya dari `--pad-hal`, jadi semuanya ikut sendiri tanpa disentuh.

   DI LEBAR TELEPON ANGKANYA 8px, dan itu angka yang sudah dipakai Daftar Item
   sejak K-104 — di sana ia dicapai dengan MENEMBUS tepi halaman
   (`margin-inline:calc(8px - var(--pad-hal))`), karena celah halamannya waktu
   itu masih 14px. Sekarang celah halamannya sendiri 8px, jadi tembusannya
   dicabut: satu angka, dan seluruh daftar berdiri di tepi yang sama. Dulu
   Daftar Item 8px sementara Pembelian, Penjualan, Transfer, dan Master Data
   11px — dua jawaban untuk pertanyaan yang sama, dan itu yang terlihat. */
.page{--pad-hal:14px;--pad-atas:18px;padding:var(--pad-atas) var(--pad-hal) var(--pad-hal);max-width:1320px;width:100%}
/* JUDUL HALAMAN adalah satu-satunya tulisan yang menjawab "saya di mana".
   Ia dinaikkan bobotnya menjadi 700 dan dirapatkan jarak hurufnya — bukan
   dibesarkan ukurannya, karena ruang di atas layar dipakai bekerja, bukan
   dipakai judul. Ruang di bawahnya dilebarkan sedikit supaya ia berdiri
   sendiri, tidak menempel pada saringan di bawahnya. */
.page-head{display:flex;align-items:flex-end;gap:20px;flex-wrap:wrap;margin-bottom:24px}
.page-head h1{font-size:var(--f16);font-weight:600;letter-spacing:normal}
.page-head p{margin:6px 0 0;color:var(--ink-2);font-size:var(--f12);max-width:70ch}
.head-actions{margin-left:auto;display:flex;gap:8px;flex-wrap:wrap}

/* ---------- BUTTON ---------- */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:7px;height:var(--tinggi-kendali);padding:0 16px;
  border-radius:var(--radius);font-weight:600;
  border:1px solid var(--line-strong);background:var(--surface);color:var(--ink);font-size:var(--f12);font-weight:500;
  cursor:pointer;white-space:nowrap;text-decoration:none}
/* `display:inline-flex` di atas MENGALAHKAN `[hidden]` bawaan peramban, jadi
   tombol yang disembunyikan dari JavaScript tetap tergambar. Jebakan yang sama
   sudah dua kali memakan korban di berkas ini — `.field[hidden]` dan
   `.railout[hidden]` — dan kali ketiga cukup ditambal sekali untuk SELURUH
   tombol: yang berikutnya tidak perlu menemukannya lagi. */
.btn[hidden]{display:none}
.btn:hover{background:var(--surface-2)}
.btn svg{width:15px;height:15px}
.btn--primary{background:var(--ink);border-color:var(--ink);color:var(--on-ink)}
.btn--primary:hover{background:var(--ink);opacity:.88}
/* Hijau dipakai satu kali saja: menjual. Ia satu-satunya tindakan pada seluruh
   ERP yang memasukkan uang, dan warna keadaan --done memang sudah berarti
   "beres" di mana-mana. Tombol lain tetap monokrom. */
.btn--jual{background:var(--done);border-color:var(--done);color:#fff}
/* Tombol baris item yang sudah menjadi KETERANGAN. Ia dimatikan, jadi tidak
   pernah menawarkan apa pun — warnanya hanya membedakan tiga akhir yang
   mungkin: selesai, dibatalkan, dikembalikan. Tetap setinggi dan selebar
   tombol biasa supaya tepi kanan daftarnya tidak berloncatan. */
.btn--hasil{gap:6px;font-weight:500;cursor:default;opacity:1}
.btn--hasil svg{width:14px;height:14px;flex:none}
.btn--hasil[disabled]{opacity:1}
.btn--hasil--ok{border-color:var(--done-line);background:var(--done-bg);color:var(--done)}
.btn--hasil--stop{border-color:var(--line);background:var(--surface-2);color:var(--ink-3)}
.btn--hasil--balik{border-color:var(--stop-line);background:var(--stop-bg);color:var(--stop)}
/* Tombol hasil yang MASIH menyimpan sesuatu di belakangnya — bukti, waktu,
   dan pelakunya. Ia tetap terbaca sebagai keadaan, cuma diberi panah kecil
   supaya tangan tahu ada yang bisa dibuka. */
.btn--hasil--tekan{cursor:pointer}
.btn--hasil--tekan svg:last-child{width:12px;height:12px;opacity:.75;transition:transform .14s}
.btn--hasil--tekan:hover{border-color:currentColor}
.btn--hasil--tekan:hover svg:last-child{transform:translateX(2px);opacity:1}
/* Foto bukti di dalam pop-up: selebar isinya, tetap 4:3 supaya tinggi
   pop-upnya tidak melompat mengikuti bentuk fotonya. */
/* Gambar kecil bukti pembayaran di baris Detail Pembayaran (K-50). */
.buktikecil{flex:none;width:40px;height:40px;padding:0;margin-right:10px;border:1px solid var(--line);
  border-radius:8px;overflow:hidden;background:var(--paper);cursor:pointer;align-self:center}
.buktikecil img{width:100%;height:100%;object-fit:cover;display:block}
.buktikecil:hover{border-color:var(--line-strong)}
.buktifoto{display:block;width:100%;padding:0;margin:0 0 14px;border:1px solid var(--line);
  border-radius:var(--radius);overflow:hidden;background:var(--surface-2);cursor:zoom-in}
.buktifoto img{width:100%;aspect-ratio:4/3;object-fit:cover;display:block}
.buktifoto:hover{border-color:var(--line-strong)}
/* Keadaan uang pada baris Total. Tiga bentuk, satu ukuran: yang berubah cuma
   sifatnya. Kurang dan Lebih menawarkan tindakan, Lunas cuma menerangkan —
   dan keduanya tidak boleh tertukar hanya karena bentuknya sama. */
.btn--bayar{min-width:148px;justify-content:center;font-variant-numeric:tabular-nums}
/* Kurang sebentuk dan sesifat dengan Terima di baris item — keduanya tombol
   utama pada barisnya masing-masing. Dulu latarnya lupa dikunci saat
   disentuh, jadi aturan .btn:hover yang lebih kuat mengambil alih dan
   melatarinya abu-abu terang di bawah tulisan putih: terbaca sebagai tombol
   yang rusak, bukan tombol yang sedang disentuh. Sekarang persis .btn--primary:
   warnanya tetap, cuma sedikit meredup. */
.btn--bayar--kurang{background:var(--ink);border-color:var(--ink);color:var(--on-ink)}
.btn--bayar--kurang:hover{background:var(--ink);opacity:.88}
.btn--bayar--lebih{background:var(--stop);border-color:var(--stop);color:#fff}
.btn--bayar--lebih:hover{background:var(--stop);opacity:.88}
/* Lunas pun sebuah tombol sekarang: ia membuka rinciannya, sama seperti
   Kurang dan Lebih. Yang membedakannya cuma warnanya — tidak ada yang perlu
   dikerjakan, tetapi rinciannya tetap boleh dibaca. */
.btn--bayar--lunas{gap:6px;border-color:var(--done-line);background:var(--done-bg);
  color:var(--done);font-weight:500}
.btn--bayar--lunas svg{width:14px;height:14px;flex:none}
/* Batalkan dan Selesaikan berdiri bersebelahan dan mengakhiri dokumen dengan
   dua cara yang berlawanan, jadi keduanya tidak boleh terlihat sama. Yang satu
   memerahkan dirinya, yang satu menghitam — mata membedakannya sebelum sempat
   membaca hurufnya. */
.btn--batal{color:var(--stop);border-color:var(--stop-line)}
.btn--batal:hover{border-color:var(--stop);background:var(--stop-bg)}
.btn--batal--kuat{background:var(--stop);border-color:var(--stop);color:#fff}
.btn--batal--kuat:hover{background:var(--stop);border-color:var(--stop);opacity:.88}
.btn--jual:hover{background:var(--done);border-color:var(--done);opacity:.9}
.btn--ghost{border-color:transparent;background:transparent}
.btn--ghost:hover{background:var(--surface-2);border-color:var(--line)}
.btn--sm{height:30px;padding:0 10px;font-size:var(--f12);border-radius:var(--radius)}
/* Tombol yang berdiri SEBAGAI PILIHAN, bukan sebagai tindakan di pojok: satu
   per baris, selebar kotaknya, supaya dua jalan yang sama beratnya juga sama
   besar di mata yang memilihnya (K-238). */
.btn--blok{width:100%;height:44px}
.btn[disabled]{opacity:.45;cursor:not-allowed}
.btn[disabled]:hover{background:var(--surface)}
.btn--primary[disabled]:hover{background:var(--ink)}
.btn.busy{pointer-events:none;opacity:.75}
.btn .spin{width:13px;height:13px;border-radius:50%;border:1.6px solid currentColor;border-right-color:transparent;animation:spin .7s linear infinite}
@keyframes spin{to{transform:rotate(360deg)}}

/* ---------- CARD ---------- */
.card{background:var(--surface);border:1px solid var(--line);border-radius:var(--radius);overflow:hidden}
.card-hd{padding:13px 16px;border-bottom:1px solid var(--line);display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.card-hd h2{font-size:var(--f12);font-weight:600}
/* Keterangan di kepala kartu tidak boleh lebih besar daripada judulnya. Tanpa
   aturan ini ia mewarisi 14,5px berwarna teks penuh — lebih besar dan lebih
   gelap daripada h2 di sebelahnya — dan yang menerangkan terbaca lebih dulu
   daripada yang diterangkan. */
.card-hd p{flex:1 1 100%;margin:0;font-size:var(--f12);color:var(--ink-3)}
.card-hd .right{margin-left:auto;display:flex;gap:8px;align-items:center}
.card-bd{padding:16px}
/* Satu petak selebar barisnya — dipakai Lap.kotakPetak bila yang boleh
   dilihat orangnya tinggal satu petak. */
/* Satu baris kesimpulan di dasar panel Jual: berapa yang dibayar pelanggan
   (atau dikembalikan kepadanya). Angkanya tebal, sisanya tenang. */
.jualbaris{margin:12px 0 0;padding-top:10px;border-top:1px solid var(--line-strong);font-size:var(--f13);color:var(--ink-2)}
.jualbaris b{color:var(--ink);font-family:var(--f-angka)}
.grid1{display:grid;grid-template-columns:minmax(0,1fr);gap:16px;align-items:start}
.grid2{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:16px;align-items:start}
.grid3{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:16px;align-items:start}
.grid4{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:12px;align-items:start}

/* ---------- PENANDA STATUS (bentuk + label) ---------- */
.pill{display:inline-flex;align-items:center;gap:6px;height:23px;padding:0 9px;
  border-radius:var(--radius-kcl);
  border:1px solid var(--line-strong);font-size:var(--f11);font-weight:600;white-space:nowrap;
  letter-spacing:.01em;color:var(--ink);background:transparent}
.pill--solid{background:var(--ink);border-color:var(--ink);color:var(--on-ink)}
.pill--dashed{border-style:dashed;color:var(--ink-2)}
.pill--quiet{color:var(--ink-2);border-color:var(--line)}
.pill--void{color:var(--ink-3);border-color:var(--line);text-decoration:line-through;text-decoration-thickness:1px}
.pill--lg{height:27px;font-size:var(--f12);padding:0 11px}
button.pill{cursor:pointer}
button.pill:hover{border-color:var(--ink)}
.mk{width:9px;height:9px;border-radius:50%;border:1.5px solid currentColor;flex:none;position:relative}
.mk--full{background:currentColor}
.mk--half{background:linear-gradient(90deg,currentColor 0 50%,transparent 50% 100%)}
.mk--x{border:0}
.mk--x::before,.mk--x::after{content:"";position:absolute;left:-1px;right:-1px;top:4px;height:1.5px;background:currentColor}
.mk--x::before{transform:rotate(45deg)}
.mk--x::after{transform:rotate(-45deg)}
.mk--check{border:0}
.mk--check::before{content:"";position:absolute;left:1px;top:-1px;width:5px;height:8px;
  border-right:1.6px solid currentColor;border-bottom:1.6px solid currentColor;transform:rotate(40deg)}
/* Mode Pilih di Daftar Item: penanda keadaan berubah menjadi KOTAK CENTANG,
   dan warnanya tetap warna keadaannya (diminta pemiliknya: "kalau warnanya
   oren, checklist ya oren"). Yang berubah cuma bentuknya — bulatan menjadi
   petak bersudut — supaya "sedang memilih" terbaca tanpa satu kata pun,
   sementara keadaan barangnya tidak ikut hilang dari kartunya. */
.mk--cek{border-radius:3px;border:1.5px solid currentColor;background:none}
.mk--cek-on{background:currentColor}
.mk--cek-on::before{content:"";position:absolute;left:2px;top:0;width:3.5px;height:6.5px;
  border-right:1.5px solid var(--surface);border-bottom:1.5px solid var(--surface);transform:rotate(40deg)}
.tag{display:inline-flex;align-items:center;gap:5px;height:21px;padding:0 8px;border-radius:var(--radius-kcl);border:1px dashed var(--line-strong);
  font-size:var(--f11);color:var(--ink-2);white-space:nowrap}
.meter{height:4px;border-radius:var(--radius);background:var(--line);overflow:hidden;min-width:70px}
.meter i{display:block;height:100%;border-radius:var(--radius);background:var(--ink)}

/* ---------- KEY / VALUE ---------- */
.kv{display:flex;flex-direction:column}
.kv-row{display:flex;align-items:center;gap:14px;padding:11px 0;border-bottom:1px solid var(--line)}
.kv-row:last-child{border-bottom:0}
.kv-row .k{font-size:var(--f12);color:var(--ink-2);flex:1 1 auto}
.kv-row .v{font-size:var(--f12);text-align:right}
.kv-row .v.big{font-family:var(--f-angka);font-size:var(--f13);font-variant-numeric:tabular-nums;white-space:nowrap}
.kv-row--total{border-top:1px solid var(--ink);border-bottom:0;padding-top:13px;margin-top:2px}
.kv-row--total .k{color:var(--ink);font-weight:600}
.kv-row--total .v{font-family:var(--f-judul);font-size:var(--f14);font-weight:600;font-variant-numeric:tabular-nums}
/* Daftar kunci-nilai yang isinya ANGKA. Deretan angka yang tepi kanannya
   tidak lurus tidak bisa dibandingkan sekali lihat, jadi di sini sebutannya
   mengisi kiri dan angkanya rata kanan dalam huruf mesin ketik. Sengaja
   dipakai lewat kelas, bukan berlaku ke semua .kv: daftar yang nilainya
   kalimat panjang justru menjadi sulit dibaca kalau dirata-kanankan. */
.kv--angka .kv-row > span{flex:1 1 auto;min-width:0;font-size:var(--f12);color:var(--ink-2)}
.kv--angka .kv-row > b{margin-left:auto;text-align:right;white-space:nowrap;
  font-family:var(--f-angka);font-variant-numeric:tabular-nums;font-weight:600}
.kv--angka .kv-row--total > span{color:var(--ink);font-weight:600}
.kv--angka .kv-row--total > b{font-family:var(--f-angka);font-size:var(--f14);letter-spacing:-.02em}

/* ---------- LIST CARD (pola L) ---------- */
.cards{display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:14px}
.lcard{position:relative;text-align:left;background:var(--surface);border:1px solid var(--line);border-radius:var(--radius);
  padding:0;cursor:pointer;display:flex;flex-direction:column;overflow:hidden;text-decoration:none;color:inherit}
.lcard:hover{border-color:var(--line-strong);box-shadow:var(--shadow)}
.lc-sec{padding:14px 16px;border-bottom:1px solid var(--line)}
.lc-sec:last-child{border-bottom:0}
.lc-title{font-family:var(--f-judul);font-size:var(--f14);font-weight:600;letter-spacing:-.01em;display:block}
.lc-sub{font-size:var(--f12);color:var(--ink-3);display:block;margin-top:3px}
.lc-amount{font-family:var(--f-angka);font-size:var(--f16);font-weight:500;font-variant-numeric:tabular-nums;letter-spacing:-.02em;display:block}
.lc-amount small{font-size:var(--f12);color:var(--ink-3);margin-right:2px}
.lc-foot{display:flex;align-items:center;justify-content:space-between;gap:12px;background:var(--surface-2)}
/* "11 data ›" tidak boleh melipat menjadi dua baris di lebar telepon: yang
   mengalah adalah kode masternya di sebelah kiri, bukan angkanya. */
.lc-go{font-size:var(--f12);color:var(--ink-2);display:inline-flex;align-items:center;gap:4px;
  flex:none;white-space:nowrap}
/* Panahnya perlu ukuran sendiri: sebagai anak flex tanpa lebar, <svg> menyusut
   sampai hilang begitu lajurnya dipatok flex:none. */
.lc-go svg{width:13px;height:13px;flex:none}
.lc-foot .mono{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* ---------- ITEM CARD + EXPAND (pola T) ---------- */
.tcard{border:1px solid var(--line);border-radius:var(--radius);background:var(--surface);overflow:hidden}
.tcard + .tcard{margin-top:10px}
.tcard-hd{display:flex;align-items:center;gap:14px;padding:14px 16px;flex-wrap:wrap}
.tcard-hd .t{flex:1 1 190px;min-width:0}
.tcard-hd .t b{font-size:var(--f13);font-weight:500;display:block}
.tcard-hd .t span{font-size:var(--f12);color:var(--ink-3);display:block;margin-top:2px}
.tcard-f{display:flex;flex-direction:column;gap:2px;min-width:78px}
.tcard-f .k{font-size:var(--f10);letter-spacing:.08em;text-transform:uppercase;color:var(--ink-3)}
.tcard-f .v{font-size:var(--f12);font-family:var(--f-angka);font-variant-numeric:tabular-nums}
.tcard-f .v.txt{font-family:inherit}
.tcard-act{margin-left:auto;display:flex;gap:8px;align-items:center}
.tcard-more{display:none;padding:0 16px 14px;border-top:1px solid var(--line);margin-top:-1px}
.tcard[data-open="1"] .tcard-more{display:block;padding-top:14px}
.tcard[data-attn="1"]{box-shadow:inset 3px 0 0 var(--ink)}

/* ---------- QUICK ACTION ---------- */
.qa{display:flex;gap:8px;flex-wrap:wrap;padding:14px 16px;background:var(--surface);border:1px solid var(--line);border-radius:var(--radius)}
.qa .qa-l{font-size:var(--f10);letter-spacing:.1em;text-transform:uppercase;color:var(--ink-3);align-self:center;margin-right:4px}

/* ---------- TAB ---------- */
.tabs{display:flex;gap:2px;padding:0 6px;border-bottom:1px solid var(--line);overflow-x:auto;background:var(--surface);
  border-radius:var(--radius) var(--radius) 0 0}
.tab{border:0;background:transparent;padding:12px 12px 10px;font-size:var(--f12);color:var(--ink-2);cursor:pointer;
  border-bottom:2px solid transparent;white-space:nowrap}
.tab:hover{color:var(--ink)}
.tab[aria-selected="true"]{color:var(--ink);font-weight:600;border-bottom-color:var(--ink)}
.tab .b{display:inline-grid;place-items:center;min-width:16px;height:16px;padding:0 4px;border-radius:var(--radius-kcl);
  background:var(--line);color:var(--ink-2);font-family:var(--f-angka);font-size:var(--f10);margin-left:6px}
.tab .b--attn{background:var(--ink);color:var(--on-ink)}
.tabbody{background:var(--surface);border:1px solid var(--line);border-top:0;border-radius:0 0 var(--radius) var(--radius);padding:16px}

/* ---------- HEADER DETAIL (pola D) ---------- */
/* Kepala buatan sendiri (`.dhead-top` + `.dhead-nama` + `.dhead-id` +
   `.dhead-actions`) SUDAH TIDAK ADA lagi di satu halaman pun: seluruh
   halaman detail memakai `E.kepalaDok`. Aturannya ikut dicabut bersama
   halaman terakhir yang memakainya (Detail Template Operasional). */
.dhead{position:sticky;top:56px;z-index:35;background:var(--surface);border:1px solid var(--line);
  border-radius:var(--radius);margin-bottom:16px;overflow:hidden}
/* SEDANG DI MODUL APA, DAN BERHADAPAN DENGAN SIAPA (K-266). Dua kata di atas
   nama pihaknya, dan sengaja dibuat TENANG: ia menjawab pertanyaan yang cuma
   ditanyakan sekali saat halamannya dibuka, lalu tidak pernah lagi. Yang
   dicari mata sesudah itu nama pihaknya, dan baris ini tidak boleh ikut
   bersaing dengannya — huruf kecil berspasi, warna paling redup, tanpa kotak
   dan tanpa latar.
   HURUF BESAR SELURUHNYA, dan itu bukan selera: bentuk itu sudah dipakai
   sebutan petak di kepala yang sama (`.dfakta-l`), jadi ia terbaca sebagai
   SEBUTAN — bukan sebagai isi. Huruf biasa dengan ukuran sekecil ini terbaca
   seperti keterangan yang terpotong. */
.dhead-jenis{display:flex;align-items:center;gap:6px;
  padding:10px 16px 0;font-size:var(--f10);font-weight:600;color:var(--ink-3);
  text-transform:uppercase;letter-spacing:.06em}
.dhead-jenis i{font-style:normal;color:var(--line-strong)}
/* Kepala yang sudah membawa baris ini tidak boleh bertambah tinggi percuma:
   baris nama di bawahnya merapat, karena sebutan dan isinya memang satu
   kesatuan — persis seperti `.dfakta-l` terhadap nilainya. */
.dhead-jenis + .dhead-atas{padding-top:6px}
/* KETERANGAN POLOS TIDAK BERKOTAK (K-264). Diminta pemiliknya: *"yang boleh
   ada garis kiri kanannya cuma card, kalau cuma informasi biasa jangan"*, dan
   *"halaman detail terasa sempit"*. Diukur lebih dulu di layar 390px: Detail
   Pembelian menumpuk LIMA kotak bergaris berpojok bulat, dan dua di antaranya
   — kepala dokumen dan Ringkasan Keuangan — memang bukan kartu. Keduanya
   keterangan polos yang dibungkus kotak tanpa alasan.
   YANG DIBAYAR LEBARNYA, dan itu yang menjawab "sempit": kotaknya 374px di
   layar 390px, jadi 16px hilang untuk celah yang tidak menjelaskan apa pun.
   Dibiarkan mengalir sampai tepi layar, huruf di dalamnya mendapat 16px itu
   kembali. Pemisahnya celah berlatar halaman, bukan garis keliling — cara
   Shopee memisah bagian, dan contoh yang disebutkan pemiliknya sendiri.
   DI TELEPON SAJA (600px ke bawah): di layar lebar halaman detailnya berkolom
   dua, dan pita selebar layar di dalam salah satu kolomnya bukan
   perampingan melainkan kerusakan.
   PENANDANYA DI <body> SATU HALAMAN, bukan aturan menyeluruh: begitu ditulis
   tanpa penanda, ia berlaku di setiap halaman detail sekaligus — dan yang
   diminta pemiliknya satu halaman dulu untuk dilihat. Menyusulkan halaman
   berikutnya cukup menambahkan kelas yang sama. */
@media (max-width:600px){
  body.dok-polos .dhead,
  body.dok-polos .ringkas{border-left:0;border-right:0;border-radius:0;
    margin-left:calc(-1 * var(--pad-hal));margin-right:calc(-1 * var(--pad-hal))}
}
/* Sebesar dua baris judul + meta, jadi ia sejajar dengan keduanya dan bukan
   hanya menempel di sebelah huruf pertama. */
.avatarhuruf.dhead-ava{width:38px;height:38px;flex:none;font-size:var(--f13);border-radius:999px;
  border:1px solid var(--line);margin-top:2px}

/* ---------- TOOLBAR / SEARCH / SORT ---------- */
.toolbar{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-bottom:16px}
.search{position:relative;flex:1 1 300px;min-width:220px;max-width:380px}
.search input{width:100%;height:var(--tinggi-kendali);padding:0 30px 0 32px;border:1px solid var(--line);border-radius:var(--radius);background:var(--surface)}
.search svg{position:absolute;left:10px;top:11px;width:15px;height:15px;color:var(--ink-3)}
.search .clear{position:absolute;right:7px;top:8px;width:22px;height:22px;border:0;background:transparent;color:var(--ink-3);border-radius:var(--radius-kcl);cursor:pointer;line-height:1}
.search .clear:hover{background:var(--line)}
.tool-right{margin-left:auto;display:flex;gap:8px;align-items:center}

/* Pemindai barcode/QR (pindai.js): videonya selebar pop-up, tombol dan
   keadaannya mengambang di atasnya. Bingkai bidiknya TIDAK digambar lagi
   (tahap 7, diminta pemiliknya) — daerah yang dibaca tetap 90% × 55% di
   tengah gambarnya (K-86). */
/* Kotaknya dirapatkan ke gambarnya oleh `rapatkanKotak` di pindai.js, jadi ia
   ikut menciut — dan yang menciut harus tetap berdiri di tengah. */
.pindai-layar{position:relative;line-height:0;margin:0 auto}
/* TINGGINYA DIBATASI OLEH LAYARNYA, bukan cuma oleh 60% tinggi jendela
   (K-149, dilaporkan pemiliknya: "tampilannya saat scan itu kurang bagus untuk
   mobile karena kita harus scroll atas bawah untuk tekan tombol atau lihat
   informasi apa yang tadi tidak bisa keinput"). Di layar telepon 60vh memang
   muat — tetapi di ATASNYA masih ada kepala pop-up dan di BAWAHNYA ada baris
   kendali, baris keadaan, dan tiga tombol; bertiga mereka 250px, jadi yang
   tersisa kurang dan kakinya terdorong keluar layar. Yang dipatok karena itu
   SISA layarnya, dan yang mengalah gambarnya — bukan tombolnya, yang justru
   satu-satunya jalan memindai pada kamera yang tidak mau fokus.

   Angka 300px DIUKUR, bukan ditebak: pada layar 390×640 percobaan pertama
   menyisakan 250px dan badan pop-upnya masih harus digulir 26px — ketahuan dari
   ujinya sendiri, bukan dari membaca kodenya. Sisanya dibulatkan ke atas supaya
   baris keadaan yang melipat dua baris di telepon sungguhan tetap muat. */
.pindai-video{display:block;width:100%;max-height:min(60vh, calc(100dvh - 300px));
  background:#000;border-radius:var(--radius);object-fit:contain}
.pindai-video[hidden]{display:none}
/* TOMBOL DAN KEADAANNYA MENGAMBANG DI ATAS GAMBAR KAMERANYA (tahap 7, ala
   Google Lens — diminta pemiliknya). Tombolnya bulat, gelap tembus pandang,
   berdiri di pojok kanan atas gambarnya; keadaannya pil di tepi bawahnya.
   Warnanya DIPATOK, bukan peubah tema: yang di belakangnya gambar kamera,
   bukan bidang tema. Yang TIDAK ada lagi: garis bidik, deretan tombol zoom,
   tombol Kamera 1/2, Jepret, dan Kamera HP. */
.pindai-kendali{position:absolute;top:10px;right:10px;z-index:2;display:flex;flex-direction:column;gap:10px;line-height:normal}
.pindai-kendali[hidden]{display:none}
.pindai-bulat{width:42px;height:42px;padding:0;border:0;border-radius:50%;display:grid;place-items:center;
  background:rgba(0,0,0,.45);color:#fff;cursor:pointer;
  -webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px)}
.pindai-bulat svg{width:20px;height:20px}
.pindai-bulat--nyala{background:#fff;color:#000}
.pindai-status{position:absolute;left:50%;bottom:12px;z-index:2;transform:translateX(-50%);
  width:max-content;max-width:calc(100% - 24px);margin:0;padding:7px 14px;border-radius:999px;
  background:rgba(0,0,0,.55);color:#fff;font-size:var(--f12);line-height:1.35;text-align:center;
  -webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px)}
/* NAMANYA "SAXO LENS", TIPIS DI TENGAH ATAS (diminta pemiliknya, "kayak
   Google Lens"). Di pop-up ia judulnya: diletakkan di tengah kepala dengan
   `position:absolute`, jadi tanda silang di kanan tidak menggesernya dari
   tengah. Di pemindai yang ditanam (Opname) ia melayang di atas gambarnya. */
.mdl:has(.pindai) .mdl-hd{position:relative;align-items:center}
.mdl:has(.pindai) .mdl-hd > div{position:absolute;left:52px;right:52px;text-align:center;pointer-events:none}
.mdl:has(.pindai) .mdl-hd h3,
.pindai-merek{font-size:var(--f13);font-weight:400;letter-spacing:.02em}
.pindai-merek{position:absolute;top:12px;left:50%;z-index:2;transform:translateX(-50%);
  line-height:normal;color:#fff;white-space:nowrap;pointer-events:none;text-shadow:0 1px 3px rgba(0,0,0,.55)}
/* KAMERA YANG GAGAL MENYALA: gambarnya disembunyikan, jadi tidak ada lagi
   yang bisa ditimpa — dan kotak yang isinya melayang semua setinggi NOL,
   menelan pesan galatnya sendiri. Pilnya kembali berdiri di alirannya. */
.pindai-video[hidden] ~ .pindai-status{position:static;transform:none;margin:12px auto}
/* PEMINDAI YANG DITANAM DI HALAMAN (K-221, Opname). Diminta pemiliknya
   "ringkas aja": gambarnya dipatok sepertiga tinggi layar, dan yang di
   bawahnya cuma baris keadaan beserta dua tombolnya. Ia berdiri di dalam
   kotaknya sendiri supaya terbaca sebagai ALAT, bukan sebagai isi dokumennya.

   Baris keadaannya MEMESAN TINGGINYA (`min-height`): ia berganti bunyi pada
   setiap pindaian, dan baris yang tumbuh-menyusut membuat seluruh halaman
   melompat tepat saat orangnya sedang mendekatkan barang berikutnya. */
.pindaitanam{border:1px solid var(--line);border-radius:var(--radius);
  padding:12px;background:var(--surface-2);margin-bottom:14px}
.pindaitanam .pindai-video{max-height:min(34vh,240px)}
.pindaitanam .pindai-status{display:flex;align-items:center;justify-content:center;gap:7px;flex-wrap:wrap;min-height:20px}
.pindaitanam .pindai-status svg{width:16px;height:16px;flex:none}
.pindai-kabar-n{color:rgba(255,255,255,.7)}
.pindai-kabar-n::before{content:"·";margin-right:7px}
/* NOMOR BERLABEL (K-149): label di kiri, nomornya mengambil sisa lebarnya,
   tombol hapus di ujung kanan. Di layar telepon labelnya turun ke barisnya
   sendiri — combo selebar 150px di samping kolom nomor menyisakan enam huruf
   untuk nomor 15 angka. */
/* HARGA BAWAAN (K-151): penandanya SATU HURUF di depan angkanya, bukan kalimat
   — diminta pemiliknya ("penandanya jangan kalimat apalagi yang kalimat
   panjang, nanti khawatir memenuhi uiux"). Angkanya tetap angka biasa; yang
   ditenangkan cuma tildenya, supaya ia terbaca sebagai penanda dan bukan
   sebagai bagian dari angkanya. */
.hargabawaan > i{font-style:normal;color:var(--ink-3);margin-right:1px}
.nomorbaris{display:grid;grid-template-columns:150px 1fr auto;gap:6px;align-items:start;margin-bottom:6px}
.nomorbaris .inp{margin:0}
@media(max-width:560px){
  .nomorbaris{grid-template-columns:1fr auto;grid-template-areas:"l l" "n h"}
  .nomorbaris > .combo{grid-area:l}
  .nomorbaris > .inp{grid-area:n}
  .nomorbaris > .btn{grid-area:h}
}

/* ---------- FORM ---------- */
.form{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:14px}
.field{display:flex;flex-direction:column;gap:6px;min-width:0}
/* `.field{display:flex}` mengalahkan `[hidden]` bawaan peramban, jadi kolom
   yang disembunyikan tetap tergambar. Berlaku untuk setiap kolom yang cuma
   berdiri pada keadaan tertentu — mis. Tarif Transport pada klaim (K-138). */
.field[hidden]{display:none}
/* Harga Online Shop yang belum diisi (K-141). Ia BUKAN angka, jadi ia tidak
   boleh berupa angka: hurufnya lebih kecil, tenang, dan tidak tebal — supaya
   tidak ada satu pun cara membacanya sebagai "Rp0". */
.hargakosong{font-size:.72em;font-weight:400;color:var(--ink-3);letter-spacing:.01em}
.field.full{grid-column:1 / -1}
/* Satu lajur pada SEMUA lebar, bukan hanya di telepon. Dipakai formulir yang
   kolomnya dibaca berurutan dan tiap isian menentukan isian berikutnya —
   Catat Biaya: arahnya menentukan kategorinya, kategorinya menentukan namanya,
   nominalnya menentukan akunnya. Dua lajur di layar lebar memaksa mata
   melompat kiri-kanan-kiri untuk mengikuti satu urutan yang sebenarnya lurus,
   dan pratinjau "menjadi berapa" di kakinya jadi berjauhan dari nominal yang
   membentuknya. */
.form--tumpuk{grid-template-columns:minmax(0,1fr)}
.field label{font-size:var(--f12);color:var(--ink-2)}
/* Wajib ditandai bintang merah, bukan kata. Kata "wajib" pada delapan kolom
   berturut-turut menjadi kolom teks kelima yang ikut dibaca; bintang terbaca
   sebagai tanda dan bukan sebagai isi. Kata aslinya tetap ada di dalam HTML
   supaya pembaca layar tetap mengucapkannya. Tidak ada penanda "opsional" sama
   sekali — tanpa bintang berarti opsional, dan itu keadaan mayoritas. */
/* Kata "wajib" tetap ditulis apa adanya di HTML supaya pembaca layar
   mengucapkannya; yang terlihat di layar cuma bintang merah.

   `.setsel` ikut di sini sejak baris item Pembelian memakainya: tanpa itu
   labelnya berbunyi "NAMA ITEM WAJIB" — katanya tercetak utuh, dan di label
   yang memang sudah berhuruf besar semua ia terbaca sebagai bagian dari nama
   kolomnya. */
.field .req,.setsel .req{font-size:0;line-height:0;color:var(--stop)}
.field .req::after,.setsel .req::after{content:"*";font-size:var(--f13);line-height:1;font-weight:700;vertical-align:-1px}
.field .hint{font-size:var(--f11);color:var(--ink-3)}
.inp{height:var(--tinggi-kendali);padding:0 11px;border:1px solid var(--line);border-radius:var(--radius);background:var(--surface);width:100%}
/* Ikon yang dititipkan langsung di dalam kolom isian. Tanpa ukuran, SVG
   tanpa lebar melar memenuhi kolomnya — dan sekali terjadi, seluruh kolom
   itu berubah menjadi gambar kaca pembesar setinggi layar. */
.inp > svg{width:15px;height:15px;flex:none;color:var(--ink-3)}
textarea.inp{height:auto;min-height:76px;padding:9px 11px;resize:vertical;font-family:inherit}
.inp[readonly]{background:var(--surface-2);color:var(--ink-2)}
.inp-money{position:relative}
.inp-money span{position:absolute;left:11px;top:9px;font-size:var(--f12);color:var(--ink-3);font-family:var(--f-angka)}
.inp-money input{padding-left:32px;font-family:var(--f-angka);font-variant-numeric:tabular-nums;text-align:right}
.qtybox{display:flex;align-items:center;border:1px solid var(--line);border-radius:var(--radius);overflow:hidden;width:136px;background:var(--surface)}
.qtybox button{width:34px;height:34px;border:0;background:var(--surface-2);cursor:pointer;font-size:var(--f13);color:var(--ink-2)}
.qtybox button:hover{background:var(--line);color:var(--ink)}
.qtybox input{width:100%;height:34px;border:0;text-align:center;background:transparent;font-family:var(--f-angka);font-variant-numeric:tabular-nums}
.radios{display:flex;flex-direction:column;gap:8px}
.radio{display:flex;gap:10px;align-items:flex-start;padding:12px 14px;border:1px solid var(--line);border-radius:var(--radius);cursor:pointer}
.radio:hover{border-color:var(--line-strong)}
.radio input{margin-top:2px;accent-color:var(--ink);width:15px;height:15px}
.radio b{font-size:var(--f12);font-weight:500;display:block}
.radio span{font-size:var(--f12);color:var(--ink-2);display:block;margin-top:1px}
.radio:has(input:checked){border-color:var(--ink);box-shadow:inset 0 0 0 1px var(--ink)}
.chipset{display:flex;flex-wrap:wrap;gap:7px}
.chipopt{border:1px solid var(--line);background:var(--surface);border-radius:999px;padding:6px 12px;font-size:var(--f12);cursor:pointer}
.chipopt:hover{border-color:var(--line-strong)}
.chipopt[aria-pressed="true"]{background:var(--ink);border-color:var(--ink);color:var(--on-ink);font-weight:500}
.inp.err,.combo-btn.err,.qtybox.err{border-color:var(--ink);box-shadow:inset 0 0 0 1px var(--ink)}
.errmsg{font-size:var(--f11);color:var(--ink);display:flex;align-items:center;gap:5px}
.errmsg::before{content:"";width:11px;height:11px;border-radius:50%;background:var(--ink);flex:none}

/* ---------- SELECT / COMBOBOX / MENU ---------- */
.selectwrap{position:relative}
.selectwrap::after{content:"";position:absolute;right:11px;top:14px;width:6px;height:6px;pointer-events:none;
  border-right:1.4px solid var(--ink-2);border-bottom:1.4px solid var(--ink-2);transform:rotate(45deg)}
.selectwrap select{appearance:none;height:var(--tinggi-kendali);padding:0 28px 0 11px;border:1px solid var(--line);border-radius:var(--radius);
  background:var(--surface);cursor:pointer;font-size:var(--f12)}
.selectwrap select:hover{border-color:var(--line-strong)}
.combo{position:relative}
.combo-btn{display:flex;align-items:center;gap:8px;width:100%;height:var(--tinggi-kendali);padding:0 30px 0 11px;border:1px solid var(--line);
  border-radius:var(--radius);background:var(--surface);cursor:pointer;font-size:var(--f12);text-align:left;position:relative}
.combo-btn:hover{border-color:var(--line-strong)}
.combo-btn::after{content:"";position:absolute;right:12px;top:15px;width:6px;height:6px;
  border-right:1.4px solid var(--ink-2);border-bottom:1.4px solid var(--ink-2);transform:rotate(45deg)}
.combo-btn .ph{color:var(--ink-3)}
.combo-btn .sub{font-size:var(--f11);color:var(--ink-3);margin-left:auto;padding-right:8px}
/* Tingginya dipatok oleh posisiPop pada ruang yang benar-benar ada; isinya
   yang menggulir, bukan popnya yang tumbuh melewati tepi layar. */
.pop{position:absolute;z-index:120;background:var(--surface);border:1px solid var(--line);border-radius:var(--radius);
  box-shadow:var(--shadow);padding:5px;min-width:200px;max-width:calc(100vw - 20px);
  display:flex;flex-direction:column;overflow:hidden}
.pop button.mi{display:flex;width:100%;align-items:center;gap:10px;padding:8px 10px;border:0;background:transparent;
  border-radius:var(--radius);cursor:pointer;font-size:var(--f12);text-align:left;color:var(--ink)}
.pop button.mi:hover{background:var(--surface-2)}
.pop button.mi[disabled]{opacity:.42;cursor:not-allowed}
.pop button.mi svg{width:15px;height:15px;flex:none;color:var(--ink-2)}
.pop hr{border:0;border-top:1px solid var(--line);margin:5px 4px}
.pop .k{font-size:var(--f10);letter-spacing:.1em;text-transform:uppercase;color:var(--ink-3);padding:7px 10px 4px}
.combo-pop{padding:0}
.combo-search{padding:8px;border-bottom:1px solid var(--line)}
.combo-search input{width:100%;height:32px;padding:0 10px;border:1px solid var(--line);border-radius:var(--radius);background:var(--surface-2)}
/* flex:1 supaya daftarnya menyusut mengikuti tinggi pop yang sudah dipatok —
   kotak Cari dan kaki "Tambah …" tetap terlihat berapa pun sempitnya ruang. */
.combo-list{flex:1 1 auto;max-height:230px;min-height:60px;overflow-y:auto;padding:5px}
.combo-search,.combo-foot{flex:none}
.combo-opt{display:flex;width:100%;align-items:center;gap:8px;padding:8px 10px;border:0;background:transparent;
  border-radius:var(--radius);cursor:pointer;font-size:var(--f12);text-align:left;color:var(--ink)}
.combo-opt .t{flex:1 1 auto}
.combo-opt .m{font-size:var(--f11);color:var(--ink-3)}
.combo-opt:hover,.combo-opt.cur{background:var(--surface-2)}
.combo-opt[aria-selected="true"]{font-weight:600}
.combo-empty{padding:14px 12px;font-size:var(--f12);color:var(--ink-3);text-align:center}
.combo-foot{border-top:1px solid var(--line);padding:6px}

/* ---------- MODAL / DRAWER ---------- */
.ov{position:fixed;inset:0;z-index:100;background:rgba(8,9,10,.5);display:flex;opacity:0;transition:opacity .14s ease}
.ov.on{opacity:1}
.ov--modal{align-items:flex-start;justify-content:center;padding:44px 20px;overflow-y:auto}
.mdl{background:var(--surface);border:1px solid var(--line);border-radius:var(--radius);box-shadow:var(--shadow);
  width:min(var(--w,540px),100%);display:flex;flex-direction:column;max-height:calc(100vh - 88px);
  transform:translateY(-8px);transition:transform .14s ease}
.ov.on .mdl{transform:none}
.mdl-hd{display:flex;align-items:flex-start;gap:12px;padding:16px 18px;border-bottom:1px solid var(--line)}
.mdl-hd h3{font-size:var(--f14);font-weight:600}
.mdl-hd p{margin:3px 0 0;font-size:var(--f12);color:var(--ink-2)}
.mdl-x{margin-left:auto;border:0;background:transparent;width:30px;height:30px;border-radius:var(--radius);cursor:pointer;color:var(--ink-3);flex:none;
  display:grid;place-items:center}
.mdl-x:hover{background:var(--surface-2);color:var(--ink)}
.mdl-x svg{width:15px;height:15px}
.mdl-bd{padding:18px;overflow-y:auto}
/* Pop-up yang seluruh isinya sudah tertulis di judulnya tidak menyisakan
   badan kosong bersepatu 18px di bawahnya. */
.mdl-bd:empty{display:none}
.mdl-bd > * + *{margin-top:16px}
.mdl-ft{display:flex;gap:8px;justify-content:flex-end;padding:14px 18px;border-top:1px solid var(--line);background:var(--surface-2);flex-wrap:wrap}
.mdl-ft .left{margin-right:auto;align-self:center;font-size:var(--f12);color:var(--ink-2)}
.ov--drawer{justify-content:flex-end}
.drw{background:var(--surface);border-left:1px solid var(--line);width:min(var(--w,460px),100%);height:100%;
  display:flex;flex-direction:column;transform:translateX(14px);transition:transform .16s ease}
.ov.on .drw{transform:none}
.drw-hd{display:flex;align-items:flex-start;gap:12px;padding:16px 18px;border-bottom:1px solid var(--line)}
.drw-hd h3{font-size:var(--f14);font-weight:600}
/* Inisial di kepala drawer: lingkaran berukuran tetap, bukan anak flex yang
   diregangkan setinggi barisnya. `.avatarhuruf` sendiri berukuran 100% karena
   ia dibuat untuk mengisi petak foto yang sudah punya ukuran. */
.avatarhuruf.drw-ava{width:40px;height:40px;flex:none;border-radius:999px;font-size:var(--f13);font-weight:600}
.drw-hd p{margin:3px 0 0;font-size:var(--f12);color:var(--ink-2)}
.drw-bd{padding:18px;overflow-y:auto;flex:1}
.drw-bd > * + *{margin-top:16px}
.drw-ft{display:flex;gap:8px;justify-content:flex-end;padding:14px 18px;border-top:1px solid var(--line);background:var(--surface-2)}

/* ---------- NOTICE ---------- */
.notice{display:flex;gap:11px;padding:13px 15px;border:1px solid var(--line-strong);border-radius:var(--radius);background:var(--surface-2);font-size:var(--f12)}
.notice--strong{border-color:var(--ink);box-shadow:inset 3px 0 0 var(--ink)}
.notice b{display:block;font-size:var(--f12);margin-bottom:3px}
.notice ul{margin:6px 0 0;padding-left:18px;color:var(--ink-2)}
.notice li{margin:2px 0}

/* ---------- EMPTY / LOADING ---------- */
.empty{display:flex;flex-direction:column;align-items:center;gap:10px;padding:56px 24px;text-align:center}
/* KEADAAN KOSONG: SATU gambar saja, bukan dua yang bertumpuk.
   Dulu petak ini menggambar "kartu kosong" sendiri — kotak bergaris putus
   dengan dua garis abu di dalamnya — sementara setiap pemanggilnya menaruh
   IKON di dalam petak yang sama. Yang terlihat: ikon bertumpuk di atas dua
   garis kartu, di setiap halaman yang datanya belum ada. Dilaporkan
   pemiliknya: "iconnya itu selalu ada 2 tumpang tindih, mending icon card yang
   di tengah dihapus." Yang dicabut kartunya; ikon pemanggilnya yang bicara. */
.empty-art{width:92px;height:68px;border:1.5px dashed var(--line-strong);border-radius:var(--radius);
  display:flex;align-items:center;justify-content:center;color:var(--ink-3)}
.empty-art svg{width:30px;height:30px}
.empty h3{font-size:var(--f14);font-weight:600;margin-top:6px}
.empty p{margin:0;color:var(--ink-2);font-size:var(--f12);max-width:46ch}
/* Kerangka daftar: DIAM, tanpa kilau yang menyapu (K-102). Lihat `.krg`. */
.skel{height:10px;border-radius:var(--radius-kcl);background:var(--line)}
.skelcard{border:1px solid var(--line);border-radius:var(--radius);padding:16px;display:flex;flex-direction:column;gap:11px;background:var(--surface)}
@media (prefers-reduced-motion:reduce){.ov,.mdl,.drw,.tst{transition:none}.btn .spin{animation:none}}

/* ---------- TIMELINE ---------- */
.tl{position:relative;padding-left:26px}
.tl::before{content:"";position:absolute;left:5px;top:6px;bottom:6px;width:1px;background:var(--line)}
.tl-item{position:relative;padding:0 0 20px}
.tl-item:last-child{padding-bottom:0}
.tl-dot{position:absolute;left:-26px;top:3px;width:11px;height:11px;border-radius:50%;background:var(--surface);border:1.5px solid var(--line-strong)}
.tl-item[data-key="1"] .tl-dot{background:var(--ink);border-color:var(--ink)}
.tl-time{font-size:var(--f11);color:var(--ink-3);font-variant-numeric:tabular-nums}
.tl-title{font-size:var(--f12);font-weight:500;margin-top:2px}
.tl-desc{font-size:var(--f12);color:var(--ink-2);margin-top:2px}
.tl-who{font-size:var(--f12);color:var(--ink-3);margin-top:3px}

/* ---------- TOAST ---------- */
.toasts{position:fixed;left:50%;bottom:24px;transform:translateX(-50%);z-index:130;display:flex;flex-direction:column;gap:8px;align-items:center;pointer-events:none}
.tst{background:var(--ink);color:var(--on-ink);padding:10px 14px;border-radius:var(--radius);font-size:var(--f12);box-shadow:var(--shadow);
  max-width:min(560px,92vw);display:flex;align-items:center;gap:9px;opacity:0;transform:translateY(10px);
  transition:opacity .15s ease, transform .15s ease}
.tst.on{opacity:1;transform:none}
.tst .m{width:14px;height:14px;border-radius:50%;border:1.6px solid currentColor;flex:none;position:relative}
.tst--ok .m::before{content:"";position:absolute;left:3.5px;top:1px;width:4px;height:7px;border-right:1.6px solid currentColor;border-bottom:1.6px solid currentColor;transform:rotate(40deg)}
.tst--warn .m::before{content:"";position:absolute;left:5.4px;top:2px;width:1.6px;height:5px;background:currentColor}
.tst--warn .m::after{content:"";position:absolute;left:5.4px;bottom:2px;width:1.6px;height:1.6px;background:currentColor}

/* ---------- MISC ---------- */
.amt{font-family:var(--f-angka);font-variant-numeric:tabular-nums;white-space:nowrap}
.amt small{color:var(--ink-3);font-size:var(--f11);margin-right:2px}
.stat{background:var(--surface);border:1px solid var(--line);border-radius:var(--radius);padding:14px 16px;display:flex;flex-direction:column;gap:2px;
  text-align:left;cursor:default;width:100%}
button.stat{cursor:pointer}
button.stat:hover{border-color:var(--line-strong)}
.stat-k{font-size:var(--f11);letter-spacing:.09em;text-transform:uppercase;color:var(--ink-3)}
/* ANGKA TERBESAR DI SELURUH ERP, dan dulu ia satu-satunya yang tidak berhuruf
   mesin ketik. Akibatnya di Dashboard: lima angka bersebelahan yang tidak
   berjajar satu pun — padahal itulah lima angka yang paling sering
   dibandingkan orang, dan dibandingkan sambil lewat. */
.stat-v{font-family:var(--f-angka);font-weight:600;font-size:var(--f18);letter-spacing:-.03em;
  font-variant-numeric:tabular-nums;line-height:1.3}
.stat-v small{font-size:var(--f12);font-weight:500;color:var(--ink-2);margin-right:2px}
.stat-s{font-size:var(--f11);color:var(--ink-2)}
.stat--attn{box-shadow:inset 3px 0 0 var(--ink)}
.minilist{display:flex;flex-direction:column}
.minirow{display:flex;gap:12px;align-items:flex-start;padding:11px 0;border-bottom:1px solid var(--line)}
.minirow:last-child{border-bottom:0}
.minirow .t{flex:1 1 auto;font-size:var(--f12)}
.minirow .t span{display:block;font-size:var(--f11);color:var(--ink-3);margin-top:2px}
.minirow .v{font-family:var(--f-angka);font-size:var(--f12);font-variant-numeric:tabular-nums;white-space:nowrap}
.railtoggle{display:none}

/* ---------- RESPONSIF (desktop-first) ---------- */
@media (max-width:1180px){.grid4{grid-template-columns:repeat(2,minmax(0,1fr))}.grid3{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (max-width:960px){
  .app{grid-template-columns:minmax(0,1fr)}
  /* SELEBAR LAJUR MENU DI LAYAR LEBAR, tidak lebih. Ia sempat dilebarkan
     menjadi 320px karena baris kepalanya dulu berisi tiga benda; sejak tombol
     lokasi turun ke barisnya sendiri dan tombol tutup dicabut, isinya tinggal
     lambangnya saja. 320px di layar 390px menyisakan 70px latar — terlalu
     sempit untuk ditekan dengan ibu jari, padahal justru latar itulah yang
     sekarang menutup lacinya. Dengan 262px sisanya 128px. */
  .rail{position:fixed;left:0;top:0;width:262px;max-width:78vw;z-index:95;transform:translateX(-100%);transition:transform .18s ease}
  body.rail-on .rail{transform:none}
  .railtirai{display:block;position:fixed;inset:0;z-index:94;background:rgba(0,0,0,.45);
    opacity:0;pointer-events:none;transition:opacity .18s ease}
  body.rail-on .railtirai{opacity:1;pointer-events:auto}
  /* Halaman di belakang tidak ikut tergulir selama lacinya terbuka. */
  body.rail-on{overflow:hidden}
  .railtoggle{display:inline-flex}
  .grid2,.grid3,.grid4,.form{grid-template-columns:minmax(0,1fr)}
  .page{--pad-hal:11px;--pad-atas:13px;padding:var(--pad-atas) var(--pad-hal) var(--pad-hal)}
  .dhead{position:static}
}

/* ---------- TABEL (ledger: Stock Card, Mutation, History) ---------- */
.tablewrap{overflow-x:auto;border:1px solid var(--line);border-radius:var(--radius);background:var(--surface)}
table{width:100%;border-collapse:collapse;min-width:640px}
th{text-align:left;font-size:var(--f10);letter-spacing:.09em;text-transform:uppercase;color:var(--ink-3);font-weight:500;
  padding:11px 16px;border-bottom:1px solid var(--line);background:var(--surface-2);white-space:nowrap}
th.r,td.r{text-align:right}
td{padding:12px 16px;border-bottom:1px solid var(--line);font-size:var(--f12);vertical-align:middle}
tbody tr:last-child td{border-bottom:0}
tbody tr[data-click]{cursor:pointer}
tbody tr[data-click]:hover td{background:var(--surface-2)}
td .sub{display:block;font-size:var(--f11);color:var(--ink-3);margin-top:2px}
td a{text-decoration:underline;text-underline-offset:2px}
.qtypos{color:var(--ink);font-weight:500}
.qtyneg{color:var(--ink);font-weight:500}

/* ==========================================================================
   TAMBAHAN REVISI — kartu ringkasan yang bisa diklik, seksi, baris item,
   settlement, dan opname. Tetap satu bahasa visual: monokrom, bentuk sebagai
   pembeda status, bukan warna.
   ========================================================================== */

.grid5{display:grid;grid-template-columns:repeat(5,1fr);gap:12px}
@media (max-width:1180px){ .grid5{grid-template-columns:repeat(3,1fr)} }
@media (max-width:720px){ .grid5{grid-template-columns:repeat(2,1fr)} }

button.stat{cursor:pointer;text-align:left;font:inherit;width:100%;transition:border-color .14s,background .14s,transform .1s}
button.stat:hover{border-color:var(--line-strong);background:var(--surface-2)}
button.stat:active{transform:translateY(1px)}
button.stat[aria-pressed="true"]{border-color:var(--ink);box-shadow:inset 0 0 0 1px var(--ink)}
.stat-go{display:block;margin-top:8px;font-size:var(--f11);letter-spacing:.04em;text-transform:uppercase;color:var(--ink-3)}

s.strike,.strike{text-decoration:line-through;color:var(--ink-3);font-weight:400}
.newval{font-weight:600}
.stackline{display:flex;align-items:baseline;gap:8px;flex-wrap:wrap}

/* Saringan TIDAK melipat, ia MENGGULIR ke samping. Dilipat, satu halaman
   berisi lima saringan berdiri dua baris di layar sempit dan seluruh daftarnya
   terdorong turun; digulir, urutannya tetap sama di lebar layar mana pun dan
   yang tidak muat tinggal digeser. Pop-up combonya menempel pada <body>, jadi
   ia tidak ikut terpotong oleh kotak yang menggulir ini. */
.filters{display:flex;gap:8px;flex-wrap:nowrap;align-items:center;margin-bottom:14px;
  overflow-x:auto;scrollbar-width:thin;overscroll-behavior-x:contain;padding-bottom:2px}
.filters::-webkit-scrollbar{height:6px}
.filters::-webkit-scrollbar-thumb{background:var(--line-strong);border-radius:99px}
/* Yang tidak boleh menyusut: setiap saringannya. Yang boleh: pengganjal
   `flex:1` yang mendorong Urutkan ke kanan — begitu isinya tidak muat, ia
   memang tidak punya alasan untuk memakan tempat. */
.filters > .combo,.filters > .btn,.filters > .pilihbar,.filters > .chipset{flex:none}
.filters .combo{min-width:0}
.filters .combo-btn{min-width:152px;height:var(--tinggi-kendali);padding:0 12px;font-size:var(--f12)}
.filters .combo-btn .sub{display:none}
.filterhead{display:flex;gap:10px;align-items:center;justify-content:space-between;flex-wrap:wrap;margin-bottom:12px}
/* Saringan baris kedua dilarutkan menjadi anak langsung baris pertama, jadi
   seluruh saringan berdiri dalam SATU baris yang sama — di layar lebar ia
   melipat sendiri bila tidak muat, di telepon ia menggulir ke samping. */
.filterhead--satu > .filters{display:contents}
/* BARIS SARINGAN YANG DILIPAT (K-250). `[hidden]` bawaan peramban tidak cukup:
   baris di atas penyebutnya lebih kuat dan akan memenangkannya, jadi cip-cipnya
   justru tetap tergambar — jebakan yang sudah tiga kali memakan korban di
   berkas ini (`.field[hidden]`, `.btn[hidden]`, dan
   `.filterhead--tab > .filters[hidden]`). */
.filterhead > .filters[hidden]{display:none}
.filterhead .search{flex:1;min-width:220px}
/* Pada baris tunggal, batas menyusut kotak cari diturunkan. Ia tetap melar
   mengisi sisa tempat begitu saringannya sedikit; yang berubah cuma seberapa
   keras ia menolak menyempit — dan pada halaman bersaringan lima, dua puluh
   piksel lebar kotak cari itulah yang menentukan barisnya melipat atau tidak. */
.filterhead--satu .search{min-width:180px}
/* Sebaris penuh berarti RAPAT KE KIRI, bukan disebar rata. `space-between`
   masuk akal saat barisnya cuma berisi dua benda — kotak cari di kiri, tombol
   di kanan. Begitu seluruh saringan turun ke baris yang sama, ia menyebarkan
   sisa tempat menjadi jurang-jurang di antara saringan, dan tiga saringan pada
   layar lebar berdiri berjauhan seperti tidak saling berhubungan.
   Yang memang milik ujung kanan cuma `.filterhead-kanan`, dan ia didorong
   sendiri ke sana. */
.filterhead--satu{justify-content:flex-start}
.filterhead--satu > .filterhead-kanan{margin-left:auto}
/* Saringan TIDAK dibiarkan menyusut-dengan-titik-titik. Sempat dicoba, dan
   pada Daftar Pembelian hasilnya "Semua Komplain (7)" terpotong menjadi
   "Semua (7)" — satu-satunya kata yang membedakan saringan itu dari empat
   saringan di sebelahnya justru yang hilang. Sebuah saringan yang tidak bisa
   dikenali lagi lebih buruk daripada sebuah baris kedua. */
/* Saringan lokasi dan tombol Pilih Item berdiri berdampingan di ujung kanan
   baris pencarian, dan melipat bersama-sama saat layarnya menyempit. */
.filterhead-kanan{display:flex;gap:10px;align-items:center;flex-wrap:wrap}
/* Kotak tombol di ujung kanan Daftar Item (pemindai + Pilih Item) ikut
   sebaris: sebagai blok biasa ia diberi lebar sempit lalu kedua tombolnya
   melipat di dalamnya, dan seluruh baris saringan jadi dua baris. */
.filterhead-fp{display:contents}

/* ---------- kartu purchase / sale di halaman list ---------- */
.pcard{display:block;width:100%;text-align:left;font:inherit;background:var(--surface);border:1px solid var(--line);
  border-radius:var(--radius);padding:16px 18px;cursor:pointer;transition:border-color .14s,box-shadow .14s;margin-bottom:10px}
.pcard:hover{border-color:var(--line-strong);box-shadow:var(--shadow)}
.pcard-top{display:flex;gap:16px;align-items:flex-start;justify-content:space-between}
.pcard-name{font-family:var(--f-judul);font-weight:600;font-size:var(--f13);line-height:1.35;color:var(--ink);
  display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:100%}
.pcard-more{font-size:var(--f12);color:var(--ink-3);white-space:nowrap}
.pcard-meta{margin-top:6px;font-size:var(--f12);color:var(--ink-2);display:flex;gap:6px;flex-wrap:wrap;align-items:center}
.pcard-meta i{font-style:normal;color:var(--ink-3)}
.pcard-amt{font-family:var(--f-angka);font-variant-numeric:tabular-nums;font-size:var(--f14);font-weight:500;white-space:nowrap;text-align:right}
.pcard-amt small{display:block;font-family:var(--f-isi);font-size:var(--f11);letter-spacing:.04em;
  text-transform:uppercase;color:var(--ink-3);font-weight:500;margin-bottom:2px}
.pcard-foot{margin-top:12px;padding-top:12px;border-top:1px solid var(--line);display:flex;gap:8px;flex-wrap:wrap;align-items:center}
.chipinfo{display:inline-flex;align-items:center;gap:6px;height:24px;padding:0 9px;border:1px solid var(--line);border-radius:999px;
  font-size:var(--f12);color:var(--ink-2);background:var(--surface-2)}
.chipinfo b{font-family:var(--f-angka);font-weight:500;color:var(--ink)}
/* Cip yang MERINGKAS sesuatu bisa ditekan untuk membacanya lengkap (K-163).
   Sebagai <button> ia membawa huruf bawaan peramban, jadi dua barisnya. */
button.chipinfo{font:inherit;font-size:var(--f12);cursor:pointer}
button.chipinfo:hover{border-color:var(--line-strong)}
/* Angka di dalam chip tetap ikut arah uangnya. Aturan warna chip di atas
   terlalu galak dan sempat menelan merah-hijaunya. */
.chipinfo b.uang--keluar{color:var(--stop)}
.chipinfo b.uang--masuk{color:var(--done)}

/* ---------- seksi pada halaman detail (pengganti tab) ---------- */
.sec{margin-top:22px}
.sec-hd{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;margin-bottom:10px}
.sec-hd h2{font-family:var(--f-judul);margin:0;display:flex;align-items:center;gap:9px}
.sec-hd .n{font-family:var(--f-angka);font-size:var(--f12);color:var(--ink-3);font-weight:400}
/* Angka penerimaan di judul seksi Item. Bukan mono seperti `.n` — isinya
   kalimat pendek, bukan sebuah nominal, dan mono membuat "2 dari 4 diterima"
   terbaca seperti kode dokumen. */
.sec-hitung{font-size:var(--f12);font-weight:400;color:var(--ink-3);white-space:nowrap}
.sec-hd p{margin:2px 0 0;font-size:var(--f12);color:var(--ink-3)}

/* ---------- baris item / biaya / settlement ---------- */
.irow{display:flex;gap:14px;align-items:flex-start;padding:14px 16px;border:1px solid var(--line);border-radius:var(--radius);
  background:var(--surface);margin-bottom:8px}
.irow--btn{cursor:pointer;width:100%;text-align:left;font:inherit;transition:border-color .14s}
.irow--btn:hover{border-color:var(--line-strong)}
.irow-main{flex:1;min-width:0}
.irow-name{font-size:var(--f13);font-weight:500;color:var(--ink);line-height:1.4;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:block}
.irow-name--wrap{white-space:normal}
/* Nama barang yang menjadi jalan ke halaman lain. Bentuknya sama persis
   dengan `.dibeli` di Detail Item: teks biasa, panah kecil di ujungnya, dan
   garis bawah baru muncul saat disentuh. Ia tidak boleh berwarna tautan —
   di dalam sebuah baris item, teks berwarna berarti "angka yang bermasalah". */
.irow-name--tautan{display:flex;align-items:center;gap:5px;text-decoration:none;overflow:visible}
.irow-name--tautan > span{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.irow-name--tautan > svg{width:12px;height:12px;flex:none;color:var(--ink-3)}
.irow-name--tautan:hover > span{text-decoration:underline;text-underline-offset:3px;
  text-decoration-color:var(--line-strong)}
.irow-sub{margin-top:5px;font-size:var(--f12);color:var(--ink-3);display:flex;gap:6px;flex-wrap:wrap;align-items:center}
.irow-sub i{font-style:normal}
.irow-right{display:flex;flex-direction:column;align-items:flex-end;gap:7px;white-space:nowrap}
.irow-amt{font-family:var(--f-angka);font-variant-numeric:tabular-nums;font-size:var(--f13);font-weight:500}
.irow-act{display:flex;gap:7px;align-items:center}
.rowtotal > span:first-child{display:flex;align-items:center;gap:10px;flex-wrap:wrap;min-width:0}
/* Sebutan di kiri, angka di kanan, dan di antara keduanya garis tipis yang
   memanjang — mata menyusurinya dari nama ke angkanya tanpa kehilangan
   baris. Cipnya berdiri persis di sebelah kiri angkanya, karena ia
   menerangkan angka itu, bukan menerangkan sebutannya. */
.rowtotal-garis{flex:1 1 auto;min-width:16px;height:1px;background:var(--line)}
.rowtotal:has(.rowtotal-garis){gap:12px}
.rowtotal:has(.rowtotal-garis) > span:first-child{flex:0 0 auto}
.rowtotal{display:flex;justify-content:space-between;align-items:center;padding:14px 16px;border:1px solid var(--line);
  border-radius:var(--radius);background:var(--surface-2);font-size:var(--f12);margin-top:2px}
.rowtotal b{font-family:var(--f-angka);font-variant-numeric:tabular-nums;font-size:var(--f14);font-weight:600}

/* ---------- ringkasan settlement dan dampak ---------- */
.settlebar{display:flex;align-items:center;justify-content:space-between;gap:14px;flex-wrap:wrap;
  padding:14px 16px;border:1px solid var(--line);border-radius:var(--radius);background:var(--surface-2);margin-bottom:12px}
.settlebar .big{font-family:var(--f-angka);font-variant-numeric:tabular-nums;font-size:var(--f14);font-weight:600}
.settlebar .lbl{font-size:var(--f11);letter-spacing:.04em;text-transform:uppercase;color:var(--ink-3);display:block;margin-bottom:3px}
.impact{border:1px dashed var(--line-strong);border-radius:var(--radius);padding:12px 14px;background:var(--surface-2);font-size:var(--f12)}
.impact .row{display:flex;justify-content:space-between;gap:12px;padding:3px 0}
.impact .row b{font-family:var(--f-angka);font-variant-numeric:tabular-nums}
.srcline{display:flex;gap:8px;align-items:flex-end;margin-bottom:8px}
.srcline .field{flex:1;margin:0}
.srcline .btn{height:38px;flex:none}

/* ---------- opname ---------- */
/* Sisa waktu dibaca sebagai kalimat, bukan sebagai tanggal — merah hanya
   ketika batasnya memang sudah lewat. */
.tenggat{font-size:var(--f12);color:var(--ink-3)}
.tenggat--lewat{color:var(--stop);font-weight:600}
/* Baris kedua dan seterusnya pada isian bertumpuk: labelnya tetap ada, tapi
   tempat tombolnya dibiarkan kosong supaya kolom isiannya tidak bergeser. */
.srcline--lanjut{margin-top:-2px}
.srcline-aksi{flex:none;width:132px;display:flex;margin-bottom:1px}
.srcline-aksi .btn{width:100%}
@media (max-width:640px){ .srcline-aksi{width:100%} }
/* Satu lokasi bisa memakan dua baris — keadaannya di atas, jadwalnya
   sendiri di bawah — jadi garis pemisahnya milik pembungkusnya, bukan milik
   tiap baris; kalau tidak, satu lokasi terbaca sebagai dua. */
.oplok{border-bottom:1px solid var(--line)}
.oplok:last-child{border-bottom:0}
.oplok .setbaris{border-bottom:0}
.oplok--mati{background:var(--surface-2)}
.oplok--mati .setteks{color:var(--ink-3)}
.setbaris--oplok{grid-template-columns:1fr .8fr 1.5fr 1.3fr}
.setbaris--opjadwal{grid-template-columns:repeat(4,minmax(0,1fr));padding-top:0}
/* Nilai yang hanya dibaca ditulis sebagai teks, bukan dimasukkan ke dalam
   kotak isian yang tidak bisa diisi — kotak yang mati justru mengundang
   orang mencoba mengetiknya, dan isinya terpotong bila kepanjangan. */
.setteks{font-size:var(--f12);line-height:1.45;padding:8px 0;overflow-wrap:anywhere}
@media(max-width:900px){
  .setbaris--oplok,.setbaris--opjadwal{grid-template-columns:1fr 1fr}
}
.serialtag{font-family:var(--f-angka);font-size:var(--f12);letter-spacing:.03em;color:var(--ink-2);
  background:var(--surface-2);border:1px solid var(--line);border-radius:var(--radius-kcl);padding:1px 6px;display:inline-block}
/* Serial yang bisa DISALIN. Bentuknya tidak berubah sedikit pun — ia sudah
   berkotak, dan sebuah kotak di antara teks polos sudah cukup mengatakan "aku
   bisa ditekan", aturan yang sama dengan nomor dokumen di kepala dokumen.
   Ikon salin di sebelahnya justru menambah satu benda 12px pada baris yang
   memang sedang dihemat. */
.serialtag--salin{font:inherit;font-family:var(--f-angka);font-size:var(--f12);
  cursor:pointer;line-height:1.5}
.serialtag--salin:hover{border-color:var(--line-strong);color:var(--ink)}
/* Tautan berikon sebentuk dengan serialnya: tombol Cetak Label berdiri tepat
   di sebelah serial yang akan dicetaknya. */
.serialtag--ikon{display:inline-grid;place-items:center;padding:0 6px;cursor:pointer;color:var(--ink-2)}
.serialtag--ikon svg{width:13px;height:13px}
.serialtag--ikon:hover{border-color:var(--line-strong);color:var(--ink)}
/* Nama untuk pembaca layar, tidak untuk mata: ikon boleh menggantikan kata di
   layar, tetapi tidak boleh menghapus kata itu dari halamannya. */
.sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;
  clip:rect(0 0 0 0);white-space:nowrap;border:0}
.checkrow{display:flex;align-items:center;gap:12px;padding:12px 14px;border:1px solid var(--line);border-radius:var(--radius);
  background:var(--surface);margin-bottom:7px;cursor:pointer;width:100%;text-align:left;font:inherit;transition:border-color .14s}
.checkrow:hover{border-color:var(--line-strong)}
.checkrow .bx{width:20px;height:20px;border:1.5px solid var(--line-strong);border-radius:var(--radius-kcl);flex:none;display:grid;place-items:center}
.checkrow[aria-pressed="true"] .bx{background:var(--ink);border-color:var(--ink)}
.checkrow[aria-pressed="true"] .bx::after{content:"";width:9px;height:5px;border-left:2px solid var(--surface);
  border-bottom:2px solid var(--surface);transform:rotate(-45deg) translate(1px,-1px)}
.chipopt.on{background:var(--ink);border-color:var(--ink);color:var(--on-ink);font-weight:500}
.linkbtn{border:0;background:none;padding:0;font:inherit;font-size:var(--f11);color:var(--ink);text-decoration:underline;cursor:pointer}
.drwsub{font-family:var(--f-judul);font-size:var(--f12);font-weight:600;margin:18px 0 8px;color:var(--ink)}
.form .hint{font-size:var(--f11);color:var(--ink-3);display:block;margin-top:5px}
.sec .empty{padding:30px 18px}
.sec .empty-art{width:44px;height:44px;margin-bottom:10px}
.sec .empty-art svg{width:20px;height:20px}
.sec .empty h3{font-size:var(--f13)}


/* ==========================================================================
   TAMBAHAN REVISI KEDUA
   Warna hanya dipakai untuk status utama dokumen — abu-abu menunggu,
   kuning berjalan, hijau selesai, merah batal. Sisanya tetap monokrom.
   ========================================================================== */
:root{
  /* Menunggu itu keadaan, bukan ketiadaan keadaan. Abu-abu membuatnya
     terbaca seperti baris yang dimatikan; biru membuatnya terbaca sebagai
     pekerjaan yang memang sedang menunggu giliran. Merah tetap dipegang
     yang sudah lewat batas, jadi keduanya tidak pernah tertukar. */
  --wait:#1d4ed8; --wait-bg:#eaf0fe; --wait-line:#bacef8;
  --run:#8a6100;  --run-bg:#fdf3d7;  --run-line:#e8d08a;
  --done:#186b3f; --done-bg:#e6f4ec; --done-line:#a8d8bd;
  --stop:#a11d1d; --stop-bg:#fdeaea; --stop-line:#efb4b4;
}
:root{ --done:#186b3f; }
@media (prefers-color-scheme: dark){ :root:not([data-theme="light"]){
  --wait:#7fb0ff; --wait-bg:#131f36; --wait-line:#27467d;
  --run:#e2b23c;  --run-bg:#2e2712;  --run-line:#5c4a15;
  --done:#5fc98d; --done-bg:#12271b;  --done-line:#1f4c33;
  --stop:#f08585; --stop-bg:#2c1414;  --stop-line:#5a2626;
}}
:root[data-theme="dark"]{
  --wait:#7fb0ff; --wait-bg:#131f36; --wait-line:#27467d;
  --run:#e2b23c;  --run-bg:#2e2712;  --run-line:#5c4a15;
  --done:#5fc98d; --done-bg:#12271b;  --done-line:#1f4c33;
  --stop:#f08585; --stop-bg:#2c1414;  --stop-line:#5a2626;
}
.pill--wait{color:var(--wait);background:var(--wait-bg);border-color:var(--wait-line)}
.pill--run {color:var(--run); background:var(--run-bg); border-color:var(--run-line)}
.pill--done{color:var(--done);background:var(--done-bg);border-color:var(--done-line)}
.pill--stop{color:var(--stop);background:var(--stop-bg);border-color:var(--stop-line)}
.pill--wait .mk,.pill--run .mk,.pill--done .mk,.pill--stop .mk{border-color:currentColor}
.pill--run .mk--half{background:linear-gradient(90deg,currentColor 50%,transparent 50%)}
.pill--stop .mk--full,.pill--run .mk--full{background:currentColor}

/* ---------- sesi & akses ---------- */
.railout + .railout{margin-left:6px}
/* Tombol Pasang Aplikasi lahir tersembunyi dan hanya muncul kalau
   peramban memang menawarkannya. `.railout` memakai `display:grid`,
   yang mengalahkan `[hidden]` bawaan peramban — tanpa baris ini tombolnya
   tetap terlihat. Dan yang berdiri di belakangnya harus mengambil alih
   dorongan ke kanan, kalau tidak seluruh kaki menu bergeser ke kiri
   justru pada komputer yang tidak bisa memasang apa pun. */
.railout[hidden]{display:none}
.railout[hidden] + .railout{margin-left:auto}
.railout{margin-left:auto;width:28px;height:28px;display:grid;place-items:center;border:1px solid var(--rail-line);
  border-radius:var(--radius);background:transparent;color:var(--rail-muted);cursor:pointer}
.railout:hover{color:var(--rail-ink);border-color:var(--rail-ink)}
.railout svg{width:15px;height:15px}
.noacc{min-height:100vh;display:grid;place-items:center;padding:40px;text-align:center;background:var(--ground)}
.noacc h1{font-family:var(--f-judul);font-size:var(--f18);margin:0 0 8px}
.noacc p{color:var(--ink-2);font-size:var(--f13);max-width:460px;margin:0 auto 18px}

/* ---------- layar masuk ---------- */
.login{min-height:100vh;display:grid;grid-template-columns:1.1fr 1fr;background:var(--ground)}
.login-art{background:linear-gradient(to bottom,rgba(5,6,7,.9) 0,rgba(5,6,7,.55) 18%,rgba(5,6,7,0) 38%),linear-gradient(to top,rgba(5,6,7,.7) 0,rgba(5,6,7,0) 45%),linear-gradient(to right,rgba(5,6,7,0) 78%,#0a0b0d 100%),linear-gradient(rgba(8,10,14,.42),rgba(8,10,14,.42)),url(login-tim.jpg) 58% 35%/cover #050607;color:var(--rail-ink);padding:48px;display:flex;flex-direction:column;justify-content:space-between}
.login-form{display:grid;place-items:center;padding:40px 24px}
.login-box{width:100%;max-width:360px}
.login-box h1{font-family:var(--f-judul);font-size:var(--f18);margin:0 0 18px}
/* Ditulis SESUDAH .login-art karena keduanya sama kuat dan yang belakangan
   menang — di depan, display:none-nya kalah oleh display:flex di bawahnya
   dan lajur kirinya ikut tampil di telepon.
   Di telepon halaman Masuk MENETAP: setinggi layar persis, tidak bisa digulir,
   isinya cuma lambang, dua kolom, dan tombolnya. Lambangnya pindah ke atas
   formulir karena lajur kirinya disembunyikan; kalimat pengantar dicabut. */
.login-merek{display:none}
@media (max-width:860px){
  .login{grid-template-columns:1fr;height:100dvh;min-height:0;overflow:hidden}
  .login-art{display:none}
  .login-form{padding:16px 24px}
  .login-box h1{display:none}
  .login-merek{display:flex;flex-direction:column;align-items:center;gap:10px;margin-bottom:26px}
  .login-merek .brand-mark{width:64px;height:64px}
  .login-merek .brand-name{font-size:var(--f12);letter-spacing:.45em}
}

/* ---------- kartu daftar pembelian versi baru ---------- */
.pc{width:100%;text-align:left;font:inherit;background:var(--surface);border:1px solid var(--line);
  border-radius:var(--radius);cursor:pointer;transition:border-color .14s,box-shadow .14s;margin-bottom:10px}
.pc:hover{border-color:var(--line-strong);box-shadow:var(--shadow)}
.pc-who{min-width:0;display:flex;align-items:center;gap:11px;font-size:var(--f13);color:var(--ink-2);overflow:hidden}
.pc-who b{color:var(--ink);font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:26ch;font-size:var(--f14)}
.pc-who .id{font-family:var(--f-angka);font-size:var(--f12);color:var(--ink-3);white-space:nowrap}
.pc-more{margin-top:7px}
.pc-more>button{border:0;background:none;padding:0;font:inherit;font-size:var(--f12);color:var(--ink-2);
  text-decoration:underline;cursor:pointer}
.pc-list{margin-top:8px;border-top:1px solid var(--line);padding-top:8px;display:none}
.pc-list.on{display:block}
.pc-list .l{display:flex;justify-content:space-between;gap:12px;padding:4px 0;font-size:var(--f12);color:var(--ink-2)}
.pc-list .l span:first-child{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pc-sum{margin-top:9px;padding-top:9px;border-top:1px solid var(--line)}
.pc-sum .l{display:flex;justify-content:space-between;gap:12px;font-size:var(--f12);color:var(--ink-2);padding:2px 0}
.pc-sum .l b{font-family:var(--f-angka);font-variant-numeric:tabular-nums;color:var(--ink);font-weight:500}
.pc-tags{display:flex;gap:7px;flex-wrap:wrap;align-items:center}

/* ---------- foto unit ---------- */
.thumb{width:64px;height:64px;flex:none;border-radius:var(--radius);border:1px solid var(--line);background:var(--surface-2);
  object-fit:cover;display:block}
.thumb--empty{display:grid;place-items:center;color:var(--ink-3)}
.thumb--empty svg{width:22px;height:22px}
.fotogrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(120px,1fr));gap:10px}
.fotocell{position:relative;aspect-ratio:1;border:1px solid var(--line);border-radius:var(--radius);overflow:hidden;background:var(--surface-2)}
.fotocell img{width:100%;height:100%;object-fit:cover;display:block}
.fotocell .util{position:absolute;inset:auto 0 0 0;display:flex;gap:4px;padding:5px;background:linear-gradient(transparent,rgba(0,0,0,.6))}
.fotocell .util button{flex:1;border:0;border-radius:var(--radius-kcl);background:rgba(255,255,255,.9);color:#111;font-size:var(--f11);
  padding:3px 0;cursor:pointer}
.fotocell .pri{position:absolute;top:5px;left:5px;background:var(--ink);color:var(--on-ink);font-size:var(--f10);
  padding:2px 6px;border-radius:99px}
.cropwrap{position:relative;width:100%;aspect-ratio:1;background:#111;border-radius:var(--radius);overflow:hidden;touch-action:none;cursor:grab}
.cropwrap:active{cursor:grabbing}
.cropwrap canvas{width:100%;height:100%;display:block}
/* Tiga kali tiga, garis putih tipis. Dua garis mendatar dan dua tegak sudah
   cukup untuk mengatakan "ini bingkai potong" — kotak-kotak penuh justru
   menutupi gambar yang sedang diatur. */
.cropgrid{position:absolute;inset:0;pointer-events:none;
  background:
    linear-gradient(to right,transparent calc(33.333% - .5px),rgba(255,255,255,.45) calc(33.333% - .5px),
      rgba(255,255,255,.45) calc(33.333% + .5px),transparent calc(33.333% + .5px)),
    linear-gradient(to right,transparent calc(66.666% - .5px),rgba(255,255,255,.45) calc(66.666% - .5px),
      rgba(255,255,255,.45) calc(66.666% + .5px),transparent calc(66.666% + .5px)),
    linear-gradient(to bottom,transparent calc(33.333% - .5px),rgba(255,255,255,.45) calc(33.333% - .5px),
      rgba(255,255,255,.45) calc(33.333% + .5px),transparent calc(33.333% + .5px)),
    linear-gradient(to bottom,transparent calc(66.666% - .5px),rgba(255,255,255,.45) calc(66.666% - .5px),
      rgba(255,255,255,.45) calc(66.666% + .5px),transparent calc(66.666% + .5px));
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.35)}

/* Sama perlakuannya dengan .pc-meta pada kartu Purchase: didorong ke dasar
   kolom dan diberi garis tipis di atasnya. Dua keluarga kartu ini dibaca
   bergantian sepanjang hari — keterangan waktunya harus duduk di tempat yang
   sama di keduanya. */
/* Ikonnya disejajarkan pada GARIS TENGAH hurufnya, bukan pada garis dasar
   kotaknya. Huruf mesin ketik duduk lebih tinggi daripada tengah barisnya,
   jadi ikon yang dipusatkan begitu saja terlihat melorot setengah piksel di
   sebelah "23 Ags". */

/* ---------- katalog marketplace ---------- */
.shopgrid{display:grid}
.shopcard{border:1px solid var(--line);border-radius:var(--radius);overflow:hidden;background:var(--surface);
  display:flex;flex-direction:column;cursor:pointer;transition:box-shadow .14s,border-color .14s;text-align:left;font:inherit;padding:0}
.shopcard:hover{border-color:var(--line-strong);box-shadow:var(--shadow)}
.shopcard .ph{aspect-ratio:1;background:var(--surface-2);display:grid;place-items:center;color:var(--ink-3);overflow:hidden}
.shopcard .ph img{width:100%;height:100%;object-fit:cover}
.shopcard .bd{padding:12px 13px 14px}
.shopcard h3{font-family:var(--f-judul);font-size:var(--f13);font-weight:400;letter-spacing:normal;
  margin:0 0 7px;line-height:1.32;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.shopcard p{margin:0 0 9px;font-size:var(--f12);color:var(--ink-3);line-height:1.5;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.shopcard .pr{font-family:var(--f-angka);font-size:var(--f13);font-weight:600}

/* ---------- absensi ---------- */
.absgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));gap:10px}
.abscard{border:1px solid var(--line);border-radius:var(--radius);background:var(--surface);padding:14px}
.abscard .nm{font-weight:600;font-size:var(--f13)}
.abscard .rl{font-size:var(--f12);color:var(--ink-3);margin-top:2px}
.abscard .tm{margin-top:10px;display:flex;gap:14px;font-size:var(--f12);font-family:var(--f-angka)}
.abscard .tm span small{display:block;font-family:var(--f-isi);font-size:var(--f10);
  letter-spacing:.06em;text-transform:uppercase;color:var(--ink-3)}
.shopcard .bd{display:flex;flex-direction:column;flex:1}
.shopcard h3{min-height:2.7em}
.shopcard p{flex:1}
.shopcard .pr{margin-top:auto}

/* ==========================================================================
   PERBAIKAN GLOBAL — ISIAN, MODE GELAP, DAN TATA LETAK
   Satu tempat untuk seluruh aplikasi. Sebelumnya .inp hanya memberi kotak,
   sementara <input> dan <textarea> di dalamnya tetap memakai bawaan browser —
   itulah asal latar putih, garis asing, dan teks tak terbaca di mode gelap.
   ========================================================================== */

/* Memberi tahu browser tema yang sedang berlaku, supaya scrollbar, pemilih
   tanggal, dan tombol bawaannya ikut menyesuaikan. */
:root{color-scheme:light}
@media (prefers-color-scheme: dark){ :root:not([data-theme="light"]){color-scheme:dark} }
:root[data-theme="dark"]{color-scheme:dark}
:root[data-theme="light"]{color-scheme:light}

/* ---------- kotak isian ---------- */
.inp{display:flex;align-items:center;gap:8px;min-height:38px;height:auto;padding:0 11px;
  border:1px solid var(--line);border-radius:var(--radius);background:var(--surface);width:100%;
  transition:border-color .13s ease, box-shadow .13s ease}
.inp > input,
.inp > textarea,
.inp > select{
  flex:1 1 auto;min-width:0;width:100%;
  border:0;outline:0;background:transparent;color:var(--ink);
  font:inherit;font-size:var(--f12);padding:0;margin:0;
  -webkit-appearance:none;appearance:none;border-radius:0}
.inp > input{height:var(--tinggi-kendali);line-height:var(--tinggi-kendali)}
.inp > select{height:var(--tinggi-kendali);cursor:pointer;padding-right:18px}
.inp > textarea{min-height:66px;padding:9px 0;line-height:1.55;resize:vertical;font-family:inherit;display:block}
.inp:has(textarea){align-items:stretch;padding:0 11px}
.inp > span{flex:none;font-size:var(--f12);color:var(--ink-3)}
.inp:hover{border-color:var(--line-strong)}
.inp:focus-within{border-color:var(--focus);box-shadow:0 0 0 3px color-mix(in srgb, var(--focus) 16%, transparent)}
.inp > input::placeholder,
.inp > textarea::placeholder{color:var(--ink-3);opacity:1}
.inp[readonly],.inp:has(> input[readonly]),.inp:has(> textarea[readonly]){background:var(--surface-2)}
.inp:has(> input[readonly]) > input,
.inp:has(> textarea[readonly]) > textarea{color:var(--ink-2);cursor:default}
.inp:has(> input[readonly]):focus-within,
.inp:has(> input:disabled):focus-within{box-shadow:none;border-color:var(--line)}
.inp:has(> input:disabled),.inp:has(> select:disabled){background:var(--surface-2);opacity:.7;cursor:not-allowed}
.inp > input:disabled,.inp > select:disabled{cursor:not-allowed;color:var(--ink-3)}

/* nominal uang: prefiks Rp ikut mengalir, bukan ditumpuk absolut */
.inp-money{position:static}
.inp-money > span{position:static;font-family:var(--f-angka);color:var(--ink-3)}
.inp-money > input{padding-left:0;text-align:right;
  font-family:var(--f-angka);font-variant-numeric:tabular-nums}

/* isian berkas dan tanggal */
.inp > input[type="file"]{height:auto;padding:8px 0;line-height:1.4;font-size:var(--f12);color:var(--ink-2);cursor:pointer}
.inp > input[type="file"]::file-selector-button{
  margin-right:10px;padding:5px 11px;border:1px solid var(--line);border-radius:var(--radius);
  background:var(--surface-2);color:var(--ink);font:inherit;font-size:var(--f12);cursor:pointer}
.inp > input[type="file"]::file-selector-button:hover{border-color:var(--line-strong)}
.inp > input[type="date"],.inp > input[type="time"]{color-scheme:inherit}
.inp > input[type="date"]::-webkit-calendar-picker-indicator,
.inp > input[type="time"]::-webkit-calendar-picker-indicator{filter:none;opacity:.6;cursor:pointer}
.inp > input[type="search"]::-webkit-search-cancel-button{-webkit-appearance:none;appearance:none}
.inp > input[type="number"]::-webkit-outer-spin-button,
.inp > input[type="number"]::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}
.inp > input[type="range"]{-webkit-appearance:auto;appearance:auto;accent-color:var(--ink);height:auto}

/* isian mandiri di luar .inp — pencarian, combo, dan sejenisnya */
.search input,.combo-search input{color:var(--ink);-webkit-appearance:none;appearance:none}
.search input::placeholder,.combo-search input::placeholder{color:var(--ink-3);opacity:1}
.search input:focus,.combo-search input:focus{outline:0;border-color:var(--focus);
  box-shadow:0 0 0 3px color-mix(in srgb, var(--focus) 14%, transparent)}
.search input::-webkit-search-cancel-button{-webkit-appearance:none;appearance:none}
input[type="range"]{accent-color:var(--ink);width:100%}
.selectwrap select{color:var(--ink)}
.selectwrap select option,.inp > select option{background:var(--surface);color:var(--ink)}

/* isian otomatis dari browser jangan mengembalikan latar putih */
.inp > input:-webkit-autofill,
.inp > input:-webkit-autofill:hover,
.inp > input:-webkit-autofill:focus,
.search input:-webkit-autofill{
  -webkit-text-fill-color:var(--ink);
  -webkit-box-shadow:0 0 0 1000px var(--surface) inset;
  caret-color:var(--ink);transition:background-color 9999s ease-out}

/* tanda kesalahan: bentuk, bukan warna, tetapi cukup tegas */
.inp.err,.combo-btn.err,.qtybox.err,.inp:has(.err){border-color:var(--focus);box-shadow:inset 0 0 0 1px var(--focus)}
.inp.err:focus-within{box-shadow:inset 0 0 0 1px var(--focus), 0 0 0 3px color-mix(in srgb, var(--focus) 16%, transparent)}

/* ---------- tata letak formulir ----------
   Apa pun yang bukan .field selalu memakai lebar penuh, supaya judul bagian,
   catatan, tombol, dan baris ganda tidak terjepit di satu kolom. */
.form > *:not(.field){grid-column:1 / -1;min-width:0}
.form .field{min-width:0}
.form h4,.form .drwsub{margin:2px 0 0}
.srcline{align-items:flex-end}
.srcline > .field{min-width:0}
.srcline > .btn{margin-bottom:1px}
@media (max-width:640px){
  .form{grid-template-columns:minmax(0,1fr)}
  .srcline{flex-wrap:wrap}
  .srcline > .field{flex:1 1 100%}
}

/* ---------- pilihan combo: satu baris, tidak pernah membungkus ---------- */
.combo-opt{align-items:baseline}
.combo-opt .t{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.combo-opt .m{flex:0 0 auto;max-width:44%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  font-size:var(--f11);color:var(--ink-3);text-align:right}
.combo-btn{overflow:hidden}
.combo-btn > span:first-child{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}
.combo-btn .sub{flex:0 0 auto;max-width:40%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* Keterangan yang berupa IKON, bukan kata (K-119): saringan lokasi yang
   terkunci menyebut nama lokasinya saja plus gembok, dan kalimat lengkapnya
   tinggal di judul tetikusnya. */
.combo-btn .sub--ik{display:inline-flex;align-items:center;max-width:none}
.combo-btn .sub--ik svg{width:13px;height:13px}
.combo-pop{max-width:min(92vw, 460px)}

/* ---------- modal & drawer: tidak ada yang boleh meluber ---------- */
.mdl-bd{overflow-x:hidden;overscroll-behavior:contain}
.mdl-bd > *{min-width:0;max-width:100%}
.mdl-hd h3{min-width:0;overflow-wrap:anywhere}
.drw-bd{overflow-x:hidden}
.drw-bd > *{min-width:0;max-width:100%}
.mdl-ft .btn,.drw-ft .btn{white-space:nowrap}
@media (max-width:560px){
  .ov--modal{padding:14px 10px}
  .mdl{max-height:calc(100vh - 28px)}
  .mdl-ft{justify-content:stretch}
  .mdl-ft .btn{flex:1 1 auto;justify-content:center}
}

/* ---------- batang gulir yang tenang ---------- */
*{scrollbar-width:thin;scrollbar-color:var(--line-strong) transparent}
::-webkit-scrollbar{width:10px;height:10px}
::-webkit-scrollbar-track{background:transparent}
::-webkit-scrollbar-thumb{background:var(--line-strong);border-radius:99px;border:3px solid transparent;background-clip:content-box}
::-webkit-scrollbar-thumb:hover{background:var(--ink-3);background-clip:content-box}

/* ---------- perataan baris agar tidak bertabrakan ---------- */
.irow{flex-wrap:wrap}
.irow-main{flex:1 1 260px}
.irow-right{flex:0 0 auto;max-width:100%;align-items:flex-end}
.irow-act{flex-wrap:wrap;justify-content:flex-end}
.sec-hd{align-items:flex-end}
.sec-hd > div:first-child{min-width:0;flex:1 1 260px}
.page-head{align-items:flex-start;gap:16px}
.page-head > div:first-child{min-width:0}
.head-actions{flex-wrap:wrap;justify-content:flex-end}
.stat{min-width:0}
.stat-v{overflow-wrap:anywhere}
.settlebar{min-width:0}
.rowtotal{gap:12px;flex-wrap:wrap}

/* item lain pada kartu daftar tampil sama persis dengan item pertama */
.pc-list{margin-top:0;border-top:0;padding-top:0}
.pc-list .pc-row{margin-top:8px}
.pc-more{margin-top:8px}

/* oranye khusus tahap "sedang dikirim" — di antara menunggu dan sampai */
:root{ --send:#9a4f10; --send-bg:#fdf0e2; --send-line:#efc79b; }
@media (prefers-color-scheme: dark){ :root:not([data-theme="light"]){
  --send:#e79a55; --send-bg:#2c1d10; --send-line:#5b3a1b; } }
:root[data-theme="dark"]{ --send:#e79a55; --send-bg:#2c1d10; --send-line:#5b3a1b; }
.pill--send{color:var(--send);background:var(--send-bg);border-color:var(--send-line)}
.pill--send .mk{border-color:currentColor}
.pill--send .mk--half{background:linear-gradient(90deg,currentColor 50%,transparent 50%)}
.irow-main--btn{cursor:pointer;border-radius:var(--radius);margin:-4px -6px;padding:4px 6px}
.irow-main--btn:hover{background:var(--surface-2)}
.lblkecil{display:block;font-family:var(--f-isi);font-size:var(--f10);
  letter-spacing:.05em;text-transform:uppercase;color:var(--ink-3);font-weight:500;margin-top:2px}

/* ==========================================================================
   ONLINE SHOP — tampilan pelanggan
   ========================================================================== */
.shophead{position:sticky;top:0;z-index:40;background:var(--surface);border-bottom:1px solid var(--line)}
/* NAMA BARANG DI ETALASE DIKETIK BEBAS, DAN SERING SATU KATA PANJANG (K-179).
   Dilaporkan pemiliknya: "teksnya banyak yang keluar sampai ke kanan layar."
   Diukur di layar 360px dengan nama sepanjang nama sungguhan — bukan nama
   pendek milik data contoh: judul halaman produk melebarkan halamannya
   menjadi 879px, dua setengah kali lebar layarnya, dan nama di kartu terpotong
   di tengah huruf.

   Sebabnya satu: kata tanpa spasi tidak punya SATU PUN tempat untuk melipat,
   jadi ia menembus apa pun yang membatasinya. `anywhere` memberi tempat itu —
   dan ia ikut menentukan lebar terkecil sebuah kotak, jadi halamannya pun
   berhenti melebar. Ditulis SEKALI di pembungkus etalase (ia diwariskan ke
   seluruh isinya), bukan satu per satu di tiap judul: yang lahir besok ikut
   terjaga tanpa satu baris pun ditambahkan. */
/* `--shop-pad` supaya jarak sisinya cuma hidup di SATU tempat: foto produk
   di layar telepon menembusnya dengan margin negatif sebesar angka yang
   sama (K-182), dan dua angka yang harus cocok tetapi ditulis di dua
   tempat cepat atau lambat meleset — persis yang terjadi sebelum ini,
   dan yang tersisa celah 4px yang tidak bisa dijelaskan siapa pun. */
/* JARAK SISINYA DIPERSEMPIT DAN LAJURNYA DILEBARKAN (K-222), diminta
   pemiliknya: "pada halaman online shop masih banyak space di sisi kiri
   kanan, itu tolong lebih dipersempit". Angkanya disamakan dengan `--pad-hal`
   milik seluruh ERP (14 · 11 · 8) — Consistency Above Everything, dan dua
   angka jarak sisi yang berbeda pada satu aplikasi terbaca sebagai dua
   halaman yang tidak sekeluarga. */
.shopwrap{--shop-pad:14px;max-width:1400px;margin:0 auto;padding:0 var(--shop-pad);overflow-wrap:anywhere}
.shophead .shopwrap{display:flex;align-items:center;gap:12px;min-height:60px}
/* Lambang halaman Masuk (K-312): ikon berkeping — petak hitam bersudut bulat berpinggir perak (`assets/login-logo.png`) — sama di laptop dan telepon;
   keping itu sendiri yang menjadi permukaan gelap di belakang X-nya, jadi tidak ada lingkaran hitam lagi. */
/* KOTAK CARI ETALASE (K-209): satu kotak, kolomnya di dalamnya, dan tombol
   hitam di ujung kanannya. SUDUTNYA LANCIP sejak tahap 6a — ralat pemiliknya:
   "branding saxo cell tidak bulat, tapi lancip" — pil membulat K-209 lahir
   dari naskah berbahasa Inggris ("rounded") yang dibaca terlalu harfiah.

   Kelas `.search` SENGAJA DIPERTAHANKAN di sebelahnya: aturan placeholder,
   fokus, dan isian-otomatis peramban semuanya menempel di sana (baris 1344
   ke bawah), dan mencabutnya berarti menyalin ketiganya ke tempat kedua.
   Yang ditimpa di sini cuma rupanya. */
/* LEBIH TIPIS DAN TIDAK MENGOTAK (K-281, diminta pemiliknya: "kolom
   searchnya terlalu besar/tinggi ... terlalu mengkotak banget, dan icon search
   yang dikelilingi kotak itu terlalu kasar, sebaiknya gak usah ada kotak,
   cukup icon kaca pembesar aja"). Tingginya 36px (dulu 46px), garis tepinya
   dicabut dan diganti bidang yang sedikit lebih gelap dari latar kepalanya —
   dihitung dari tintanya, jadi terbaca di tema terang maupun gelap — dan
   tombol carinya tinggal kaca pembesar tanpa alas. Sudutnya tetap lancip. */
.shopsearch{max-width:560px;flex:1 1 auto;margin:0 auto;display:flex;align-items:center;gap:2px;
  background:color-mix(in srgb, var(--ink) 7%, var(--surface));border:1px solid transparent;
  border-radius:var(--radius);padding:0 2px 0 12px;height:36px}
.shopsearch input{flex:1;min-width:0;width:auto;height:auto;padding:6px 0;border:0;background:none;border-radius:0}
/* Cincin fokusnya pindah ke PIL-nya: kolomnya sendiri sudah tidak bergaris,
   jadi cincin di sana melayang di tengah pil tanpa tepi yang mengikutinya. */
.shopsearch input:focus{border-color:transparent;box-shadow:none}
/* Fokusnya cuma garis tipis — cincin tebal mengembalikan rupa kotak yang
   baru saja dicabut (K-281). */
.shopsearch:focus-within{border-color:var(--line-strong);box-shadow:none}
.shopcari{flex:none;width:32px;height:32px;padding:0;border:0;border-radius:var(--radius-kcl);background:none;color:var(--ink-2);
  display:grid;place-items:center;cursor:pointer;transition:color .15s}
@media (hover:hover){ .shopcari:hover{color:var(--ink)} }
/* `.search svg` menaruh ikonnya melayang di tepi kiri kotak; di sini ikonnya
   berada DI DALAM tombol, jadi letaknya dikembalikan ke aliran biasa. */
.shopcari svg{position:static;left:auto;top:auto;width:17px;height:17px;color:inherit}
/* TOMBOL X (tahap 6a): cuma tampak selagi kolomnya berisi. Kolom cari bawaan
   peramban punya silangnya sendiri — dimatikan, supaya tidak ada dua. */
.carihapus{display:none;flex:none;place-items:center;width:28px;height:28px;padding:0;border:0;
  background:none;color:var(--ink-3);cursor:pointer}
.carihapus svg{position:static;width:15px;height:15px}
@media (hover:hover){ .carihapus:hover{color:var(--ink)} }
.shopsearch:has(input:not(:placeholder-shown)) .carihapus,
.tokocari:has(input:not(:placeholder-shown)) .carihapus{display:grid}
.shopsearch input::-webkit-search-cancel-button,
.tokocari input::-webkit-search-cancel-button{-webkit-appearance:none;appearance:none}
.shopmain{padding-top:24px;padding-bottom:60px}
.tokogrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(250px,1fr));gap:12px}
.tokocard{display:flex;gap:12px;align-items:center;text-align:left;font:inherit;cursor:pointer;
  border:1px solid var(--line);border-radius:var(--radius);background:var(--surface);padding:13px 14px;transition:border-color .14s,box-shadow .14s}
.tokocard:hover{border-color:var(--line-strong);box-shadow:var(--shadow)}
/* Foto profil toko berbentuk bulat — itu bentuk yang sudah dikenali orang
   sebagai "identitas penjual" di setiap lapak, bukan kotak seperti foto
   barang. Membedakan bentuknya membuat keduanya tidak pernah tertukar. */
.tokoav{width:44px;height:44px;flex:none;border-radius:50%;background:var(--ink);color:var(--on-ink);
  display:grid;place-items:center;font-family:var(--f-judul);font-weight:700;font-size:var(--f13);letter-spacing:-.02em}
.tokoav--lg{width:68px;height:68px;border-radius:50%;font-size:var(--f18);border:3px solid var(--surface)}
.tokoinfo{min-width:0;display:flex;flex-direction:column;gap:2px}
.tokoinfo b{font-size:var(--f13);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tokoinfo span{font-size:var(--f12);color:var(--ink-3);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tokoprofil{border:1px solid var(--line);border-radius:var(--radius);overflow:hidden;background:var(--surface);margin-bottom:16px}
.tokobanner{height:132px;background:
  radial-gradient(120% 160% at 10% 0%, var(--surface-2) 0%, transparent 60%),
  linear-gradient(115deg, var(--ink) 0%, var(--ink-2) 100%)}
.tokoprofil-bd{display:flex;gap:16px;align-items:flex-end;padding:0 20px 18px;margin-top:-34px}
.tokoprofil-info{min-width:0;padding-bottom:2px}
.tokoprofil-info h1{font-size:var(--f14);font-weight:600;margin:0 0 3px}
.tokoprofil-info p{font-size:var(--f12);color:var(--ink-3);margin:0}
.tokostat{display:flex;gap:18px;flex-wrap:wrap;margin-top:9px;font-size:var(--f12);color:var(--ink-2)}
.tokostat b{font-family:var(--f-angka);color:var(--ink)}
/* ---------- FOTO SAMPUL DITIMPA KETERANGANNYA (K-256) ----------
   Diminta pemiliknya: "aku ingin foto wallpaper itu ditimpa oleh foto profil
   beserta detail jumlah foto dan ulasan dan lain2". Dulu keterangannya berdiri
   di bidang putih DI BAWAH sampulnya — foto profilnya saja yang menjorok ke
   atas — jadi kepala halaman toko menuntut dua blok bertumpuk.

   KERUDUNG GELAPNYA WAJIB, dan ia bukan hiasan: sampul toko diunggah sendiri
   pemiliknya dan boleh seterang apa pun, jadi tulisan putih tanpa kerudung
   akan hilang ke dalam separuh sampul yang mungkin diunggah orang. Alasan yang
   sama persis yang memberi alas gelap kepada dua tombol bulat di kepala
   halaman produk (K-207).

   Warnanya DIPATOK, tidak memakai peubah tema: yang berdiri di belakangnya
   sebuah FOTO, bukan bidang tema — dan tulisan yang ikut menggelap di mode
   gelap akan hilang ke dalam kerudungnya sendiri. */
/* SAMPUL DAN KETERANGANNYA BERBAGI SATU PETAK, bukan keterangan yang
   DITEMPELKAN di atas sampulnya. Ditempel (`position:absolute`), tingginya
   tidak ikut dihitung siapa pun — dan di layar 390px keterangannya memang
   lebih tinggi daripada sampulnya, jadi ia menjulur ke atas sampai menembus
   kepala halaman. Diukur: bagian atasnya berdiri di -26px.

   Berbagi petak, sampulnya yang ikut tumbuh sampai setinggi keterangannya,
   dan itu benar di lebar mana pun tanpa satu angka yang diketik. */
/* `minmax(0,1fr)` DAN `min-width:0` KEDUANYA DIBUTUHKAN, dan sebabnya halus:
   sampulnya ber-`aspect-ratio:2/1`, dan ukuran minimum otomatis sebuah petak
   grid dihitung DARI rasio itu terhadap tingginya. Tingginya sekarang datang
   dari keterangannya, jadi lajurnya melebar menjadi dua kali tinggi itu —
   diukur 426px di layar 390px, dan sampulnya menjorok keluar layar. */
/* SEKSINYA BERLATAR GELAP, dan itu bukan hiasan. Sampulnya menentukan tinggi
   petaknya lewat `aspect-ratio:2/1` — 187px di layar 390px — sementara
   keterangan yang menimpanya 213px, jadi 26px paling bawah berdiri di luar
   sampulnya. Dibiarkan bening, tulisan putihnya di situ berdiri di atas latar
   halaman yang putih dan hilang sama sekali. Digelapkan, potongan itu menyatu
   dengan kerudung yang memang sudah menggelap ke arah bawah.

   Warnanya DIPATOK hitam, bukan `var(--ink)`: yang dilanjutkannya sebuah
   kerudung `rgba(0,0,0,…)`, dan peubah tema yang memutih di mode terang akan
   membelahnya menjadi dua bidang. */
.tokoprofil--sampul{position:relative;display:grid;grid-template-columns:minmax(0,1fr);
  border:0;border-radius:var(--radius);background:#000;overflow:hidden}
.tokoprofil--sampul > .tokobanner,
.tokoprofil--sampul > .tokoprofil-bd{grid-area:1 / 1;min-width:0;min-height:0}
.tokoprofil--sampul .tokobanner{align-self:start;height:auto}
.tokoprofil--sampul::after{content:"";position:absolute;inset:auto 0 0 0;height:72%;
  border-radius:0 0 var(--radius) var(--radius);pointer-events:none;
  background:linear-gradient(to top, rgba(0,0,0,.80) 0%, rgba(0,0,0,.45) 42%, transparent 100%)}
.tokoprofil--sampul > .tokoprofil-bd{align-self:end;z-index:1;margin-top:0;align-items:flex-end}
.tokoprofil--sampul .tokoprofil-info{padding-top:0;color:#fff}
.tokoprofil--sampul .tokoprofil-info h1{color:#fff}
.tokoprofil--sampul .tokoprofil-info p{color:rgba(255,255,255,.82)}
.tokoprofil--sampul .tokostat{color:rgba(255,255,255,.82)}
.tokoprofil--sampul .tokostat b{color:#fff}
.tokoprofil--sampul .tokostat a{color:inherit}
.tokoprofil--sampul .tokoav--lg{border-color:rgba(255,255,255,.9)}
/* INFORMASI TOKO TIDAK MENYATU DENGAN SAMPULNYA (J1 pilihan B, K-284 —
   dilaporkan pemiliknya: "informasi toko secara visual tidak menyatu dengan
   wallpapernya" dan "di mode mobile informasinya bertumpuk2, tata letaknya
   berantakan"; ia memilih saran B). Kerudung gradasi saja tidak cukup: sampul
   yang diunggah pemiliknya sendiri berisi logo dan tulisan besar, dan tulisan
   putih di atas tulisan putih tetap terbaca bertumpuk.

   Karena itu BAGIAN SAMPUL DI BELAKANG INFORMASINYA DIBURAMKAN DAN DIGELAPKAN
   (`backdrop-filter`) — seperti halaman toko Shopee — sementara bagian atasnya
   tetap tajam. Tepi atas pitanya MEMUDAR (`mask-image`), jadi tidak ada garis
   yang membelah sampulnya. Isinya disusun rapi: logo di kiri, di kanannya
   nama, tagline, dan angka-angkanya SEBARIS — masing-masing satu baris,
   yang kepanjangan dipotong titik-titik, tidak pernah melipat menjadi
   tumpukan. Parallax K-283 tetap berjalan di belakangnya. */
.tokoprofil--sampul > .tokoprofil-bd{align-self:end;width:100%;align-items:center;
  padding:30px 20px 16px;
  background:linear-gradient(to top, rgba(0,0,0,.62), rgba(0,0,0,.38));
  -webkit-backdrop-filter:blur(14px) saturate(.85);backdrop-filter:blur(14px) saturate(.85);
  -webkit-mask-image:linear-gradient(to bottom, transparent, #000 26px);
  mask-image:linear-gradient(to bottom, transparent, #000 26px)}
.tokoprofil--sampul .tokoav--lg{flex:none}
.tokoprofil--sampul .tokoprofil-info{flex:1 1 auto;min-width:0}
.tokoprofil--sampul .tokoprofil-info h1{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.tokoprofil--sampul .tokoprofil-info p{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.tokoprofil--sampul .tokostat{flex-wrap:nowrap;gap:12px;margin-top:6px;min-width:0}
.tokoprofil--sampul .tokostat > *{flex:none;white-space:nowrap}
.tokoprofil--sampul .tokostat > :last-child{flex:0 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis}

/* ---------- TAB TERSEDIA/TERJUAL MULUS TANPA GAP (K-256) ----------
   Diminta pemiliknya: "seharusnya tab nya mulus tanpa gap". Dua pil yang
   dipisahkan 8px terbaca sebagai dua tombol yang berdiri sendiri-sendiri;
   yang dimaksudnya SATU kendali berisi dua pilihan.

   Bentuknya disamakan dengan tab Daftar Item di dalam ERP (K-214) — yang
   berlaku ditandai tulisan tebal beserta garis di bawahnya, bukan bidang
   berwarna. Satu bentuk tab untuk seluruh aplikasi, jadi tidak ada susunan
   baru yang harus dipelajari. */
.pilihbar--mulus{gap:0;flex-wrap:nowrap;margin-bottom:0;
  border-bottom:1px solid var(--line)}
.pilihbar--mulus .pilihopt{flex:1 1 0;min-width:0;border:0;border-radius:0;background:none;
  padding:11px 8px;color:var(--ink-3);border-bottom:2px solid transparent;margin-bottom:-1px}
.pilihbar--mulus .pilihopt:hover{color:var(--ink)}
.pilihbar--mulus .pilihopt.on{background:none;color:var(--ink);font-weight:600;
  border-bottom-color:var(--ink)}

/* Kotak cari halaman toko: bentuk yang sama dengan kotak di kepala
   etalase, karena ia memang kotak yang SAMA — yang di kepala terbit sewaktu
   digulir, dan dua kotak yang berbeda rupanya terbaca sebagai dua kotak. */
.tokocari{max-width:none;flex:none;margin:14px 0 16px;display:flex;align-items:center;gap:2px;height:36px;
  background:color-mix(in srgb, var(--ink) 7%, var(--surface));border:1px solid transparent;
  border-radius:var(--radius);padding:0 2px 0 12px}
/* MENEMPEL DI BARIS KEPALA (K-274): `--cari-atas` sejajar tombol Kembali,
   `--cari-kiri`/`--cari-kanan` celah di antara tombol-tombolnya — ketiganya
   diukur `Toko.pasangCariMenempel`. Di atas kepala (z 40) supaya ia berdiri
   DI DALAM barisnya. Di layar lebar lebarnya celah itu sejak awal (pilihan A
   pemiliknya); di telepon ia menyusut ke sana saat mendekat (`--naik`). */
/* IA BERGESER, TIDAK MENYUSUT (K-281, diminta pemiliknya: "kolom search sisi
   kiri tidak perlu mengecil atau menyusut, karena dia sudah menggantikan atau
   menggeser tombol titik tiga, begitu pula saat mode laptop"). Lebarnya SATU
   angka sejak awal — selebar barisnya dikurangi tempat tombol Kembali — dan
   saat menempel ia cuma bergeser ke kanan mengisi tempat titik tiga, yang
   disembunyikan selama kotaknya di sana (`.cari-naik`, dipasang
   `Toko.pasangCariMenempel`). Sama di telepon dan laptop. */
.tokocari{position:sticky;top:var(--cari-atas,8px);z-index:41;transition:margin .14s ease-out;
  margin-right:calc(var(--cari-kiri,0px) + var(--cari-kanan,0px))}
.tokocari--naik{margin-left:var(--cari-kiri,0px);margin-right:var(--cari-kanan,0px)}
.shophead.cari-naik #shopMenu{visibility:hidden}
@media (prefers-reduced-motion:reduce){ .tokocari{transition:none} }
/* Kepala tanpa kotak cari tetap menyisakan celahnya, supaya tombol-tombol
   kanannya tetap di ujung kanan. */
.shopsela{flex:1 1 auto}
.tokocari input{flex:1;min-width:0;width:auto;height:auto;padding:7px 0;border:0;background:none;border-radius:0}
.tokocari input:focus{border-color:transparent;box-shadow:none}
.tokocari:focus-within{border-color:var(--line-strong);box-shadow:none}

/* ---------- NAMA TOKO YANG MASIH BISA DITEKAN (K-257) ----------
   Tombol yang rupanya tetap judul: ia mewarisi ukuran dan tebal `h1` induknya,
   dan yang mengatakan "bisa ditekan" cuma chevron di ujungnya — penanda yang
   sama persis dengan nama toko di kotak halaman barang. */
.tokonama{display:inline-flex;align-items:center;gap:5px;max-width:100%;min-width:0;
  padding:0;border:0;background:none;color:inherit;font:inherit;text-align:left;cursor:pointer}
.tokonama > span:first-child{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}
.tokonama:hover > span:first-child{text-decoration:underline}

/* ---------- PANEL DETAIL TOKO (K-257) ---------- */
.tokodet{display:flex;flex-direction:column;gap:16px}
.tokodet-atas{display:flex;align-items:center;gap:13px;min-width:0}
.tokodet-atas .tokoav--lg{border-color:var(--line);flex:none}
.tokodet-judul{min-width:0;display:flex;flex-direction:column;gap:3px}
.tokodet-judul b{font-family:var(--f-judul);font-size:var(--f14);font-weight:600}
.tokodet-judul span{font-size:var(--f12);color:var(--ink-3)}
.tokodet-stat{margin:0}
.tokodet-sek h3{font-family:var(--f-judul);font-size:var(--f12);font-weight:600;color:var(--ink-3);
  margin:0 0 8px;letter-spacing:.02em;text-transform:uppercase}
.tokodet-dl{margin:0;display:flex;flex-direction:column;gap:7px}
.tokodet-dl > div{display:flex;gap:12px;align-items:baseline;font-size:var(--f12)}
.tokodet-dl dt{flex:none;width:86px;color:var(--ink-3)}
.tokodet-dl dd{margin:0;min-width:0;color:var(--ink);overflow-wrap:anywhere}

/* BATANG PROPORSI, dan ia yang menanggung seluruh permintaan pemiliknya: nama
   janji garansi tidak boleh terbaca seolah SELURUH barang toko memikulnya.
   Panjang batangnya `n / barang tersedia`, jadi batang yang jelas tidak penuh
   mengatakan "sebagian" tanpa satu huruf pun — dan angkanya di ujung kanan
   mengatakan sebagian yang mana. Lintasan yang tidak terisi itulah yang
   mewakili barang tanpa garansi; ia tidak diberi baris bernama, karena
   ketiadaan janji bukan sebuah janji (K-222). */
.tokogar{display:flex;flex-direction:column;gap:9px}
.tokogar-b{display:flex;align-items:center;gap:10px;min-width:0;font-size:var(--f12)}
.tokogar-n{flex:1 1 0;min-width:0;display:flex;align-items:center;gap:6px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tokogar-n svg{width:14px;height:14px;flex:none;color:var(--ink-3)}
.tokogar-bar{flex:0 0 76px;height:6px;border-radius:999px;background:var(--line);overflow:hidden}
.tokogar-bar i{display:block;height:100%;border-radius:999px;background:var(--ink-2)}
.tokogar-b b{flex:none;min-width:22px;text-align:right;font-family:var(--f-angka);font-weight:600}
@media(max-width:480px){ .tokogar-bar{flex-basis:52px} }

.pilihbar{display:flex;gap:8px;margin:0 0 16px;flex-wrap:wrap}
.pilihopt{border:1px solid var(--line);background:var(--surface);border-radius:var(--radius);padding:8px 16px;
  font:inherit;font-size:var(--f12);cursor:pointer;transition:border-color .14s}
.pilihopt:hover{border-color:var(--line-strong)}
.pilihopt.on{background:var(--ink);border-color:var(--ink);color:var(--on-ink);font-weight:500}
/* Deretan tab (halaman Saya): menggulir ke samping, tidak melipat dua baris. */
.pilihbar--tab{flex-wrap:nowrap;overflow-x:auto;scrollbar-width:none}
.pilihbar--tab::-webkit-scrollbar{display:none}
.pilihbar--tab .pilihopt{flex:none}
.shopcard .ph{position:relative}
/* ---------------------------------------------- penanda di atas foto (K-222)
   Dua benda, dan keduanya menimpa fotonya sendiri alih-alih memakan baris di
   badan kartunya — diminta pemiliknya. */
/* 1 · BERGARANSI. Pil gelap tembus pandang berisi perisai dan satu kata.
   Gelap, bukan berwarna: warna di ERP ini cuma milik status dokumen, arah
   uang, kepekaan hak akses, dan tombol Jual — dan sebuah janji garansi bukan
   salah satunya. Latar gelap juga satu-satunya yang terbaca di atas foto
   barang bekas, yang bisa seterang atau segelap apa pun.

   `backdrop-filter` cuma mempercantik yang mendukungnya; yang menjamin
   terbacanya warna latarnya sendiri. */
.tandagaransi{position:absolute;top:8px;left:8px;z-index:2;display:inline-flex;align-items:center;gap:5px;
  max-width:calc(100% - 16px);height:23px;padding:0 9px 0 8px;border-radius:999px;
  background:rgba(12,13,15,.72);color:#fff;font-size:var(--f11);font-weight:600;letter-spacing:.01em;
  white-space:nowrap;overflow:hidden;-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px)}
.tandagaransi svg{width:12px;height:12px;flex:none}
/* 2 · TERJUAL. Fotonya digelapkan sedikit, lalu distempel — diminta
   pemiliknya, "tapi jangan terlalu kasar". Yang menjaganya supaya tidak
   kasar tiga hal: gelapnya cuma 38%, stempelnya tembus pandang dan tidak
   pernah hitam pekat, dan ia dimiringkan sedikit saja. Warnanya MERAH, dan
   itu keputusan pemiliknya sendiri — di etalase ia satu-satunya penanda yang
   berarti "jangan menunggu barang ini". */
.fotohabis img{filter:brightness(.62) saturate(.75)}
.tandahabis{position:absolute;z-index:3;left:50%;top:50%;
  transform:translate(-50%,-50%) rotate(-11deg);
  padding:5px 16px;border:2px solid rgba(214,58,58,.85);border-radius:6px;
  color:rgba(214,58,58,.95);background:rgba(255,255,255,.14);
  font-size:var(--f13);font-weight:800;letter-spacing:.22em;text-transform:uppercase;
  white-space:nowrap;-webkit-backdrop-filter:blur(1px);backdrop-filter:blur(1px)}
/* Di halaman produk kotak fotonya berkali lipat kartunya, jadi stempel
   seukuran kartu terbaca sebagai stiker kecil yang tertinggal di tengahnya. */
.pdp-utama .tandahabis{font-size:var(--f16);padding:7px 22px;border-width:3px;border-radius:8px}
.shopcard .lok{display:flex;align-items:center;gap:4px;margin-top:7px;font-size:var(--f12);color:var(--ink-3)}
.shopcard .lok svg{width:13px;height:13px;flex:none}
/* Satu baris, dipotong titik-titik — bukan melipat: tinggi kartu di etalase
   harus tetap sama (K-176), dan nama toko yang panjang jangan sampai
   menambah dua baris pada sebagian kartu saja (K-179). */
.shopcard .lok-n{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.shopcard h3{min-height:2.7em}
/* ---------- KAKI TOKO ----------
   Tempat tautan "Masuk sebagai Staf", yang dulu memakan satu baris penuh di
   kepala halaman telepon — pada halaman yang dilihat PEMBELI. */
/* KAKI HALAMAN ETALASE MENEMPEL DI DASAR LAYAR pada halaman yang isinya
   pendek (K-176). DILAPORKAN lewat halaman Chat: daftarnya cuma tiga baris,
   dan kakinya berdiri di TENGAH layar dengan ruang kosong menganga di
   bawahnya.

   Sebabnya `html,body{height:100%}` — aturan yang memang dibutuhkan kerangka
   ERP, tempat badan halamannya diisi penuh oleh bar kiri. Halaman etalase
   tidak punya bar kiri: ia cuma kepala, isi, dan kaki yang mengalir menurun,
   jadi tinggi yang dipatok persis satu layar membuat kakinya berhenti di
   tempat isinya berhenti.

   Yang dipakai `:has()` atas kakinya sendiri, bukan kelas baru di `<body>`:
   kelas itu harus ditambahkan di sebelas halaman etalase satu per satu, dan
   yang terlupa satu akan menampakkan bug yang sama tanpa ada yang tahu
   sebabnya. */
body:has(> .shopkaki){height:auto;min-height:100%;display:flex;flex-direction:column}
/* `width:100%` BUKAN kerapian, dan sebabnya halus: `.shopwrap` memakai
   `margin:0 auto` untuk memusatkan dirinya — dan MARGIN OTOMATIS PADA PETAK
   FLEX MEMBATALKAN peregangan lintas-sumbunya. Petaknya lalu menyusut
   mengikuti isinya, dan isi yang paling lebar (deretan cip toko yang
   seharusnya digeser) MELEBARKAN badan halaman menjadi 637px di layar 390px.

   Jadi begitu badan halaman etalase menjadi flex demi kakinya, ketiga
   anaknya harus dinyatakan selebar penuh. `min-width:0` menyertainya supaya
   petaknya juga boleh MENYUSUT di bawah lebar min-content isinya.

   Tertangkap `uji/mob.js` pada 390 dan 430 piksel, bukan oleh mata — dan itu
   memang gunanya: luberan 247px tidak terlihat sebagai kesalahan di layar
   lebar tempat seluruh pekerjaan ini dikerjakan. */
/* `.pop` DIKECUALIKAN: menu dan daftar pilihan juga menempel langsung pada
   <body>, dan aturan ini meregangkan menu klik kanan penampil foto selebar
   layar (dilaporkan pemiliknya). Ia bukan petak aliran halamannya. */
body:has(> .shopkaki) > :not(.pop){width:100%;min-width:0}
body:has(> .shopkaki) > .shopmain{flex:1 0 auto}
body:has(> .shopkaki) > .shopkaki{flex:none}
.shopkaki{border-top:1px solid var(--line);background:var(--surface);margin-top:40px}
.shopkaki .shopwrap{display:flex;align-items:center;justify-content:space-between;
  gap:14px;flex-wrap:wrap;padding-top:18px;padding-bottom:18px;
  font-size:var(--f12);color:var(--ink-3)}

/* KEPALANYA SATU BARIS DI LEBAR MANA PUN (K-222). Sampai K-209 ia dua baris
   di bawah 860px — lambang, nama, tagline, Beranda, chat, dan keranjang
   memang tidak pernah muat sebaris dengan kotak carinya. Begitu merek dan
   Beranda dicabut pemiliknya, yang tersisa muat: kotak carinya melar
   mengambil sisa lebarnya, dan yang tetap berdiri di sisinya cuma tombol
   Kembali, chat, keranjang, dan titik tiga. */
@media (max-width:860px){
  .shopwrap{--shop-pad:11px}
  .shophead .shopwrap{min-height:0;padding-top:8px;padding-bottom:8px;gap:8px}
  .shopsearch{max-width:none;margin:0}
}

@media (max-width:640px){
  /* Tombol Filter tinggal ikonnya (K-281). */
  .fltbtn-t{display:none}
  .fltbtn{padding:6px 9px}
  /* Sisi halamannya dirapatkan, angka yang sama dengan seluruh ERP di lebar
     ini (K-222). */
  .shopwrap{--shop-pad:8px}
  .shophead .shopwrap{gap:8px}
  .shophead .shopchat,.shophead .shopakun{width:34px;height:34px}
  .tokoprofil-bd{flex-direction:column;align-items:flex-start;gap:10px}
  /* LOGO TOKO DI ATAS SAMPUL: TETAP SEBARIS DI KIRI NAMANYA (tahap 6a,
     dilaporkan pemiliknya: logonya "terlempar ke pojok kanan atas"). Aturan
     di atas menyusunnya MENURUN, dan `align-items:flex-end` milik
     `.tokoprofil--sampul` — yang lebih kuat — mendorong petak menurun itu ke
     tepi KANAN, jadi logonya naik menimpa titik tiga. */
  .tokoprofil--sampul > .tokoprofil-bd{flex-direction:row;align-items:center;gap:12px;padding:26px 14px 14px}
  .tokoprofil--sampul .tokostat{font-size:var(--f12);gap:10px}
  .tokoprofil--sampul .tokoav--lg{width:56px;height:56px;font-size:var(--f14)}

  /* TOMBOL BELI MENEMPEL DI BAWAH LAYAR dan ikut ke mana pun halaman
     digulir. Dulu ia berdiri di tengah deretan empat tombol yang sama
     besarnya — tindakan yang menghasilkan uang justru yang paling lemah
     terlihat, dan ia hilang dari layar begitu pembeli membaca deskripsi
     barangnya. Di layar lebar ia tetap di tempatnya: di sana seluruh
     tombolnya terlihat sekaligus tanpa digulir. */
  /* `fixed`, bukan `sticky`. Yang `sticky` cuma menempel selama induknya
     masih terlihat — begitu pembeli menggulir sampai deskripsi barangnya,
     bilahnya ikut hilang bersama induknya. Sudah dicoba, dan memang begitu
     yang terjadi. */
  .pdp-aksi{position:fixed;left:0;right:0;bottom:0;z-index:60;margin:0;padding:10px 14px;
    background:var(--surface);border-top:1px solid var(--line);
    box-shadow:0 -6px 22px -14px rgba(0,0,0,.55)}
  .pdp-aksi > .btn{flex:1 1 0;min-width:0}
  /* Ikon WhatsApp yang berdiri sendirian (etalase publik) menepi ke kanan,
     tempat tombol utama berdiri di setiap bilah bawah ERP ini (K-281). */
  .pdp-aksi{justify-content:flex-end}
  .pdp-aksi > .btn--beli{flex:1.6 1 0}
  /* WhatsApp disembunyikan di bilah bawah HANYA BILA ADA TOMBOL BELI, yaitu
     di dalam ERP: empat tombol pada 390 piksel membuat keempatnya sama
     sempitnya, dan yang paling penting ikut menyempit. Di sana ia tetap
     terjangkau lewat Chat Toko.

     DI ETALASE PUBLIK IA SATU-SATUNYA TOMBOL, dan aturan lama
     menyembunyikannya juga di sana — jadi bilah bawahnya BERDIRI KOSONG dan
     pengunjung tidak punya satu pun jalan menghubungi toko. Terukur: bilahnya
     390px dengan satu anak ber-`display:none`. Ini bug yang paling mahal di
     antara semua yang dilaporkan pemiliknya, karena yang hilang bukan
     kerapian melainkan satu-satunya jalan berjualan. */
  .pdp-aksi:has(.btn--beli) > a.btn{display:none}
  /* Ruang di kaki halaman supaya isinya tidak tertutup bilah itu. */
  .shopkaki{padding-bottom:64px}
}

/* ---------- Hot Info ---------- */
.ceklis{display:flex;gap:7px;flex-wrap:wrap;margin-top:10px}
.ceklisopt{display:inline-flex;align-items:center;gap:7px;border:1px solid var(--line);background:var(--surface);
  border-radius:999px;padding:5px 12px 5px 8px;font:inherit;font-size:var(--f12);cursor:pointer;transition:border-color .13s}
.ceklisopt:hover{border-color:var(--line-strong)}
.ceklisopt .bx{width:16px;height:16px;border:1.5px solid var(--line-strong);border-radius:var(--radius-kcl);flex:none;display:grid;place-items:center}
.ceklisopt.on{border-color:var(--ink)}
.ceklisopt.on .bx{background:var(--ink);border-color:var(--ink)}
.ceklisopt.on .bx::after{content:"";width:8px;height:4px;border-left:2px solid var(--on-ink);
  border-bottom:2px solid var(--on-ink);transform:rotate(-45deg) translate(1px,-1px)}
.irow--done{opacity:.62}

/* ==========================================================================
   HR — absensi, jadwal, dan gaji
   ========================================================================== */
.harinav{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;
  border:1px solid var(--line);border-radius:var(--radius);background:var(--surface);padding:12px 16px;margin-bottom:14px}
.harinav-tgl{text-align:center;min-width:0;flex:1 1 auto}
.harinav-tgl b{display:block;font-family:var(--f-judul);font-size:var(--f14);font-weight:600}
.harinav-tgl span{display:block;font-size:var(--f12);color:var(--ink-3);margin-top:2px}
/* Di telepon tanggalnya di atas, kedua tombol harinya berbagi satu baris di
   bawahnya — dilipat sendiri, "← Senin" dan "Rabu →" jatuh ke dua baris
   yang berbeda mengapit tanggalnya. */
@media(max-width:560px){
  .harinav-tgl{order:-1;flex:1 1 100%}
  .harinav > .btn{flex:1 1 0}
}
.absgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(272px,1fr));gap:12px}
.abscard{border:1px solid var(--line);border-radius:var(--radius);background:var(--surface);padding:15px;display:flex;flex-direction:column;gap:10px}
.abscard--saya{border-color:var(--ink);box-shadow:inset 0 0 0 1px var(--ink)}
.abshd{display:flex;align-items:flex-start;justify-content:space-between;gap:10px}
.absshift{display:block;font-family:var(--f-judul);font-size:var(--f13);font-weight:600}
.abscard .nm{display:block;font-size:var(--f12);color:var(--ink-2);margin-top:2px}
.absjam{display:flex;flex-direction:column;gap:2px}
.absjam b{font-family:var(--f-angka);font-size:var(--f13);font-variant-numeric:tabular-nums}
.absjam span{font-size:var(--f11);color:var(--ink-3)}
.sidikrow{display:flex;gap:10px;border-top:1px solid var(--line);padding-top:10px}
.sidik{display:flex;gap:8px;align-items:center;flex:1;min-width:0}
.sidik svg{width:22px;height:22px;flex:none}
.sidik span{min-width:0;font-size:var(--f12);font-family:var(--f-angka)}
.sidik span small{display:block;font-family:var(--f-isi);font-size:var(--f10);
  letter-spacing:.05em;text-transform:uppercase;color:var(--ink-3)}
.sidik--wait{color:var(--ink-3)}
.sidik--ok{color:var(--done)}
.sidik--no{color:var(--stop)}
.absnote{font-size:var(--f12);color:var(--run);background:var(--run-bg);border:1px solid var(--run-line);
  border-radius:var(--radius);padding:7px 10px}
/* Selfie absen (K-63): dua gambar kecil di bawah baris sidik; disentuh
   membuka penampil foto. Baris posisi di panel absen: mencari → terbaca /
   di luar radius / tidak terbaca. */
/* Kuota libur khusus per orang (K-80): satu baris satu nama, kolom kecil
   di kanan. Kosong = ikut angka tim, yang tertulis samar di kolomnya. */
.kuotakhusus{display:flex;flex-direction:column;gap:6px}
.kuotarow{display:flex;align-items:center;justify-content:space-between;gap:10px}
.kuotarow > span{font-size:var(--f12);color:var(--ink-2);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.kuotarow .inp{flex:none;width:130px}
.absfoto{display:flex;gap:6px;margin:0 0 8px}
.absfoto img{width:44px;height:44px;border-radius:8px;object-fit:cover;border:1px solid var(--line);cursor:pointer;background:var(--bg-2)}
.absnote--luar{color:var(--wait);background:var(--wait-bg);border-color:var(--wait-line)}
.absposisi{display:flex;align-items:center;gap:8px;min-height:38px;padding:8px 12px;border:1px solid var(--line);border-radius:10px;font-size:var(--f12);color:var(--ink-2)}
.absposisi--ok{color:var(--done);border-color:var(--done-line);background:var(--done-bg)}
.absposisi--warn{color:var(--wait);border-color:var(--wait-line);background:var(--wait-bg)}
.absposisi--no{color:var(--stop);border-color:var(--stop-line);background:var(--stop-bg)}
.absact{display:flex;gap:7px;flex-wrap:wrap}
.absact:empty{display:none}
/* Titik tiga di kepala kartu absen (K-203). `.absmenu` berisi tombol yang
   SUNGGUHAN dan tidak pernah digambar — ia yang ditekan ulang oleh menunya,
   jadi seluruh pendengar kartunya tetap berlaku (pola corong K-65).
   `display:none` ditulis apa adanya: `[hidden]` bawaan peramban kalah oleh
   aturan layout mana pun yang berdiri di bawahnya, dan itu sudah tiga kali
   memakan korban di berkas ini. */
.abshd-kanan{display:flex;align-items:center;gap:7px;flex:none}
.abskebab{width:28px;height:28px}
.abskebab svg{width:16px;height:16px}
.absmenu{display:none}
.form > .btn{justify-self:start}
.form > .chipset{margin-top:-2px}

/* ---------- rapikan sisa jarak dan tinggi ---------- */
.filters .combo-btn{min-width:170px;height:var(--tinggi-kendali);padding:0 28px 0 12px;font-size:var(--f12)}
.filterhead .combo-btn{min-width:170px;padding:0 28px 0 12px}
.filters{align-items:center}
.filters > .btn{height:var(--tinggi-kendali)}
.filters .pilihbar .pilihopt{height:var(--tinggi-kendali);padding:0 16px;display:inline-flex;align-items:center}
.tabs{overflow-x:auto;scrollbar-width:none}
.tabs::-webkit-scrollbar{display:none}
.tab{white-space:nowrap}
.kv-row{gap:14px;align-items:flex-start}
.kv-row > span:first-child{flex:0 0 auto;max-width:46%}
.kv-row > b{min-width:0;overflow-wrap:anywhere}
.notice > div{min-width:0}
.notice b{display:block;margin-bottom:2px}
.minirow{gap:12px}
.minirow .t{min-width:0}
.minirow .t span{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.minirow .v{flex:none;white-space:nowrap}
.grid1,.grid3,.grid4,.grid2{min-width:0}
.grid1 > *,.grid2 > *,.grid3 > *,.grid4 > *,.grid5 > *{min-width:0}
@media (max-width:900px){
  .grid3,.grid4{grid-template-columns:repeat(2,minmax(0,1fr))}
  .grid2{grid-template-columns:minmax(0,1fr)}
}
@media (max-width:600px){
  .grid3,.grid4,.grid5{grid-template-columns:minmax(0,1fr)}
  .page{--pad-hal:8px;--pad-atas:12px;padding:var(--pad-atas) var(--pad-hal) var(--pad-hal)}
  .irow{padding:12px 13px}
  .irow-right{align-items:flex-start;width:100%}
  .irow-act{justify-content:flex-start}
}

/* ==========================================================================
   KALKULATOR
   ========================================================================== */
.hasilcard{position:sticky;top:72px}
.hasil-k{display:block;font-size:var(--f11);letter-spacing:.06em;text-transform:uppercase;color:var(--ink-3)}
.hasil-v{display:block;font-family:var(--f-angka);font-variant-numeric:tabular-nums;
  font-size:var(--f22);font-weight:600;line-height:1.15;margin-top:5px;overflow-wrap:anywhere}
.hasil-s{margin:8px 0 0;font-size:var(--f12);color:var(--ink-3)}
.rulecard{border:1px solid var(--line);border-radius:var(--radius);background:var(--surface);margin-bottom:10px;overflow:hidden}
.rulecard-hd{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;flex-wrap:wrap;
  padding:13px 15px;border-bottom:1px solid var(--line);background:var(--surface-2)}
.rulecard-nm{display:block;font-family:var(--f-judul);font-size:var(--f13);font-weight:600}
.rulecard-sub{display:block;font-size:var(--f12);color:var(--ink-3);margin-top:2px}
.rulecard-ft{padding:10px 15px;border-top:1px solid var(--line)}
.rulerow{display:flex;align-items:center;gap:12px;padding:11px 15px;border-bottom:1px solid var(--line);flex-wrap:wrap}
.rulerow:last-child{border-bottom:0}
.rulemark{width:22px;height:22px;flex:none;border-radius:50%;border:1px solid var(--line-strong);
  display:grid;place-items:center;font-size:var(--f11);color:var(--ink-3)}
.rulerow.on{background:var(--done-bg)}
.rulerow.on .rulemark{background:var(--done);border-color:var(--done);color:#fff}
.ruletxt{flex:1;min-width:0}
.ruletxt b{display:block;font-family:var(--f-angka);font-size:var(--f12);font-weight:500}
.ruletxt span{display:block;font-size:var(--f12);color:var(--ink-3);margin-top:2px}
.rulebox{border:1px solid var(--line);border-radius:var(--radius);margin-bottom:10px;overflow:hidden}
.rulebox-hd{display:flex;justify-content:space-between;gap:12px;flex-wrap:wrap;padding:11px 14px;
  background:var(--surface-2);border-bottom:1px solid var(--line);font-size:var(--f12)}
.rulebox-hd span{font-family:var(--f-angka);color:var(--ink-2)}

/* ==========================================================================
   HASIL DOKUMEN — untung rugi per Purchase dan per Penjualan
   Tetap monokrom. Untung atau rugi dibaca dari kata, bukan dari warna,
   karena warna di aplikasi ini hanya milik status utama dokumen.
   ========================================================================== */
.hasil{border:1px solid var(--line);border-radius:var(--radius);background:var(--surface);overflow:hidden}
.hasil-row{display:flex;align-items:flex-start;justify-content:space-between;gap:18px;
  padding:12px 16px;border-bottom:1px solid var(--line)}
.hasil-row:last-child{border-bottom:0}
.hasil-row .t{font-size:var(--f12);min-width:0}
.hasil-row .t small{display:block;font-size:var(--f11);color:var(--ink-3);margin-top:3px;line-height:1.5}
.hasil-row .v{font-family:var(--f-angka);font-variant-numeric:tabular-nums;
  font-size:var(--f13);white-space:nowrap;text-align:right;flex:none}
.hasil-row .v small{display:block;font-family:var(--f-isi);
  font-size:var(--f10);letter-spacing:.05em;text-transform:uppercase;color:var(--ink-3);font-weight:500;margin-top:3px}
.hasil-row--sub{padding-top:0;padding-bottom:11px;border-bottom:1px solid var(--line)}
.hasil-row--sub .t,.hasil-row--sub .v{color:var(--ink-3);font-size:var(--f12)}
.hasil-row--sub .t{padding-left:14px;position:relative}
.hasil-row--sub .t::before{content:"";position:absolute;left:2px;top:.62em;width:7px;height:1px;background:var(--line-strong)}
.hasil-row--sum{background:var(--surface-2)}
.hasil-row--sum .t{font-weight:600}
.hasil-row--sum .v{font-size:var(--f13);font-weight:600}
.hasil-row--akhir{background:var(--surface-2);border-top:1.5px solid var(--ink);border-bottom:0}
.hasil-row--akhir .t{font-family:var(--f-judul);font-weight:600;font-size:var(--f13)}
.hasil-row--akhir .v{font-family:var(--f-judul);font-weight:600;font-size:var(--f16);letter-spacing:-.01em}
.hasil-row--akhir .v small{color:var(--ink-2);font-weight:600}
@media (max-width:640px){
  .hasil-row{gap:12px;padding:11px 13px}
  .hasil-row--akhir .v{font-size:var(--f14)}
}

/* ---------- kalkulator: tiga angka utama tampil sekaligus ---------- */
.hasil3{display:flex;flex-direction:column}
.hasil3 > div{min-width:0;padding:11px 0;border-bottom:1px solid var(--line)}
.hasil3 > div:first-child{padding-top:0}
.hasil3 > div:last-child{border-bottom:0;padding-bottom:0}
.hasil3 .hasil-k{display:block;font-size:var(--f11);letter-spacing:.05em;text-transform:uppercase;
  color:var(--ink-3);font-weight:500;margin-bottom:3px}
.hasil3 .hasil-v{display:block;font-family:var(--f-angka);font-weight:600;
  font-size:var(--f16);letter-spacing:-.02em;font-variant-numeric:tabular-nums;overflow-wrap:anywhere;line-height:1.2}
.hasil3 > div:first-child .hasil-v{font-size:var(--f22)}
.rulerow--mati{opacity:.5}
.rulerow--mati .ruletxt b{text-decoration:line-through}
@media (max-width:640px){ .hasil3 > div:first-child .hasil-v{font-size:var(--f18)} }
.syaratkecil{display:block;font-size:var(--f11);color:var(--ink-3);line-height:1.45;margin-top:3px;font-weight:400}
.kv-row .syaratkecil{max-width:100%}

/* ==========================================================================
   PANEL ISIAN — pengganti pop-up untuk semua form
   Isian terbuka di dalam halaman, bukan menutupi halaman. Total yang sedang
   berjalan tetap terlihat sementara orang mengisi. Pop-up hanya dipakai
   untuk pertanyaan dan konfirmasi.
   ========================================================================== */
.panel{border:1px solid var(--ink);border-radius:var(--radius);background:var(--surface);
  margin:14px 0 4px;overflow:hidden;box-shadow:var(--shadow);
  opacity:0;transform:translateY(-6px);transition:opacity .16s ease,transform .16s ease}
.panel.on{opacity:1;transform:none}
.panel-hd{display:flex;align-items:flex-start;justify-content:space-between;gap:14px;
  padding:15px 18px;border-bottom:1px solid var(--line);background:var(--surface-2)}
.panel-hd h3{font-family:var(--f-judul);font-size:var(--f14);font-weight:600;margin:0}
.panel-hd p{font-size:var(--f12);color:var(--ink-3);margin:3px 0 0}
.panel-bd{padding:18px}
.panel-ft{display:flex;justify-content:flex-end;gap:9px;flex-wrap:wrap;
  padding:14px 18px;border-top:1px solid var(--line);background:var(--surface-2)}
.panel .form{max-width:var(--w)}
@media (max-width:640px){ .panel-bd{padding:14px} .panel-hd,.panel-ft{padding:13px 14px} }

/* arah uang: keluar merah, masuk hijau — permintaan eksplisit agar tidak
   terbaca terbalik. Selain ini, warna tetap milik status dokumen saja. */
.uang--keluar{color:var(--stop)}
.uang--masuk{color:var(--done)}

/* ---------- Hot Info: kartu berfoto, bisa diklik, bisa dipilih ---------- */
.hotrow{display:flex;align-items:flex-start;gap:14px;padding:13px 15px;border:1px solid var(--line);
  border-radius:var(--radius);background:var(--surface);margin-bottom:8px;transition:border-color .14s}
.hotrow:hover{border-color:var(--line-strong)}
.hotrow--on{border-color:var(--ink);background:var(--surface-2)}
.hotrow--done{opacity:.72}
/* Seluruh kartu adalah jalan menuju itemnya, jadi yang menyala saat disentuh
   adalah kartunya — bukan tulisan namanya. */
.hotrow--btn{cursor:pointer}
.hotrow--btn:hover{border-color:var(--ink)}

.hotrow--btn:focus-visible{outline:2px solid var(--ink);outline-offset:2px}
.hotpick{flex:none;border:0;background:none;padding:2px 0 0;cursor:pointer}
.hotpick .bx{display:block;width:20px;height:20px;border:1.5px solid var(--line-strong);border-radius:var(--radius-kcl)}
.hotpick[aria-pressed="true"] .bx{background:var(--ink);border-color:var(--ink);position:relative}
.hotpick[aria-pressed="true"] .bx::after{content:"";position:absolute;left:5px;top:4px;width:8px;height:4px;
  border-left:2px solid var(--surface);border-bottom:2px solid var(--surface);transform:rotate(-45deg)}
.hotfoto{flex:none;width:62px;height:62px;border-radius:var(--radius);overflow:hidden;background:var(--surface-2);
  border:1px solid var(--line);cursor:pointer}
.hotfoto .ph,.hotfoto img,.hotfoto .hotfoto-img{width:100%;height:100%;object-fit:cover;display:block}
.hotbody{flex:1 1 auto;min-width:0;display:flex;flex-direction:column;gap:4px}
.hotnama{font-size:var(--f13);font-weight:500;overflow-wrap:anywhere}
.hotright{flex:none;display:flex;align-items:center;padding-top:2px}
.pilihbar-aksi{display:flex;align-items:center;gap:12px;flex-wrap:wrap;padding:11px 14px;margin-bottom:10px;
  border:1px solid var(--ink);border-radius:var(--radius);background:var(--surface-2)}
@media (max-width:640px){
  .hotrow{gap:11px;padding:11px}
  .hotfoto{width:52px;height:52px}
  .hotright{width:100%;padding-top:6px}
  .hotrow{flex-wrap:wrap}
}

/* ---------- kotak keterangan: SELALU bertumpuk, selebar wadahnya ----------
   Lampiran & Catatan, Deskripsi & Inspeksi, Biaya Maintenance — semuanya
   memakai kerangka ini, dan semuanya berdiri SATU LAJUR sepenuh lebar
   wadahnya. Dua kotak bersebelahan pernah dipakai dengan alasan menghemat
   tinggi, tetapi isinya kalimat: dibelah dua, setiap kalimat pendek melipat
   menjadi tiga baris dalam kotak 330px sementara separuh lebarnya menganggur,
   dan urutan bacanya jadi mendatar lalu menurun — bukan menurun lurus seperti
   yang dibaca orang. Yang dihemat tingginya hilang lagi oleh lipatannya. */
.dwi{display:grid;grid-template-columns:1fr;gap:12px}
/* ---------- badan dokumen dibelah dua ----------
   Kiri isinya (Item), kanan keterangannya (Lampiran, Catatan). Di telepon
   pembelahan luruh menjadi satu kolom, dan kotak Lampiran/Catatan yang di
   layar lebar berdiri bersebelahan ikut bertumpuk — dua kotak selebar
   setengah layar telepon tidak muat apa-apa. */
.docsplit{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:16px;align-items:start}
.docsplit-kiri,.docsplit-kanan{min-width:0}
.docsplit .sec{margin-bottom:16px}
.docsplit .sec:last-child{margin-bottom:0}
.docsplit .dhead{position:static;margin-bottom:16px}
@media(max-width:1080px){
  .docsplit{grid-template-columns:1fr;gap:0}
}
/* ---- badan dokumen uang: kiri digulir, kanan MENGGANTUNG ----
   Yang menentukan pembagiannya adalah seberapa sering sesuatu dibaca, bukan
   seberapa besar. Kiri: kepala, daftar item, lalu Lampiran dan Catatan di
   kaki — dibaca sekali dari atas ke bawah. Kanan: Ringkasan Keuangan, dan
   tidak ada yang lain; ia satu-satunya benda yang dilirik berulang kali
   sambil mengerjakan yang di kiri. Di kaki daftar item ia hilang dari layar
   begitu daftarnya lebih panjang dari satu layar, dan setiap lirikan berarti
   menggulir turun lalu naik lagi.

   `top` = tinggi baris kepala (56px) + jarak nafas, karena baris kepala
   sendiri menempel; tanpa itu ringkasannya berhenti DI BALIK baris kepala. */
.docsplit--uang{grid-template-rows:auto auto}
.docsplit--uang > .docsplit-kiri{grid-column:1;grid-row:1}
.docsplit--uang > .docsplit-bawah{grid-column:1;grid-row:2;min-width:0}
.docsplit--uang > .docsplit-kanan{grid-column:2;grid-row:1 / -1;
  position:sticky;top:70px;align-self:start}
.docsplit--uang > .docsplit-kanan > * + *{margin-top:16px}
@media(max-width:1080px){
  /* Satu kolom: penempatan tegasnya dilepas dan ketiganya kembali mengalir
     menurut urutan tulisnya — item, ringkasan uang, lalu lampiran. Menggantung
     pun dilepas: di layar setinggi 800px sebuah kotak menggantung setinggi
     300px berarti sepertiga layar tidak pernah bisa dipakai. */
  .docsplit--uang > .docsplit-kiri,
  .docsplit--uang > .docsplit-kanan,
  .docsplit--uang > .docsplit-bawah{grid-column:auto;grid-row:auto;position:static}
}
/* ---- satu isi kolom kanan yang NAIK begitu kolomnya luruh ----
   Lampiran dan Catatan memang benar jatuh ke bawah di telepon: keduanya
   dibaca paling akhir. Tetapi sebagian kolom kanan bukan itu — kotak pindai
   Opname adalah ALAT yang dipakai sambil berdiri di gudang, dan strip Masa
   Garansi adalah keterangan kepala yang dicari lebih dulu daripada isi
   dokumennya. Keduanya harus naik ke atas, bukan tenggelam di bawah daftar.

   `display:contents` melarutkan kotak kolom kanan sehingga isinya menjadi
   anak langsung petak yang sama dengan kolom kiri, lalu `order` menyusun
   ulang ketiganya. `min-width:0` tetap harus dipasang tangan: yang tadinya
   dijaga oleh `.docsplit-kanan` sekarang tidak punya penjaga, dan satu baris
   tab yang panjang akan melebarkan seluruh halaman. */
@media(max-width:1080px){
  .docsplit--pecah .docsplit-kanan{display:contents}
  .docsplit--pecah > *,.docsplit--pecah .docsplit-kanan > *{min-width:0}
  .docsplit--pecah .kanan-naik{order:-1;margin-top:0}
  .docsplit--pecah .docsplit-kiri{order:0}
  .docsplit--pecah .docsplit-kanan > *:not(.kanan-naik){order:1}
}

/* ---------- KARTU DOKUMEN DI DAFTAR ----------
   Menurun, bukan berlajur. Kartu berlajur memaksa nama pihak, foto, nama
   barang, angka, dan keadaannya berebut satu baris; di kolom setengah lebar
   semuanya lalu terpotong bersama-sama. Menurun, setiap hal dapat barisnya
   sendiri — dan garis pembatas tegak di antara lajur ikut hilang bersama
   lajurnya. */
.dok{display:block;width:100%;text-align:left;font:inherit;background:var(--surface);
  border:1px solid var(--line);border-radius:var(--radius);padding:13px 15px;cursor:pointer}
.dok:hover{border-color:var(--line-strong);box-shadow:var(--shadow)}
.dok:focus-visible{outline:2px solid var(--ink);outline-offset:2px}
/* Nama pihak di pojok kiri atas dan keadaannya sebaris dengannya: dua hal
   yang menjawab "punya siapa" dan "sudah sampai mana". */
.dok-hd{display:flex;align-items:center;gap:10px;padding-bottom:11px;border-bottom:1px solid var(--line)}
.dok-pihak{min-width:0;flex:1 1 auto;font-family:var(--f-judul);
  font-size:var(--f14);font-weight:600;letter-spacing:-.01em;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.dok-st{flex:none}
/* IKON MODUL DI KEPALA KARTU (K-266 lanjutan, diminta pemiliknya). Ia
   PENANDA, bukan isi: warnanya paling redup dan ukurannya sebesar huruf di
   sebelahnya, karena ia menjawab pertanyaan yang cuma ditanyakan sekali —
   "daftar apa ini" — dan sesudah terjawab ia tidak boleh berebut perhatian
   dengan nama pihaknya. */
.dok-ik{flex:none;display:inline-flex;color:var(--ink-3)}
.dok-ik svg{width:15px;height:15px}
/* KEADAAN DOKUMEN DI KARTU BERHENTI BERKOTAK (diminta pemiliknya: *"statusnya
   gak usah dikasih kotak kayak gitu, karena memenuhi tempat, cukup tulisan
   aja"*). Yang dibayar LEBAR: garis keliling beserta padding-nya memakan 20px
   di baris yang sudah berebut tempat dengan nama pihak, dan di 390px nama
   yang panjang terpotong karenanya.

   YANG DICABUT KOTAKNYA SAJA, BUKAN WARNANYA: warna itu yang mengatakan
   keadaan mana, dan mencabutnya berarti empat keadaan berbunyi sama. Dan ia
   dicabut DI KARTU saja — pil yang sama tetap berkotak di kepala halaman
   detail, tempat ia berdiri sendirian sebagai keterangan utama dan memang
   perlu dibaca sebagai sebutan. */
.dok-st .pill{height:auto;padding:0;border:0;background:transparent}
.dok-st .pill--solid{color:var(--ink)}
/* Satu baris satu barang. Fotonya milik barang itu, 1:1, dan tetap 1:1
   berapa pun tinggi barisnya. */
.dok-item{display:flex;align-items:flex-start;gap:11px;padding:11px 0;border-bottom:1px solid var(--line)}
.dok-item--sisa{display:none}
.dok--buka .dok-item--sisa{display:flex;animation:dokMuncul .34s ease both}
@keyframes dokMuncul{from{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}
@media (prefers-reduced-motion:reduce){ .dok--buka .dok-item--sisa{animation:none} }
.dok-foto{flex:none;width:58px;aspect-ratio:1/1;border-radius:var(--radius);overflow:hidden;
  background:var(--surface-2);border:1px solid var(--line);display:grid;place-items:center}
.dok-foto img{width:100%;height:100%;object-fit:cover;display:block}
.dok-foto[role="button"]{cursor:zoom-in}
.dok-foto[role="button"]:hover{border-color:var(--line-strong)}
.dok-foto-kosong{color:var(--ink-3)}
.dok-foto-kosong svg{width:22px;height:22px}
/* align-self:stretch + space-between: baris uang DIKUNCI di dasar barisnya,
   bukan mengambang mengikuti panjang nama barangnya. Tanpa itu, kartu yang
   nama barangnya satu baris menaruh angkanya belasan piksel lebih tinggi
   daripada kartu yang namanya dua baris — dan pada daftar yang digulir cepat,
   angka yang berpindah-pindah ketinggian tidak bisa disusuri sekali lihat.
   Yang menentukan dasar barisnya adalah fotonya (58px), jadi seluruh kartu
   mengunci angkanya pada garis yang sama. */
.dok-nm{flex:1 1 auto;min-width:0;align-self:stretch;
  display:flex;flex-direction:column;justify-content:space-between;gap:3px}
/* Baris pertama memakai SELURUH lebar barisnya — angkanya turun ke baris
   kedua, tempat nama inventory yang pendek dan baku memang menyisakan ruang. */
.dok-nm-t{font-size:var(--f13);font-weight:500;line-height:1.35;
  display:-webkit-box;-webkit-line-clamp:2;line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
/* flex-start: HARGANYA yang sejajar dengan nama inventory, dan "Biaya:"
   menggantung di bawahnya.

   Dulu diratakan dari BAWAH, dengan alasan agar barisnya tidak bertambah
   tinggi. Akibatnya terbalik dari yang dimaksud: pada dokumen yang punya
   biaya, harganya justru terangkat ke baris NAMA PEMBELIAN di atas dan
   "Biaya:" yang sejajar dengan nama inventory — jadi angka pokoknya seolah
   berdiri di baris sendiri sementara angka pelengkapnya menempati tempat yang
   seharusnya miliknya. Kartu tanpa biaya dan kartu dengan biaya lalu menaruh
   harganya di dua ketinggian yang berbeda, dan itu persis yang tidak boleh
   terjadi di daftar yang digulir cepat. */
.dok-nm-b{display:flex;align-items:flex-start;gap:12px;min-width:0}
.dok-nm-s{flex:1 1 auto;font-size:var(--f12);color:var(--ink-3);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* Lajur kanan baris item: harganya, lalu bagian biaya yang menempel padanya.
   Keduanya rata kanan pada satu tepi yang sama dengan angka-angka di kaki
   kartu, jadi mata menyusuri satu garis dari atas ke bawah. */
/* Garis tegak tipis di kiri angkanya: tanpa itu, nama inventory yang kebetulan
   panjang terbaca menyambung ke nominalnya — "…Titan Grey Rp4.100.000" sebagai
   satu kalimat. */
/* Garis tegak itu PEMISAH. Pada dokumen yang barisnya tidak punya nama
   inventory — seluruh item penjualan — ia tidak memisahkan apa pun dan
   berdiri sebagai satu garis menggantung di tengah kartu. */
.dok-nm-s:empty + .dok-kanan{border-left:0;padding-left:0}
.dok-kanan{flex:none;display:flex;flex-direction:column;align-items:flex-end;gap:4px;text-align:right;
  padding-left:12px;border-left:1px solid var(--line)}
.dok-hrg{flex:none;font-family:var(--f-angka);
  font-variant-numeric:tabular-nums;font-size:var(--f13);font-weight:600}
.dok-bagi{display:inline-flex;align-items:baseline;gap:8px;font-size:var(--f11);color:var(--ink-3);
  white-space:nowrap}
.dok-bagi b{font-family:var(--f-angka);font-variant-numeric:tabular-nums;
  font-size:var(--f12);font-weight:500;color:var(--ink-3)}
.dok-item--mati .dok-nm-t{text-decoration:line-through;color:var(--ink-3);font-weight:400}
/* "Lihat Semua" berdiri sendiri di tengah, seperti di daftar pesanan toko
   daring: ia bukan tindakan atas dokumennya, cuma membuka barisnya. */
.dok-lagi{display:flex;align-items:center;justify-content:center;gap:6px;width:100%;
  padding:8px 0;border:0;background:none;font:inherit;font-size:var(--f12);color:var(--ink-2);cursor:pointer}
.dok-lagi svg{width:13px;height:13px;transform:rotate(90deg);transition:transform .16s}
.dok--buka .dok-lagi svg{transform:rotate(-90deg)}
.dok-lagi:hover{color:var(--ink)}
/* Kesimpulan uangnya: sebutan dan angka berpasangan, rata kanan, menurun —
   bentuk yang sama dengan Ringkasan Keuangan di halaman detailnya. */
.dok-total{display:flex;flex-direction:column;align-items:flex-end;gap:5px;
  padding:9px 0 11px;font-size:var(--f12);color:var(--ink-2);border-bottom:1px solid var(--line)}
.dok-trow{display:flex;align-items:baseline;justify-content:flex-end;gap:10px;max-width:100%}
.dok-total b{font-family:var(--f-angka);font-variant-numeric:tabular-nums;
  font-size:var(--f14);font-weight:600;color:var(--ink)}
/* Baris terakhir berdiri di balik garisnya sendiri: ia kesimpulan dari dua
   baris di atasnya, bukan baris ketiga yang setara. */
.dok-trow--akhir{border-top:1px solid var(--line);padding-top:7px;margin-top:2px}
.dok-trow--akhir > span{color:var(--ink)}
.dok-kaki{display:flex;align-items:center;gap:10px;padding-top:11px}
.dok-meta{flex:1 1 auto;min-width:0;display:flex;align-items:center;gap:7px;
  font-size:var(--f12);color:var(--ink-3);font-family:var(--f-angka);
  overflow:hidden;white-space:nowrap;text-overflow:ellipsis}
.dok-meta i{font-style:normal;opacity:.5}
/* Yang mengalah saat kaki kartu kekurangan lebar adalah NAMA LOKASINYA, dan
   ia mengalah dengan titik-titik — bukan terpotong di tengah huruf sampai
   bertabrakan dengan cip di sebelahnya. Tanggalnya tidak pernah mengalah:
   ia sudah kehilangan tahun dan jamnya di bawah 560px. */
.dok-lok{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* Baris meta boleh membawa ikon (panah masuk gudang, pin lokasi). Tanpa
   ukuran, sebuah <svg> di dalam baris flex tumbuh setinggi barisnya sendiri
   dan menelan seluruh kartu. */
.dok-meta svg{width:13px;height:13px;flex:none;opacity:.8}
.dok-tag{flex:none;display:flex;align-items:center;gap:6px}

/* ---------- daftar kartu selebar setengah halaman ----------
   Kolomnya dipatok dengan grid yang sama persis dengan .docsplit, jadi kartu
   di daftar dan dokumen di halaman detail berdiri pada lebar yang identik:
   mata yang berpindah dari daftar ke detail tidak perlu menyesuaikan diri.
   Kartunya sendiri yang harus menyusut isinya — nomor, jam, dan nama pembuat
   dicabut — bukan lebarnya yang dipaksa memuat semuanya. */
.daftarsempit{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:16px 16px;align-items:start}
.daftarsempit > *{grid-column:1;min-width:0}
/* Dua lajur: kartunya sudah cukup ringkas untuk berdiri berdampingan, jadi
   lajur kanan tidak dibiarkan kosong. Baris keterangan di atasnya tetap
   melintasi keduanya supaya angkanya benar-benar mepet ke tepi kanan
   halaman, bukan ke tengah. */
.daftarsempit--dua > *{grid-column:auto}
/* Satu lajur PENUH: dipakai saat daftarnya sendiri sudah berdiri di kolom
   sempit — kartu penjualan di Detail Item, misalnya. Tanpa ini kartunya masuk
   ke lajur kiri dari dua lajur, jadi separuh dari kolom yang sudah separuh. */
.daftarsempit--satu{grid-template-columns:1fr}
/* UBIN: kartu bergambar yang dijejer, jumlah lajurnya mengikuti lebar layar —
   dan di telepon TETAP DUA (diminta pemiliknya untuk Daftar Item). Kartu
   bergambar yang berdiri satu lajur memaksa menggulir dua kali lebih jauh
   untuk daftar yang sama, dan foto selebar layar telepon berarti 358px hanya
   untuk satu barang.

   Lajurnya ditulis sebagai angka, bukan `auto-fill`: dengan auto-fill lebar
   kartunya berubah-ubah beberapa piksel mengikuti sisa ruang, dan foto 1:1
   yang lebarnya berubah membuat tinggi seluruh barisnya ikut berubah. */
.daftarsempit--ubin{grid-template-columns:repeat(5,minmax(0,1fr))}
.daftarsempit--ubin > *{grid-column:auto}
.daftarsempit .daftarhead,.daftarsempit .empty,
.daftarsempit .skel{grid-column:1 / -1}
@media(max-width:1080px){ .daftarsempit,.daftarsempit--dua{grid-template-columns:1fr} }
/* Ditulis SESUDAH aturan 1080px di atas supaya ia menang: daftar berubin
   tidak pernah luruh menjadi satu lajur. */
/* JUMLAH LAJURNYA DIPILIH SUPAYA LEBAR KARTUNYA HAMPIR TIDAK BERUBAH (K-132,
   diminta pemiliknya: "agar ukurannya proporsional sebaiknya satu baris jangan
   4 kartu, tapi 5 kartu").

   Yang membuatnya terasa tidak proporsional bukan angka lajurnya melainkan
   LONCATANNYA. Diukur di peramban pada susunan lama:

       1440 → 5 lajur, kartu 215px      1024 → 3 lajur, kartu 231px
       1366 → 5 lajur, kartu 200px       900 → 3 lajur, kartu 279px
       1280 → 4 lajur, kartu 233px

   Jadi layar yang MENYEMPIT justru melahirkan kartu yang MEMBESAR — di layar
   laptop 1280 dan 1366 yang paling sering dipakai, kartunya paling gemuk. Yang
   dikejar sekarang lebar kartu yang tidak melompat jauh, dan sesudah diukur
   ulang ia berkisar 169–234px di SELURUH lebar:

       1536 → 5 · 234    1366 → 5 · 200    1100 → 4 · 188    900 → 4 · 205
       1440 → 5 · 215    1280 → 5 · 183    1024 → 4 · 169    830 → 4 · 188

   Lajur 3 DICABUT: di setiap lebar tempat ia dulu berlaku, 4 lajur memberi
   kartu yang lebih dekat ke ukuran tetangganya. Loncatan 5→4 selalu 25%
   (daftar/5 menjadi daftar/4), jadi yang bisa dipilih cuma DI MANA ia jatuh —
   1224px, tempat kedua sisinya masih di dalam rentang di atas. Layar laptop
   yang paling sering dipakai (1280, 1366, 1440, 1536) seluruhnya dapat 5.

   Satu lebar yang memang kurang, dan disebut apa adanya: 1024px, tempat menu
   kirinya masih terbuka dan menyisakan 724px untuk daftarnya. Di situ 4 lajur
   memberi 169px dan 3 lajur memberi 241px — tidak ada jawaban yang enak;
   yang dipilih yang lebih dekat ke lebar kartu di telepon (183px). */
@media(max-width:1224px){ .daftarsempit--ubin{grid-template-columns:repeat(4,minmax(0,1fr))} }
@media(max-width:820px){ .daftarsempit--ubin{grid-template-columns:repeat(2,minmax(0,1fr));gap:12px 9px} }
/* CELAH KIRI DAN KANAN KARTU DIMEPETKAN (diminta pemiliknya, dengan Shopee
   sebagai contoh: "bisa memanfaatkan semua space dengan baik"). Daftar berubin
   MENEMBUS jarak sisi halaman sampai menyisakan 8 px saja — bukan dengan
   mengubah `--pad-hal`, yang berlaku untuk seluruh ERP dan akan menggeser
   setiap halaman lain sekaligus. Yang melebar cuma daftar ini. */
@media(max-width:560px){
  .daftarsempit--ubin{gap:10px 8px}
}
/* Layar 360px: harganya diturunkan setengah piksel supaya cip Batas di
   sebelahnya tetap tercetak utuh, bukan berakhir titik-titik. */
/* Di kolom setengah lebar, yang mengecil lebih dulu adalah foto dan kolom
   angkanya — bukan nama pihak dan nama barang, karena keduanya itulah yang
   dicocokkan orang sambil menyusuri daftar. */
.daftarsempit .pc{gap:12px;padding:12px 13px}
.daftarsempit .pc-foto{width:92px;min-height:0}
.daftarsempit .pc-isi{gap:7px}
.daftarsempit .avatarhuruf.pc-ava{width:30px;height:30px;font-size:var(--f12)}
.daftarsempit .pc-who{gap:8px}
.daftarsempit .pc-who b{font-size:var(--f13);max-width:100%}
.daftarsempit .pc-brg{font-size:var(--f13);line-height:20px;height:20px}
.daftarsempit .pc-barang{min-height:43px}
.daftarsempit .pc-meta{flex-wrap:nowrap;overflow:hidden;font-size:var(--f11);gap:6px;padding-top:7px}
.daftarsempit .pc-meta > span{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.daftarsempit .pc-kanan{width:158px;padding-left:12px;gap:5px}
.daftarsempit .pc-total{font-size:var(--f14)}
.daftarsempit .pc-catat{font-size:var(--f11)}
.daftarsempit .chipinfo{font-size:var(--f11);height:20px;padding:0 7px}
/* Tiga baris juga di kolom setengah lebar. Kolom kanan kartu ini tidak lagi
   memakan sepertiga lebarnya untuk sederet angka — angkanya menumpuk di pojok
   kanan atas — jadi deskripsinya punya tempat, dan baris keempatnya diisi
   serial. */
/* Yang mengalah saat baris keterangannya kehabisan tempat adalah NAMA
   LOKASI, bukan tanggalnya: nama lokasi masih bisa ditebak dari sepotong
   awalnya, tanggal yang terpotong tidak bisa dibaca sama sekali. */
/* Di kartu Item, yang mengalah adalah nama lokasinya — bukan tanggalnya.
   Aturan di atas memotong butir pertama, dan butir pertama di sini adalah
   tanggal masuk: "25 Ags 20…" berhenti menjadi tanggal, sedangkan
   "Outlet Kediri Ko…" masih terbaca sebagai nama outlet. */
.dwi-kolom{border:1px solid var(--line);border-radius:var(--radius);background:var(--surface);padding:14px 15px;min-width:0}
/* Tinggi kepalanya dipatok. Kotak yang kepalanya cuma berisi ikon pensil dan
   kotak yang kepalanya berisi tombol penuh dulu berbeda beberapa piksel, jadi
   dua kotak sepasang tidak pernah benar-benar sejajar dasarnya. */
.dwi-hd{display:flex;align-items:center;justify-content:space-between;gap:10px;flex-wrap:wrap;min-height:30px}
.dwi-hd b{font-family:var(--f-judul);font-size:var(--f12);font-weight:600}
.dwi-kolom{display:flex;flex-direction:column}
/* Tingginya dipendekkan seperempat, dan dijadikan batas atas — isi yang
   pendek tidak lagi menyisakan ruang kosong. overscroll-behavior:contain
   dicabut: ia menahan gulir halaman begitu kursor berada di atas kotak ini,
   sehingga halaman terasa macet padahal tidak ada yang salah. */
/* Tingginya MENGIKUTI ISI, dengan 143px sebagai batas atas dan gulir sesudah
   itu. Dulu ia dipatok 143px, dengan alasan dua kotak yang bersebelahan harus
   sama tinggi — tetapi sejak kotaknya bertumpuk satu lajur, tidak ada lagi
   tetangga yang harus disamai, dan kotak 143px yang isinya satu baris memakan
   sepertiga layar untuk memperlihatkan ruang kosong. Tinggi minimum tetap ada
   supaya kotak kosong tidak menciut menjadi satu garis yang tidak terbaca
   sebagai kotak. */
.dwi-isi{font-size:var(--f12);line-height:1.65;color:var(--ink-2);overflow-wrap:anywhere;white-space:pre-wrap;
  height:auto;max-height:143px;min-height:40px;overflow-y:auto;padding-right:6px;flex:none;margin-top:10px}
.dwi-isi .lblkecil{margin-top:8px}
.fotogrid--kecil{grid-template-columns:repeat(3,1fr);gap:6px}
/* Deretan foto kecil di dalam kotak yang tingginya DIPATOK (kotak Inspeksi).
   Ukurannya dipatok pada foto, bukan pada lebar kolomnya: dibagi rata tiga
   kolom, satu foto saja sudah setinggi seluruh kotak dan teks di bawahnya
   terdorong keluar. */
.fotogrid--strip{grid-template-columns:repeat(auto-fill,54px);gap:6px}
/* Tiga petak sudah satu baris penuh di kolom setengah lebar; sisanya diringkas
   menjadi satu angka di petak terakhir. Menekannya membuka SEMUANYA, jadi
   tidak ada foto yang benar-benar tersembunyi. */
.fotolebih{position:absolute;inset:0;display:grid;place-items:center;border-radius:inherit;
  background:rgba(0,0,0,.55);color:#fff;font-weight:600;font-size:var(--f13);pointer-events:none}
/* Jalur foto lampiran: empat muat, sisanya digeser ke samping di dalam
   kotaknya sendiri. Tingginya persis sama dengan kotak Deskripsi supaya
   keduanya berdiri sejajar, jadi ia menggeser ke kiri, bukan ke bawah. */
/* align-items:center, bukan stretch. Sebagai anak flex yang dibiarkan
   meregang, foto persegi ikut setinggi kotaknya yang 143px sementara lebarnya
   tetap seperempat kolom — jadi tampil memanjang ke atas padahal gambarnya
   sendiri 1:1. */
.dwi-isi--foto{display:flex;align-items:center;gap:8px;overflow-x:auto;overflow-y:hidden;padding-bottom:6px;
  scroll-snap-type:x proximity;overscroll-behavior-x:contain}
/* Ubin BERUKURAN TETAP, bukan seperempat lebar kolomnya. Sejak kotaknya
   selebar wadah penuh, seperempat lebar berarti foto 160px — lebih tinggi
   daripada batas kotaknya sendiri, jadi satu foto pun sudah membuatnya
   menggulir. Ukuran tetap juga berarti jumlah foto per baris menyesuaikan
   lebar layar dengan sendirinya. */
.dwi-isi--foto img{flex:none;align-self:center;width:96px;height:96px;object-fit:cover;
  border-radius:var(--radius);border:1px solid var(--line);cursor:zoom-in;scroll-snap-align:start}

/* ==========================================================================
   ONLINE SHOP — HALAMAN PRODUK
   Dibuat padat: foto dan keputusan membeli muat dalam satu layar.
   ========================================================================== */
/* Wallpaper toko dibuat 2:1 — itu rasio yang diunggah dan dipotong admin.
   Di layar lebar tingginya dibatasi supaya tidak memakan satu layar penuh;
   gambarnya tetap menutup penuh, hanya terpangkas di atas dan bawah. */
.tokobanner{width:100%;aspect-ratio:2/1;height:auto;max-height:340px;background-color:var(--surface-2)}
.pdp{display:grid;grid-template-columns:minmax(0,420px) minmax(0,1fr);gap:24px;align-items:start;margin-bottom:30px}
.pdp-foto{position:sticky;top:80px;min-width:0}  /* min-width:0 — K-183. Petak grid bawaannya tidak mau menyusut di bawah lebar
     TERKECIL isinya, dan isi tersempit di sini jejeran foto kecil: delapan foto
     berarti 489px, dan petak yang menolak menyusut itu melebarkan HALAMANNYA.
     Lihat bagiannya di prototipe/CLAUDE.md. */
.pdp-utama{position:relative;aspect-ratio:1/1;border:1px solid var(--line);border-radius:var(--radius);overflow:hidden;background:var(--surface-2)}
.pdp-utama img{width:100%;height:100%;object-fit:cover;display:block}
.pdp-kosong{width:100%;height:100%;display:grid;place-items:center;color:var(--ink-3)}
.pdp-mini{display:flex;gap:7px;margin-top:9px;overflow-x:auto;padding-bottom:3px}
.pdp-minibtn{flex:none;width:62px;height:62px;border:1px solid var(--line);border-radius:var(--radius);overflow:hidden;
  background:none;padding:0;cursor:pointer;transition:border-color .14s}
.pdp-minibtn.on{border-color:var(--ink);border-width:2px}
.pdp-minibtn img{width:100%;height:100%;object-fit:cover;display:block}
.pdp-info{min-width:0}
/* NAMANYA MENTOK KE KANAN DULU, BARU TURUN (K-252, dilaporkan pemiliknya
   dengan tangkapan layar: *"harusnya tulisan Like New masih lanjut diatas,
   bukan ditaruh dibawah"*).

   Sebabnya `text-wrap:balance` yang dibawa `h1,h2,h3,h4` di kepala berkas
   ini: ia membagi tulisannya menjadi baris-baris yang SAMA PANJANG, jadi
   "Huawei Matepad Mini 12/256" berhenti di situ sementara di kanannya masih
   kosong selebar "Like New". Balance memang enak untuk judul halaman yang
   pendek — "Daftar Penjualan" — tetapi nama barang bekas panjang dan tidak
   pernah perlu seimbang; yang dibutuhkan pembacanya baris yang penuh.

   PERSIS penyakit yang sama sudah dibetulkan untuk Detail Item di dalam ERP
   (`.itemjudul h1`, beberapa ratus baris di bawah) atas laporan pemiliknya
   juga. Yang di etalase tidak ikut waktu itu, dan cacatnya karena itu lahir
   dua kali dari satu sebab.

   `overflow-wrap:anywhere` ikut, alasan yang sama dengan kembarannya: nama
   yang mengandung satu kata sangat panjang — kode warna pabrik, misalnya —
   akan melebar melewati kotaknya kalau tidak boleh dipenggal. */
.pdp-info h1{font-family:var(--f-judul);font-size:var(--f16);font-weight:400;line-height:1.35;margin:0 0 8px;letter-spacing:normal;
  overflow-wrap:anywhere;text-wrap:wrap}
.pdp-harga{font-family:var(--f-judul);font-size:var(--f22);font-weight:700;letter-spacing:-.02em;
  font-variant-numeric:tabular-nums;margin-bottom:8px}
.pdp-meta{display:flex;align-items:center;gap:7px;flex-wrap:wrap;font-size:var(--f12);color:var(--ink-3);margin-bottom:16px}
.pdp-meta svg{width:14px;height:14px;vertical-align:-2px;margin-right:3px}
/* TINDAKAN YANG MENGHASILKAN UANG berdiri PALING KANAN dan paling besar.
   Dulu "Beli" berada di tengah empat tombol yang sama besarnya, dan karena
   tulisannya paling pendek ia justru yang paling kecil di antara semuanya. */
.pdp-aksi{display:flex;gap:9px;flex-wrap:wrap;margin-bottom:16px}
.btn--beli{padding:0 30px}
.pdp-aksi .notice{flex:1 1 100%}
/* WhatsApp tinggal ikonnya (K-281). */
.pdp-aksi > .pdp-wa{flex:none;width:44px}
.pdp-wa svg{width:20px;height:20px}
/* KOTAK TOKO DI HALAMAN PRODUK (K-222, diminta pemiliknya "dirapikan").
   Tiga bagian yang BERTUMPUK, masing-masing menjawab satu pertanyaan: toko
   apa ini, angkanya berapa, dan di mana tempatnya. Dulu ketiganya berdesakan
   dalam satu baris flex yang boleh membungkus, dan yang terlempar ke baris
   berikutnya berbeda-beda menurut panjang nama tokonya. */
/* PETAKNYA DI SEBELAH KANAN TOKONYA (K-255), diminta pemiliknya "biar tidak
   memenuhi tempat". Yang dibayar bentuk bertumpuk sebelumnya TINGGI: empat
   petak yang berdiri sendiri di bawah tokonya mendorong harga barangnya turun
   satu blok penuh, dan harga itulah yang dicari orang begitu halamannya
   terbuka.

   LAJUR KIRI YANG MENGALAH, bukan petaknya: `flex:1 1 0` beserta `min-width:0`
   membuat nama toko yang panjang dipotong titik-titik, sementara petak
   angkanya tetap selebar isinya. Dibalik, nama toko sepanjang apa pun
   mendorong petaknya keluar kotak. */
.pdp-toko{display:flex;align-items:center;gap:14px;padding:14px;border:1px solid var(--line);
  border-radius:var(--radius);background:var(--surface-2);margin-bottom:18px}
.pdp-toko-atas{flex:1 1 0;display:flex;align-items:center;gap:12px;min-width:0}
.pdp-toko-info{flex:1 1 auto;min-width:0;display:flex;flex-direction:column;gap:2px}
.pdp-toko-nama{font-family:var(--f-judul);font-size:var(--f13);font-weight:600;color:var(--ink);text-decoration:none}
.pdp-toko-nama:hover{text-decoration:underline}
.pdp-toko-info .muted{font-size:var(--f12);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* EMPAT PETAK SETARA, angkanya di atas dan sebutannya di bawah — bentuk yang
   sama dengan petak angka di dalam ERP. Yang memisahkannya GARIS dan
   pergantian bidang (K-219), bukan jarak kosong; lebarnya seperempat kotak
   di lebar mana pun, jadi tingginya tidak pernah berloncatan. */
/* TANPA KOTAK (K-274, diminta pemiliknya dengan contoh Shopee: "4 informasi
   ... itu jangan dibikin kotak kotak gitu"). Angkanya di atas, sebutannya di
   bawah, dan yang memisahkannya GARIS TEGAK tipis — bukan bingkai dan bukan
   bidang berbeda. */
.pdp-toko-stat{flex:0 0 auto;display:grid;grid-template-columns:repeat(4,auto)}
.pdp-toko-stat > *{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;
  min-width:0;padding:2px 16px;color:inherit;text-decoration:none;border-left:1px solid var(--line)}
.pdp-toko-stat > *:first-child{border-left:0}
.pdp-toko-stat b{max-width:100%;font-family:var(--f-angka);font-size:var(--f13);font-weight:600;color:var(--ink);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pdp-toko-stat i{font-style:normal;font-size:var(--f12);color:var(--ink-3)}
.pdp-toko-kunjungi{flex:none;height:34px;padding:0 16px}
.pdp-toko-stat a:hover b{text-decoration:underline}
.pdp-desk h2{font-family:var(--f-judul);margin:0 0 8px}
.pdp-desk p{font-size:var(--f13);line-height:1.7;color:var(--ink-2);margin:0 0 11px}
.pdp-desk p:last-child{margin-bottom:0}

/* baris rekomendasi yang digeser menyamping */
.barisrek{margin-bottom:30px}
.barisrek-hd{display:flex;align-items:baseline;justify-content:space-between;gap:14px;margin-bottom:12px}
.barisrek-hd h2{font-family:var(--f-judul);margin:0}
/* HURUF BESAR SELURUHNYA DICABUT (K-184). "PRODUK LAIN DARI TOKO INI"
   berhuruf besar dan berjarak lebar adalah bentuk LABEL, bukan judul —
   dan di etalase ia berdiri sebaris dengan dua judul seksi lain yang
   berhuruf biasa. Shopee pun menulisnya biasa. */
.barisgeser{display:flex;gap:12px;overflow-x:auto;padding-bottom:2px;scroll-snap-type:x proximity}
/* LEBIH RAMPING daripada kartu etalase (K-274, "bentuk cardnya tolong
   dibedakan, yaitu lebih ramping"), dan TANPA BATANG GULIR — batang tipis
   yang ikut bergeser itulah "kotak kecil melayang" yang diminta dicabut
   pemiliknya. Geserannya sendiri tetap. */
.barisgeser > *{flex:none;width:180px;scroll-snap-align:start}
.barisgeser{scrollbar-width:none}
.barisgeser::-webkit-scrollbar{display:none}
/* TOMBOL GESER BARIS (tahap 6b): persegi panjang tipis menempel di tepi
   kiri dan kanan barisnya, hanya di layar bertetikus selebar laptop. */
.barisgeser-bungkus{position:relative}
.gesertombol{display:none}
@media (hover:hover) and (pointer:fine) and (min-width:641px){
  .gesertombol{position:absolute;top:50%;z-index:2;display:grid;place-items:center;width:26px;height:72px;
    margin-top:-36px;padding:0;cursor:pointer;color:var(--ink);background:var(--surface);
    border:1px solid var(--line-strong);border-radius:var(--radius);box-shadow:var(--shadow);transition:opacity .15s}
  .gesertombol--kiri{left:-10px}
  .gesertombol--kanan{right:-10px}
  .gesertombol svg{width:16px;height:16px}
  .gesertombol--kiri svg{transform:rotate(180deg)}
  .gesertombol:hover{border-color:var(--ink)}
  .ujung-kiri > .gesertombol--kiri,.ujung-kanan > .gesertombol--kanan{opacity:0;pointer-events:none}
}
/* "LIHAT SEMUA" DI UJUNG BARISNYA (K-274): "tipis tapi besar" — lingkaran
   bergaris tipis berisi panah, tulisannya di bawahnya, tanpa kotak. */
.lihatsemua{flex:none;width:120px;display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:10px;text-decoration:none;color:var(--ink-2);font-size:var(--f12)}
.lihatsemua:hover{color:var(--ink)}
.lihatsemua-ik{display:grid;place-items:center;width:52px;height:52px;border:1px solid var(--line-strong);
  border-radius:50%}
.lihatsemua:hover .lihatsemua-ik{border-color:var(--ink)}
.lihatsemua-ik svg{width:20px;height:20px;transform:rotate(180deg);stroke-width:1.1}
.rekmuat{text-align:center;font-size:var(--f12);color:var(--ink-3);padding:18px 0;cursor:pointer}
/* BARIS "SEDANG MEMUAT" di dasar daftar etalase (K-200), diminta pemiliknya:
   daftarnya menyambung sendiri saat gulirannya hampir mentok, dengan animasi
   memuat di bagian paling bawah — bukan tombol "Muat lagi" yang harus
   ditekan. Ia TENANG: yang dibaca orang barangnya, bukan barisnya. */
.shopmuat{display:flex;align-items:center;justify-content:center;gap:9px;padding:26px 0;
  font-size:var(--f12);color:var(--ink-3);cursor:pointer}
.shopmuat .spin{width:15px;height:15px;border-radius:50%;border:1.8px solid currentColor;
  border-right-color:transparent;animation:spin .7s linear infinite}
@media (prefers-reduced-motion:reduce){.shopmuat .spin{animation:none}}

/* HALAMAN PENCARIAN (K-201). Dua seksi saja: pencarian terakhir orangnya
   sendiri (disimpan di perambannya) dan rekomendasi. Jarak antar seksinya
   sama dengan halaman etalase lain, jadi ia tidak terbaca sebagai halaman
   dari aplikasi yang berbeda. */
.carisek{margin-bottom:22px}
.carichips{display:flex;flex-wrap:wrap;gap:8px}
/* Kata dan silangnya SATU CIP, bukan dua benda bersebelahan: silang yang
   berdiri sendiri di sebelah kata terbaca sebagai cip berikutnya. */
.carichip{display:inline-flex;align-items:stretch;border:1px solid var(--line);
  border-radius:999px;overflow:hidden;background:var(--surface-2)}
.carichip-t{border:0;background:none;color:var(--ink);font:inherit;font-size:var(--f12);
  padding:7px 4px 7px 13px;cursor:pointer;max-width:200px;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}
.carichip-x{border:0;background:none;color:var(--ink-3);cursor:pointer;
  display:grid;place-items:center;padding:0 10px 0 6px}
.carichip-x svg{width:13px;height:13px}
.carichip:hover{border-color:var(--ink-3)}
.carichip-x:hover{color:var(--ink)}
/* HAPUS SEMUA = IKON SAMPAH (K-281), di ujung kanan judul seksinya. */
.carisampah{flex:none;width:32px;height:32px;padding:0;border:0;background:none;color:var(--ink-3);
  display:grid;place-items:center;cursor:pointer;border-radius:var(--radius-kcl)}
.carisampah svg{width:17px;height:17px}
@media (hover:hover){ .carisampah:hover{color:var(--ink)} }
.carisek .sec-hd{align-items:center}

/* DAFTAR REKOMENDASI DI HALAMAN PENCARIAN (K-222), diminta pemiliknya:
   *"bagian bawah itu terasa seperti benar2 merekomendasikan, jadi tampilannya
   harus beda dengan halaman utama."*

   Yang membedakannya BENTUKNYA: satu kotak berisi baris-baris yang dipisah
   garis (K-219), bukan ubin yang berjajar.

   SATU BARIS SATU BARANG, di lebar mana pun (K-225, diminta pemiliknya:
   *"kenapaa kok ada yang 2 lapis? kan itu harus 1 per 1? dan harus
   simpel"*). Ia sempat dua lajur di layar lebar, dan itu mengembalikan
   persis yang dicabut K-222: dua benda bersebelahan terbaca sebagai
   ETALASE, bukan sebagai daftar yang sudah disusunkan untuk orangnya.
   Satu lajur pula yang membuat mata cuma punya SATU tepi untuk disusuri. */
.reklist{display:grid;grid-template-columns:1fr;border:1px solid var(--line);
  border-radius:var(--radius);background:var(--surface);overflow:hidden}
.rekbaris{display:flex;align-items:center;gap:12px;min-width:0;padding:11px 13px;
  color:inherit;text-decoration:none;border-top:1px solid var(--line)}
.reklist > .rekbaris:first-child{border-top:0}
.rekbaris:hover{background:var(--surface-2)}
.rekbaris-ph{flex:none;width:62px;height:62px;border-radius:var(--radius);overflow:hidden;
  background:var(--surface-2);display:grid;place-items:center;color:var(--ink-3)}
.rekbaris-ph img{width:100%;height:100%;object-fit:cover}
.rekbaris-bd{display:flex;flex-direction:column;gap:3px;min-width:0}
/* Namanya DUA BARIS berpotong titik tiga: satu baris memotong terlalu dini
   pada nama barang bekas yang memang panjang ("… 8/256 Graphite Second
   Normal"), tiga baris membuat tinggi barisnya berloncatan. */
.rekbaris-n{font-size:var(--f12);line-height:1.35;color:var(--ink);
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.rekbaris .hrg{font-size:var(--f13)}
.rekbaris-lok{display:flex;align-items:center;gap:5px;min-width:0;font-size:var(--f11);color:var(--ink-3)}
.rekbaris-lok svg{width:12px;height:12px;flex:none}
.rekbaris-lok > span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.rekbaris-gar{display:inline-flex;align-items:center;gap:4px;flex:none;font-style:normal;
  padding-left:7px;border-left:1px solid var(--line)}
.rekbaris-gar svg{width:12px;height:12px}

.chatpin{display:flex;align-items:center;gap:11px;padding:10px 12px;border:1px solid var(--line);
  border-radius:var(--radius);background:var(--surface-2);margin-bottom:14px;grid-column:1 / -1}
.chatpin img,.chatpin-kosong{width:46px;height:46px;border-radius:var(--radius);object-fit:cover;flex:none;
  background:var(--surface);display:grid;place-items:center;color:var(--ink-3)}
.chatpin > span{display:flex;flex-direction:column;gap:2px;min-width:0}
.chatpin b{font-size:var(--f12);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.chatpin span span{font-family:var(--f-angka);font-size:var(--f12)}

@media (max-width:900px){
  .pdp{grid-template-columns:1fr;gap:14px}
  .pdp-foto{position:static}
  .pdp-info h1{font-size:var(--f14)}
  .pdp-harga{font-size:var(--f18)}
  .barisgeser > *{width:140px}
  .barisgeser > .lihatsemua{width:104px}
  /* FOTONYA TIDAK BOLEH MEMAKAN SETENGAH LAYAR (K-177, dilaporkan pemiliknya:
     "saat lihat detail item ini kebesaran"). Persegi selebar layar berarti
     382px dari 844px — separuh layar untuk satu gambar, dan harga barangnya
     baru terlihat sesudah digulir. Dibatasi 42% tinggi layar; yang lebih
     tinggi daripada itu dipotong tengahnya, bukan dikecilkan, supaya barangnya
     tetap sebesar mungkin. */
  .pdp-utama,.pdp-utama.itemfoto-utama{aspect-ratio:auto;height:min(78vw,42dvh)}
  .pdp-minibtn{width:50px;height:50px}
  .pdp-toko{padding:11px}
}
/* kartu produk kini berupa tautan agar bisa dibuka di tab baru — tampilannya
   tetap kartu, bukan tautan biasa */
a.shopcard{text-decoration:none;color:inherit;display:flex;flex-direction:column}
a.shopcard *{text-decoration:none;color:inherit}
a.shopcard .pr{color:var(--ink)}
a.shopcard .lok{color:var(--ink-3)}
/* Garis bawah judul saat kursor di atas kartunya DICABUT (K-274, diminta
   pemiliknya): bingkai dan bayangan kartunya sudah mengatakan "bisa ditekan". */
/* Nama toko tidak boleh menumpuk di atas wallpaper — yang menjorok ke atas
   hanya foto profilnya, teksnya tetap di bawah garis banner. */
.tokoprofil-info{padding-top:40px}
@media (max-width:640px){ .tokoprofil-info{padding-top:0} }

/* ---------- kelola toko ---------- */
.tokoedit{border:1px solid var(--line);border-radius:var(--radius);overflow:hidden;background:var(--surface);margin-bottom:12px}
.tokoedit-banner{width:100%;aspect-ratio:2/1;max-height:190px;background-color:var(--surface-2);
  background-size:cover;background-position:center;
  background-image:radial-gradient(120% 160% at 10% 0%, var(--surface-2) 0%, transparent 60%),
    linear-gradient(115deg, var(--ink) 0%, var(--ink-2) 100%)}
.tokoedit-bd{display:flex;gap:15px;align-items:flex-start;padding:0 18px 16px;margin-top:-30px}
.tokoedit-bd .tokoav--lg{border:3px solid var(--surface);flex:none}
.tokoedit-info{flex:1 1 240px;min-width:0;padding-top:36px}
.tokoedit-info h3{font-family:var(--f-judul);font-size:var(--f14);font-weight:600;margin:0 0 3px}
.tokoedit-info p{font-size:var(--f12);color:var(--ink-3);margin:0}
.tokoedit-bd > .irow-act{padding-top:36px;flex:none}
.fotoslot{position:relative;width:100%;border:1px solid var(--line);border-radius:var(--radius);overflow:hidden;
  background:var(--surface-2);display:grid;place-items:center}
.fotoslot img{width:100%;height:100%;object-fit:cover;display:block}
.fotoslot-kosong{color:var(--ink-3)}
.fotoslot-kosong svg{width:34px;height:34px}
.fotoslot-akt{position:absolute;left:0;right:0;bottom:0;display:flex;gap:6px;justify-content:center;
  padding:8px;background:linear-gradient(transparent,rgba(0,0,0,.45))}
@media (max-width:700px){
  .tokoedit-bd{flex-wrap:wrap}
  .tokoedit-info,.tokoedit-bd > .irow-act{padding-top:0}
  .tokoedit-bd{margin-top:-24px;padding-top:0}
  .tokoedit-info{padding-top:30px}
}
/* slot foto profil tidak perlu sebesar wallpaper */
#fpAvatar .fotoslot{max-width:210px}

/* ---------- POV lokasi ---------- */

/* ---------- grafik untung rugi lokasi ---------- */
.grafikbox{border:1px solid var(--line);border-radius:var(--radius);background:var(--surface);padding:14px 12px 10px}
.grafik{width:100%;height:auto;display:block}
.grafik .bar{fill:var(--ink)}
.grafik .bar--rugi{fill:none;stroke:var(--ink);stroke-width:1.2;
  fill:url(#arsir)}
.grafik .gz{stroke:var(--line-strong);stroke-width:1}
.grafik .gl{fill:var(--ink-3);font-size:var(--f10);font-family:var(--f-isi)}
.grafikket{display:flex;gap:16px;flex-wrap:wrap;align-items:center;font-size:var(--f12);color:var(--ink-3);
  margin-top:8px;padding:0 14px}
.grafikket i.gk{display:inline-block;width:10px;height:10px;border-radius:var(--radius-kcl);background:var(--ink);
  margin-right:6px;vertical-align:-1px}
.grafikket i.gk--rugi{background:repeating-linear-gradient(45deg,var(--ink) 0 2px,transparent 2px 4px);
  border:1px solid var(--ink)}

/* ---------- teks panjang yang bisa dibuka ---------- */
.lipat{position:relative}
.lipat-isi{max-height:7.6em;overflow:hidden;transition:max-height .18s ease}
.lipat--buka .lipat-isi{max-height:none}
.lipat-isi p{font-size:var(--f12);line-height:1.65;color:var(--ink-2);margin:0 0 10px}
.lipat-isi p:last-child{margin-bottom:0}
.lipat:not(.lipat--buka):not(.lipat--pas) .lipat-isi::after{content:"";position:absolute;left:0;right:0;
  bottom:2.1em;height:2.4em;background:linear-gradient(transparent,var(--surface))}
.lipat-btn{border:0;background:none;padding:4px 0 0;font:inherit;font-size:var(--f12);font-weight:500;
  color:var(--ink);text-decoration:underline;cursor:pointer}

/* ---------- Operasional ---------- */
.opscard{display:flex;flex-direction:column;gap:0;width:100%;text-align:left;font:inherit;cursor:pointer;
  border:1px solid var(--line);border-radius:var(--radius);background:var(--surface);margin-bottom:9px;
  padding:0;overflow:hidden;transition:border-color .14s,box-shadow .14s}
.opscard:hover{border-color:var(--line-strong);box-shadow:var(--shadow)}
.opscard-hd{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:12px 15px}
.opscard-ttl{display:flex;align-items:center;gap:9px;min-width:0}
.opscard-ttl svg{width:22px;height:22px;flex:none;color:var(--ink-2)}
.opscard-ttl > span{display:flex;flex-direction:column;min-width:0}
.opscard-ttl b{font-family:var(--f-judul);font-size:var(--f12);font-weight:600}
.opscard-ttl > span > span{font-size:var(--f12);color:var(--ink-3)}
.opscard-bd{display:flex;flex-direction:column;gap:9px;margin:0 15px;padding:12px 14px;
  border:1px solid var(--line);border-radius:var(--radius);background:var(--surface-2)}
.opscard-nama{font-family:var(--f-judul);font-size:var(--f14);font-weight:600;overflow-wrap:anywhere}
.opscard-row{display:flex;align-items:center;justify-content:space-between;gap:14px;flex-wrap:wrap;
  border-top:1px solid var(--line);padding-top:9px}
.opscard-meta{display:flex;flex-direction:column;gap:4px;min-width:0}
.opscard-meta span{display:flex;align-items:center;gap:6px;font-size:var(--f12);color:var(--ink-2)}
.opscard-meta svg{width:14px;height:14px;flex:none;color:var(--ink-3)}
.opscard-ft{padding:11px 15px 13px;font-size:var(--f12);color:var(--ink-3)}
.opstandas{display:flex;gap:6px;flex:none}
.opstanda{width:26px;height:26px;border-radius:50%;display:grid;place-items:center;flex:none;
  background:var(--line);color:var(--surface);font-size:var(--f12);font-weight:700;opacity:.55}
.opstanda svg{width:14px;height:14px}
.opstanda.on{background:var(--ink);color:var(--on-ink);opacity:1}
.opsring{display:flex;gap:20px;align-items:center;flex-wrap:wrap;padding:16px;margin-bottom:12px;
  border:1px solid var(--line);border-radius:var(--radius);background:var(--surface)}
.opsdonat{width:112px;height:112px;flex:none}
.opsring-isi{flex:1 1 240px;min-width:0}
.opsring-isi h3{font-family:var(--f-judul);font-size:var(--f14);font-weight:600;margin:0 0 6px}
.opsdot{display:inline-block;width:9px;height:9px;border-radius:50%;margin-right:7px;vertical-align:0}
.opsdot--done{background:var(--done)} .opsdot--stop{background:var(--stop)}
.opsjadwal{display:flex;gap:6px;flex-wrap:wrap}
.opschip{display:inline-flex;align-items:center;gap:6px;height:26px;padding:0 10px;border-radius:var(--radius);
  background:var(--ink);color:var(--on-ink);font-size:var(--f12);font-weight:500}
.opschip button{border:0;background:none;color:inherit;cursor:pointer;font-size:var(--f12);line-height:1;padding:0}
@media (max-width:640px){
  .opscard-bd{margin:0 11px;padding:11px}
  .opscard-hd,.opscard-ft{padding-left:11px;padding-right:11px}
  .opsring{gap:14px}
  .opsdonat{width:88px;height:88px}
}
/* angka sorotan kalkulator: tombol salin menempel di sampingnya */
.hasil-sorot{display:flex;align-items:center;gap:12px;flex-wrap:wrap}
/* kedua tombol salin SATU PASANG: turun ke baris berikutnya bersama-sama, tidak satu per satu */
.hasil-salin{display:flex;gap:8px;flex:none}
.hasil-salin .btn{flex:none}

/* ============================================================================
   DETAIL ITEM: FOTONYA MENGGANTUNG DI KIRI, KETERANGANNYA DIGULIR DI KANAN
   ============================================================================
   Yang menentukan pembagiannya adalah barang FISIKNYA lawan KETERANGANNYA.
   Foto satu-satunya benda di halaman ini yang dilihat berulang kali sambil
   membaca yang lain — orang membaca deskripsi lalu melirik fotonya, membaca
   catatan inspeksi lalu melirik lagi. Ikut tergulir, ia hilang dari layar
   tepat saat dibutuhkan.

   `top` = tinggi baris kepala (56px) + jarak nafas: baris kepala sendiri
   menempel, jadi tanpa itu fotonya berhenti DI BALIK baris kepala. */
.unitsplit{display:grid;grid-template-columns:minmax(0,420px) minmax(0,1fr);
  gap:22px;align-items:start}
.unitkiri,.unitkanan{min-width:0}
/* Menggantung TEPAT DI BAWAH baris kepala, bukan 14px di bawahnya: sejak
   jarak atas halaman ini dinolkan (K-105) fotonya sudah mulai di 56px, dan
   `top:70px` membuatnya melompat turun 14px pada gambar pertama — persis
   "ngambang" yang dilaporkan pemiliknya. */
.unitkiri{position:sticky;top:56px}
/* — kecuali di layar 961px ke atas, tempat baris kepalanya memang tidak
   digambar lagi (K-213): di sana 56px itu ruang kosong yang menahan fotonya
   turun, persis "ngambang" yang dilaporkan pemiliknya di K-105.

   Ia ditulis SESUDAH baris di atasnya dengan sengaja. Keduanya sama kuat
   penyebutnya, dan media query tidak menambah kekuatan apa pun — ditulis
   lebih dulu (di dekat `.topbar`, tempat aturan baris kepalanya berdiri), ia
   kalah tanpa satu pun tanda. */
/* JARAKNYA 20px, dan menggantungnya dipatok pada angka yang SAMA dengan jarak
   atas halamannya (lihat `--pad-atas` di blok K-105): fotonya tidak lagi
   mentok ke tepi layar (tampilan tahap 1, "foto dan judulnya terlalu mepet
   keatas"), dan tetap tidak bisa "ketarik keatas dikit" — ia mulai persis di
   titik tempat ia menempel. */
@media (min-width:961px){ .unitkiri{top:20px} }
.unitfoto{display:flex;flex-direction:column;gap:10px}
/* 1:1 dan sebesar kolomnya. Foto barang bekas adalah bukti kondisi — lecet
   sebesar kuku di pojok kanan atas tidak terlihat sama sekali pada gambar
   190px, dan itulah satu-satunya hal yang benar-benar dicari orang di sana. */
.unitfoto-utama{aspect-ratio:1/1;height:auto}
/* Kursornya TIDAK berubah di atas gambar. Badan gambar membuka penampil foto —
   sebuah tindakan yang tidak mengubah apa pun — dan kursor tangan di seluruh
   permukaan gambar membuat orang mengira menekannya akan memindahkan sesuatu.
   Yang boleh berubah cuma di atas kedua tombol sisinya (`.korselsisi`). */
.unitfoto-utama{cursor:default}
/* Jejeran foto, digulir ke samping. Batang gulirnya disembunyikan: ia
   menambah 8px tinggi pada baris yang seluruh gunanya adalah gambar kecil. */
.fotostrip{display:flex;gap:8px;overflow-x:auto;padding-bottom:2px;
  scrollbar-width:none;-webkit-overflow-scrolling:touch}
.fotostrip::-webkit-scrollbar{display:none}
.fotostrip-b{flex:none;width:74px;height:74px;padding:0;border-radius:var(--radius);overflow:hidden;
  border:1px solid var(--line);background:var(--surface-2);cursor:pointer;
  transition:border-color .14s,box-shadow .14s}
.fotostrip-b img{width:100%;height:100%;object-fit:cover;display:block}
.fotostrip-b:hover{border-color:var(--line-strong)}
.fotostrip-b.on{border-color:var(--ink);box-shadow:0 0 0 1px var(--ink)}
.fotostrip-b:focus-visible{outline:2px solid var(--ink);outline-offset:2px}
/* Kepala di kolom kanan tidak lagi berlajur: fotonya sudah pindah ke kolom
   kiri, jadi yang tersisa cuma keterangan dan kotak angkanya, dan keduanya
   bertumpuk selebar kolomnya. Dipaksa bersebelahan, nama barang — satu-satunya
   hal yang dicocokkan orang sambil memegang barangnya — tinggal 330px. */
.unitkanan .itemtop{display:flex;flex-direction:column;align-items:stretch;gap:14px;margin-bottom:16px}
/* Ketiga kotak keterangan BERTUMPUK, masing-masing selebar kolomnya penuh —
   bukan dua yang bersebelahan setengah-setengah lalu satu di bawahnya.

   Alasan menaruh Lampiran dan Catatan bersebelahan di dokumen tidak berlaku
   di sini. Di sana keduanya sepasang dan sama-sama pendek, dan kolom kanannya
   memang selebar setengah halaman. Di sini ketiganya berisi kalimat: deskripsi
   kondisi, catatan inspeksi, daftar biaya. Dibelah dua, setiap kalimat pendek
   melipat menjadi tiga baris dalam kotak selebar 330px sementara separuh
   kolomnya menganggur — dan urutan bacanya pun jadi mendatar lalu menurun,
   bukan menurun lurus seperti yang dibaca orang. */
/* Angka modal yang bisa ditekan: tetap terbaca sebagai ANGKA, bukan tombol.
   Garis bawah putus-putus mengatakan "ada keterangan di baliknya" tanpa
   memberinya bingkai yang membuatnya berebut perhatian dengan harga besar
   dua baris di atasnya. */
.hargatekan{padding:0;border:0;background:none;font:inherit;font-weight:600;
  color:var(--ink);cursor:pointer;text-decoration:underline dotted;
  text-underline-offset:3px;text-decoration-color:var(--line-strong)}
.hargatekan:hover{text-decoration-color:var(--ink)}
.hargatekan:focus-visible{outline:2px solid var(--ink);outline-offset:2px;border-radius:var(--radius)}
@media (max-width:1080px){
  /* Menggantung dilepas dan kolomnya bertumpuk: di layar setinggi 800px
     sebuah foto menggantung 420px berarti separuh layar tidak pernah bisa
     dipakai membaca apa pun. */
  .unitsplit{grid-template-columns:1fr;gap:16px}
  .unitkiri{position:static}
  .unitfoto-utama{max-width:420px}
  .fotostrip{max-width:420px}
}
@media (max-width:640px){
  .unitfoto-utama,.fotostrip{max-width:none}
  .fotostrip-b{width:62px;height:62px}
}

/* ---------- detail item: foto dan harga naik ke atas ----------
   Tiga lajur melintasi halaman penuh: fotonya, keterangannya, lalu angkanya.
   Nama sebuah unit cuma beberapa kata, jadi di halaman penuh lajur tengah
   menyisakan ruang kosong panjang bila angkanya diletakkan di bawahnya. */
.itemtop{display:grid;grid-template-columns:minmax(0,240px) minmax(0,1fr) minmax(0,336px);
  gap:20px;align-items:start;margin-bottom:16px}
.itemfoto-utama{position:relative;aspect-ratio:1/1;border:1px solid var(--line);border-radius:var(--radius);
  overflow:hidden;background:var(--surface-2)}
.itemfoto-utama img{width:100%;height:100%;object-fit:cover;display:block}
.itemharga{border:1px solid var(--line);border-radius:var(--radius);background:var(--surface);padding:16px 18px;min-width:0}
.inspfoto{flex:none;width:46px;height:46px;border-radius:var(--radius);overflow:hidden;border:1px solid var(--line);
  background:var(--surface-2);margin-right:12px}
.inspfoto img{width:100%;height:100%;object-fit:cover;display:block}
/* Di layar sedang lajur angkanya turun ke bawah keterangan — dua lajur yang
   tersisa lebih baik lebar daripada tiga lajur yang sama-sama sempit. */
@media (max-width:1180px){
  .itemtop{grid-template-columns:minmax(0,240px) minmax(0,1fr)}
  .itemtop > .itemfoto{grid-column:1;grid-row:1 / 3}
  .itemtop > .itemsisi{grid-column:2;grid-row:1}
  .itemtop > .itemharga{grid-column:2;grid-row:2}
}
@media (max-width:820px){ .itemtop{grid-template-columns:1fr}
  .itemtop > .itemfoto,.itemtop > .itemsisi,.itemtop > .itemharga{grid-column:1;grid-row:auto} }

/* ---------- kartu item: barangnya di atas, tindakannya di bawah ----------
   Dua petak bertumpuk yang dipisah satu garis melintang penuh. Di atas garis:
   fotonya dan — di sebelahnya — nama, deskripsi, lalu harganya di pojok kanan
   bawah. Di bawah garis cuma dua hal, masing-masing di ujungnya sendiri:
   kapan barangnya masuk, dan tindakan yang tersedia.

   Susunan lama membelah kartu menjadi tiga lajur dan menaruh sederet angka
   pembanding (batas harga, modal, target margin) di lajur ketiga. Ketiganya
   angka untuk MENIMBANG, bukan untuk mengenali — dan berdiri di setiap kartu,
   mereka membuat satu-satunya angka yang benar-benar dicari orang sambil
   menyusuri daftar, harga Online Shop, tenggelam di antara tiga angka lain
   yang bentuknya mirip semua. */
/* Selama mode Pilih menyala, kartunya sendiri yang bisa ditekan — jadi
   kursornya harus mengatakan itu, dan tidak boleh ada benda di dalamnya yang
   mengaku sebagai sasaran kedua. */
/* Garisnya melintasi SELURUH lebar kartu — dari bawah foto sampai tepi kanan —
   bukan cuma di bawah kolom keterangannya. */
/* Tombolnya sudah pindah ke atas garis, jadi yang tersisa di sini cuma penanda
   dan kotak centangnya — dan baris keterangannya boleh memakai seluruh sisa
   lebar tanpa harus memotong nama lokasi. */
/* Kolom kanan yang berisi harga hampir selalu lebih tinggi daripada foto dan
   keterangan barangnya. Dulu keduanya dipaku ke atas, jadi ada ruang kosong
   menganga di bawah foto. Sekarang keduanya berdiri di tengah tinggi kartu,
   sehingga sisa ruangnya terbagi rata atas dan bawah. */
/* Foto dan keterangan barang dibuat setinggi kolom harga di kanannya. Dulu
   foto 112px berdiri di tengah kartu setinggi 200-an piksel, jadi separuh
   kartu bagian kiri kosong sementara kolom kanannya padat. */
/* Judul dimentokkan ke atas, bukan dipusatkan. Dipusatkan, judul satu baris
   dan judul tiga baris mulai di ketinggian yang berbeda — dan judul adalah
   satu-satunya hal yang dicocokkan orang sambil memegang barangnya, jadi ia
   harus selalu ada di titik yang sama. */
/* Nama item dibesarkan 2,7x dari 16px. Kartu ini dibaca sambil berdiri di
   depan rak dan sambil memegang barangnya — nama itulah satu-satunya yang
   dicocokkan, sisanya baru dibaca setelah kartunya ketemu. Dibatasi lebar
   layar supaya di ponsel tidak memakan satu layar penuh. */
/* Nama barang TIDAK bergaris bawah saat kartunya disentuh. Yang bisa ditekan
   adalah seluruh kartunya, dan kartunya sudah mengatakan itu lewat garis
   tepinya yang menyala — garis bawah pada namanya membuat orang mengira ada
   dua sasaran berbeda di dalam satu kartu. */
/* Dua baris penuh, lalu titik tiga. Satu baris terlalu pendek untuk kalimat
   kondisi barang ("Ex inter, mulus 95%, ada dent halus di frame bawah"), dan
   dibiarkan bebas ia membuat tiap kartu setinggi berbeda. */
/* Deskripsi menempati 70% lebar, menyisakan sepertiga kanan untuk angka
   harganya. Dibiarkan selebar penuh, kalimat kondisi barang berjalan lurus
   ke bawah angka Rp5.350.000 dan keduanya terbaca sebagai satu blok. */
/* Batas harga jual yang berada di bawah modal: angkanya sendiri yang menjadi
   penandanya sekaligus pintunya. Tidak ada baris keterangan tambahan — pada
   unit yang sehat baris itu cuma memakan tempat, dan yang perlu diceritakan
   cuma unit yang tidak sehat. */
.hargarugi{font:inherit;font-weight:600;color:var(--stop);background:none;border:0;padding:0;
  cursor:pointer;text-decoration:underline;text-decoration-style:dotted;text-underline-offset:3px}
.hargarugi:hover{opacity:.75}

/* Tinggi kolom kiri DIPATOK pada tiga baris deskripsi, terisi atau tidak.
   Dibiarkan menyusut, kartu barang yang belum berdeskripsi berdiri lebih
   pendek daripada tetangganya dan daftar yang tingginya berloncatan tidak bisa
   dibaca sambil menggulir. */
/* Serial berdiri sebagai baris terakhir kolom kiri: ia identitas satu barang,
   dan yang mencocokkannya membaca huruf demi huruf — jadi huruf mesin ketik,
   satu baris, dan berhenti dengan titik-titik kalau tidak muat. */
/* Harga menempel ke pojok kanan BAWAH petak atas — tepat di atas garis, dan
   tepinya lurus dengan tombol di bawah garis. */
/* Angka-angkanya menurun dari pojok KANAN ATAS, sejajar dengan baris pertama
   deskripsi di sebelahnya. Dulu ia dipaku ke bawah, jadi letaknya bergeser
   mengikuti panjang deskripsi kartu di sebelahnya. */
/* Kecil dan tipis: keduanya keterangan atas angka besar di atasnya, bukan
   angka yang berdiri sendiri. */
/* Angka besar boleh turun ke baris kedua. Dipotong dengan titik-titik ia
   akan BERBOHONG — "Rp1.040.000.000…" terbaca sebagai angka yang jauh lebih
   kecil daripada isinya — jadi yang boleh mengalah adalah tinggi kartunya,
   bukan angkanya. */
.hargabesar{font-family:var(--f-judul);font-size:var(--f18);font-weight:700;letter-spacing:-.02em;
  font-variant-numeric:tabular-nums;line-height:1.2;min-width:0;overflow-wrap:anywhere}
.hargakecil{font-size:var(--f12);color:var(--ink-3);font-variant-numeric:tabular-nums}
.hargakecil b{font-family:var(--f-angka);font-weight:500}
/* GARANSI BAWAAN (K-152) berdiri satu baris penuh di bawah kolom angka, tepat
   di atas tombol Jual: ia bukan angka, jadi ia tidak ikut ke lajur sempit
   tempat Batas Harga Jual dan Modal berjajar. Namanya bisa panjang, jadi ia
   yang mengalah dengan titik-titik — ikon dan pensilnya tidak pernah. */
.garansibawaan{display:flex;align-items:center;gap:5px;margin-top:8px;min-width:0;
  font-size:var(--f12);color:var(--ink-3)}
.garansibawaan b{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  font-weight:500;color:var(--ink)}
.garansibawaan b.muted{color:var(--ink-3)}
.garansibawaan .hargaikon,.garansibawaan .ikonbtn{flex:none}
.hargagaris{display:block;height:1px;background:var(--line);margin:7px 0}
/* Tombol dan status memakai ruang yang memang sudah ada di bawah kolom
   harga, bukan menambah tinggi kartu. */
/* Tiga angka yang selalu dibandingkan orang: label kiri, nilai kanan, satu
   garis lurus ke bawah. Sebagai kalimat berjajar ("Batas Harga Rp… Harga
   beli Rp…") mata harus mencari lagi di mana angkanya pada setiap kartu. */
/* Satu baris tetap satu baris. Dibiarkan membungkus, "Target Margin
   +Rp3.000.000" menjadi dua baris pada layar yang menyempit sementara
   "Modal Rp4.100.000" tetap satu — dan tinggi kartu ikut berbeda menurut
   panjang angkanya. */
/* Yang mengalah SEBUTANNYA, bukan angkanya: "Batas Harga" yang tinggal
   "Batas H…" masih terbaca, angka yang terpotong tidak. */
/* Satu petak, isinya satu hal saja: tombol bila ada yang bisa dikerjakan,
   keadaannya bila tidak. Ia tinggal di dalam kolom harga — DI ATAS garis —
   supaya baris keterangan di bawah garis (tanggal · jam · lokasi) tidak lagi
   berebut lebar dengannya. */
/* Penanda status yang bisa ditekan. Bentuknya tetap penanda — ia menerangkan
   keadaan, bukan menawarkan tindakan — jadi yang membedakannya cuma panah
   kecil dan warnanya yang menguat saat disentuh. */
/* Kotak foto yang cuma menerangkan, bukan tombol. */
.irowfoto--diam{cursor:default}
/* Baris barang di pop-up "kenapa unit ini ditahan" TIDAK melipat, seberapa
   sempit pun layarnya: foto di kiri, nama satu baris di kanannya, serial dan
   lokasi di baris kedua. Melipat, fotonya berdiri sendirian di baris pertama
   dan keterangannya turun semua — empat baris untuk satu barang, di pop-up
   yang seluruh isinya memang cuma satu barang itu. */
.irow--tahan{flex-wrap:nowrap;align-items:center}
.irow--tahan .irow-main{flex:1 1 auto;min-width:0}
.irow--tahan .irow-sub{flex-wrap:nowrap;min-width:0;margin-top:5px}
.irow--tahan .irow-sub .serialtag{flex:none}
/* Keterangan di dalam baris yang punya rincian di baliknya. Bentuknya tetap
   teks — garis putus tipis di bawahnya yang mengatakan ia bisa dibuka —
   supaya ia tidak berebut perhatian dengan tombol yang benar-benar menawarkan
   tindakan pada baris yang sama. */
.tautbaris{padding:0;border:0;background:none;font:inherit;color:inherit;cursor:pointer;
  text-decoration:underline dotted;text-underline-offset:3px;text-decoration-color:var(--line-strong)}
.tautbaris:hover{color:var(--ink);text-decoration-color:currentColor}
.tautbaris:focus-visible{outline:2px solid var(--ink);outline-offset:2px;border-radius:var(--radius)}

/* ---------- kepala dokumen yang menyempit ke setengah kiri ----------
   Susunannya menurun, bukan berebut satu baris: siapa, lalu keadaannya, lalu
   tindakan yang tersedia, lalu garis, lalu keterangan dokumennya. Di lebar
   setengah halaman, tiga hal itu tidak akan pernah muat sebaris. */
/* Satu baris, tidak pernah melipat di lebar biasa: nama pihak yang mengalah
   dan dipotong titik-titik, bukan lencana keadaan yang terlempar ke bawah.
   Keadaan adalah hal pertama yang dicari orang saat membuka dokumen. */
.dhead-atas{display:flex;align-items:center;gap:10px;
  padding:14px 16px 12px;flex-wrap:nowrap}
.dhead-pihak{display:flex;align-items:center;gap:11px;min-width:0;flex:1 1 auto;
  padding:0;border:0;background:none;font:inherit;color:inherit;cursor:pointer;text-align:left}
/* Nama yang tidak punya apa-apa di baliknya: tanpa panah, tanpa kursor tangan.
   Dipakai Master Data — sebuah Brand tidak membuka kartu pihak. */
.dhead-pihak--diam{cursor:default}
/* Lingkaran yang punya tindakannya sendiri: mengganti foto profil pegawai.
   Ia berdiri di LUAR tombol nama — tombol di dalam tombol bukan HTML yang sah. */
.dhead-ava-btn{position:relative;flex:none;padding:0;border:0;background:none;cursor:pointer;line-height:0}
.dhead-ava--foto{display:block;width:38px;height:38px;border-radius:999px;overflow:hidden;
  border:1px solid var(--line)}
.dhead-ava--foto img{width:100%;height:100%;object-fit:cover;display:block}
.dhead-ava-ubah{position:absolute;right:-2px;bottom:-2px;display:grid;place-items:center;
  width:16px;height:16px;border-radius:999px;background:var(--ink);color:var(--on-ink)}
.dhead-ava-ubah svg{width:9px;height:9px}
.dhead-ava-btn + .dhead-pihak{margin-left:11px}
/* Waktu yang bukan tombol: keterangan tenang, bukan pintu ke timeline. */
.dhead-tgl--diam{cursor:default}
.dhead-tgl--diam:hover{background:none;color:var(--ink-3)}
.dhead-pihak--diam:hover .dhead-nm{text-decoration:none}
.dhead-nm{min-width:0;font-family:var(--f-judul);font-size:var(--f16);font-weight:600;
  line-height:1.25;letter-spacing:-.012em;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* Lajur kanan: keadaan di atas, waktu di bawah. Dua baris kecil ini setinggi
   satu baris nama pihak, jadi kepala dokumen tidak bertambah tinggi hanya
   karena waktunya pindah ke bawah. */
.dhead-kanan{display:flex;flex-direction:column;align-items:flex-end;justify-content:center;
  gap:3px;flex:none;margin-left:auto;min-width:0}
.dhead-pihak > svg{width:15px;height:15px;flex:none;color:var(--ink-3);transition:color .14s,transform .14s}
.dhead-pihak:hover .dhead-nm{text-decoration:underline;text-underline-offset:3px;text-decoration-color:var(--line-strong)}
.dhead-pihak:hover > svg{color:var(--ink);transform:translateX(2px)}
.dhead-pihak:focus-visible{outline:2px solid var(--ink);outline-offset:3px;border-radius:var(--radius)}
/* Waktu dokumen berdiri sebagai TOMBOL BERISI TANGGALNYA, bukan ikon jam
   telanjang: yang ingin diketahui orang dari sebuah jam di kepala dokumen
   adalah tanggalnya, dan menyembunyikannya di balik ikon berarti satu tekan
   untuk membaca satu baris teks. Menekannya membuka Timeline. */
/* Waktu dokumen: keterangan, bukan tombol yang menuntut perhatian. Ia
   berkotak sendiri dulu — sekotak lencana keadaan di atasnya — dan dua benda
   berkotak bertumpuk membuat lajur kanan terlihat seperti dua tombol yang
   sama pentingnya. Sekarang ia teks kecil yang bergaris bawah putus saat
   disentuh: cukup untuk mengatakan "aku bisa ditekan", tidak lebih. */
.dhead-tgl{display:inline-flex;align-items:center;gap:5px;flex:none;
  height:auto;padding:0;border:0;border-radius:var(--radius);
  background:none;font:inherit;font-size:var(--f11);color:var(--ink-3);cursor:pointer;
  font-family:var(--f-angka);white-space:nowrap}
.dhead-tgl svg{width:12px;height:12px;flex:none;color:var(--ink-3);transition:color .14s}
.dhead-tgl:hover{color:var(--ink-2);text-decoration:underline;text-underline-offset:3px;
  text-decoration-color:var(--line-strong)}
.dhead-tgl:hover svg{color:var(--ink-2)}
.dhead-tgl:focus-visible{outline:2px solid var(--ink);outline-offset:2px}
/* Tanggal dan jamnya dirapatkan: " · " dengan dua spasi penuh dalam huruf
   mono memakan 14px pada baris yang sisanya diperebutkan nama pihak. */
.dhead-atas .dhead-tgl{gap:0}
.dtgl-j::before{content:"·";margin:0 3px;opacity:.55}
.dhead-atas .dhead-status{flex:none}
/* ---- lencana keadaan di kepala dokumen: IKON DAN TEKS, tanpa kotak ----
   Kotak lencana punya garis, latar, dan tinggi 24px sendiri, dan itu
   menyisakan sepotong ruang tipis di atas dan di bawah nama pihak yang tidak
   berisi apa pun. Yang benar-benar mengatakan "ini keadaan" adalah IKONNYA —
   setengah lingkaran untuk berjalan, centang untuk selesai — bukan kotaknya.
   Ikonnya sengaja DITAHAN: teks berwarna tanpa ikon, di seluruh ERP ini,
   selama ini berarti "bisa ditekan", dan orang akan mencoba mengkliknya. */
.dhead-status .pill{height:auto;padding:0;border:0;background:none;
  font-size:var(--f12);font-weight:600;gap:5px}
.dhead-status .pill .mk{margin:0}

/* Keterangan dokumen: tiga petak SETARA, masing-masing dengan ikonnya
   sendiri, dipisah garis tegak. Ketiganya jawaban atas pertanyaan yang
   setara — nomor apa, di mana, oleh siapa — jadi tidak boleh ada yang
   terlihat lebih penting daripada yang lain. */
.dhead-fakta{display:flex;align-items:stretch;border-top:1px solid var(--line)}
.dfakta{flex:1 1 0;min-width:0;display:flex;align-items:center;gap:6px;
  padding:11px 14px;border:0;background:none;font:inherit;color:inherit;text-align:left}
.dfakta + .dfakta{border-left:1px solid var(--line)}
/* Teksnya yang mengalah, panahnya tidak. Nama yang tidak muat dipotong
   titik-titik ("Outlet Probo…"), dan panahnya tetap berdiri di ujung kanan
   petaknya — tanda "bisa ditekan" tidak boleh ikut hilang bersama nama yang
   kepanjangan. */
.dfakta-isi{flex:1 1 auto;min-width:0;display:block}
.dfakta-t{display:block;flex:1 1 auto;min-width:0;
  font-size:var(--f12);color:var(--ink-2);font-family:var(--f-angka);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* Petak bersebutan: sebutan kecil di atas, nilainya di bawah dengan huruf
   biasa — bukan mono. Mono dipakai untuk hal yang dibaca karakter demi
   karakter (nomor, serial); nama outlet dibaca sebagai kata. */
.dfakta--label .dfakta-l{display:block;font-style:normal;font-size:var(--f10);line-height:1.2;
  font-weight:400;letter-spacing:.05em;text-transform:uppercase;color:var(--ink-3);margin-bottom:3px}
.dfakta--label .dfakta-t{font-family:inherit;font-size:var(--f12);font-weight:600;color:var(--ink)}
.dfakta > svg{width:12px;height:12px;flex:none;margin-left:auto;
  color:var(--ink-3);transition:transform .14s,color .14s}
/* ---- nomor dokumen: DI KAKI kepala, rata kiri, TANPA kotak ----
   Ia berdiri persis di sebelah Batalkan dan Selesaikan, jadi ia tidak boleh
   berkotak. Kotak dan latar yang dulu menandainya bisa ditekan justru
   membuatnya terbaca sebagai tombol ketiga yang mengerjakan sesuatu pada
   dokumennya — dan tombol ketiga di sebelah "Batalkan" adalah tombol yang
   ditekan orang untuk mencari tahu apa isinya.

   Yang dipakai garis bawah putus-putus: di seluruh ERP ini bentuk itu berarti
   "ada sesuatu di balik teks ini", tidak pernah berarti tombol, dan ia sudah
   dipakai pada angka Modal di Detail Item. */
.dnomor{flex:0 1 auto;min-width:0;padding:0;border:0;background:none;cursor:pointer;
  font-family:var(--f-angka);font-size:var(--f12);color:var(--ink-3);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  text-decoration:underline dotted;text-underline-offset:3px;
  text-decoration-color:var(--line-strong);transition:color .14s,text-decoration-color .14s}
.dnomor:hover{color:var(--ink-2);text-decoration-color:var(--ink-3)}
.dnomor:focus-visible{outline:2px solid var(--ink);outline-offset:2px;border-radius:var(--radius)}
.dfakta--tekan{cursor:pointer}
.dfakta--tekan:hover .dfakta-t{color:var(--ink)}
.dfakta--tekan:hover > svg{transform:translateX(2px);color:var(--ink)}
.dfakta--tekan:focus-visible{outline:2px solid var(--ink);outline-offset:-2px;border-radius:var(--radius)}

/* Tindakan yang MENGUBAH dokumen: paling bawah, di balik garisnya sendiri,
   rata kanan dan berjajar kiri-kanan — keduanya setara, satu dokumen
   berakhir dengan salah satunya. */
.dhead-kaki{display:flex;align-items:center;gap:12px;padding:12px 16px;border-top:1px solid var(--line);min-height:52px}
.dhead-aksi{display:flex;flex-direction:row;align-items:center;gap:8px;
  margin-left:auto;flex:none;flex-wrap:wrap;justify-content:flex-end}
@media(max-width:560px){
  /* `.dhead-atas` TETAP nowrap di sini. Dibiarkan melipat, lencana keadaan
     dan tanggalnya terlempar ke baris kedua dan ketiga, dan kepala dokumen
     jadi tiga baris yang setengahnya kosong — padahal ketiganya muat: nama
     pihaknya yang mengalah dan dipotong titik-titik, persis aturan yang
     berlaku di lebar mana pun. */
  .dhead-fakta{flex-direction:column}
  .dfakta + .dfakta{border-left:0;border-top:1px solid var(--line)}
}
/* Kepala kartu pihak: inisialnya besar, karena itulah satu-satunya "foto"
   yang dimiliki pihak di ERP ini. */

/* ---------- daftar item: satu kotak, dipisah garis ----------
   Item bukan benda yang berdiri sendiri-sendiri melainkan isi dari satu
   dokumen yang sama. Sederet kotak terpisah membuat mata menghitung kotak,
   bukan membaca daftar. */
.ilist{border:1px solid var(--line);border-radius:var(--radius);background:var(--surface);overflow:hidden}
.ilist .irow{margin:0 !important;border:0;border-top:1px solid var(--line);border-radius:0;background:transparent}
.ilist .irow:first-child{border-top:0}
/* Barisnya tidak membungkus di lebar setengah halaman: nama dan angkanya
   tetap satu baris, yang mengalah adalah panjang namanya. */
.irow--rapat{gap:13px;padding:12px 14px;align-items:stretch;flex-wrap:nowrap}
/* Namanya rata atas, sejajar dengan tepi atas fotonya — bukan mengambang di
   tengah, yang membuat baris tinggi terlihat berlubang di atasnya. */
.irow--rapat .irow-main{display:flex;flex-direction:column;justify-content:flex-start;gap:4px}
/* SELURUH barisnya yang bisa ditekan, bukan cuma petak namanya. Tombol di
   dalamnya tetap berdiri sendiri — penekanannya dihentikan di JS, dan di sini
   kursornya dikembalikan supaya tangan pun tahu itu benda yang lain. */
/* Blok Tukar Tambah di panel Jual Unit. Bergaris supaya ia terbaca sebagai
   SATU kesatuan yang berdiri di luar daftar unit yang dijual — barangnya
   memang bergerak ke arah yang berlawanan. */
/* Baris tukar tambah di kaki daftar item, di kedua modul. Ia TAUTAN, bukan
   baris item: arah barangnya berlawanan dengan isi daftarnya, dan dijejer di
   dalam daftar ia akan ikut terbaca sebagai barang yang dijual. */
.tukarbaris{display:flex;align-items:center;gap:10px;margin-top:10px;padding:10px 14px;
  border:1px dashed var(--line-strong);border-radius:var(--radius);background:var(--surface);
  color:var(--ink);text-decoration:none}
.tukarbaris:hover{background:var(--surface-2)}
.tukarbaris-ik{flex:none;display:grid;place-items:center;width:26px;height:26px;
  border-radius:999px;background:var(--surface-2);color:var(--ink-2)}
.tukarbaris-ik svg{width:14px;height:14px}
.tukarbaris-t{flex:1 1 auto;min-width:0;font-size:var(--f12);font-weight:600}
.tukarbaris-t span{display:block;font-weight:400;font-size:var(--f12);color:var(--ink-3);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tukarbaris-v{flex:none;font-family:var(--f-angka);font-variant-numeric:tabular-nums;
  font-size:var(--f12);font-weight:600;white-space:nowrap}
.tukarbaris > svg{flex:none;width:15px;height:15px;color:var(--ink-3)}

/* Nota yang sudah dikirim ke WhatsApp (K-58): sebentuk dengan baris tukar
   tambah, tetapi bukan tautan — tombolnya yang bekerja. */
.notabaris{display:flex;align-items:center;gap:10px;margin-top:10px;padding:8px 10px 8px 14px;
  border:1px dashed var(--line-strong);border-radius:var(--radius);background:var(--surface)}
.notabaris .btn{flex:none}

.tukarblok{border:1px solid var(--line-strong);border-radius:var(--radius);
  padding:12px 13px;background:var(--surface-2)}
.tukarblok-hd{display:flex;align-items:center;justify-content:space-between;gap:10px}
.tukarblok-hd b{font-family:var(--f-judul);font-size:var(--f12);font-weight:600}

/* Blok "Biaya sudah dicatat semua?" di kotak Selesaikan. Bergaris tegas dan
   berlatar tua supaya ia terbaca sebagai PERTANYAAN, bukan sebagai satu lagi
   petak angka di antara petak-petak akibatnya. */
.tanyabiaya{margin-bottom:14px;padding:12px 13px;border:1px solid var(--line-strong);
  border-radius:var(--radius);background:var(--surface-2)}
.tanyabiaya-hd{display:flex;align-items:center;justify-content:space-between;gap:10px;flex-wrap:wrap}
.tanyabiaya-hd b{font-family:var(--f-judul);font-size:var(--f13);font-weight:600}
.tanyabiaya-ket{margin:4px 0 0;font-size:var(--f12);color:var(--ink-3)}
.tanyabiaya-isi{margin-top:10px;padding-top:9px;border-top:1px solid var(--line);
  max-height:132px;overflow-y:auto}
.tanyabiaya-isi .row{display:flex;align-items:baseline;gap:12px;padding:3px 0;font-size:var(--f12)}
.tanyabiaya-isi .row > span{flex:1 1 auto;min-width:0;color:var(--ink-2);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tanyabiaya-isi .row > b{flex:none;font-family:var(--f-angka);
  font-variant-numeric:tabular-nums;font-weight:600}

/* Kaki daftar item. Ia BUKAN sebuah baris item: latarnya lebih tua dan
   garisnya lebih tegas, supaya tidak terbaca sebagai barang kelima yang
   entah kenapa tidak punya foto. Angkanya berdiri di tepi kanan yang sama
   dengan harga di baris-baris di atasnya, jadi keduanya bisa dijumlahkan
   dengan mata tanpa memindahkan pandangan. */
.itotal{display:flex;align-items:center;gap:12px;
  padding:11px 15px;border-top:2px solid var(--line-strong);background:var(--surface-2)}
.itotal-k{flex:1 1 auto;min-width:0;font-size:var(--f12);color:var(--ink-2);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.itotal-v{flex:none;font-family:var(--f-angka);font-variant-numeric:tabular-nums;
  font-size:var(--f13);font-weight:700;white-space:nowrap}
.ilist .irow--klik{cursor:pointer;transition:background .12s}
.ilist .irow--klik:hover{background:var(--surface-2)}
.ilist .irow--klik:focus-visible{outline:2px solid var(--ink);outline-offset:-2px}
.ilist .irow--klik button,.ilist .irow--klik a{cursor:pointer}
.irow--rapat .irow-sub{margin-top:0}
.irow--rapat .irow-right{flex:none;justify-content:center;gap:8px}
/* ---------- baris item dokumen: tindakan di bawah nama ----------
   Tombol barisnya turun ke bawah nama barangnya, menempel ke dasar baris, dan
   harganya menempel ke pojok kanan bawah. Dulu keduanya bertumpuk di lajur
   kanan yang sama, jadi tombol dan angka berebut satu kolom sempit: angkanya
   terdesak, tombolnya melipat, dan tepi kanan daftar berloncatan dari baris
   ke baris. Sekarang masing-masing punya sudutnya sendiri. */
/* ---------- baris item penjualan: dibelah satu garis melintang ----------
   Di atas garis barangnya — foto, nama, tombol, harga. Di bawah garis dua
   keterangan yang bukan tentang barangnya melainkan tentang kesepakatannya:
   garansi di kiri, margin di kanan. Berjajar dalam satu baris sub seperti
   dulu, keduanya berebut tempat dengan nama barang dan sama-sama terpotong. */
.irow--belah{flex-direction:column;align-items:stretch;gap:0}
.irow-atas{display:flex;align-items:stretch;gap:13px;min-width:0}
.irow-bawah{display:flex;align-items:center;gap:12px;min-width:0;
  margin-top:11px;padding-top:10px;border-top:1px solid var(--line)}
.irow-bawah-kiri{flex:1 1 auto;min-width:0;font-size:var(--f12);color:var(--ink-3);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.irow-bawah-kanan{flex:none;font-size:var(--f12);color:var(--ink-3);white-space:nowrap}
.irow-bawah-kanan b{font-family:var(--f-angka);font-variant-numeric:tabular-nums;
  font-size:var(--f12);font-weight:600;margin-left:5px}
@media(max-width:620px){
  .irow--belah .irow-atas{flex-wrap:wrap}
}
/* Baris paling bawah dari kolom nama: tombolnya di kiri, harganya di pojok
   kanan. Harga TIDAK lagi berdiri sebagai lajur ketiga — sebagai lajur ia
   memakan lebar pada setiap baris di kolom itu, termasuk baris nama, sehingga
   nama barang terpotong titik-titik jauh sebelum tepi kanan kotaknya padahal
   ruangnya masih ada. */
/* ---------- baris tindakan di bawah garis melintang ----------
   Di ATAS garis: barangnya — foto, nama, nama inventory / deskripsi, serial.
   Di BAWAH garis: apa yang bisa dikerjakan padanya (Terima/Serahkan,
   Komplain) mentok kiri, dan harganya mentok kanan.

   Dulu tombol dan harga berbagi baris terbawah dari KOLOM NAMA, jadi keduanya
   cuma selebar sisa lajur di sebelah foto — dan di lebar telepon harganya
   terdorong turun ke barisnya sendiri, tidak lagi sejajar dengan tombolnya.
   Garis melintang memberi baris tindakan seluruh lebar kartunya, jadi
   letaknya sama di lebar mana pun. */
.irow-aksibar{display:flex;align-items:center;gap:12px;min-width:0;
  margin-top:11px;padding-top:10px;border-top:1px solid var(--line)}
.irow-aksibar .irow-act{flex:none;flex-wrap:nowrap;justify-content:flex-start}
.irow-aksibar .irow-amt{flex:none;margin-left:auto;white-space:nowrap}
/* Serial: satu-satunya keterangan yang membedakan dua unit bernama sama
   persis. Ruang di bawah nama inventory memang ada — dibiarkan kosong ia cuma
   membuat barisnya terlihat setengah jadi. */
.irow-serial{display:block;margin-top:3px;min-width:0;
  font-family:var(--f-angka);font-size:var(--f11);letter-spacing:.02em;
  color:var(--ink-3);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* Baris serial yang juga memuat margin: serial boleh terpotong titik-titik,
   angkanya TIDAK — angka yang terpotong terbaca sebagai angka lain. */
.irow-serial:has(.irow-margin){display:flex;align-items:baseline;gap:9px}
.irow-serial > span{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.irow-margin{flex:none;margin-left:auto;font-size:var(--f12);font-weight:600;
  font-variant-numeric:tabular-nums;letter-spacing:0}
.irow--aksibawah .irow-main{justify-content:flex-start}
/* Yang MENGALAH saat lebarnya kurang adalah HARGANYA, bukan tombolnya.
   Dulu sebaliknya: petak tombol boleh menyusut (`flex:0 1 auto`) dan boleh
   melipat, sementara harga dipatok `flex:none` dan `nowrap` — jadi di lebar
   telepon tombol Terima dan segitiga Komplain bertumpuk dua baris di bawah
   sebuah harga yang tetap utuh. Padahal keduanya SEPASANG: dua tombol atas
   satu barang yang sama, dan dipisah baris ia terbaca seperti dua urusan.
   Sekarang petak tombol tidak boleh menyusut maupun melipat, dan kakinya
   sendiri yang melipat — harganya turun utuh ke barisnya sendiri, tetap rata
   kanan karena `margin-left:auto` berlaku juga di baris keduanya. */
.irow-kaki{display:flex;align-items:flex-end;gap:10px 12px;margin-top:auto;padding-top:9px;
  min-width:0;flex-wrap:wrap}
.irow-kaki .irow-act{flex:none;flex-wrap:nowrap;justify-content:flex-start}
.irow-kaki .irow-amt{flex:none;margin-left:auto;white-space:nowrap}
/* Kaki tanpa nominal (Detail Servis, K-296): tombolnya mepet kanan. */
.irow-kaki--kanan{justify-content:flex-end}
/* Foto membentang setinggi barisnya: batas atas dan bawahnya lurus dengan
   isi di sebelahnya. */
.irow-name--potong{display:block;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.irow-potong{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* Di layar sempit angkanya turun ke barisnya sendiri, sejajar di bawah teks —
   dipaksa tetap sebaris, kolom kanannya menghimpit nama sampai tinggal
   sepotong kata per baris. */
@media(max-width:620px){
  .irow--rapat{flex-wrap:wrap}
  .irow--rapat .irow-main{flex:1 1 0}
  .irow--rapat .irow-right{flex:1 1 100%;flex-direction:row;justify-content:space-between;
    align-items:center;padding-left:87px;white-space:normal}
  .irow--rapat .irow-amt{order:2}
  .irow--rapat .irow-act{order:1}
}

/* ---------- RINGKASAN KEUANGAN ----------
   Satu kotak untuk seluruh uang sebuah dokumen. Urutannya menjawab satu
   pertanyaan demi satu pertanyaan — berapa barangnya, berapa biayanya, jadi
   berapa seluruhnya, sudah dibayar berapa, jadi sisanya berapa — dan tiga
   jenis garis memisahnya menurut beratnya: garis penuh memisah pertanyaan
   dari kesimpulannya, garis putus-putus memisah dua baris yang setara. */
.ringkas{margin-top:12px;border:1px solid var(--line);border-radius:var(--radius);
  background:var(--surface);overflow:hidden}
.ringkas-hd{display:flex;align-items:center;gap:11px;padding:13px 15px 11px}
/* Tindakan di kepala kotak, mepet kanan — sejajar judulnya, bukan di kaki. */
.ringkas-hd > .btn{margin-left:auto;flex:none}
.ringkas-hd h2{font-family:var(--f-judul)}
.ringkas-ik{display:inline-flex;align-items:center;justify-content:center;flex:none;
  width:30px;height:30px;border-radius:var(--radius);border:1px solid var(--line);
  background:var(--surface-2);color:var(--ink-2)}
.ringkas-ik svg{width:15px;height:15px}
.ringkas-ik--hd{width:34px;height:34px;border-radius:var(--radius);color:var(--ink)}
.ringkas-ik--hd svg{width:17px;height:17px}
.ringkas-bd{padding:0 15px 4px}
.ringkas-baris{display:flex;align-items:center;gap:11px;width:100%;padding:9px 0;
  border:0;background:none;color:inherit;font:inherit;text-align:left}
.ringkas-baris > svg{width:15px;height:15px;flex:none;color:var(--ink-3);transition:transform .14s}
.ringkas-baris--tekan{cursor:pointer;border-radius:var(--radius);padding-left:8px;padding-right:8px;margin:0 -8px}
.ringkas-baris--tekan:hover{background:var(--surface-2)}
.ringkas-baris--tekan:hover > svg{color:var(--ink);transform:translateX(2px)}
.ringkas-baris--tekan:focus-visible{outline:2px solid var(--ink);outline-offset:-2px}
.ringkas-k{flex:0 0 auto;font-size:var(--f13);color:var(--ink-2)}
/* Ruang kosong, bukan garis. Garis penghubung antara sebutan dan angkanya
   membuat setiap baris terlihat seperti kuitansi tua, dan di kotak yang cuma
   berisi enam baris ia tidak menolong siapa pun menemukan angkanya: angkanya
   sudah rata kanan semua, dan mata mengikuti tepi itu sendiri. */
.ringkas-garis{flex:1 1 auto;min-width:12px}
/* Tombol rincian pindah ke sisi SEBUTANNYA, bukan di ujung kanan: kalau ia
   berdiri di kanan, angka baris itu terdorong ke dalam dan tepi kanan
   kotaknya tidak lagi lurus. */
.ringkas-tanya{display:inline-flex;align-items:center;justify-content:center;flex:none;
  width:22px;height:22px;margin-left:-3px;padding:0;border:0;border-radius:999px;
  background:none;color:var(--ink-3);cursor:pointer}
.ringkas-tanya svg{width:14px;height:14px}
.ringkas-tanya:hover{background:var(--surface-2);color:var(--ink)}
.ringkas-tanya:focus-visible{outline:2px solid var(--ink);outline-offset:2px}
.ringkas-v{flex:none;font-family:var(--f-angka);font-variant-numeric:tabular-nums;
  font-size:var(--f13);font-weight:600;color:var(--ink)}
.ringkas-v--kurang{color:var(--stop)}
.ringkas-v--sunyi{font-family:inherit;font-size:var(--f12);font-weight:500;color:var(--ink-3)}
/* Kesimpulan: namanya ikut menghitam dan angkanya membesar, karena inilah
   yang dicari orang lebih dulu sebelum membaca penyusunnya. */
.ringkas-baris--kuat .ringkas-k{color:var(--ink);font-weight:600;font-size:var(--f13)}
.ringkas-baris--kuat .ringkas-v{font-size:var(--f14)}
.ringkas-baris--sunyi .ringkas-v{font-weight:500;color:var(--ink-2)}
.ringkas-pisah{display:block;height:1px;background:var(--line-strong);margin:4px 0}
/* Satu tombol yang sekaligus keadaan dan angkanya, berdiri di ujung kanan
   barisnya — tepi yang sama dengan angka-angka di atasnya. */
.ringkas-baris .btn--bayar{min-width:0;flex:none}
.ringkas-kaki{display:flex;gap:10px;padding:12px 15px;border-top:1px solid var(--line);
  background:var(--surface-2)}
/* Tenang dan di dasar kotak: menghapus tagihan adalah jalan terakhir, bukan
   tindakan sehari-hari yang pantas berdiri sejajar dengan tombol bayar. */
/* Jalan keluar untuk sisa yang tidak tertagih. Ia tinggal di dalam Detail
   Pembayaran, menempel pada baris "Kurang Dibayar" — bukan di dasar Ringkasan
   Keuangan seperti dulu, tempat ia berdiri permanen dan mengajak orang
   menghapus tagihan yang masih bisa ditagih besok. */
.rincihapus{display:flex;justify-content:flex-end;padding:8px 0 0}
.rincihapus .linkbtn{font-size:var(--f12);color:var(--ink-3)}
.rincihapus .linkbtn:hover{color:var(--stop)}
.ringkas-kaki .btn{flex:1 1 0;justify-content:center}
@media(max-width:520px){
  .ringkas-baris{flex-wrap:wrap;gap:8px}
  .ringkas-kaki{flex-direction:column}
}
/* Satu foto bukti pada penerimaan dan penyerahan. Kotaknya 1:1 seperti kotak
   foto lain di ERP ini supaya bentuknya tidak perlu dipelajari ulang. */
.buktikosong{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:10px;
  aspect-ratio:1/1;max-width:190px;border:1.5px dashed var(--line-strong);border-radius:var(--radius);
  background:var(--surface-2);color:var(--ink-3)}
.buktikosong-ikon svg{width:26px;height:26px}
.buktikosong-aksi{display:flex;gap:7px;flex-wrap:wrap;justify-content:center}
.buktifoto{position:relative;max-width:190px}
.buktifoto img{width:100%;aspect-ratio:1/1;object-fit:cover;border-radius:var(--radius);border:1px solid var(--line);display:block}
.buktifoto-aksi{display:flex;gap:7px;margin-top:8px}
/* Lencana yang bisa ditekan pada kepala detail unit: bentuknya tetap lencana,
   panah kecil di sebelahnya yang mengatakan ada rincian di baliknya. */
/* Keadaan di kepala pop-up penurunan angka. Satu baris tenang, bukan kotak
   notice setinggi tiga baris: ia menyebut KEADAAN dokumennya ("Belum final",
   "Dalam masa · sisa 5 hari"), bukan menerangkan cara membaca tabelnya. */
.mrgkeadaan{display:inline-flex;align-items:center;margin:0 0 12px;padding:4px 11px;
  border:1px solid var(--line);border-radius:999px;background:var(--surface-2);
  font-size:var(--f12);font-weight:500;color:var(--ink-2)}

/* ---------- lencana keadaan yang bisa DILIPAT ----------
   Terlipat ia tinggal ikonnya; tulisannya menyusut ke lebar nol, bukan
   dihilangkan, supaya pembaca layar tetap mengucapkannya dan supaya
   membukanya berupa gerakan — bukan benda yang tiba-tiba muncul.
   Dua sasaran yang berbeda saat terbuka: ikonnya melipat lagi, panahnya
   membuka dokumen yang menahan unitnya. */
.stlipat{display:inline-flex;align-items:center;gap:2px;flex:none;max-width:100%}
.stlipat-b{cursor:pointer;font:inherit;gap:0;overflow:hidden;max-width:100%}
.stlipat-b:focus-visible{outline:2px solid var(--ink);outline-offset:2px}
.stlipat-t{max-width:0;opacity:0;overflow:hidden;white-space:nowrap;margin-left:0;
  transition:max-width .2s ease,opacity .16s ease,margin-left .2s ease}
.stlipat[data-buka] .stlipat-t{max-width:200px;opacity:1;margin-left:6px}
.stlipat-go{display:none;align-items:center;justify-content:center;flex:none;
  width:20px;height:23px;padding:0;border:0;background:none;color:var(--ink-3);cursor:pointer}
/* Panahnya menunjuk KE KANAN, bukan ke kiri. Lencana ini berdiri di tepi
   KANAN barisnya, jadi membukanya menumbuhkannya ke KIRI dan melipatnya
   menggerakkannya kembali ke KANAN — arah panah harus arah gerakannya. Dulu
   ia diputar 180 derajat "menunjuk balik ke labelnya", dan pemiliknya
   membacanya kebalik: panah ke kiri di tepi kanan berbunyi "buka lagi". */
.stlipat-go svg{width:13px;height:13px}
.stlipat-go:hover{color:var(--ink)}
.stlipat-go:focus-visible{outline:2px solid var(--ink);outline-offset:2px;border-radius:var(--radius-kcl)}
.stlipat[data-buka] .stlipat-go{display:inline-flex}
@media (prefers-reduced-motion:reduce){ .stlipat-t{transition:none} }

.pilltanya{display:inline-flex;align-items:center;gap:3px;padding:0;border:0;background:none;
  font:inherit;cursor:pointer;color:var(--ink-3)}
.pilltanya svg{width:13px;height:13px;transition:transform .14s}
/* Panah berputar ke bawah selagi keterangannya terbuka: arah panah selalu
   menyebut apa yang terjadi bila ia ditekan, bukan apa yang sedang terjadi. */
.pilltanya--buka svg{transform:rotate(90deg)}
/* Keterangan status yang turun di tempat, bukan pop-up. Ia sengaja tidak
   berkotak dan tidak berlatar: ia keterangan lanjutan dari lencana yang
   berdiri dua baris di atasnya, bukan sebuah kotak pemberitahuan baru. */
.tahanbox{margin-top:9px;padding-left:11px;border-left:2px solid var(--line-strong)}
.tahanbox p{font-size:var(--f12);line-height:1.55;color:var(--ink-2);margin:0}
.tahanbox .dibeli{margin-top:5px}
.pilltanya:hover{color:var(--ink)}
.pilltanya:focus-visible{outline:2px solid var(--ink);outline-offset:3px;border-radius:var(--radius)}
/* Tombol yang berdiri sebaris dengan penanda status dibuat setinggi penanda
   itu, bukan setinggi tombol biasa. Dua benda yang bersebelahan dan
   sama-sama kecil harus terbaca sebagai satu baris, bukan dua ukuran. */
.btn--pil{height:23px;padding:0 11px;font-size:var(--f11);border-radius:999px;font-weight:500}
.btn--pil svg{width:12px;height:12px}
/* Antara 820px dan 1180px kartu masih berdiri tiga lajur, tetapi foto dan
   kolom angkanya dikecilkan lebih dulu. Yang harus mengalah saat ruang menipis
   adalah gambar dan angka — bukan nama barang, karena namanya yang dicocokkan
   orang sambil memegang barangnya. */
@media (max-width:1180px){
}
@media (max-width:820px){
}
/* Di telepon, waktu dan tombolnya bertumpuk: tombol selebar kartu adalah
   sasaran yang lebih mudah dikenai ibu jari daripada tombol 150px yang
   berdesakan dengan tanggal di sebelahnya. */
@media (max-width:560px){
}

/* --------------------------------------------- baris rincian di pop-up
   Bentuk baris yang sama untuk item dan untuk transaksi, supaya rincian
   pembayaran terbaca sebagai satu daftar menurun, bukan dua tabel berbeda. */
/* ------------------------------------------------------- pop-up Bukti
   Yang ditanyakan orang saat membuka bukti penerimaan atau penyerahan cuma
   satu: KAPAN, dan oleh siapa. Karena itu keduanya berdiri sebagai satu blok
   besar di bawah fotonya, dan keterangan lain (unit, serial) turun menjadi
   baris kecil di bawahnya. Dulu keempatnya baris kv yang sama besar, jadi
   "Serial" dan "Waktu" berbobot sama dan tidak ada yang bisa dibaca sekilas. */
.buktilead{margin:14px 0 4px}
.buktilead-t{display:block;font-family:var(--f-judul);font-size:var(--f16);font-weight:600;
  letter-spacing:-.01em;color:var(--ink);font-variant-numeric:tabular-nums}
.buktilead-s{display:block;margin-top:3px;font-size:var(--f12);color:var(--ink-3)}
.buktikv .kv-row{padding:9px 0}
.buktikv .kv-row > span:first-child{font-size:var(--f12);color:var(--ink-3)}
.buktikv .kv-row > b{margin-left:auto;text-align:right;font-size:var(--f12);font-weight:500}
/* Tidak ada fotonya pun bentuknya tetap sama: petak bergaris putus-putus di
   tempat foto seharusnya berada, bukan sebuah kalimat yang menggantung. */
.buktinihil{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:8px;
  height:150px;border:1px dashed var(--line-strong);border-radius:var(--radius);background:var(--surface-2);
  color:var(--ink-3);font-size:var(--f12);text-align:center}
.buktinihil svg{width:22px;height:22px}

/* -------------------------------------------------- Detail Pembayaran
   Empat tingkat, dan tingkatnya harus terbaca tanpa membaca isinya:

   1. SEBUTAN SEKSI (.drwsub--rinci) — label kecil berhuruf besar, bukan judul.
      Ia memisah, bukan bersaing dengan isinya.
   2. BARIS (.rincirow-t dan .rincirow-v) — yang benar-benar dibaca: apa, dan
      berapa. Keduanya sama kuat karena keduanya dibaca sepasang.
   3. KETERANGAN BARIS (.rincirow-t > span, .rincirow-st) — rekening, waktu,
      pelaku, keadaan. Ia menjawab pertanyaan lanjutan, jadi ia tenang.
   4. TOTAL (.rincitabel) — jumlahnya kecil dan kelabu, KESIMPULANNYA besar.

   Dulu semuanya 13.5px dengan warna yang mirip, jadi nama item, nama
   rekening, dan angka kesimpulan berdiri dengan bobot yang sama dan mata
   tidak punya satu pun titik untuk berhenti. */
/* Sebutan seksi berdiri di atas GARISNYA SENDIRI dan berwarna teks penuh —
   bukan label kelabu yang tenggelam di antara baris-baris di bawahnya. Item
   dan Biaya adalah dua asal uang yang berbeda, dan pemisahnya harus terbaca
   sekali lihat; tetapi ia tetap 11px berhuruf besar, jadi ia MEMISAH tanpa
   ikut bersaing dengan nama barang di bawahnya. Angka di ujung kanan adalah
   jumlah barisnya. */
.drwsub--rinci{font-family:var(--f-isi);font-size:var(--f11);font-weight:700;
  letter-spacing:.1em;text-transform:uppercase;color:var(--ink);margin:24px 0 2px;
  display:flex;align-items:center;justify-content:space-between;gap:10px;
  padding-bottom:7px;border-bottom:1.5px solid var(--ink)}
.drwsub--rinci > i{font-style:normal;font-size:var(--f11);font-weight:600;letter-spacing:.04em;
  color:var(--ink-3);font-family:var(--f-angka)}
.drwsub--rinci:first-child{margin-top:0}
.rincirow{display:flex;align-items:baseline;justify-content:space-between;gap:14px;
  padding:11px 0;border-bottom:1px solid var(--line)}
/* DUA garis di satu tempat. `:last-of-type` menghitung di antara SELURUH
   `div` bersaudara, bukan di antara `.rincirow` saja — jadi baris terakhir
   sebuah seksi tetap membawa garisnya sendiri, lalu sebutan seksi berikutnya
   (`.drwsub--rinci`, bergaris 1,5px) berdiri tepat di bawahnya. Yang terbaca:
   satu garis tipis lalu satu garis tebal, berdempetan, di bawah baris item
   terakhir. Yang benar cuma satu — garis milik sebutan seksi berikutnya. */
.rincirow:last-of-type,
.rincirow:last-child,
.rincirow:has(+ .drwsub--rinci){border-bottom:0}
.rincirow-t{min-width:0;font-size:var(--f13);font-weight:500;color:var(--ink);line-height:1.35}
.rincirow-t > span{display:block;margin-top:4px;font-size:var(--f11);font-weight:400;
  color:var(--ink-3);line-height:1.5}
/* Keadaan barangnya berdiri di barisnya sendiri, bukan menempel pada
   keterangan di atasnya. Dirangkai sebaris, "…normal semua" dan "Diterima"
   terbaca sebagai satu kalimat yang tidak pernah ditulis siapa pun. */
.rincirow-st{color:var(--ink-2);font-weight:600;letter-spacing:.01em}
/* Kategori biaya. Berdiri sebagai cip supaya tidak mungkin tertukar dengan
   nama biayanya di baris atas maupun dengan nama rekening di sebelahnya —
   tiga potong teks yang berjajar dengan bentuk yang sama memang tidak bisa
   dibedakan tanpa dibaca satu per satu. */
.rincikat{display:inline-block;margin-right:8px;padding:1px 7px;border:1px solid var(--line);
  border-radius:var(--radius-kcl);background:var(--surface-2);color:var(--ink-2);font-size:var(--f11);font-weight:500;
  letter-spacing:.01em}
.rincirow-v{flex:none;font-family:var(--f-angka);font-weight:600;font-size:var(--f13);color:var(--ink)}
.rincirow-v--nol{color:var(--ink-3);text-decoration:line-through}
.rowtotal--akhir{border-top:2px solid var(--line-strong);margin-top:4px}
.rowtotal--akhir b{font-size:var(--f16)}
/* ---------- tabel total di dalam pop-up ----------
   Sebutan di kiri, angka di kanan, TANPA garis penghubung di antaranya. Garis
   penghubung berguna pada tabel yang lebar; di pop-up selebar 560px ia cuma
   menambah satu coretan mendatar pada setiap baris, dan bertumpuk dengan garis
   pemisah baris item di atasnya seluruh pop-up jadi terlihat penuh garis yang
   tidak jelas mana memisahkan apa.

   Yang tersisa cuma dua garis, dan keduanya benar-benar memisahkan: satu di
   atas tabelnya (batas antara daftar dan hitungannya) dan satu di atas baris
   kesimpulan. */
.rincitabel{margin-top:14px;border-top:1px solid var(--line-strong);padding-top:4px}
.rincitabel--rapat{margin-top:0;border-top:0}
.rincitabel .rowtotal{border:0;background:none;padding:6px 2px;margin-top:0;gap:14px;
  font-size:var(--f12);color:var(--ink-3)}
.rincitabel .rowtotal b{font-size:var(--f12);font-weight:500;color:var(--ink-2)}
.rincitabel .rowtotal-garis{display:none}
.rincitabel .rowtotal > span:first-child{flex:1 1 auto}
.rincitabel .rowtotal--kuat{border-top:1px solid var(--line);margin-top:3px;padding-top:11px}
.rincitabel .rowtotal--kuat > span:first-child{font-size:var(--f12);font-weight:600;color:var(--ink)}
.rincitabel .rowtotal--kuat b{font-size:var(--f16);font-weight:600;color:var(--ink)}

/* ------------------------------------------------------ penampil foto
   Dua komponen saja: fotonya, dan nama barangnya. Segala keterangan lain
   sudah terbaca di halaman yang memanggilnya. */
.lihatfoto{display:flex;flex-direction:column;align-items:flex-start;gap:11px}
.lihatfoto-bingkai{position:relative;width:100%;aspect-ratio:1;border-radius:var(--radius);overflow:hidden;
  background:var(--surface-2);border:1px solid var(--line)}
.lihatfoto-bingkai .itemfoto-rel{display:flex;height:100%;transition:transform .22s ease}
.lihatfoto-bingkai .itemfoto-rel img{flex:0 0 100%;width:100%;height:100%;object-fit:contain;
  display:block;user-select:none;background:var(--surface-2)}
/* Nama barangnya rata KIRI, satu baris, berpotong titik-titik. Ikon "i" di
   sebelahnya menerangkan kenapa nama di sini bisa berbeda dari nama pembelian
   di dokumennya — bergaris tipis dan sewarna teks tenang, supaya tidak
   tertukar dengan tanda seru Komplain yang berarti "laporkan". */
.lihatfoto-nama{margin:0;width:100%;display:flex;align-items:center;gap:7px;
  font-size:var(--f13);font-weight:500;line-height:1.45;color:var(--ink)}
.lihatfoto-nama-t{flex:0 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.lihatfoto-i{flex:none;border:0;background:none;padding:0;width:18px;height:18px;
  display:grid;place-items:center;color:var(--ink-3);cursor:pointer}
.lihatfoto-i:hover{color:var(--ink)}
.lihatfoto-i svg{width:15px;height:15px}
/* Jejak foto yang sedang dilihat (K-172 batch 1b): siapa yang menaruhnya dan
   kapan. Setengah langkah lebih kecil dan lebih tenang daripada nama
   barangnya — ia keterangan tentang fotonya, bukan judulnya. */
.lihatfoto-jejak{margin:2px 0 0;width:100%;font-size:var(--f12);line-height:1.5;
  color:var(--ink-3);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* Titik gulirnya menumpang di atas foto — .fototitik memang sudah
   position:absolute, jadi yang perlu dijamin cuma induknya berposisi. */
.lihatfoto-bingkai .fototitik{bottom:9px}

/* ---------- PENAMPIL FOTO LAYAR PENUH, LATAR HITAM (K-117) ----------
   Diminta pemiliknya: "seluruh area dibikin blank hitam, full hitam, terus
   foto 1:1 terpampang pas di tengah, terus ada tombol di bawahnya di area
   jempol, terus fotonya memenuhi seluruh kanan dan kiri layar tanpa celah."

   Alasannya bukan selera: barang bekas dinilai dari fotonya, dan setiap
   piksel yang diambil bingkai, jarak, atau latar terang adalah piksel yang
   tidak dipakai memeriksa lecet di pojok layarnya. Hitam pula yang membuat
   mata berhenti membandingkan warna foto dengan warna halaman di sekitarnya.

   HITAMNYA TETAP HITAM di tema terang maupun gelap — ia bukan permukaan
   ERP, ia ruang kosong di belakang sebuah gambar. Karena itu warnanya
   ditulis apa adanya, bukan lewat token.

   Ditulis SESUDAH blok penampil foto di atas, dan menimpa lembar-bawah di
   `@media(max-width:640px)` lewat pemilih yang lebih kuat: penampil foto
   tidak naik dari bawah seperti pop-up lain, ia MENGGANTIKAN layarnya. */
.ov:has(.mdl--foto){padding:0;align-items:stretch;justify-content:stretch;
  background:#000;overflow:hidden}
.ov .mdl--foto{width:100%;max-width:100%;height:100dvh;max-height:100dvh;
  border:0;border-radius:0;box-shadow:none;background:#000;color:#fff;transform:none}
.ov.on .mdl--foto{transform:none}
.mdl--foto .mdl-bd{padding:0;overflow:hidden;flex:1 1 auto;min-height:0;display:flex}
.mdl--foto .lihatfoto{flex:1 1 auto;min-height:0;gap:0;align-items:stretch;justify-content:center}
/* Mentok kanan-kiri: tanpa bingkai, tanpa sudut membulat, tanpa latar
   permukaan. Perbandingannya tetap 1:1 — di layar telepon itu berarti
   selebar layarnya penuh, dan tingginya mengikuti.

   `--foto-sisa` = tinggi yang sudah dipakai nama barang dan kaki tombolnya.
   Di layar LEBAR persegi selebar layar akan jauh lebih tinggi daripada
   layarnya sendiri, jadi yang membatasi di sana TINGGInya; di telepon
   lebarnya yang lebih dulu mentok. `min()` memilih yang benar tanpa satu pun
   media query. */
.mdl--foto .lihatfoto-bingkai{border:0;border-radius:0;background:#000;
  width:min(100%, calc(100dvh - var(--foto-sisa)));margin-inline:auto;flex:none}
.mdl--foto .lihatfoto-bingkai .itemfoto-rel img{background:#000}
.mdl--foto{--foto-sisa:152px}
/* Baris jejak foto (K-172 batch 1b) menambah tinggi yang BUKAN milik
   gambarnya, jadi `--foto-sisa` ikut naik — TETAPI hanya di penampil yang
   benar-benar menggambarnya. Dinaikkan untuk semua, penampil tanpa jejak
   (bukti pembayaran, berkas pegawai, foto komplain) kehilangan 22px tinggi
   foto tanpa satu pun alasan. */
.mdl--foto:has(.lihatfoto-jejak){--foto-sisa:174px}
.mdl--foto .lihatfoto-nama{padding:14px 16px 2px;color:#fff}
.mdl--foto .lihatfoto-jejak{padding:0 16px 2px;color:rgba(255,255,255,.62)}
.mdl--foto .lihatfoto-i{color:rgba(255,255,255,.55)}
.mdl--foto .lihatfoto-i:hover{color:#fff}
/* Kakinya menempel di dasar layar — di situlah jempolnya. */
.mdl--foto .mdl-ft{border-top:0;background:#000;
  padding-bottom:calc(14px + env(safe-area-inset-bottom))}
/* Pegangan lembar-bawah tidak berlaku di sini: ia tidak datang dari bawah. */
.mdl--foto .mdl-hd::before{display:none}
/* PENAMPIL PELANGGAN (K-274): tanpa kaki bertombol. Di bawah nama barangnya
   berdiri SATU baris: deretan foto kecil (yang sedang dilihat bergaris
   putih) dan tanda silang kecil di pojok kanan bawah. Tingginya lebih pendek
   daripada kaki bertombol, jadi fotonya mendapat sisa tinggi yang lebih
   besar. */
.mdl--foto:has(.lihatfoto-bawah){--foto-sisa:132px}
/* Deretan foto kecilnya MENTOK KE TEPI KANAN (diminta pemiliknya: "foto2
   jejer2 itu tidak kepotong sampai situ"). Silangnya berdiri di bawah
   deretannya, jadi tidak ada yang perlu dicadangkan di kanan; jarak 16px di
   ujung kanan milik GULIRANNYA, supaya foto terakhir tetap bisa digeser
   sampai lepas dari tepi. */
.lihatfoto-bawah{display:flex;align-items:center;gap:10px;width:100%;
  padding:10px 0 10px 16px}
.lihatfoto-mini{flex:1 1 auto;min-width:0;display:flex;gap:8px;overflow-x:auto;scrollbar-width:none;
  padding-right:16px}
.lihatfoto-mini::-webkit-scrollbar{display:none}
.lihatfoto-minib{flex:none;width:52px;height:52px;padding:0;border:2px solid transparent;border-radius:6px;
  overflow:hidden;background:#111;cursor:pointer;opacity:.55;transition:opacity .15s,border-color .15s}
.lihatfoto-minib img{width:100%;height:100%;object-fit:cover;display:block}
.lihatfoto-minib.on{opacity:1;border-color:#fff}
.mdl--foto{position:relative}
/* Silangnya di POJOK KANAN BAWAH LAYAR, bukan di ujung deretan fotonya — di
   situ yang diminta pemiliknya, dan di situ pula jempolnya. */
.lihatfoto-x{position:absolute;right:14px;bottom:calc(14px + env(safe-area-inset-bottom));z-index:2;
  display:grid;place-items:center;width:32px;height:32px;padding:0;
  border:0;border-radius:50%;background:rgba(255,255,255,.14);color:#fff;cursor:pointer}
.lihatfoto-x:hover{background:rgba(255,255,255,.26)}
.lihatfoto-x svg{width:15px;height:15px}
/* LAYAR LEBAR (diminta pemiliknya): seluruh isinya satu lajur SELEBAR
   FOTONYA di tengah layar — nama dan deretan foto kecil rata dengan tepi kiri
   fotonya, bukan dengan tepi layar. Silangnya DI LUAR pojok kanan atas foto:
   tidak menimpa gambarnya dan tidak menggesernya. 128px dicadangkan di lebar
   layar supaya silang itu selalu punya tempat di kanan foto. */
@media (min-width:641px){
  .mdl--foto:has(.lihatfoto-bawah) .mdl-bd{align-items:center;justify-content:center}
  .mdl--foto .lihatfoto:has(.lihatfoto-bawah){flex:none;position:relative;
    width:min(calc(100vw - 128px), calc(100dvh - var(--foto-sisa)))}
  .mdl--foto .lihatfoto:has(.lihatfoto-bawah) .lihatfoto-bingkai{width:100%}
  .mdl--foto .lihatfoto:has(.lihatfoto-bawah) .lihatfoto-nama{padding:14px 0 2px}
  .lihatfoto-bawah{padding:10px 0}
  .lihatfoto-mini{padding-right:0}
  .lihatfoto-x{top:0;bottom:auto;right:auto;left:calc(100% + 12px)}
}
/* PENAMPIL FOTO ERP DI LAYAR LEBAR (tahap 4, diminta pemiliknya): nama
   barang, jejak foto, dan tombolnya RATA TENGAH, di bawah foto yang juga di
   tengah. Di telepon tetap rata kiri (fotonya selebar layar, jadi tengah dan
   kiri tidak berbeda arti di sana). */
@media (min-width:641px){
  .mdl--foto:not(:has(.lihatfoto-bawah)) .lihatfoto-nama{justify-content:center}
  .mdl--foto:not(:has(.lihatfoto-bawah)) .lihatfoto-jejak{text-align:center}
  .mdl--foto .mdl-ft{justify-content:center}
}
/* Menu klik kanan penampil foto: lembar selebar fotonya yang naik dari tepi
   bawahnya (`openPop` bersasaran "bingkai"). */
.pop--bingkai{position:fixed;min-width:0;border-radius:var(--radius) var(--radius) 0 0;border-bottom:0;
  animation:bingkaiNaik .2s cubic-bezier(.22,.7,.25,1)}
.pop--bingkai .mi{min-height:40px}
@keyframes bingkaiNaik{from{transform:translateY(24px);opacity:0}to{transform:none;opacity:1}}
@media (prefers-reduced-motion:reduce){ .pop--bingkai{animation:none} }

/* ---------- TOMBOL SISI FOTO (tahap 6b, diminta pemiliknya) ----------
   30% tepi kiri dan kanan foto korsel mana pun (K-282, ralat pemiliknya atas
   10% tahap 6b): gradasi gelap setinggi
   fotonya dan panah arahnya MENYALA saat kursor masuk; menekannya menggeser.
   Hanya di layar bertetikus selebar laptop ("saat pakai mode laptop") — di
   layar sentuh jari yang menggeser, dan tombol tak terlihat di tepi foto
   akan menelan gesekan yang dimulai di sana. */
.korselsisi{display:none}
@media (hover:hover) and (pointer:fine) and (min-width:641px){
  .korselsisi{position:absolute;top:0;bottom:0;z-index:3;display:grid;place-items:center;
    width:30%;padding:0;border:0;cursor:pointer;color:#fff;opacity:0;
    background:linear-gradient(to right, rgba(0,0,0,.46), rgba(0,0,0,0));transition:opacity .16s ease}
  .korselsisi--kiri{left:0}
  .korselsisi--kanan{right:0;background:linear-gradient(to left, rgba(0,0,0,.46), rgba(0,0,0,0))}
  .korselsisi:hover,.korselsisi:focus-visible{opacity:1}
  .korselsisi svg{width:24px;height:24px;filter:drop-shadow(0 1px 2px rgba(0,0,0,.55))}
  .korselsisi--kiri svg{transform:rotate(180deg)}
}
@media (prefers-reduced-motion:reduce){ .korselsisi{transition:none} }

/* Foto pada baris item: kotak 1:1 di ujung kiri baris, bukan tombol bertulis
   "Foto 2". Gambar barangnya sendiri yang dikenali orang saat menyusuri
   daftar; angka di tombol tidak mengatakan apa-apa sampai ditekan. */
.irowfoto{flex:none;position:relative;width:56px;height:56px;padding:0;border:1px solid var(--line);
  border-radius:var(--radius);overflow:hidden;background:var(--surface-2);cursor:pointer;
  display:grid;place-items:center;color:var(--ink-3);transition:border-color .14s}
.irowfoto:hover{border-color:var(--line-strong)}
.irowfoto img{width:100%;height:100%;object-fit:cover;display:block}
.irowfoto > svg{width:18px;height:18px}
/* Foto pada baris rapat membentang setinggi barisnya: batas atas dan bawahnya
   lurus dengan isi di sebelahnya, bukan kotak kecil yang mengambang. */
/* SELALU 1:1, apa pun tinggi barisnya. Dulu ia diregangkan setinggi baris
   (align-self:stretch), jadi barang yang barisnya pendek — satu item tanpa
   nama inventory di bawahnya — tampil gepeng, dan barang yang sama di baris
   lain tampil normal. Yang menentukan tinggi foto adalah fotonya. */
.irow--rapat .irowfoto--besar{width:74px;height:auto;aspect-ratio:1/1;align-self:flex-start;min-height:0}
.irow--rapat .irowfoto--besar > svg{width:22px;height:22px}
.irowfoto-n{position:absolute;right:3px;bottom:3px;min-width:16px;height:16px;padding:0 4px;
  border-radius:var(--radius-kcl);background:rgba(17,17,19,.72);color:#fff;font-size:var(--f10);line-height:16px;
  font-weight:500;text-align:center;backdrop-filter:blur(4px)}

/* ------------------------------------------------- pop-up Buat Case
   Isinya tiga hal berurutan: item mana, tindakan apa, lalu buktinya. */
.casebuat-ket{margin:0 0 10px;font-size:var(--f12);color:var(--ink-2)}
.casebuat-item{margin:0;cursor:default}
.casebuat-res{margin:9px 0 4px;font-size:var(--f12);line-height:1.55;color:var(--ink-3)}
/* Petak penambah foto: bentuknya sama persis dengan foto yang sudah ada, jadi
   tempat foto berikutnya terlihat sebagai TEMPAT — bukan sebagai perintah yang
   harus dicari di kaki pop-up. Ia bergeser ke kanan mengikuti foto yang
   bertambah, lalu hilang sendiri begitu batasnya tercapai. */
.fototambah{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:7px;
  aspect-ratio:1;border:1px dashed var(--line-strong);border-radius:var(--radius);background:none;
  font:inherit;font-size:var(--f11);color:var(--ink-3);cursor:pointer;padding:6px;text-align:center;
  transition:border-color .14s,color .14s,background .14s}
.fototambah:hover{border-color:var(--ink);color:var(--ink);background:var(--surface-2)}
.fototambah svg{width:20px;height:20px}
/* Sisa tempat, tenang, di bawah katanya. */
.fototambah small{font-size:var(--f11);color:var(--ink-3);margin-top:-3px}
.fototambah:focus-visible{outline:2px solid var(--ink);outline-offset:2px}
/* Satu tombol tidak melebar sepenuh sel. Aturan flex:1 dibuat untuk dua
   tombol berdampingan; sendirian ia jadi bilah putih selebar foto yang
   terbaca sebagai tombol utama, padahal isinya cuma "hapus". */
.fotocell .util:has(> button:only-child){justify-content:flex-end;background:none;padding:6px}
.fotocell .util > button:only-child{flex:none;width:26px;height:26px}
/* Papan foto yang tidak bisa disunting: tanpa tombol, tanpa kursor tangan. */
.fotogrid--kunci .fotocell{cursor:default}
.fotokosong{margin:0;padding:14px;border:1px dashed var(--line-strong);border-radius:var(--radius);
  font-size:var(--f12);line-height:1.55;color:var(--ink-3);text-align:center}

/* Isi janji garansi pada kartu jenisnya. Boleh panjang, jadi ia dipatok dua
   baris — yang selengkapnya dibaca saat jenisnya dibuka untuk diubah. */
.garansi-desk{margin:0;font-size:var(--f12);line-height:1.55;color:var(--ink-2);
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;overflow-wrap:anywhere}

/* ---------- catatan & bukti pada dokumen ---------- */
/* Catatan & Bukti dibaca menyamping, bukan menumpuk ke bawah: satu layar
   memuat sekitar dua setengah kartu, jadi jelas masih ada lanjutannya, dan
   seksi ini tidak pernah memanjangkan halaman apa pun banyaknya catatan. */
.cttwrap{overflow-x:auto;overflow-y:hidden;padding-bottom:6px;scroll-snap-type:x proximity;overscroll-behavior-x:contain}
.cttlist{display:flex;flex-direction:row;gap:10px;align-items:stretch}
.cttcard{flex:0 0 calc((100% - 20px) / 2.7);min-width:230px;max-height:210px;overflow-y:auto;scroll-snap-align:start;
  border:1px solid var(--line);border-radius:var(--radius);background:var(--surface-2);padding:12px 14px}
@media (max-width:820px){ .cttcard{flex:0 0 82%} }
.cttcard-hd{display:flex;align-items:baseline;justify-content:space-between;gap:12px;margin-bottom:6px}
.cttcard-hd b{font-size:var(--f12);font-weight:600}
.cttcard-hd span{font-size:var(--f12);color:var(--ink-3)}
.cttcard-teks{font-size:var(--f12);line-height:1.6;color:var(--ink-2);white-space:pre-wrap;overflow-wrap:anywhere}
.cttcard-foto{display:flex;gap:7px;flex-wrap:wrap;margin-top:9px}
.cttcard-foto img{width:64px;height:64px;object-fit:cover;border-radius:var(--radius);border:1px solid var(--line);cursor:pointer}
.cttcard-foto img:hover{border-color:var(--line-strong)}
.pdp-lipat .lipat-isi{max-height:10em}
.pdp-lipat .lipat-isi p{font-size:var(--f13);line-height:1.7}
.dwi-isi .lipat-isi{max-height:6.5em}

/* ---------------------------------------------------------------- chat pelanggan
   Tombol chat duduk di kepala halaman toko. Angka merah hanya muncul kalau
   memang ada yang belum dibaca, jadi lingkaran kosong tidak pernah tampil. */
.shopchat,.shopakun{position:relative;flex:none;width:38px;height:38px;border-radius:var(--radius);border:1px solid var(--line);
  display:grid;place-items:center;color:var(--ink);background:var(--surface)}
.shopchat:hover,.shopakun:hover{border-color:var(--line-strong);background:var(--surface-2)}
.shopchat svg,.shopakun svg{width:19px;height:19px}
.shopchat-n{position:absolute;top:-6px;right:-6px;min-width:19px;height:19px;padding:0 5px;border-radius:999px;
  background:var(--stop);color:#fff;font-size:var(--f11);font-weight:600;line-height:19px;text-align:center;
  border:2px solid var(--surface);font-family:var(--f-isi)}
.utas{border:1px solid var(--line);border-radius:var(--radius);background:var(--surface);color:inherit;
  text-decoration:none;padding:14px 16px;margin-bottom:10px;display:flex;gap:14px;align-items:center}
.utas,.utas *{text-decoration:none}
.utas:hover{border-color:var(--line-strong);box-shadow:var(--shadow)}
.utas-bd{min-width:0;flex:1}
/* Nama toko SATU BARIS berpotong titik-titik (K-176): nama panjang yang
   melipat membuat satu baris utas berdiri lebih tinggi daripada tetangganya,
   dan daftar yang tepinya bergerigi terbaca seperti rusak. */
.utas-bd h3{margin:0 0 3px;font-size:var(--f13);font-weight:600;display:flex;align-items:center;gap:8px;
  min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:block}
.utas-bd p{margin:0;font-size:var(--f12);color:var(--ink-3);line-height:1.5;
  display:-webkit-box;-webkit-line-clamp:1;-webkit-box-orient:vertical;overflow:hidden}
.utas-kanan{flex:none;text-align:right;display:flex;flex-direction:column;align-items:flex-end;gap:6px}
.utas-jam{font-size:var(--f11);color:var(--ink-3);font-family:var(--f-angka)}
.utas-n{min-width:20px;height:20px;padding:0 6px;border-radius:999px;background:var(--stop);color:#fff;
  font-size:var(--f11);font-weight:600;line-height:20px;text-align:center}
.utas--baru .utas-bd p{color:var(--ink);font-weight:500}
.ruang{border:1px solid var(--line);border-radius:var(--radius);background:var(--surface);overflow:hidden}
.ruang-isi{padding:18px 18px 6px;display:flex;flex-direction:column;gap:10px;max-height:58vh;overflow:auto}
.gel{max-width:min(78%,520px);padding:10px 13px;border-radius:var(--radius);font-size:var(--f12);line-height:1.55;
  border:1px solid var(--line);background:var(--surface-2);align-self:flex-start;white-space:pre-wrap;word-break:break-word}
.gel--saya{align-self:flex-end;background:var(--ink);color:var(--on-ink);border-color:var(--ink)}
/* JAMNYA DUDUK DI EKOR KALIMATNYA, bukan di baris sendiri (K-176). Sebagai
   baris tersendiri ia menambah tinggi setiap gelembung — pada percakapan
   pendek "ya" dan "oke", separuh tinggi gelembungnya dipakai sebuah jam. */
.gel-jam{float:right;margin:6px 0 0 10px;font-size:var(--f11);opacity:.6;
  font-family:var(--f-angka);line-height:1}
.ruang-kaki{border-top:1px solid var(--line);padding:12px 14px;display:flex;gap:10px;align-items:flex-end;background:var(--surface)}
.ruang-kaki .inp{flex:1}
.ruang-hari{align-self:center;font-size:var(--f11);color:var(--ink-3);padding:2px 10px;border-radius:999px;background:var(--surface-2)}

/* ------------------------------------------------------------------ penilaian */
.bintang{display:inline-flex;gap:2px;line-height:0}
.bintang svg{width:15px;height:15px}
.bnt--penuh{color:#f5a524}
.bnt--penuh svg,.bnt--separuh svg{fill:currentColor}
.bnt--separuh{color:#f5a524;opacity:.5}
.bnt--kosong{color:var(--line-strong)}
.bintang--lg svg{width:20px;height:20px}
.nilaikotak{width:100%;text-align:left;border:1px solid var(--line);border-radius:var(--radius);background:var(--surface);
  padding:18px 20px;display:flex;align-items:center;gap:20px;cursor:pointer;font:inherit;color:inherit}
.nilaikotak:hover{border-color:var(--line-strong);box-shadow:var(--shadow)}
.nilaikotak-angka{flex:none;display:flex;flex-direction:column;gap:6px}
.nilaikotak-angka b{font-family:var(--f-judul);font-size:var(--f22);line-height:1;letter-spacing:-.02em}
.nilaikotak-angka b small{font-size:var(--f13);font-weight:500;color:var(--ink-3)}
.nilaikotak-bd{flex:1;min-width:0}
.nilaikotak-bd h3{margin:0 0 4px;font-size:var(--f13);font-weight:600}
.nilaikotak-bd p{margin:0;font-size:var(--f12);color:var(--ink-3)}
.nilaikotak-chev{flex:none;color:var(--ink-3);font-size:var(--f16);line-height:1}
.barbintang{display:flex;align-items:center;gap:10px;margin-bottom:9px;font-size:var(--f12)}
.barbintang-k{flex:none;width:46px;display:flex;align-items:center;gap:3px;color:var(--ink-2)}
.barbintang-k svg{width:13px;height:13px;color:#f5a524;fill:currentColor}
.barbintang-jalur{flex:1;height:8px;border-radius:999px;background:var(--surface-2);overflow:hidden}
.barbintang-isi{height:100%;background:#f5a524;border-radius:999px}
.barbintang-n{flex:none;width:44px;text-align:right;font-family:var(--f-angka);color:var(--ink-2)}
.ulasan{border-bottom:1px solid var(--line);padding:16px 0}
.ulasan:last-child{border-bottom:0}
.ulasan-atas{display:flex;align-items:center;gap:10px;margin-bottom:7px}
.ulasan-nama{font-size:var(--f12);font-weight:600}
.ulasan-jam{font-size:var(--f11);color:var(--ink-3);margin-left:auto;font-family:var(--f-angka)}
.ulasan p{margin:0;font-size:var(--f12);line-height:1.6;color:var(--ink-2)}
.ulasan-foto{display:flex;gap:8px;margin-top:10px;flex-wrap:wrap}
.ulasan-foto img{width:72px;height:72px;object-fit:cover;border-radius:var(--radius);border:1px solid var(--line);cursor:zoom-in}

/* -------------------------------------------------------- pengaturan rentang
   Atur Harga dan Voucher memakai bentuk yang sama persis: baris pengaturan,
   bukan kartu. Batas bawah selalu mengikuti baris di atasnya, jadi kolom itu
   hanya dibaca, tidak diisi. */
.setgrup{border:1px solid var(--line);border-radius:var(--radius);background:var(--surface);overflow:hidden;margin-bottom:14px}
.setgrup-kepala{padding:15px 18px;border-bottom:1px solid var(--line);background:var(--surface-2)}
.setgrup-kepala h2{margin:0 0 3px;font-size:var(--f13)}
.setgrup-kepala p{margin:0;font-size:var(--f12);color:var(--ink-3);line-height:1.55}
.setbaris{display:grid;grid-template-columns:1.4fr .9fr .9fr .8fr .9fr auto;gap:12px 14px;align-items:start;
  padding:16px 18px;border-bottom:1px solid var(--line)}
.setbaris:last-child{border-bottom:0}
.setbaris--mati{background:var(--surface-2)}
.setbaris--mati .setsel label,.setbaris--mati .setsel .inp{opacity:.55}
.setsel{min-width:0}
.setsel label{display:block;font-size:var(--f11);font-weight:600;color:var(--ink-3);margin-bottom:5px;
  text-transform:uppercase;letter-spacing:.04em}
.setsel .hint{display:block;margin-top:5px;font-size:var(--f11);color:var(--ink-3)}
.setsel .inp input[readonly]{color:var(--ink-3)}
.setakt{display:flex;gap:6px;align-items:center;padding-top:22px}
.setkaki{display:flex;gap:10px;align-items:center;padding:14px 18px;border-top:1px solid var(--line);background:var(--surface-2)}
.setkaki .tumbuh{flex:1}
/* Kalimat panjang tidak bisa dibaca di dalam sepertiga lebar panelnya, dan
   pratinjaunya harus berbunyi persis seperti yang diterima pelanggan —
   termasuk pindah barisnya (K-170). */
.setbaris--teks{grid-template-columns:1fr}
.setkaki--pratinjau{display:block;font-size:var(--f12);line-height:1.6;white-space:pre-wrap}
@media(max-width:900px){.setbaris{grid-template-columns:1fr 1fr}.setakt{grid-column:1/-1;justify-content:flex-end}}

/* ---------------------------------------------------------- papan foto
   Foto diurutkan dengan menyeretnya. Sel yang sedang diseret diredupkan,
   sel yang akan menerima diberi garis tebal — dua tanda itu cukup untuk
   tahu barang mendarat di mana. */
.fotocell{cursor:grab}
.fotocell:active{cursor:grabbing}
.fotocell--seret{opacity:.4}
.fotocell--target{outline:2px solid var(--ink);outline-offset:-2px}
.fotocell .util button{display:grid;place-items:center;padding:5px 0}
.fotocell .util button svg{width:14px;height:14px}

/* ------------------------------------------------------- detail item: foto
   Foto digeser, bukan diganti: satu baris panjang berisi semua foto yang
   digeser mendatar, jadi perpindahannya terlihat sebagai gerakan. */
.itemfoto-utama{overflow:hidden}
.itemfoto-rel{display:flex;width:100%;height:100%;transition:transform .28s cubic-bezier(.22,.61,.36,1)}
/* BARIS FOTO PUNYA LAPISANNYA SENDIRI (K-287, dilaporkan pemiliknya: foto
   Detail Item di HP "susah sekali di-slide, agak macet"). DIUKUR: tanpa ini
   satu geseran ±15 bingkai menggambar ulang fotonya 51 kali dan mengurai
   ulang gambarnya 65 kali — setiap gerakan jari melukis ulang foto besar.
   Dengan lapisan sendiri kartu grafisnya cuma menggeser gambar yang sudah
   jadi. Berlaku untuk ketiga korsel (Detail Item, halaman produk, penampil
   foto), satu aturan. */
.itemfoto-rel{will-change:transform;backface-visibility:hidden}
.itemfoto-rel img{width:100%;height:100%;flex:0 0 100%;object-fit:cover;display:block;user-select:none}
.fototitik{position:absolute;left:50%;bottom:10px;transform:translateX(-50%);display:flex;gap:6px;z-index:2}
.fototitik-b{width:7px;height:7px;padding:0;border:0;border-radius:50%;background:rgba(255,255,255,.55);cursor:pointer}
.fototitik-b.on{background:#fff;width:18px;border-radius:999px}

/* Tombol ikon telanjang — dipakai untuk "ubah" di samping teks yang diubah,
   supaya maksudnya jelas tanpa memakan satu baris tombol sendiri. */
.ikonbtn{width:26px;height:26px;flex:none;border:1px solid var(--line);border-radius:var(--radius);background:var(--surface);
  color:var(--ink-2);display:inline-grid;place-items:center;cursor:pointer;vertical-align:middle}
.ikonbtn:hover{border-color:var(--line-strong);color:var(--ink);background:var(--surface-2)}
.ikonbtn svg{width:14px;height:14px}
/* Tanda seru pengaju Komplain: sengaja tenang dan tanpa kotak, supaya ia
   tidak terbaca sebagai tombol yang menunggu ditekan. Warnanya baru hidup
   saat disentuh — mengeluh bukan langkah biasa pada sebuah pembelian. */
/* Sebesar cip .btn--pil yang berdiri sebaris dengannya. */
.ikonbtn--kecil{width:23px;height:23px;border-radius:999px}
.ikonbtn--kecil svg{width:12.5px;height:12.5px}
/* Segitiga peringatan pada baris item: SATU tombol untuk seluruh urusan
   Komplain, dan ia setinggi tombol Terima/Serahkan di sebelahnya supaya tepi
   kanan daftarnya rata. Kosong = belum ada apa-apa (menekannya mencatat
   komplain baru); terisi dan berwarna = ada yang terbuka. Angka kecil di
   pojoknya cuma muncul bila lebih dari satu — satu komplain sudah terkatakan
   oleh warnanya sendiri. */
/* Setinggi dan selebar tombol Terima/Serahkan di sebelahnya, mengalahkan
   .btn--sm.btn--ikon yang ditulis belakangan: dua tombol yang berdiri
   sebaris harus setinggi, kalau tidak tepi kanan daftarnya berloncatan. */
.btn--sm.btn--ikon.btn--seru{position:relative;width:30px;height:30px;color:var(--ink-3)}
.btn--sm.btn--ikon.btn--seru svg{width:16px;height:16px}
.btn--seru:hover{border-color:var(--stop-line);background:var(--stop-bg);color:var(--stop)}
.btn--seru--ada{border-color:var(--stop-line);background:var(--stop-bg);color:var(--stop)}
.btn--seru--ada:hover{background:var(--stop-bg);opacity:.85}
.btn-seru-n{position:absolute;top:-5px;right:-5px;min-width:16px;height:16px;padding:0 4px;
  display:inline-flex;align-items:center;justify-content:center;border-radius:999px;
  background:var(--stop);color:#fff;font-size:var(--f10);font-weight:600;line-height:1;
  font-family:var(--f-isi)}
.ikonbtn--seru{width:24px;height:24px;border-color:transparent;background:none;color:var(--ink-3)}
.ikonbtn--seru:hover{border-color:var(--stop-line);background:var(--stop-bg);color:var(--stop)}
.ikonbtn--seru svg{width:15px;height:15px}
.judulbaris{display:flex;align-items:center;gap:9px;flex-wrap:wrap}
/* Nama unit di halaman detail memakai ukuran judul detail yang biasa —
   pembesaran 2.7x itu untuk nama di KARTU daftar Item, bukan di sini. */
.judulbaris--besar{gap:10px;align-items:center}

/* Blok harga pada detail item memakai susunan yang sama persis dengan kartu
   item, supaya angka yang sama tidak dibaca dengan dua cara berbeda. */
.itemharga{display:flex;flex-direction:column;gap:4px}
/* 22px di lebar mana pun (tampilan tahap 4, diminta pemiliknya: "harganya
   juga kebesaran"). */
.itemharga .hargabesar{font-size:var(--f18)}
.itemharga .hargakecil b{color:var(--ink);font-weight:600}
/* Harga besar di kiri, dua angka pembanding di KANANNYA — bukan dua baris di
   bawahnya. Keduanya melipat turun sendiri begitu kotaknya menyempit. */
/* Sejak angkanya diringkas (K-211) lajur kanannya cukup sempit untuk tetap
   berdiri DI SEBELAH angka besarnya — jadi ia tidak lagi boleh melipat turun
   sendiri: itulah yang diminta pemiliknya, dan itu pula yang membuat ketiga
   angkanya terbaca dalam satu tarikan mata. Yang masih menurunkannya cuma
   layar telepon, lewat media query di bawah. */
.hargautama{display:flex;align-items:flex-start;justify-content:space-between;gap:12px 18px;flex-wrap:nowrap}
.hargasisi{display:flex;flex-direction:column;align-items:flex-end;gap:6px;min-width:0;flex:none}
/* Ikon menggantikan sebutan. Ukurannya sengaja setara huruf di sebelahnya —
   ikon yang lebih besar daripada angkanya akan terbaca sebagai tombol. */
.hargaikon{display:grid;place-items:center;width:15px;height:15px;flex:none;color:var(--ink-3)}
.hargaikon svg{width:14px;height:14px}
/* Di layar sempit lajur kanan turun dan kembali rata kiri: rata kanan di
   dalam kotak selebar layar membuat dua angka menggantung sendirian jauh dari
   angka besar yang mereka bandingkan. */
/* DI TELEPON PUN LAJUR KANANNYA TETAP DI KANAN (tampilan tahap 1, diminta
   pemiliknya: "harusnya harga modal dan batas harga bawah itu diletakkan di
   sisi kanan harga besar"). Aturan lama menurunkannya ke bawah dengan alasan
   rata kanan di kotak selebar layar membuat angkanya menggantung jauh — alasan
   itu hilang begitu ikon "i" pindah ke pojok dan angka besarnya mengecil
   sedikit: ketiga angkanya kini berdempetan dalam satu tarikan mata. Yang
   tetap tidak muat (harga delapan digit di layar 320px) MELIPAT, tidak
   meluber. */
@media (max-width:520px){
  .hargautama{flex-wrap:wrap;gap:9px 10px}
}
/* Ikon "i" berdiri di pojok kanan atas kotak harganya, bukan menempel pada
   angka besarnya — ia menerangkan KETIGA angka. Lajur kanan TURUN selebar
   ikonnya di telepon, bukan bergeser ke kiri: di situ setiap piksel lebar
   dipakai supaya lajur itu tetap di sebelah angka besarnya. Di layar yang
   lebih lebar ruangnya ada, jadi lajurnya bergeser dan tetap sejajar. */
.itemharga{position:relative}
.hargautama > .hargainfo{position:absolute;top:10px;right:8px;display:grid;place-items:center;
  width:24px;height:24px;padding:0;border:0;border-radius:50%;background:none;color:var(--ink-3);cursor:pointer}
.hargautama > .hargainfo:hover{color:var(--ink);background:var(--surface-2)}
.hargautama > .hargainfo svg{width:16px;height:16px}
.itemharga > .hargautama{padding-right:26px}
/* TELEPON (K-275): tombolnya BERHENTI mengambang. Ia berdiri sebaris di ujung
   kanan, dan ketiga angkanya SEJAJAR — harga besar di tengah tinggi lajur
   kanannya, bukan lajur kanan yang turun 24px menghindari tombol di pojok
   ("tanda panah kanan pada harga itu kelempar dan harga yang 2 ... tidak
   sejajar dengan harga yang besar"). */
@media (max-width:520px){
  .itemharga > .hargautama{padding-right:0;align-items:center;flex-wrap:nowrap}
  .hargautama > .hargainfo{position:static;flex:none;margin-left:-4px}
  .hargautama > .itemharga-besar{flex:1 1 auto;min-width:0}
  /* Angka besarnya TIDAK PERNAH patah di tengah — ukurannya yang mengikuti
     lebar layar: delapan digit di layar 360px tetap satu baris. */
  .itemharga .hargabesar{white-space:nowrap;font-size:min(22px, 5.4vw)}
}
/* Layar yang lebih sempit lagi: lajur kanannya melipat ke bawah, bukan
   meluber. */
@media (max-width:340px){ .itemharga > .hargautama{flex-wrap:wrap} }
.hargaarti{display:flex;flex-direction:column;gap:10px;font-size:var(--f12);color:var(--ink)}
.hargaarti-b{display:flex;align-items:center;gap:10px}
.hargaarti-i{display:grid;place-items:center;width:24px;height:24px;flex:none;
  border-radius:6px;background:var(--surface-2);color:var(--ink-2);font-size:var(--f12)}
.hargaarti-i svg{width:14px;height:14px}
.hargariwayat-j{margin:22px 0 10px;font-size:var(--f12);font-weight:600;color:var(--ink)}
.hargariwayat-kosong{font-size:var(--f12);margin:0}

/* Judul dan harga berdiri di satu kolom di sebelah kanan foto. Sebelumnya
   nama unit ada di kepala halaman dan harganya di kotak tersendiri, jadi tiga
   keterangan atas satu barang yang sama — gambar, nama, harga — terpencar dan
   mata harus menyatukannya sendiri. Urutan bacanya sekarang menurun: nama,
   lalu penanda unitnya, lalu angka-angkanya. */
.itemsisi{display:flex;flex-direction:column;min-width:0}
/* TITIK TIGA TETAP DI KANAN JUDUL (tampilan tahap 4, dilaporkan pemiliknya:
   "titik tiganya kelempar ke bawah kiri"). Dengan `flex-wrap:wrap` nama yang
   panjang mengambil seluruh lebar dan tombolnya jatuh ke baris berikutnya. */
.itemjudul{display:flex;align-items:flex-start;justify-content:space-between;gap:12px 14px;flex-wrap:nowrap}
.itemjudul h1{flex:1 1 auto;min-width:0}
/* Judulnya mengalir sebagai teks biasa, bukan baris flex: dengan flex, nama
   yang panjang mengambil seluruh lebar dan pensilnya terlempar sendirian ke
   baris berikutnya. Sebagai teks, pensilnya menempel di ujung kata terakhir
   di mana pun nama itu berakhir. */
/* Judulnya dipotong di tingkat TEKS (E.potongTampil), bukan lewat clamp CSS:
   pensil dan ikon riwayat berdiri sebaris di ujung namanya, dan clamp akan
   ikut memotong keduanya sampai hilang. Nama selengkapnya ada di judul
   tetikus dan di panel Ubah Nama. */
/* `text-wrap:wrap`, bukan `balance` bawaan judul: balance membagi dua baris
   sama panjang, jadi baris pertama berhenti di "Samsung Galaxy A56" sementara
   di kanannya masih kosong selebar "8/256". Pemiliknya meminta namanya
   mentok ke kanan dulu, baru turun. */
/* 17px di lebar mana pun (tampilan tahap 4, diminta pemiliknya: "font judul
   juga kebesaran banget") — dulu 20px di layar lebar, 17px cuma di 820px ke
   bawah. */
.itemjudul h1{display:block;font-size:var(--f18);font-weight:600;letter-spacing:normal;line-height:1.3;margin:0;overflow-wrap:anywhere;text-wrap:wrap}
.itemjudul h1 .ikonbtn{margin-left:5px;vertical-align:3px}
.itemjudul .btn{flex:none;margin-top:3px}
.itemsisi .itemmeta{margin-top:9px}
/* Kalimat "Dibeli sebagai …" ITULAH jalan menuju dokumen pembeliannya. Ia
   tetap terbaca sebagai kalimat keterangan — kecil dan tenang — dan hanya
   menunjukkan dirinya sebagai jalan saat disentuh. */
.dibeli{display:flex;align-items:center;gap:5px;margin:7px 0 0;min-width:0;
  font-size:var(--f12);font-weight:400;color:var(--ink-3);text-decoration:none}
.dibeli > span{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.dibeli > svg{width:12px;height:12px;flex:none;transition:transform .14s}
.dibeli:hover{color:var(--ink-2)}
.dibeli:hover > span{text-decoration:underline;text-underline-offset:3px;
  text-decoration-color:var(--line-strong)}
.dibeli:hover > svg{transform:translateX(2px)}
.dibeli:focus-visible{outline:2px solid var(--ink);outline-offset:3px;border-radius:var(--radius)}
/* TIGA TINDAKANNYA MENTOK KE TEPI KANAN KOTAKNYA, dan Jual paling kanan
   (K-211, diminta pemiliknya).

   Aturan lamanya mendorongnya ke tepi KIRI, "sejajar dengan angka-angka yang
   membuat orang memutuskan untuk menekannya". Alasan itu tidak berlaku lagi
   sejak angka pembandingnya sendiri berdiri di tepi KANAN kotak yang sama
   (Batas Harga Jual dan Modal di `.hargasisi`): yang sejajar dengan keduanya
   sekarang justru tepi kanan, dan Jual berdiri tepat di bawah angka yang
   menentukan boleh dilepas berapa. */
.itemharga .irow-act{justify-content:flex-end;flex-wrap:nowrap}
.batasbaris{display:flex;align-items:center;gap:7px;flex-wrap:wrap}

/* ---------- pratinjau akibat sebuah pencatatan ----------
   Berdiri di kaki formulirnya, sesudah kolom terakhir: ia jawaban atas isian
   yang baru saja diketik, bukan pengantar sebelum mengisi. Warnanya tenang —
   ia BUKAN benda yang bisa ditekan — tetapi angka kesimpulannya sekuat angka
   di Ringkasan Keuangan, karena itulah yang dicari mata. */
.pratinjau{border:1px solid var(--line);border-radius:var(--radius);background:var(--surface-2);
  padding:12px 14px}
.pratinjau-hd{font-size:var(--f10);font-weight:700;letter-spacing:.1em;text-transform:uppercase;
  color:var(--ink-3);margin-bottom:8px}
.pratinjau-row{display:flex;align-items:baseline;justify-content:space-between;gap:14px;
  padding:5px 0;font-size:var(--f12);color:var(--ink-2)}
/* Sebutannya TIDAK BOLEH melipat. Ia satu-dua kata; yang tumbuh saat orang
   mengetik nominalnya adalah lajur angkanya — dan lajur angka yang `nowrap`
   mendorong sebutan di sebelahnya sampai pecah menjadi dua baris. Yang
   mengalah harus yang bisa mengalah tanpa kehilangan arti: sebutannya
   dipotong titik-titik (judul tetikusnya membawa yang lengkap), sementara
   angkanya utuh — angka setengah tidak mengatakan apa-apa. */
.pratinjau-row > span{min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.pratinjau-row b{flex:none;font-family:var(--f-angka);font-variant-numeric:tabular-nums;
  font-size:var(--f12);font-weight:600;color:var(--ink);white-space:nowrap}
@media(max-width:560px){
  .pratinjau{padding:11px 12px}
  .pratinjau-row{gap:10px;font-size:var(--f12)}
  .pratinjau-row b{font-size:var(--f12)}
  /* Baris kesimpulan TIDAK dibesarkan di lebar telepon: 14px membuat
     "Rp26.150.000 → Rp26.350.000" memakan 205px, dan sebutan "Total
     Transaksi" di sebelahnya tinggal kebagian setengah katanya. Yang
     membedakan baris kesimpulan di sini sudah cukup garis dan warnanya. */
  .pratinjau-row--kuat b{font-size:var(--f12)}
  .pratinjau-row b i{margin:0 4px}
}
/* Angka lama dicoret dan dikelabukan, panah kecil di antaranya: "dari berapa"
   itulah yang membuat "menjadi berapa" ada artinya. */
.pratinjau-row b s{font-weight:400;color:var(--ink-3);text-decoration-thickness:1px}
.pratinjau-row b i{font-style:normal;color:var(--ink-3);margin:0 6px;font-family:var(--f-isi)}
.pratinjau-row--kuat{border-top:1px solid var(--line);margin-top:5px;padding-top:9px;color:var(--ink)}
.pratinjau-row--kuat b{font-size:var(--f14)}
.pratinjau-kaki{margin-top:10px;padding-top:9px;border-top:1px dashed var(--line);
  font-size:var(--f12);color:var(--ink-2)}
.pratinjau-kaki b{font-weight:600;color:var(--ink)}
/* Dua baris keterangan unit yang berdiri sendiri-sendiri, masing-masing
   melipat di dalam dirinya saja. */
.itemmeta{display:flex;align-items:center;gap:8px 12px;flex-wrap:wrap;min-width:0;
  font-size:var(--f12);color:var(--ink-2)}
.itemmeta--asal{margin-top:8px;gap:6px 12px}
.itemmeta--asal .dibeli{margin:0}
/* Angka besar dan ikon penjelasnya sebaris, ikonnya sejajar dasar angkanya. */
.itemharga-besar{display:flex;align-items:flex-end;gap:8px;min-width:0}
/* Tombol keterangan: lingkaran "i" bergaris tipis, sewarna teks tenang.
   Ia MENERANGKAN, jadi ia tidak boleh sekuat benda yang menawarkan tindakan —
   dan tidak boleh berbentuk segitiga, yang di ERP ini berarti "laporkan". */
.infobtn{flex:none;border:0;background:none;padding:0;width:20px;height:20px;
  display:grid;place-items:center;color:var(--ink-3);cursor:pointer;border-radius:50%}
.infobtn:hover{color:var(--ink);background:var(--surface-2)}
.infobtn svg{width:15px;height:15px}
/* Di dalam baris angka dan di dalam label formulir ia menempel pada teksnya,
   bukan turun ke baris sendiri: `display:grid` membuatnya elemen blok, dan
   sebuah ikon yang berdiri sendirian di bawah kata yang diterangkannya tidak
   lagi terbaca sebagai keterangan kata itu. */
.kv-row .infobtn,label .infobtn,.sec-hd h2 .infobtn,.setgrup-ket .infobtn{display:inline-grid;vertical-align:-5px;margin-left:3px}

/* Penunjuk jumlah karakter di pojok kanan bawah kolom teks panjang. */
.inp--hitung{position:relative}
.inp--hitung textarea{padding-bottom:22px}
.inp-hitung{position:absolute;right:10px;bottom:6px;font-family:var(--f-angka);font-size:var(--f11);
  color:var(--ink-3);pointer-events:none;background:var(--surface);padding:0 2px;border-radius:var(--radius)}
.inp-hitung--penuh{color:var(--stop)}

/* Keterangan yang masih menuntut tindakan menyala; yang sudah beres tenang.
   Warna tidak dipakai di sini — yang membedakan hanya terang dan tidaknya,
   sesuai aturan bahwa warna hanya untuk status dokumen utama. */
.chipinfo--nyala{background:var(--ink);border-color:var(--ink);color:var(--on-ink)}
.chipinfo--nyala b{color:var(--on-ink)}

/* Foto kecil di kiri baris tabel — cukup untuk mengenali barangnya tanpa
   membuat barisnya setinggi kartu. */
.irow-foto{width:44px;height:44px;flex:none;border-radius:var(--radius);object-fit:cover;border:1px solid var(--line);background:var(--surface-2)}
.irow-foto.thumb--empty{display:grid;place-items:center;color:var(--ink-3)}
.irow-foto.thumb--empty svg{width:18px;height:18px}
.cttlist--tegak{flex-direction:column}
.cttlist--tegak .cttcard{flex:none;max-height:none;min-width:0;width:100%}

/* Mode tampilan hasil kalkulator duduk di dalam kotak hasilnya sendiri,
   bukan di kepala halaman — ia mengatur kotak itu, bukan halamannya. */
/* Saklar Simpel/Detail di KAKI kotak hasil Kalkulator (diminta pemiliknya:
   "taruh di bawah, model saklar, ada animasinya"). Bentuknya saklar umum
   (.saklar) yang boleh dipakai layar lain; kedua sebutannya tombol sendiri
   supaya menekan "Simpel" saat sudah Simpel tidak membalik saklarnya. */
.hasil-kaki{display:flex;align-items:center;justify-content:center;gap:12px;margin-top:14px;padding-top:12px;border-top:1px solid var(--line)}
.saklar{position:relative;display:inline-flex;align-items:center;cursor:pointer;flex:none}
.saklar input{position:absolute;opacity:0;width:0;height:0;margin:0}
.saklar-jalur{position:relative;width:42px;height:24px;border-radius:12px;background:var(--line-strong);transition:background .22s}
.saklar-jalur::after{content:"";position:absolute;top:3px;left:3px;width:18px;height:18px;border-radius:50%;background:#fff;
  box-shadow:0 1px 2px rgba(0,0,0,.28);transition:transform .22s cubic-bezier(.2,.8,.2,1)}
.saklar input:checked + .saklar-jalur{background:var(--ink)}
.saklar input:checked + .saklar-jalur::after{transform:translateX(18px)}
.saklar input:focus-visible + .saklar-jalur{outline:2px solid var(--ink);outline-offset:2px}
.saklar-t{background:none;border:0;padding:4px 2px;font:inherit;font-size:var(--f12);color:var(--ink-3);cursor:pointer;transition:color .2s}
.saklar-t--on{color:var(--ink);font-weight:600}
.hasil-rinci{animation:dokMuncul .3s ease both}
@media (prefers-reduced-motion:reduce){ .saklar-jalur,.saklar-jalur::after,.saklar-t{transition:none} .hasil-rinci{animation:none} }
.hasil-v u{text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:3px}

/* Yang disembunyikan benar-benar hilang, apa pun display bawaannya. */
[hidden]{display:none!important}

/* ------------------------------------------------------------ hak akses
   Modul induk dan halaman di dalamnya dibaca sebagai satu blok, supaya
   terlihat mana yang diberikan utuh dan mana yang sengaja dipangkas. */
.modlist{display:grid;grid-template-columns:repeat(2,1fr);gap:10px}
@media(max-width:900px){.modlist{grid-template-columns:1fr}}
.modblok{border:1px solid var(--line);border-radius:var(--radius);padding:12px 14px;background:var(--surface)}
.modblok--on{border-color:var(--line-strong);background:var(--surface-2)}
.modblok-induk{margin:0}
.modanak{margin:10px 0 0 26px;padding-top:10px;border-top:1px solid var(--line);
  display:grid;grid-template-columns:repeat(2,1fr);gap:2px 10px}
.modanak .radio{margin:0;font-size:var(--f12)}
@media(max-width:560px){ .modanak{grid-template-columns:1fr} }
.modanak .radio b{font-weight:400}
.modanak input:disabled + span{opacity:.45}
/* HALAMAN DI DALAM MODUL MENGUNCUP (K-163). Panel Atur Peran dulu menggambar
   99 kotak centang sekaligus — 4.305px, 5,3 layar penuh — sementara yang dicari
   orang yang membukanya hampir selalu satu modul saja.

   Yang menguncup HANYA halamannya: baris induknya tetap berdiri utuh, jadi
   memberikan satu modul penuh tetap satu tekan seperti dulu, dan berapa halaman
   yang diberikan tetap terbaca dari luar lewat angka di sebelah panahnya.

   Disembunyikan CSS, bukan tidak digambar: centangnya adalah keadaan yang
   sedang disunting, dan keadaan yang ikut hilang bersama simpulnya akan hilang
   pula dari kiriman yang disimpan. */
.modblok-hd{display:flex;align-items:center;gap:10px}
.modblok-hd .modblok-induk{flex:1;min-width:0}
.modblok-lipat{flex:none;display:inline-flex;align-items:center;gap:5px;
  border:0;padding:2px 0;background:none;cursor:pointer;font:inherit;
  font-variant-numeric:tabular-nums;font-size:var(--f12);color:var(--ink-3)}
.modblok-lipat svg{width:16px;height:16px;transition:transform .16s}
.modblok--buka .modblok-lipat svg{transform:rotate(90deg)}
.modblok .modanak{display:none}
.modblok--buka .modanak{display:grid}
/* Keterangan sebuah HAK TAMBAHAN menguncup dengan cara yang sama. Dua puluh
   empat keterangan yang berdiri sekaligus memakan 1.952px — dua layar penuh —
   dan masing-masing dibaca sekali seumur hidup, sementara namanya dibaca tiap
   kali. Namanya yang berdiri, keterangannya satu tekan di belakangnya. */
.modanak--ket{display:block;font-size:var(--f12);color:var(--ink-3);line-height:1.5}
.modblok--buka .modanak--ket{display:block}

/* ------------------------------------------------------------- transfer
   Keadaan dokumen dibaca lebih dulu daripada isinya, jadi ia berdiri di
   kiri sebagai lambang berwarna, bukan sebagai label kecil di kanan. */
/* Keadaan dibaca dari ikonnya lebih dulu, labelnya menyusul sebagai
   pemastian. Karena itu ikonnya berdiri tanpa kotak berwarna: kotak tint
   membuat tiga kartu berturut-turut terlihat seperti tiga tombol, padahal
   yang bisa ditekan adalah kartunya, bukan ikonnya. */
/* Setiap keterangan membawa ikonnya sendiri, jadi tidak perlu titik pemisah:
   ikonnya sudah menandai di mana satu keterangan berakhir dan yang berikutnya
   mulai, dan mata bisa langsung melompat ke yang dicarinya. */
/* Di kolom setengah lebar kartunya harus menyusut sendiri: petak keadaan dan
   petak jumlah dipersempit, dan keterangan waktunya berhenti membungkus —
   yang mengalah adalah nama pelakunya, bukan tanggalnya. */

@media(max-width:760px){
}

/* ==========================================================================
   KARTU OPNAME
   Bentuknya satu keluarga dengan kartu Transfer: keadaan di kiri, isi di
   tengah, angka di kanan. Bedanya keadaan opname adalah sebuah PERTANYAAN
   yang sudah atau belum dijawab, jadi ikonnya dibulatkan dan diberi latar —
   ia lencana, bukan gambar barang.
   ========================================================================== */
.opncard{display:flex;align-items:center;gap:18px;padding:16px 18px;margin-bottom:10px;cursor:pointer;
  border:1px solid var(--line);border-radius:var(--radius);background:var(--surface);text-align:left}
.opncard:hover{border-color:var(--line-strong);box-shadow:var(--shadow)}
.opnbd{flex:1;min-width:0;display:flex;flex-direction:column;gap:8px}
.opnnama{display:block;font-size:var(--f13);font-weight:600;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.opnmeta{display:flex;align-items:center;gap:8px;flex-wrap:wrap;font-size:var(--f12);color:var(--ink-3);
  font-family:var(--f-angka)}
.opnmeta > span{display:inline-flex;align-items:center;gap:6px;min-width:0}
.opnmeta svg{width:13px;height:13px;flex:none;opacity:.85}
.opnmeta > i{font-style:normal;opacity:.5}
.opnkanan{flex:none;display:flex;flex-direction:column;align-items:flex-end;gap:9px}
.opncip{display:flex;align-items:center;gap:8px;flex-wrap:wrap;justify-content:flex-end}
/* Cip angka: labelnya tetap redup, angkanya yang berwarna. Yang dicari mata
   adalah angkanya; labelnya cuma menerangkan angka itu angka apa. */
.cip{display:inline-flex;align-items:center;gap:7px;height:26px;padding:0 11px;border-radius:var(--radius);
  border:1px solid var(--line);font-size:var(--f12);color:var(--ink-3);white-space:nowrap;background:var(--surface)}
.cip b{font-family:var(--f-angka);font-weight:600;font-size:var(--f12);color:var(--ink)}
.cip--wait b{color:var(--wait)}
.cip--done b{color:var(--done)}
.cip--stop b{color:var(--stop)}
.cip--run{border-color:var(--run-line);background:var(--run-bg);color:var(--run)}
.cip--run b{color:var(--run)}
.opnchev{flex:none;color:var(--ink-3);display:grid;place-items:center}
.opnchev svg{width:16px;height:16px}
/* Lencana keadaan memakai ikon garis, bukan bulatan penuh seperti .mk —
   bentuknya harus sama dengan ikon di lingkaran kiri supaya keduanya
   terbaca sebagai satu hal yang sama. */
.pill--ikon svg{width:13px;height:13px;flex:none}
/* KARTU OPNAME DI DALAM DAFTAR DUA LAJUR.

   Sejak daftarnya berdiri dua lajur, kartunya selebar 555px di layar 1440 —
   bukan 1130px lagi. Bentuk satu barisnya (lingkaran · nama & waktu · lencana
   & tiga cip · panah) memang tidak pernah muat di lebar itu: nama lokasinya
   terpotong menjadi "Warehouse …" padahal justru nama itulah judul kartunya.

   Yang dipakai sekarang bentuk melipat yang sudah ada di `@media(max-width:900px)`
   — nama dan waktu di baris atas, lencana dan cip di baris bawah — dan ia
   dipasang berdasarkan DI MANA kartunya berdiri, bukan berdasarkan lebar
   layarnya: lebar kartu inilah yang menentukan bentuknya, dan lebar kartu
   tidak bisa ditanyakan kepada media query. Panahnya ikut dicabut: seluruh
   kartunya sudah bisa ditekan, dan panah di ujung kanan cuma menghabiskan
   16px yang sedang diperebutkan nama lokasi. */
.daftarsempit .opncard{flex-wrap:wrap;gap:12px;padding:14px 16px;margin-bottom:0}
.daftarsempit .opnbd{flex:1 1 200px}
.daftarsempit .opnkanan{flex:1 1 100%;align-items:flex-start}
.daftarsempit .opncip{justify-content:flex-start}
.daftarsempit .opnchev{display:none}
@media(max-width:900px){
  .opncard{flex-wrap:wrap;gap:12px;padding:14px}
  .opnbd{flex:1 1 200px}
  .opnkanan{flex:1 1 100%;align-items:flex-start}
  .opncip{justify-content:flex-start}
  .opnchev{display:none}
}
@media(max-width:560px){ .daftarsempit .opnkanan{padding-left:0} }
@media(max-width:560px){
  .opnbd{padding-left:14px}
  .opnkanan{padding-left:0}
}

/* Memilih unit langsung di isian transfer — foto kecil ikut ditampilkan
   supaya tidak salah ambil unit yang namanya mirip. */
.pilihunit{border:1px solid var(--line);border-radius:var(--radius);max-height:260px;overflow:auto;background:var(--surface)}
/* Unit yang DICENTANG membuka kolomnya sendiri di tempat yang sama. Yang belum
   dicentang tidak menampilkan kolom apa pun, jadi daftar dua puluh unit tidak
   berubah menjadi empat puluh kolom kosong yang harus dilewati. */
.pilihunit-blok{border-bottom:1px solid var(--line)}
.pilihunit-blok:last-child{border-bottom:0}
.pilihunit-blok .pilihunit-baris{border-bottom:0}
.pilihunit-blok.on{background:var(--surface-2)}
.pilihunit-isi{display:flex;flex-wrap:wrap;gap:12px;padding:0 12px 12px 46px}
.pilihunit-isi .field{margin:0;flex:1 1 240px;min-width:0}
.pilihunit-isi .field:has(.inp-money){flex:0 0 190px}
.pilihunit-baris{display:flex;align-items:center;gap:12px;padding:9px 12px;cursor:pointer;
  border-bottom:1px solid var(--line);margin:0}
.pilihunit-baris:last-child{border-bottom:0}
.pilihunit-baris:hover{background:var(--surface-2)}
.pilihunit-baris.on{background:var(--surface-2)}
.pilihunit-foto{flex:none}
.pilihunit-foto .thumb--sm{width:34px;height:34px;border-radius:var(--radius)}
.pilihunit-bd{min-width:0;display:flex;flex-direction:column;gap:3px}
.pilihunit-bd b{font-size:var(--f12);font-weight:500}

/* ============================================================ ONLINE SHOP
   Kartu produk sengaja KECIL supaya satu layar memuat lebih banyak pilihan —
   yang dicari pembeli adalah membandingkan, bukan mengagumi satu kartu.

   Ukurannya dulu ditulis dua kali: 220 piksel di bagian Online Shop di atas,
   lalu ditimpa 168 piksel di sini tanpa syarat apa pun. Yang pertama tidak
   pernah menang satu kali pun, jadi ia dicabut — dua angka untuk satu hal
   membuat siapa pun yang mengubah salah satunya mengira sudah selesai. */
.shopgrid{grid-template-columns:repeat(auto-fill,minmax(168px,1fr));gap:12px}
.shopcard .bd{padding:10px 11px 12px}
.shopcard h3{font-size:var(--f12);min-height:2.6em;margin-bottom:5px}
/* ======= SATU UKURAN JUDUL SEKSI UNTUK SELURUH ERP (K-184, K-185) =======
   Dulu EMPAT nilai untuk satu benda yang sama, dan dua di antaranya berdiri
   di halaman yang sama: 'Barang Tersedia' 16px/700, 'Ringkasan Keuangan'
   16px/600, 'Deskripsi' 15px/600, 'PRODUK LAIN DARI TOKO INI' 14px/600
   berhuruf besar. Yang membacanya berhenti menebak apakah keempatnya
   tingkatan yang berbeda — padahal keempatnya judul seksi.

   Aturan ini sengaja berdiri PALING BELAKANG di antara keempat rumahnya,
   jadi tidak ada satu pun yang bisa menimpanya diam-diam. Rumahnya
   masing-masing tinggal mengurus huruf dan jaraknya. */
.sec-hd h2,.ringkas-hd h2,.pdp-desk h2,.barisrek-hd h2,.tokolist h2{
  font-size:var(--f14);font-weight:600;letter-spacing:normal}
.shopcard .lok{font-size:var(--f11)}
.shopcard .ph{position:relative}
/* Label ditempel di foto, pojok kanan bawah, dan dibesarkan sedikit supaya
   terbaca sekilas tanpa mencuri ruang judul. */

/* Harga: yang besar selalu harga yang benar-benar dibayar. */
.hrg{display:flex;align-items:baseline;gap:7px;flex-wrap:wrap;margin-top:auto}
.hrg b{font-family:var(--f-angka);font-size:var(--f14);font-weight:600;letter-spacing:-.02em}
/* HARGA DI KARTU LEBIH KECIL DAN RAPAT (K-274): "fontnya kurang mepet dikit
   sama agak kebesaran khususnya font harga". 15px dan dirapatkan, supaya cip
   potongannya muat di sebelahnya pada kartu selebar 168px. Judulnya ikut
   dirapatkan setengah langkah. */
/* Cipnya TURUN ke bawah harganya bila memang tidak muat (harga delapan
   digit di layar 360px, atau layar 320px) — meluber keluar kartu bukan
   pilihan, dan harganya tidak pernah boleh terpotong. */
.shopcard .hrg{gap:2px 5px;flex-wrap:wrap}
.shopcard .hrg b{font-size:var(--f13);letter-spacing:-.035em}
/* JUDUL KARTU MENGEPRES LEBARNYA (K-281, dilaporkan pemiliknya: "judul
   produk turun kebawah ... kurang mau ngepres"). Penyakit K-252 yang sama:
   `text-wrap:balance` bawaan `h3` membagi nama barang menjadi dua baris SAMA
   PANJANG, jadi "Nubia Neo 5 8/256" turun sendirian padahal "Mulus" masih
   muat. Nama barang mengisi barisnya dulu, baru turun. */
.shopcard h3{letter-spacing:-.01em;text-wrap:wrap}
/* CORETANNYA DIKEMBALIKAN. Kartu toko adalah tautan, dan aturan yang
   mematikan garis bawah tautan (`a.shopcard *`) ikut mematikan coretan di
   sini — jadi harga lama dan harga baru berdiri berdampingan tanpa satu pun
   tanda mana yang mana. Pada halaman yang dilihat PEMBELI, itu bukan soal
   rupa: dua angka tanpa penjelasan adalah dua angka yang bisa salah dibaca,
   dan yang salah baca membawanya ke kasir. */
.hrg s{font-family:var(--f-angka);font-size:var(--f12);color:var(--ink-3);
  text-decoration:line-through;text-decoration-thickness:1px}
.hrg--diskon b{color:var(--stop)}
.hrg--besar b{font-size:var(--f18);letter-spacing:-.01em}
.hrg--besar s{font-size:var(--f13)}
.pdp-voucher{display:flex;align-items:flex-start;gap:9px;margin:0 0 14px;padding:10px 12px;
  border:1px solid var(--done-line);background:var(--done-bg);border-radius:var(--radius);font-size:var(--f12);color:var(--done)}
.pdp-voucher svg{width:16px;height:16px;flex:none;margin-top:1px}
.pdp-voucher b{font-weight:600}
/* Garansi di halaman produk: sebentuk dengan kotak voucher di atasnya, tetapi
   TENANG — voucher mengabarkan uang yang dihemat hari ini, garansi cuma
   menyebutkan apa yang berlaku sesudahnya. */
.pdp-garansi{display:flex;align-items:center;gap:9px;margin:0 0 14px;padding:10px 12px;
  border:1px solid var(--line);border-radius:var(--radius);font-size:var(--f12);color:var(--ink-2)}
.pdp-garansi svg{width:16px;height:16px;flex:none}
.pdp-garansi b{font-weight:600;color:var(--ink)}
.btn--ikon{padding:0;width:38px;flex:none;display:grid;place-items:center}
.btn--ikon svg{width:18px;height:18px}
/* Ikon saja pada ukuran kecil: kotaknya ikut mengecil supaya ia tidak
   berdiri lebih tinggi daripada tombol bertulisan di sebelahnya — 30px,
   sama persis dengan `.btn--sm`. Dulu 32px, dan dua piksel itu terlihat
   sebagai satu tombol yang menonjol di baris yang seluruhnya rata. */
.btn--sm.btn--ikon{width:30px;height:30px}
.btn--sm.btn--ikon svg{width:16px;height:16px}
.pdp-toko-av{flex:none}
.pdp-toko-nama{display:inline-flex;align-items:flex-start;gap:5px;max-width:100%;min-width:0}
/* NAMA TOKO YANG PANJANG MEMOTONG DIRINYA, TIDAK MELEBARKAN HALAMANNYA
   (K-179). Dilaporkan pemiliknya: "teksnya banyak yang keluar sampai ke
   kanan layar." Diukur di layar 360px dengan nama sepanjang nama sungguhan:
   halaman produk melebar menjadi 879px — dua setengah kali layarnya — dan
   satu-satunya pelakunya nama toko di kartu ini, yang tidak pernah menyusut.
   Data contoh bernama pendek-pendek, jadi ia tidak pernah terlihat di sini.
   Chevronnya tetap berdiri: ia yang mengatakan namanya bisa ditekan. */
/* DUA BARIS, LALU DIPOTONG (K-255). Satu baris beserta titik-titiknya sudah
   memotong "Warehouse Kediri" begitu kotaknya menyempit — dan sejak petak
   angkanya pindah ke sebelah kanan, kotaknya memang menyempit di mana-mana.
   Nama toko satu-satunya hal di kotak ini yang tidak boleh hilang.
   Dua baris tidak membayar tinggi sama sekali: lajur kanannya sudah lebih
   tinggi daripada itu di lebar mana pun. `overflow-wrap` mengurus nama yang
   satu katanya sangat panjang — tanpanya ia tidak punya tempat melipat sama
   sekali, dan kembali melebarkan halamannya seperti K-179. */
.pdp-toko-namat{overflow:hidden;min-width:0;overflow-wrap:anywhere;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}
.pdp-toko-chev{flex:none;color:var(--ink-3);font-size:var(--f14);line-height:1.35}
.wajib{color:var(--stop);font-weight:700}
.pilihalasan{display:flex;flex-direction:column;gap:8px}
.pilihalasan-opt{display:flex;align-items:center;gap:12px;width:100%;text-align:left;font:inherit;color:inherit;
  border:1px solid var(--line);border-radius:var(--radius);background:var(--surface);padding:13px 15px;cursor:pointer;font-size:var(--f12)}
.pilihalasan-opt:hover{border-color:var(--line-strong);background:var(--surface-2)}
.pilihalasan-opt span:first-child{flex:1}
.pilihalasan-chev{color:var(--ink-3);font-size:var(--f14);line-height:1}
.shopchat-n--kalem{background:var(--ink);color:var(--on-ink)}

/* --------------------------------------------------------------- keranjang */
.krjgrid{display:grid;grid-template-columns:1fr 300px;gap:18px;align-items:start}
@media(max-width:820px){.krjgrid{grid-template-columns:1fr}}
.krjbaris{display:flex;gap:14px;align-items:center;padding:12px 14px;margin-bottom:10px;
  border:1px solid var(--line);border-radius:var(--radius);background:var(--surface)}
.krjbaris--habis{opacity:.62}
.krjfoto{flex:none;width:72px;height:72px;border-radius:var(--radius);overflow:hidden;background:var(--surface-2);
  display:grid;place-items:center;color:var(--ink-3)}
.krjfoto img{width:100%;height:100%;object-fit:cover}
.krjbd{flex:1;min-width:0;display:flex;flex-direction:column;gap:5px}
.krjnama{font-size:var(--f13);font-weight:600;color:inherit;text-decoration:none}
.krjnama:hover{text-decoration:underline}
.krjhabis{font-size:var(--f12);color:var(--stop)}
.krjtotal{border:1px solid var(--line);border-radius:var(--radius);background:var(--surface);padding:16px 18px;position:sticky;top:80px}
.krjtotal h2{margin:0 0 12px;font-size:var(--f13)}
.krjtotal .btn{width:100%;margin-top:14px;justify-content:center}
.krjtotal .hint{display:block;margin-top:9px;text-align:center}

/* ---------------------------------------------------------- cakupan akses */
.cakupan-lok{display:flex;flex-direction:column;gap:6px;margin-bottom:6px}
.cakupan-opt{display:flex;align-items:center;justify-content:space-between;gap:10px;width:100%;
  border:1px solid var(--line);border-radius:var(--radius);background:var(--surface);padding:10px 13px;
  cursor:pointer;font:inherit;color:inherit;text-align:left;font-size:var(--f12)}
.cakupan-opt:hover{border-color:var(--line-strong);background:var(--surface-2)}
.cakupan-opt.on{border-color:var(--ink);background:var(--surface-2);font-weight:600}
.cakupan-opt small{display:block;font-size:var(--f11);color:var(--ink-3);font-weight:400;margin-top:2px}
.cakupan-opt .mk{border-color:var(--done);color:var(--done);position:relative;flex:none}

/* ------------------------------------------------------------- tim saya */
.ringkasbaris{display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin:14px 0 4px;
  font-size:var(--f12);color:var(--ink-2)}
.ringkasbaris i{font-style:normal;color:var(--ink-3)}
.ringkasbaris b{font-weight:600;color:var(--ink)}
.irow--sorot{border-color:var(--line-strong);background:var(--surface-2)}
.profilku{display:flex;gap:20px;align-items:flex-start;padding:18px}
.profilku-av{flex:none;width:88px;height:88px;border-radius:var(--radius);background:var(--ink);color:var(--on-ink);
  display:grid;place-items:center;font-family:var(--f-judul);font-size:var(--f22);overflow:hidden}
.profilku-av img{width:100%;height:100%;object-fit:cover}
.profilku-bd{flex:1;min-width:0}
.profilku-bd h3{margin:0 0 3px;font-size:var(--f14)}
@media(max-width:760px){.profilku{flex-direction:column}.profilku .irow-act{align-self:stretch}}

/* ------------------------------------------------------------ lembar isian
   Isian panjang dibaca seperti halaman tersendiri: judul di atas, tombol
   kembali di kiri, isi yang bisa digulir, dan kaki yang selalu menempel di
   bawah sehingga tombol Simpan tidak pernah hilang dari pandangan. */
.ov--lembar{align-items:stretch;justify-content:center;padding:0}
.panel--lembar{opacity:1;position:relative;margin:0;border:0;border-radius:0;box-shadow:none;
  width:100%;max-width:100%;height:100%;max-height:100%;
  display:flex;flex-direction:column;transform:translateY(10px)}
.ov--lembar.on .panel--lembar{transform:none}
.panel--lembar .panel-hd{position:sticky;top:0;z-index:2;align-items:center;padding:16px 24px;
  background:var(--surface);border-bottom:1px solid var(--line)}
.panel--lembar .panel-hd > div{flex:1;min-width:0}
.panel--lembar .panel-hd h3{font-size:var(--f16)}
.panel--lembar .panel-bd{flex:1;overflow-y:auto;padding:24px;background:var(--bg)}
.panel--lembar .panel-bd > .form,
.panel--lembar .panel-bd > *{max-width:calc(var(--w) + 120px);margin-left:auto;margin-right:auto}
.panel--lembar .panel-ft{position:sticky;bottom:0;z-index:2;justify-content:center;
  padding:14px 24px;background:var(--surface);border-top:1px solid var(--line)}
.panel--lembar .panel-ft > *{max-width:none}
/* TOMBOL KEMBALI TANPA KOTAK (diminta pemiliknya): tinggal panah berbatang,
   bentuk yang sama dengan tombol Kembali di baris kepala dan Detail Item. */
.panel-back{flex:none;width:34px;height:34px;padding:0;border:0;border-radius:var(--radius);
  background:none;color:var(--ink);display:grid;place-items:center;cursor:pointer}
@media (hover:hover){ .panel-back:hover{color:var(--ink-2)} }
.panel-back svg{width:21px;height:21px}
@media(max-width:640px){
  .panel--lembar .panel-hd{padding:13px 14px}
  .panel--lembar .panel-bd{padding:16px 14px}
  .panel--lembar .panel-ft{padding:12px 14px}
}

/* ------------------------------------------------- strip keadaan dokumen
   Tiga pertanyaan yang selalu ditanyakan orang tentang sebuah dokumen,
   dijawab satu kali di kepala dan tidak diulang lagi di bawah. */
.dstrip{display:grid;grid-template-columns:repeat(3,1fr);gap:0;margin:0 0 16px;
  border:1px solid var(--line);border-radius:var(--radius);background:var(--surface);overflow:hidden}
/* Tiga petak, tiga baris yang sama: sebutan, angka, keterangan. Barisnya
   dipatok tingginya supaya petak yang membawa tombol tidak menggeser baris
   keterangan tetangganya ke bawah — dulu tombol di satu petak membuat dua
   petak lain menyisakan ruang kosong menganga di dasarnya, dan strip terbaca
   seperti tiga kotak yang tidak sejajar. */
.dcell{position:relative;padding:12px 16px;text-align:left;font:inherit;color:inherit;
  border:0;border-left:1px solid var(--line);background:transparent;overflow:hidden;
  display:flex;flex-direction:column;gap:6px;min-width:0;transition:background .14s}
.dcell:first-child{border-left:0}
/* Sebutan dan tombolnya satu baris, dan barisnya setinggi tombol. Sebutannya
   dibesarkan dari 10,5px supaya ia tidak tenggelam di sebelah tombol yang
   berdiri di baris yang sama. */
.dcell-k{display:flex;align-items:center;gap:10px;flex-wrap:nowrap;min-height:30px;min-width:0;
  font-size:var(--f12);font-weight:600;letter-spacing:.04em;text-transform:uppercase;
  color:var(--ink-3);line-height:16px;padding-right:26px}
.dcell-kt{flex:none;white-space:nowrap}
/* Tinggi dipatok: satu baris angka, atau satu baris tombol setinggi 30px. */
.dcell-v{display:flex;align-items:center;gap:10px;flex-wrap:nowrap;min-height:30px;min-width:0;
  font-family:var(--f-angka);font-size:var(--f16);font-weight:600;
  line-height:1.15;letter-spacing:-.01em}
.dcell-v b{font-weight:600}
.dcell-s{font-size:var(--f12);color:var(--ink-3);line-height:16px;min-height:16px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* Panah berdiri di TENGAH tinggi petak, di ujung kanan — sama letak, sama
   ukuran, sama ikon di setiap petak yang punya rincian. Tanpa kotak: yang
   bisa ditekan adalah seluruh petaknya, dan kotak di sekelilingnya justru
   mengatakan bahwa cuma kotak itu yang bisa ditekan. */
.dcell-chev{position:absolute;right:10px;top:50%;transform:translateY(-50%);
  width:24px;height:24px;padding:0;z-index:1;
  display:grid;place-items:center;border:0;border-radius:var(--radius);
  background:none;color:var(--ink-3);cursor:pointer;transition:color .14s}
.dcell-chev svg{width:15px;height:15px}
/* Bentangan tak terlihat yang membuat SELURUH petak menjadi area kliknya. */
.dcell-chev::after{content:"";position:absolute;inset:-999px;z-index:-1}
.dcell:has(.dcell-chev){cursor:pointer}
.dcell:has(.dcell-chev):hover{background:var(--surface-2)}
.dcell:has(.dcell-chev):hover .dcell-chev{color:var(--ink)}
/* Menyentuh tombol di dalam petak TIDAK menyalakan petaknya: yang akan
   ditekan jarinya adalah tombolnya, bukan rinciannya, dan dua benda yang
   menyala bersamaan membuat orang menebak mana yang akan terjadi. */
.dcell:has(.dcell-aksi:hover){background:transparent}
.dcell:has(.dcell-aksi:hover) .dcell-chev{color:var(--ink-3)}
.dcell-chev:focus-visible{outline:2px solid var(--ink);outline-offset:2px}
/* Tombol di dalam petak berdiri di atas bentangan itu supaya tetap bisa
   ditekan sendiri tanpa ikut membuka rinciannya. */
.dcell-aksi{position:relative;z-index:2}
/* Tindakan berdiri SEBARIS dengan angkanya, di sebelah kirinya. Ditaruh di
   baris sendiri di bawah, strip kepala tumbuh satu baris lagi ke bawah dan
   mendorong seluruh isi halaman turun. */
.dstrip--aksi{grid-template-columns:.82fr 1.5fr .82fr}
/* Kaki strip. Margin bukan angka yang dipakai untuk bekerja — tidak ada
   tindakan yang diambil karenanya sepanjang dokumen masih berjalan — jadi ia
   tidak berhak atas petak sebesar Item dan Pembayaran. Ia turun menjadi satu
   tulisan tenang di dasar kotak yang sama: selalu ada, selalu di tempat yang
   sama pada Pembelian maupun Penjualan, dan hanya ramai kalau memang dicari. */
.dstrip-kaki{grid-column:1 / -1;border-top:1px solid var(--line);padding:5px 16px;
  display:flex;align-items:center;justify-content:flex-end;flex-wrap:wrap;gap:8px}
.tautsunyi{display:inline-flex;align-items:center;gap:5px;padding:4px 0;border:0;background:none;
  font:inherit;font-size:var(--f12);font-weight:400;letter-spacing:0;text-transform:none;
  color:var(--ink-3);cursor:pointer;transition:color .14s}
.tautsunyi:hover{color:var(--ink)}
/* Angkanya ikut di dalam tulisannya. Tenang bukan berarti kosong: yang
   dicari orang adalah angkanya, dan menyembunyikannya di balik satu tekan
   cuma membuat setiap orang menekan. */
.tautsunyi b{font-family:var(--f-angka);font-variant-numeric:tabular-nums;
  font-weight:600;color:var(--ink)}
.tautsunyi svg{width:13px;height:13px}
.tautsunyi:focus-visible{outline:2px solid var(--ink);outline-offset:3px;border-radius:var(--radius)}
@media(max-width:1180px){.dstrip--aksi{grid-template-columns:1fr}
  .dstrip--aksi .dcell{border-left:0;border-top:1px solid var(--line)}
  .dstrip--aksi .dcell:first-child{border-top:0}}
/* Di dalam kolom setengah lebar strip ini SELALU bertumpuk, berapa pun lebar
   layarnya: tiga petak dalam kolom 530px menyisakan 170px untuk sebuah
   tanggal lengkap, dan yang terjadi bukan teks terpotong rapi melainkan petak
   ketiga terdorong keluar kotaknya. Lebar layar tidak menjawab pertanyaan
   ini — lebar KOLOMNYA yang menjawab. */
.docsplit .dstrip{grid-template-columns:1fr}
.docsplit .dstrip .dcell{border-left:0;border-top:1px solid var(--line)}
.docsplit .dstrip .dcell:first-child{border-top:0}
.dcell-aksi{display:flex;gap:7px;flex-wrap:nowrap;min-width:0;position:relative;z-index:2;margin-left:auto}
.dcell-n{min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* Petak yang punya panah menyisakan tempat untuk panahnya di baris angka
   juga, bukan hanya di baris sebutan — kalau tidak, isi yang panjang
   berjalan tepat ke bawah panahnya dan titik-titik pemotongnya terbaca
   menempel pada tanda ">". */
.dcell:has(.dcell-chev) .dcell-v{padding-right:24px}
/* Sebagian petak berisi NAMA, bukan angka. Nama barang dalam huruf mesin
   ketik terbaca seperti kode, dan 19px huruf mesin ketik memakan lebar dua
   kali lipat untuk keterangan yang sama. */
.dcell-teks{min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  font-family:var(--f-judul);font-size:var(--f14);font-weight:600;letter-spacing:-.005em}
/* Kolom unggah berkas: tombol biasa, nama berkasnya di sebelahnya. */
/* Sisa tagihan berdiri di baris paling atas pop-up pembayaran, sebaris
   dengan tombol yang mengisikannya. Angka dan cara memakainya dalam satu
   gerakan mata. */
.sisabayar{display:flex;align-items:center;gap:14px;flex-wrap:wrap;padding:13px 15px;
  border:1px solid var(--wait-line);background:var(--wait-bg);border-radius:var(--radius)}
.sisabayar--beres{border-color:var(--line);background:var(--surface-2)}
.sisabayar-k{flex:1;min-width:0;font-size:var(--f12);color:var(--ink-2)}
.sisabayar-v{font-family:var(--f-angka);font-size:var(--f16);font-weight:600;letter-spacing:-.01em}
/* Akibatnya, tepat di sebelah angkanya. Paragraf penjelas di bawah kotak ini
   sudah dicabut: yang perlu diketahui orang cuma sisa ini menjadi apa, dan
   jawabannya tiga kata. */
.sisabayar-jadi{flex:none;font-size:var(--f12);font-weight:600;color:var(--ink-2);
  padding:3px 9px;border:1px solid var(--line);border-radius:999px;background:var(--surface)}
.berkas{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.berkas-nama{min-width:0;font-size:var(--f12);color:var(--ink-3);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.berkas-nama--ada{color:var(--ink-2);font-family:var(--f-angka);font-size:var(--f12)}
.dcell--wait .dcell-k{color:var(--send)}
.dcell--done .dcell-k{color:var(--done)}
.dcell--stop .dcell-k{color:var(--stop)}
@media(max-width:760px){.dstrip{grid-template-columns:1fr}
  .dcell{border-left:0;border-top:1px solid var(--line)}
  .dcell:first-child{border-top:0}
  /* Petaknya sudah bertumpuk satu kolom, jadi tingginya tidak perlu lagi sama
     — dan memaksa sebutan beserta kedua tombolnya muat dalam satu baris
     selebar layar telepon hanya memotong tombol yang kedua. */
  .dcell-k{flex-wrap:wrap;min-height:0;padding-right:24px}
  .dcell-aksi{margin-left:0;flex-wrap:wrap}}
.rowtotal--kuat b{font-size:var(--f14)}

/* ---------------------------------------------- kartu dokumen (hierarki)
   Tiga tingkat: siapa dan berapa, lalu barangnya, lalu apa yang menyimpang.
   Yang sudah beres tidak dicetak — supaya yang bermasalah menonjol sendiri. */
/* ==========================================================================
   KARTU PURCHASE
   Tiga lajur yang selalu di tempat yang sama: barangnya, isinya, uangnya.
   Foto di paling kiri karena itulah yang pertama dikenali orang saat
   menggulir daftar panjang — nomor purchase baru dicari sesudah kartunya
   ketemu, bukan sebaliknya.
   ========================================================================== */
.pc{display:flex;align-items:stretch;gap:16px;padding:14px 16px}
.pc-foto{flex:none;width:132px;position:relative;border-radius:var(--radius);overflow:hidden;
  background:var(--surface-2);border:1px solid var(--line);display:grid;place-items:center;min-height:132px}
.pc-foto img{width:100%;height:100%;object-fit:cover;display:block}
.pc-foto-kosong{color:var(--ink-3)}
.pc-foto-kosong svg{width:30px;height:30px}
/* Cip jumlah item menempel di fotonya, bukan berdiri sendiri di baris lain:
   "berapa barang" adalah keterangan tentang foto itu, bukan angka keempat
   yang harus dicari tempatnya. */
.pc-fotochip{position:absolute;left:7px;bottom:7px;display:inline-flex;align-items:center;gap:5px;
  height:22px;padding:0 8px;border-radius:var(--radius);font-size:var(--f11);font-weight:500;
  background:rgba(17,17,19,.72);color:#fff;backdrop-filter:blur(6px)}
.pc-fotochip svg{width:12px;height:12px}
/* Tidak lagi dipusatkan: isi kartu berdiri dari atas, dan keterangan waktu di
   bawahnya didorong menempel ke dasar kartu (lihat .pc-meta). Dengan begitu
   baris "tanggal · jam · lokasi · orang" berada di ketinggian yang sama persis
   pada setiap kartu, jadi mata tidak perlu mencarinya lagi tiap turun satu
   baris. */
.pc-isi{flex:1;min-width:0;display:flex;flex-direction:column;gap:9px}
/* Lingkaran berinisial menggantikan foto pihak, yang memang tidak pernah ada.
   Satu ikon orang yang sama untuk semua pihak justru tidak membedakan apa
   pun — dua huruf membedakan. */
.avatarhuruf.pc-ava{width:36px;height:36px;flex:none;font-size:var(--f12);border-radius:999px;
  border:1px solid var(--line)}
/* Dua baris, selalu. Purchase berisi satu item dan purchase berisi enam item
   dulu melahirkan kartu setinggi dua kali lipat, dan daftar yang tingginya
   berloncatan tidak bisa dibaca dengan menggulir cepat. Sekarang tempatnya
   dipatok dua baris: yang cuma punya satu item menyisakan satu baris kosong,
   yang punya lebih diringkas dengan "+N lagi" di ujung baris kedua. */
.pc-barang{min-width:0;display:flex;flex-direction:column;gap:3px;min-height:47px;justify-content:center}
.pc-brg{display:flex;align-items:baseline;gap:9px;min-width:0;
  font-size:var(--f14);font-weight:500;line-height:22px;height:22px}
.pc-brg-n{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* Sisanya berdiri sebagai keterangan, bukan sebagai nama barang ketiga —
   ukurannya lebih kecil dan warnanya tenang supaya tidak ikut dibaca sebagai
   isi purchase. */
.pc-brg-sisa{flex:none;font-style:normal;font-size:var(--f12);font-weight:400;color:var(--ink-3);
  white-space:nowrap}
.pc-brg--mati .pc-brg-n{text-decoration:line-through;text-decoration-thickness:1px;
  color:var(--ink-3);font-weight:400}
/* Didorong menempel ke dasar kartu dan diberi garis tipis di atasnya: ia
   keterangan tentang kartunya, bukan baris ketiga dari isinya. Garisnya juga
   yang membuat tinggi kartu terbaca sama walau isi di atasnya berbeda. */
.pc-meta{margin-top:auto;padding-top:9px;border-top:1px solid var(--line);
  display:flex;align-items:center;gap:8px;flex-wrap:wrap;font-size:var(--f12);color:var(--ink-3);
  font-family:var(--f-angka)}
.pc-meta > span{display:inline-flex;align-items:center;gap:6px;min-width:0}
.pc-meta svg{width:13px;height:13px;flex:none;opacity:.85}
.pc-meta > i{font-style:normal;opacity:.5}
.pc-kanan{flex:none;width:272px;padding-left:20px;border-left:1px solid var(--line);
  display:flex;flex-direction:column;align-items:flex-end;gap:6px;justify-content:center}
.pc-total{font-family:var(--f-angka);font-size:var(--f16);font-weight:600;letter-spacing:-.01em}
/* Margin dan Biaya berbagi satu baris, dan barisnya tetap berdiri walau
   keduanya kosong. Dulu keduanya baris sendiri-sendiri dan hanya muncul bila
   ada isinya, jadi cip di bawahnya naik-turun satu sampai dua tingkat dari
   kartu ke kartu. */
.pc-catat{display:flex;align-items:baseline;justify-content:flex-end;gap:7px;flex-wrap:nowrap;
  height:18px;line-height:18px;overflow:hidden;font-size:var(--f12);color:var(--ink-3);white-space:nowrap;
  font-family:var(--f-angka)}
.pc-catat i{font-style:normal;opacity:.5}
.pc-catat b{font-weight:500;color:var(--ink-2)}
/* Satu cip satu baris, dan tempatnya dipatok dua baris. Cip yang dibiarkan
   membungkus sendiri melahirkan kartu satu, dua, atau tiga baris tergantung
   panjang angkanya — tinggi kartu jadi tidak bisa ditebak. */
.pc-tags{margin-top:4px;display:flex;flex-direction:column;align-items:flex-end;
  justify-content:flex-end;gap:7px;min-height:55px;flex-wrap:nowrap}
.pc-tagrow{display:flex;align-items:center;gap:6px;max-width:100%}
.chipinfo--lagi{flex:none;color:var(--ink-3);font-weight:500}
/* Keterangan waktu dijaga tetap satu baris. Dibiarkan membungkus, ia menjadi
   dua baris hanya pada sebagian kartu — dan tinggi kartu yang sudah dipatok
   dengan susah payah di kolom kanan kembali berloncatan di kolom tengah. */
@media(max-width:1180px){
  .pc-foto{width:112px;min-height:112px}
  .pc-kanan{width:234px;padding-left:14px}
  .pc-meta{flex-wrap:nowrap;overflow:hidden}
  .pc-meta > span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
}
@media(max-width:900px){
  .pc{flex-wrap:wrap;gap:12px}
  .pc-foto{width:88px;min-height:88px}
  .pc-barang{min-height:0}
  .pc-kanan{flex:1 1 100%;width:auto;padding-left:0;border-left:0;border-top:1px solid var(--line);
    padding-top:11px;align-items:flex-start}
  /* Di layar sempit kartu memang berdiri sendiri-sendiri, jadi tidak ada
     tetangga yang perlu disamakan tingginya. */
  .pc-tags{align-items:flex-start;min-height:0}
  .pc-catat{justify-content:flex-start;height:auto}
}
.chipinfo--stop{border-color:var(--stop-line);background:var(--stop-bg);color:var(--stop);font-weight:600}
.chipinfo--kalem{color:var(--ink-3)}
/* SIAPA YANG DITUNGGU, DIKATAKAN WARNANYA (K-264). Dilaporkan pemiliknya:
   *"statusnya kebanyakan ... kita bingung mana yang harusnya dikerjakan"*.
   Diperiksa, dan yang salah BUKAN jumlah statusnya: satu pembelian memang
   memikul empat hal yang berjalan sendiri-sendiri (dokumennya, barangnya,
   uangnya, komplainnya) dan tidak satu pun bisa dibuang tanpa membuang
   jawabannya. Yang salah, tidak satu pun mengatakan GILIRAN SIAPA. "Kurang
   Rp2.000.000" berarti KITA harus membayar; "Menunggu Diterima 2" berarti kita
   menunggu SUPPLIER — dua keadaan yang berlawanan arah, dan sampai K-264
   keduanya memakai `--nyala` yang sama persis, berdampingan, dengan bentuk
   yang sama.
   PEMBEDANYA PEKAT LAWAN KOSONG, bukan warna baru: yang menuntut kita berbuat
   sesuatu tetap berlatar pekat, yang cuma menunggu pihak lain berubah menjadi
   kosong bergaris. Keduanya sudah ada di dalam sistem ini sejak awal; yang
   belum ada cuma ATURAN siapa memakai yang mana.
   IA DITULIS TERSENDIRI walau hari ini bentuknya sama persis dengan cip polos:
   cip polos berarti "tidak ada yang istimewa", `--tunggu` berarti "bolanya di
   tangan orang lain", dan dua arti yang berbeda tidak boleh menumpang satu
   nama — yang menumpang cepat atau lambat ikut berubah waktu yang ditumpangi
   digeser. */
.chipinfo--tunggu{background:var(--surface-2);border-color:var(--line);color:var(--ink-2)}

/* ------------------------------------------------ batas waktu pelunasan */
.tempo{display:flex;align-items:center;gap:18px;margin:0 0 16px;padding:14px 18px;
  border:1px solid var(--line);border-radius:var(--radius);background:var(--surface)}
.tempo-bd{flex:1;min-width:0}
.tempo-bd b{display:block;font-size:var(--f13);margin-bottom:3px}
.tempo-bd span{display:block;font-size:var(--f12);color:var(--ink-3);line-height:1.55}
.tempo-nilai{flex:none;text-align:right}
.tempo-nilai small{display:block;font-size:var(--f10);text-transform:uppercase;letter-spacing:.05em;
  color:var(--ink-3);margin-bottom:3px}
.tempo-nilai b{font-family:var(--f-angka);font-size:var(--f16);font-weight:600}
.tempo--lewat{border-color:var(--stop-line);background:var(--stop-bg)}
.tempo--lewat .tempo-bd b{color:var(--stop)}
.tempo--hangus{border-color:var(--stop-line)}
.tempo--hangus .tempo-bd b{color:var(--stop)}
/* Tombolnya tetap DI SAMPING KANAN di lebar telepon, tidak turun ke barisnya
   sendiri. Ditumpuk, bilah tempo tumbuh dari 60px menjadi hampir 130px —
   sepertujuh layar telepon untuk satu tanggal dan satu tombol dua suku kata,
   dan Ringkasan Keuangan di bawahnya terdorong keluar layar pertama. Yang
   mengalah cukup keterangannya, yang memang boleh melipat.

   Pengecualiannya bilah "Lewat Batas": di situ tombolnya DUA dan salah
   satunya menutup pesanan — keduanya tidak boleh berdempetan di lajur sempit
   di samping kalimat yang panjang. */
@media(max-width:700px){
  .tempo{gap:12px;padding:13px 14px}
  .tempo > .irow-act{flex:none;align-self:center}
  .tempo--lewat{flex-direction:column;align-items:stretch}
  .tempo--lewat > .irow-act{align-self:flex-end}
}

/* ------------------------------------------------------- judul yang memilih
   Nama kalkulator di BARIS KEPALA sekaligus pemilih jenisnya (tampilan tahap
   1 — dulu judul besar di badan halaman, yang tidak terlihat di telepon sejak
   K-217 dan di layar lebar sejak remah roti dicabut). Nama jenisnya tidak
   diulang lagi sebagai isian di bawah — satu keterangan ditulis satu kali. */
.topjudul--pilih{cursor:pointer}
.topjudul-chev{display:inline-grid;place-items:center;vertical-align:middle;margin-left:6px;
  width:22px;height:22px;border-radius:var(--radius);color:var(--ink-3)}
.topjudul--pilih:hover .topjudul-chev{color:var(--ink);background:var(--surface-2)}
.topjudul-chev svg{width:14px;height:14px;transform:rotate(90deg)}

/* Baris pengaturan pada Atur Tampilan memakai jumlah kolom yang berbeda
   menurut isinya, bukan satu kisi yang dipaksakan untuk semuanya. */
.setbaris--nilai{grid-template-columns:1.2fr 1fr 1.4fr}
.setbaris--mode{grid-template-columns:1.6fr 1fr auto}
.setbaris--field{grid-template-columns:1fr 1.3fr 1.1fr auto}
.setbaris .setakt .btn{padding:0 9px}
@media(max-width:900px){
  .setbaris--nilai,.setbaris--mode,.setbaris--field{grid-template-columns:1fr 1fr}
}

/* ---------------------------------------------------------- pemilih tanggal
   Tiga roda: tanggal, bulan, tahun. Baris tengah adalah yang terpilih, dan
   pita di belakangnya menandai posisi itu supaya tidak perlu ditebak. */
/* TINGGI SATU BARIS HIDUP DI SATU TEMPAT, `--rd`. Lima baris terlihat
   sekaligus — yang terpilih di tengah, dua di atasnya, dua di bawahnya — jadi
   seluruh ukuran roda diturunkan darinya: tingginya 5 baris, jarak isinya 2
   baris, dan pita penandanya setinggi satu baris. Layar telepon cukup
   menggeser satu angka itu (K-119).

   `pasangRoda` MENGUKUR tinggi barisnya dari DOM, bukan menuliskannya lagi
   sebagai angka — kalau tidak, mengecilkan barisnya di sini membuat rodanya
   memilih tanggal yang salah tanpa satu pun pesan. */
.rodabar{--rd:44px;position:relative;display:grid;grid-template-columns:1fr 1.6fr 1fr;gap:0;
  height:calc(var(--rd) * 5);border-top:1px solid var(--line);border-bottom:1px solid var(--line)}
.rodakol{position:relative;height:calc(var(--rd) * 5);overflow:hidden}
/* Setengah atas dan setengah bawah roda bisa ditekan untuk melangkah satu
   baris; kursornya menyatakan arahnya sebelum ditekan. */
.rodanav{position:absolute;left:0;right:0;height:calc(var(--rd) * 2);z-index:3;border:0;background:transparent;padding:0}
.rodanav--atas{top:0;cursor:n-resize}
.rodanav--bawah{bottom:0;cursor:s-resize}
.rodanav:hover::after{content:"";position:absolute;left:50%;transform:translateX(-50%);
  width:0;height:0;border-left:6px solid transparent;border-right:6px solid transparent;opacity:.55}
.rodanav--atas:hover::after{top:12px;border-bottom:7px solid var(--ink)}
.rodanav--bawah:hover::after{bottom:12px;border-top:7px solid var(--ink)}
.roda{height:calc(var(--rd) * 5);overflow-y:auto;scroll-snap-type:y mandatory;scrollbar-width:none;
  -ms-overflow-style:none;position:relative;z-index:2;outline:0}
.roda::-webkit-scrollbar{display:none}
.roda-isi{padding:calc(var(--rd) * 2) 0}
.roda-opt{height:var(--rd);display:flex;align-items:center;justify-content:center;scroll-snap-align:center;
  font-size:var(--rd-f,16px);color:var(--ink-3);cursor:pointer;transition:color .12s,font-weight .12s;user-select:none}
.roda-opt.on{color:var(--ink);font-weight:700}
.roda-band{position:absolute;left:0;right:0;top:calc(var(--rd) * 2);height:var(--rd);background:var(--surface-2);
  border-radius:var(--radius);pointer-events:none;z-index:1}
.rodapesan{margin-top:14px;font-size:var(--f12);color:var(--stop);text-align:center}
.mdl--kirix .mdl-hd{gap:12px}
/* Pop-up tanpa kepala: badannya sendiri yang memberi jarak dari tepi atas. */
.mdl--tanpakepala .mdl-bd{padding-top:18px}
.mdl--kirix .mdl-hd h3{font-size:var(--f16)}
.mdl--kirix .mdl-x{order:-1;border:0;background:transparent}
.mdl--kirix .mdl-x svg{width:22px;height:22px}
.btn--lebar{width:100%;justify-content:center;padding:13px 18px;font-size:var(--f13)}
.rentangbar{display:grid;grid-template-columns:1fr 1fr;gap:0;border-top:1px solid var(--line);
  border-bottom:1px solid var(--line)}
.rentangsel{text-align:left;border:0;border-left:1px solid var(--line);background:transparent;
  padding:16px 18px;font:inherit;color:inherit;cursor:pointer}
.rentangsel:first-child{border-left:0}
.rentangsel:hover{background:var(--surface-2)}
.rentangsel small{display:block;font-size:var(--f12);color:var(--ink-3);margin-bottom:5px}
.rentangsel b{font-family:var(--f-judul);font-size:var(--f16);font-weight:700;letter-spacing:-.01em}

/* Kolom tanggal yang tidak bisa diketik — ia hanya membuka pemilihnya. */
.inp-tgl{display:flex;align-items:center;justify-content:space-between;gap:10px;width:100%;
  cursor:pointer;text-align:left;font:inherit;color:inherit}
.inp-tgl svg{width:16px;height:16px;color:var(--ink-3);flex:none}
.inp-tgl:hover{border-color:var(--line-strong)}
.inp-tgl-v.ph{color:var(--ink-3)}
/* Sebesar isi kotak ketik (13.5px). Selama judulnya berdiri di atas, selisih
   ukurannya tidak terbaca; sejak K-271 namanya tinggal DI DALAM kotak, dan
   kolom tanggal jadi satu-satunya yang berbisik di antara kolom lain. */
.inp-tgl-v{font-size:var(--f12)}
/* Foto pada baris daftar: pembungkusnya yang mengatur ukuran, supaya
   gambar dan kotak kosong sama besarnya. */
.irow > .irow-foto{display:grid;place-items:center;overflow:hidden}
.irow > .irow-foto .thumb{width:100%;height:100%;object-fit:cover;border:0;border-radius:0}
/* Nomor urut rentang menggantikan nama yang tidak pernah dibaca siapa pun. */
.setbaris--harga{grid-template-columns:auto .9fr .9fr .8fr .9fr auto}
.setno{width:26px;height:26px;border-radius:var(--radius);background:var(--surface-2);border:1px solid var(--line);
  display:grid;place-items:center;font-family:var(--f-angka);font-size:var(--f12);
  color:var(--ink-3);margin-top:22px}
.setbaris .btn--ikon{width:32px;height:32px;padding:0}
.setbaris .btn--ikon svg{width:14px;height:14px}
@media(max-width:900px){.setbaris--harga{grid-template-columns:auto 1fr 1fr}}

/* Seret foto: kursor menyatakan sejak awal bahwa sel ini bisa dipindahkan,
   dan bayangannya mengikuti jari supaya tempat mendaratnya jelas. */
/* `pan-y`, BUKAN `none`. Dengan `none` papan foto tidak bisa digulir sama
   sekali: jari yang hendak menggulir ke bawah selalu mendarat di atas sebuah
   foto lebih dulu, dan yang terjadi bukan menggulir melainkan menyeret. Gulir
   menurun kini lewat apa adanya, dan seret baru mulai sesudah ditekan dan
   ditahan sebentar (lihat photo.js — yang menahan gulir SESUDAH tahanannya
   genap adalah preventDefault pada touchmove, bukan touch-action, karena
   touch-action hanya dibaca pada detik jari menyentuh). */
/* SEJAK K-282 `touch-action`-NYA DIBIARKAN (bukan `pan-y`): sentilan mendatar
   di atas bidang `pan-y` membuat peramban menelan ketukan berikutnya di mana
   pun — lihat catatan `pasangKorsel` di photo.js. Yang menahan gulir tetap
   `preventDefault` sesudah tahanannya genap, jadi seretnya tidak berubah. */
.fotocell{cursor:grab}
/* Fotonya menyusut sedikit begitu tahanannya genap — satu-satunya tanda bahwa
   ia sekarang mengikuti jari, dan orangnya tahu itu sebelum menggerakkannya. */
.fotocell--siap{transform:scale(.94);transition:transform .12s ease}
body.sedang-seret{touch-action:none;overscroll-behavior:contain}
.fotocell:active{cursor:grabbing}
.fotocell .util button{cursor:pointer}
body.sedang-seret{cursor:grabbing;user-select:none}
.fotocell--bayang{position:fixed;z-index:9999;pointer-events:none;opacity:.9;
  transform:scale(1.04);box-shadow:0 12px 28px rgba(0,0,0,.28);border-radius:var(--radius)}
.fotocell--seret{opacity:.35}
.fotocell--target{outline:2px solid var(--ink);outline-offset:2px}

/* Titik kepekaan modul. Warnanya dikunci di kode, bukan disetel per
   perusahaan — warna hanya berguna selama artinya tidak berpindah-pindah. */

/* Aksi yang menempel pada seksinya sendiri, bukan menumpuk di kepala
   dokumen — supaya jelas tombol ini bekerja pada tabel mana. */

/* --------------------------------------------------------------- lampiran */
/* Kolom telepon: satu kotak, benderanya menempel di dalamnya. Bendera bukan
   tombol dan bukan dropdown — ia hanya memantulkan apa yang sedang diketik,
   jadi ia tidak boleh terlihat bisa diklik. */
.inp-tel{display:flex;align-items:center;gap:0}
.inp-tel .tel-bendera{flex:none;font-size:var(--f14);line-height:1;padding:0 9px 0 2px;
  border-right:1px solid var(--line);margin-right:9px;user-select:none}
.inp-tel input{font-family:var(--f-angka);letter-spacing:.01em}

.lampiran{border:1px solid var(--line);border-radius:var(--radius);background:var(--surface);padding:16px 18px}
.lampiran-jud{font-family:var(--f-judul);font-size:var(--f13);font-weight:600;margin:0 0 10px}
.lampiran-jud + .lampiran-teks,.lampiran-foto + .lampiran-jud{margin-top:0}
.lampiran-foto{display:flex;gap:10px;flex-wrap:wrap;margin-bottom:18px}
.lampiran-foto img{width:110px;height:110px;object-fit:cover;border-radius:var(--radius);
  border:1px solid var(--line);cursor:zoom-in}
.lampiran-teks{font-size:var(--f12);line-height:1.6;color:var(--ink-2);white-space:pre-wrap}
.lampiran-oleh{margin:10px 0 0;font-size:var(--f12);line-height:16px;min-height:16px;
  color:var(--ink-3);font-family:var(--f-angka)}

/* Warna hak akses. Warnanya berhenti di tepi kotaknya sendiri — tidak
   mewarnai apa pun di luar kotak itu, supaya halaman tidak ikut menyala. */
:root{ --oren:#9a4f10; --oren-bg:#fdf0e2; --oren-line:#efc79b;
       --kuning:#7a5c00; --kuning-bg:#fdf6de; --kuning-line:#e6d38a; }
@media (prefers-color-scheme: dark){ :root:not([data-theme="light"]){
  --oren:#e79a55; --oren-bg:#2c1d10; --oren-line:#5b3a1b;
  --kuning:#d9bf62; --kuning-bg:#282214; --kuning-line:#544726; } }
:root[data-theme="dark"]{ --oren:#e79a55; --oren-bg:#2c1d10; --oren-line:#5b3a1b;
  --kuning:#d9bf62; --kuning-bg:#282214; --kuning-line:#544726; }

.modblok--merah{border-color:var(--stop-line);background:var(--stop-bg)}
.modblok--oren{border-color:var(--oren-line);background:var(--oren-bg)}
.modblok--kuning{border-color:var(--kuning-line);background:var(--kuning-bg)}
.modblok--merah.modblok--on{border-color:var(--stop)}
.modblok--oren.modblok--on{border-color:var(--oren)}
.modblok--kuning.modblok--on{border-color:var(--kuning)}
.modblok .modanak{background:var(--surface);border-radius:var(--radius);margin-left:26px;padding:10px 12px}

/* Label warna pada chip modul di kartu peran, dan pada kartu perannya. */
.chipinfo--merah{border-color:var(--stop-line);background:var(--stop-bg);color:var(--stop)}
.chipinfo--oren{border-color:var(--oren-line);background:var(--oren-bg);color:var(--oren)}
.chipinfo--kuning{border-color:var(--kuning-line);background:var(--kuning-bg);color:var(--kuning)}
.irow--merah{border-left:3px solid var(--stop)}
.irow--oren{border-left:3px solid var(--oren)}
.irow--kuning{border-left:3px solid var(--kuning)}
/* Label peran pada kartu pegawai dan pada detailnya. Warnanya diambil dari
   warna kepekaan yang sudah disetel di Hak Akses Peran — dulu kelasnya
   ditulis tetapi gayanya tidak pernah ada, jadi labelnya tetap abu. */
.tag--merah{border-style:solid;border-color:var(--stop-line);background:var(--stop-bg);color:var(--stop)}
.tag--oren{border-style:solid;border-color:var(--oren-line);background:var(--oren-bg);color:var(--oren)}
.tag--kuning{border-style:solid;border-color:var(--kuning-line);background:var(--kuning-bg);color:var(--kuning)}
.chipopt--merah.on{background:var(--stop);border-color:var(--stop);color:#fff}
.chipopt--oren.on{background:var(--oren);border-color:var(--oren);color:#fff}
.chipopt--kuning.on{background:var(--kuning);border-color:var(--kuning);color:#fff}
.setbaris--warna{grid-template-columns:1.4fr 1fr;align-items:center}
.setbaris--warna .setsel label{text-transform:none;font-size:var(--f12);color:var(--ink);letter-spacing:0;margin:0}
.btn--ikon svg{width:15px;height:15px}
/* Pilihan yang sudah terpakai tetap terlihat supaya orang tahu ia ada,
   tetapi tidak bisa dipilih dua kali. */
/* Pilihan yang membawa ikon keadaan. Ikonnya berwarna menurut keadaannya,
   dan yang sedang berlaku ditandai centang di ujung kanan — tebal saja
   ternyata tidak cukup terbaca saat lima baris berdempetan. */
.combo-opt--ik{align-items:center}
.combo-ik{flex:none;display:grid;place-items:center;width:17px;height:17px;color:var(--ink-3)}
.combo-ik svg{width:15px;height:15px}
.combo-ik--wait{color:var(--wait)}
.combo-ik--run{color:var(--run)}
.combo-ik--done{color:var(--done)}
.combo-ik--stop{color:var(--stop)}
.combo-ik--send{color:var(--send)}
.combo-ck{flex:none;display:grid;place-items:center;width:15px;height:15px;color:var(--wait)}
.combo-ck svg{width:14px;height:14px}
.combo-opt--mati{opacity:.45;cursor:not-allowed}
.combo-opt--mati:hover{background:transparent}
/* Baris item pada dokumen penjualan diperbesar supaya fotonya terbaca —
   di situlah orang mengenali barangnya, bukan dari namanya saja. */
.irow--besar{padding:14px 16px}
.irow > .irow-foto--besar{width:66px;height:66px;border-radius:var(--radius)}
/* Penolakan berwarna merah: ia bukan keterangan biasa, melainkan jalan
   buntu yang harus terbaca sebelum orang menekan tombol simpan. */
.notice--tolak{border-color:var(--stop-line);background:var(--stop-bg)}
.notice--tolak b{color:var(--stop)}

/* --------------------------------------------------------------- gaji
   Layar aturan gaji memakai bentuk pengaturan yang sama dengan Online Shop:
   satu grup, banyak baris, satu kaki penyimpan. Yang berbeda hanya jumlah
   kolomnya, karena isian tiap rule memang tidak sama banyaknya. */
.setgrup-kepala--aksi{display:flex;align-items:center;gap:14px}
.setgrup-kepala--aksi .tumbuh{flex:1;min-width:0}
.setbaris--dasar{grid-template-columns:1fr 1fr 1fr}
.setbaris--komp{grid-template-columns:auto 1.5fr 1fr 1.6fr 1fr auto}
.setbaris--tingkat{grid-template-columns:auto 1fr 1fr 1.4fr 1fr auto}
.setbaris--rentang{grid-template-columns:auto 1fr auto}
/* Baris tangga di kartu Target Insentif (K-295): label di kiri, batas di kanan.
   Tanpa garis tegak `.dok-kanan` — garis itu memisahkan nama dari nominal, dan
   di sini tidak ada yang dipisahkan. Nilainya boleh turun baris: empat rentang
   rupiah tidak muat sebaris di telepon. */
.tgbaris{display:flex;justify-content:space-between;align-items:baseline;gap:12px;min-width:0;padding:2px 0}
.tgbaris span{flex:none;font-size:var(--f12);color:var(--ink-3)}
.tgbaris b{min-width:0;font-size:var(--f12);font-weight:500;font-variant-numeric:tabular-nums;
  text-align:right;overflow-wrap:anywhere}
/* Sebutan sub-blok di dalam satu blok pengaturan (K-195, dipakai tiga tangga insentif sejak K-295):
   sebentuk dengan sebutan seksi Detail Pembayaran (`.drwsub--rinci`) —
   kecil, huruf besar, berjarak, dan berdiri di atas barisnya sendiri. */
.setsub{padding:14px 18px 0;font-size:var(--f11);font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--ink-3)}
.setbaris--hadir{grid-template-columns:1.3fr 1fr 1.4fr}
/* Baris item pada Pembelian Baru. Nama item ditulis apa adanya oleh orangnya
   dan hampir selalu panjang, jadi ia mendapat dua kali lebar kolom harganya. */
/* Lajur tombol hapus DIPATOK selebar tombolnya, bukan `auto`. Dengan `auto`
   lajur itu menciut jadi nol pada baris pertama — yang memang tidak punya
   tombol hapus — jadi kolom Harga baris pertama mulai 21 piksel lebih kanan
   daripada baris kedua, dan tepi kanan keduanya tidak lurus. Dipatok, setiap
   baris berkolom sama persis. */
/* Sejak R4 (K-308) baris itemnya berkolom nomor · nama · harga · foto · hapus:
   lajur foto memuat tombol Kamera/Galeri atau gambar kecilnya. Di layar telepon
   semuanya bertumpuk lewat aturan `.setsel{grid-column:1/-1}` di bawah. */
.setbaris--beli{grid-template-columns:auto 2fr 1fr 1.4fr 30px}
/* BERKAS PEGAWAI (K-155). Bentuknya BARIS, bukan papan foto persegi: yang
   membedakan satu berkas dari berkas lain bukan gambarnya — scan KTP dan scan
   ijazah sama-sama selembar kertas putih — melainkan JENISNYA. Jadi gambar
   kecilnya cuma penanda di ujung kiri, dan yang dibaca tulisannya. */
.berkaslist{border:1px solid var(--line);border-radius:10px;overflow:hidden}
.berkasrow{display:flex;align-items:center;gap:10px;padding:8px 10px;
  border-bottom:1px solid var(--line)}
.berkasrow:last-child{border-bottom:0}
.berkasfoto{width:38px;height:38px;flex:none;border-radius:6px;object-fit:cover;
  border:1px solid var(--line);background:var(--bg-2);cursor:pointer}
.berkasnm{display:flex;flex-direction:column;min-width:0;flex:1 1 auto;font-size:var(--f12)}
.berkasnm i{font-style:normal;font-size:var(--f11);color:var(--ink-3);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.berkasjejak{flex:none;font-size:var(--f11);color:var(--ink-3);text-align:right}
.setbaris--berkas{grid-template-columns:38px 1fr 1.2fr auto;align-items:end}
.setbaris--berkas .berkasfoto{align-self:center}
@media(max-width:560px){
  .berkasjejak{display:none}
  .setbaris--berkas{grid-template-columns:38px 1fr auto}
}
/* RIWAYAT PERISTIWA PEGAWAI (K-156). Satu kotak dipisah garis, bukan sederet
   kartu terpisah — aturan yang sama dengan daftar item sebuah dokumen: yang
   dibaca orang adalah DAFTARNYA, dan sederet kotak membuat mata menghitung
   kotak alih-alih menyusuri riwayat. */
.prwlist{border:1px solid var(--line);border-radius:10px;overflow:hidden}
.prwlist > .muted{display:block;padding:12px;font-size:var(--f12)}
.prwrow{padding:10px 12px;border-bottom:1px solid var(--line)}
.prwrow:last-child{border-bottom:0}
/* Yang DIBATALKAN tetap berdiri — History First — tetapi ditenangkan: ia
   keterangan tentang sesuatu yang tidak jadi terjadi. */
.prwrow--batal{opacity:.62}
.prwrow-kp{display:flex;align-items:center;gap:8px;font-size:var(--f12)}
.prwrow-kp b{font-weight:650}
.prwrow-batal{margin-left:auto;flex:none}
.prwrow-sas{margin-top:2px;font-size:var(--f12)}
.prwrow-sas i{font-style:normal;color:var(--ink-3);margin:0 4px}
.prwrow-al{margin-top:3px;font-size:var(--f12);color:var(--ink-2)}
/* Jejaknya TENANG dengan sengaja (11,5px): ia keterangan tentang siapa dan
   kapan, sementara yang dicari orang di baris itu peristiwanya sendiri. */
.prwrow-jejak{margin-top:3px;font-size:var(--f11);color:var(--ink-3)}

/* HASIL SIMULASI GAJI (Aturan Gaji › Simulasi Gaji).
   Bentuknya meniru kartu gaji yang sungguhan — nama komponen di kiri beserta
   catatannya, nominal rata kanan, kesimpulan di baris terakhir — karena yang
   dijawabnya memang "kartunya nanti berbunyi apa". */
.simhasil{border:1px solid var(--line);border-radius:10px;margin-top:12px;
  background:var(--bg-2);overflow:hidden}
.simhasil-kepala{display:flex;justify-content:space-between;gap:10px;
  padding:8px 12px;border-bottom:1px solid var(--line);
  font-size:var(--f11);letter-spacing:.04em;text-transform:uppercase;color:var(--ink-3)}
.simrow{display:flex;align-items:flex-end;justify-content:space-between;gap:12px;
  padding:7px 12px;border-bottom:1px solid var(--line)}
.simrow:last-child{border-bottom:0}
.simrow-n{display:flex;flex-direction:column;min-width:0;font-size:var(--f12)}
.simrow-n i{font-style:normal;font-size:var(--f11);color:var(--ink-3)}
.simrow b{font-size:var(--f12);white-space:nowrap;font-variant-numeric:tabular-nums}
.simrow--total{background:var(--bg-1)}
.simrow--total .simrow-n{font-weight:600}
.simrow--total b{font-size:var(--f14)}

/* JAWABAN SATU BARIS PENGATURAN, melintasi seluruh lajurnya.
   Ia keterangan tentang AKIBAT isian di atasnya — dalam rupiah, bukan sebagai
   kalimat panduan — jadi ia tenang dan berdiri di bawah isiannya, bukan
   berebut tempat dengan label. */
.sethasil{grid-column:1/-1;font-size:var(--f11);color:var(--ink-3);
  border-top:1px dashed var(--line);padding-top:6px;margin-top:2px}
.setbaris--hadir .chipset{gap:6px}
.setbaris--hadir .chipopt{padding:8px 14px}
@media(max-width:900px){
  .setbaris--dasar,.setbaris--komp,.setbaris--tingkat,.setbaris--hadir{grid-template-columns:1fr 1fr}
}

/* --------------------------------------------------------------- pegawai
   Kepala halaman detail pegawai: wajah di kiri, nama dan penempatan di
   kanan. Foto berbentuk bulat dan sekaligus menjadi tombol menggantinya —
   pensilnya menempel di sudut, tidak melayang di luar lingkaran. */
.pegkepala{display:flex;align-items:center;gap:16px;min-width:0}
.pegfoto{position:relative;flex:none;width:76px;height:76px;border-radius:50%;overflow:hidden;
  border:1px solid var(--line);background:var(--surface-2);padding:0;cursor:pointer;display:block}
.pegfoto img{width:100%;height:100%;object-fit:cover;display:block}
.pegfoto-edit{position:absolute;right:0;bottom:0;width:26px;height:26px;border-radius:50%;
  background:var(--ink);color:var(--on-ink);display:grid;place-items:center;border:2px solid var(--surface)}
.pegfoto-edit svg{width:12px;height:12px}
.pegfoto:hover{border-color:var(--ink)}
/* Yang belum berfoto memakai inisial namanya, bukan kotak kosong. */
.avatarhuruf{display:grid;place-items:center;width:100%;height:100%;background:var(--surface-2);
  font-family:var(--f-judul);font-size:var(--f13);font-weight:600;color:var(--ink-2);letter-spacing:.02em}
.avatarhuruf--lg{font-size:var(--f18)}
/* Foto pegawai pada kartu daftar: <img> tanpa kelas pun harus tetap
   memenuhi kotaknya. */
.irow > .irow-foto > img{width:100%;height:100%;object-fit:cover;display:block}
@media(max-width:600px){
  .pegkepala{gap:12px}
  .pegfoto{width:62px;height:62px}
  .avatarhuruf--lg{font-size:var(--f16)}
}

/* --------------------------------------------------- titik lokasi di peta
   Tiga angka yang hanya berguna bersama-sama, jadi ia satu blok, bukan tiga
   kolom yang berjauhan. */
.pingrid{display:grid;grid-template-columns:1fr 1fr .8fr auto;gap:12px;align-items:end}
.pingrid .setsel label{display:block;font-size:var(--f11);font-weight:600;color:var(--ink-3);
  margin-bottom:5px;text-transform:uppercase;letter-spacing:.04em}
.pingrid .btn{width:100%}
@media(max-width:760px){ .pingrid{grid-template-columns:1fr 1fr} .pingrid .setsel:last-child{grid-column:1/-1} }
.pinbaris{display:inline-flex;align-items:center;gap:10px;flex-wrap:wrap;justify-content:flex-end}

/* CIP POTONGAN DI SEBELAH HARGA KARTU (K-274; dulu menimpa foto, K-259).
   `.kartuvoucher` — keping bernama voucher yang dulu berdiri di barisnya
   sendiri di bawah harga — sudah dicabut sejak K-259.

   Ia MERAH karena potongan harga adalah arah uang. Sejak ia pindah dari atas
   foto ke badan kartu, merahnya kembali memakai TOKEN (`--stop`): alasan
   merah patok K-259 — foto tidak punya mode gelap — tidak berlaku lagi di
   atas permukaan kartu. Bergaris tipis tanpa alas, supaya ia tidak berebut
   berat dengan harganya. */
.tandadisk{display:inline-flex;align-items:center;gap:2px;flex:none;align-self:center;
  height:18px;padding:0 4px;border:1px solid var(--stop-line);border-radius:4px;color:var(--stop);
  font-family:var(--f-angka);font-size:var(--f10);font-weight:700;letter-spacing:0;white-space:nowrap}
.tandadisk svg{width:11px;height:11px;flex:none}

/* BURAM `fotokasar` (K-259) DICABUT (K-273, diralat pemiliknya: "saya ralat
   keputusan saya yang fotonya tampil dengan buram dulu baru pertajam ... foto
   yang udah ada di card tinggal ditampilkan"). Gambar kecil yang SAMA dengan
   foto kartunya tampil apa adanya — ia sudah di tembolok peramban, jadi tidak
   ada yang dimuat — lalu gambar besarnya menggantikannya diam-diam sesudah
   tiba (`tajamkan` di photo.js). Tidak ada tanda "belum selesai" sama sekali. */

/* Korsel Online Shop memakai kotak foto yang sama dengan detail unit.
   `touch-action` TIDAK ditulis di mana pun untuk korsel: sejak K-282
   `Foto.pasangKorsel` menahan `touchmove` yang mendatar sendiri — `pan-y`
   membuat ketukan sesudah geseran hilang (lihat catatannya di photo.js). */
.pdp-utama.itemfoto-utama{aspect-ratio:1/1;overflow:hidden}

/* Deretan penanda di kaki kartu master. */
.lc-tanda{display:flex;gap:6px;align-items:center;flex-wrap:wrap;min-width:0}

/* ------------------------------------------------------------ margin
   Margin bukan yang dicari orang saat membuka dokumen, jadi ia turun dari
   kepala halaman dan menempel pada Biaya — angka yang membentuknya. Bentuknya
   satu baris tipis, bukan kartu, supaya ia tidak berebut perhatian dengan
   barang dan uang. */
.marginbaris{display:flex;align-items:center;gap:12px;width:100%;margin-top:10px;
  padding:11px 14px;border:1px dashed var(--line-strong);border-radius:var(--radius);
  background:transparent;cursor:pointer;text-align:left;color:inherit}
.marginbaris:hover{border-style:solid;background:var(--surface-2)}
.marginbaris-k{font-size:var(--f12);color:var(--ink-2)}
.marginbaris-v{margin-left:auto;font-family:var(--f-angka);font-size:var(--f13);
  font-weight:600;font-variant-numeric:tabular-nums;white-space:nowrap}
.marginbaris-s{display:inline-flex;align-items:center;gap:4px;font-size:var(--f12);color:var(--ink-3);white-space:nowrap}
.marginbaris-s svg{width:13px;height:13px}
@media(max-width:600px){
  .marginbaris{flex-wrap:wrap;gap:6px}
  .marginbaris-v{margin-left:auto}
  .marginbaris-s{width:100%;justify-content:flex-end}
}

/* Satu baris di atas daftar: berapa yang tampil, dan angka yang ikut
   saringan itu. Menggantikan kartu ringkasan besar yang dulu memakan
   sepertiga layar sebelum satu baris data pun terbaca. */
.daftarhead{display:flex;align-items:baseline;gap:12px;flex-wrap:wrap;
  margin:0 0 10px;font-size:var(--f12);color:var(--ink-3)}

/* ---------- baris hitungan yang berubah menjadi baris tindakan ----------
   Satu baris, dua isi. Bilah gelap melintang yang dulu muncul di atas daftar
   sudah dicabut: ia menambah satu benda setinggi 44px di layar telepon,
   membawa kalimat yang cuma mengulang apa yang sudah dikatakan tombolnya, dan
   mendorong kartu pertama keluar dari layar pertama. */
.daftarhead--aksi{align-items:center;gap:10px;flex-wrap:nowrap;min-height:32px}
/* Kedua tulisan menempati PETAK yang sama, jadi yang satu bisa bergeser keluar
   sementara yang lain bergeser masuk tanpa barisnya ikut melompat. */
.daftarhead-slot{flex:1 1 auto;min-width:0;display:grid}
.daftarhead-slot > *{grid-area:1/1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  transition:transform .22s ease,opacity .22s ease}
.daftarhead-p{transform:translateX(-16px);opacity:0;font-weight:600;color:var(--ink)}
.daftarhead--pilih .daftarhead-n{transform:translateX(-16px);opacity:0}
.daftarhead--pilih .daftarhead-p{transform:none;opacity:1}
/* display:none saat mode Pilih mati — bukan sekadar disembunyikan. Dibiarkan
   berdiri tak terlihat, keempat tombolnya tetap memakan lebar, dan di layar
   telepon barisnya melewati tepi halaman padahal tidak ada yang terlihat di
   sana. Geserannya dipasang sebagai ANIMASI, bukan transisi: elemen yang baru
   berpindah dari display:none memang memulai animasinya dari awal. */
.daftarhead-aksi{display:none}
/* Tombol yang berdiri di ujung kanan baris hitungan — bukan tombol mode Pilih
   (itu `.daftarhead-aksi`, yang memang tersembunyi sampai modenya menyala),
   melainkan tindakan tetap halaman yang turun dari kepala halaman ke sini. */
.daftarhead-tombol{margin-left:auto;flex:none;display:flex;align-items:center;gap:8px}
.daftarhead--pilih .daftarhead-aksi{flex:none;display:flex;align-items:center;gap:8px;
  animation:aksiMasuk .24s ease}
@keyframes aksiMasuk{from{opacity:0;transform:translateX(22px)}to{opacity:1;transform:none}}
.daftarhead-pisah{width:1px;align-self:stretch;background:var(--line);margin:0 2px}
/* "Pilih Semua" diringkas menjadi satu petak centang bertulisan "Semua":
   di lebar telepon, empat tombol berkata-kata memakan dua baris penuh sebelum
   satu kartu pun terlihat. */
.btn--pilihsemua{gap:7px}
.btn--pilihsemua > i{width:15px;height:15px;flex:none;border:1.5px solid var(--line-strong);
  border-radius:var(--radius);display:grid;place-items:center;background:var(--surface)}
.btn--pilihsemua[aria-pressed="true"] > i{background:var(--ink);border-color:var(--ink)}
.btn--pilihsemua[aria-pressed="true"] > i::after{content:"";width:7px;height:4px;
  border-left:2px solid var(--on-ink);border-bottom:2px solid var(--on-ink);
  transform:rotate(-45deg) translate(1px,-1px)}
/* Di lebar telepon kata-katanya dilepas; ikonnya yang tinggal, dan ketiga
   tindakan tetap berdiri di baris yang sama. */
@media (max-width:620px){
  .daftarhead-aksi .btn > span{display:none}
  .btn--pilihsemua{padding:0 9px}
}
.daftarhead-nilai{margin-left:auto;display:inline-flex;align-items:baseline;gap:7px;white-space:nowrap}
.daftarhead-nilai b{font-family:var(--f-angka);font-size:var(--f13);
  font-weight:600;font-variant-numeric:tabular-nums}
@media(max-width:600px){ .daftarhead-nilai{margin-left:0;width:100%} }

/* Pop-up pemotong foto tidak boleh punya gulir sendiri: menggulirnya
   menggeser kanvas saat orang sedang menyeret gambarnya. Kotaknya sudah
   dihitung agar muat, jadi gulirnya cukup dimatikan. */
.mdl-bd:has(.cropwrap){overflow:hidden;overscroll-behavior:none}
.cropwrap{touch-action:none}

/* Blok di dalam satu seksi. Biaya dan pembayaran dulu dua seksi terpisah
   padahal keduanya bercerita tentang satu hal: uang pada dokumen ini.
   Sebagai blok, keduanya tetap punya judul sendiri tanpa memutus ceritanya. */

/* Kartu yang berupa tautan tidak digarisbawahi. Garis bawah dipakai untuk
   kata yang bisa diklik di dalam kalimat, bukan untuk kotak yang seluruhnya
   sudah jelas bisa ditekan. */
a.stat, a.stat *, a.lcard, a.lcard *, a.tokocard, a.tokocard *{text-decoration:none}

/* --------------------------------------------------- combo berwarna
   Dipakai pada Atur Warna Hak Akses. Di dalam daftarnya, nama warnanya
   diblok memakai warna itu sendiri — membaca kata "Merah" jauh lebih lambat
   daripada melihat merahnya. Setelah terpilih, bingkai kolomnya ikut
   berwarna supaya yang berlaku terbaca tanpa membuka daftarnya lagi. */
.combo-opt--w .t{display:inline-block;padding:2px 9px;border-radius:var(--radius);font-weight:500}
.combo-opt--merah .t{background:var(--stop-bg);color:var(--stop);box-shadow:inset 0 0 0 1px var(--stop-line)}
.combo-opt--oren .t{background:var(--oren-bg);color:var(--oren);box-shadow:inset 0 0 0 1px var(--oren-line)}
.combo--merah .combo-btn{border-color:var(--stop);box-shadow:inset 0 0 0 1px var(--stop)}
.combo--oren .combo-btn{border-color:var(--oren);box-shadow:inset 0 0 0 1px var(--oren)}
.combo--merah .combo-btn > span:first-child{color:var(--stop);font-weight:500}
.combo--oren .combo-btn > span:first-child{color:var(--oren);font-weight:500}

/* ------------------------------------------------------------ halaman Saya
   Tiga kartu di kepala halaman: yang mendesak tidak boleh bersembunyi di
   balik tab. Bentuknya sama dengan .stat tetapi berisi tindakan, jadi ia
   perlu ruang bawah untuk tombolnya. */
.sayakartu{display:flex;flex-direction:column;gap:4px;min-height:132px;
  padding:15px 16px;border:1px solid var(--line);border-radius:var(--radius);background:var(--surface)}
.sayakartu--attn{border-color:var(--ink)}
.sayakartu-k{font-size:var(--f11);font-weight:600;color:var(--ink-3);text-transform:uppercase;letter-spacing:.05em}
.sayakartu-v{font-family:var(--f-judul);font-size:var(--f18);font-weight:700;
  letter-spacing:-.02em;line-height:1.2;overflow-wrap:anywhere}
.sayakartu-s{font-size:var(--f12);color:var(--ink-3);line-height:1.5;overflow-wrap:anywhere}
@media(max-width:900px){ .sayakartu{min-height:0} }

/* ---------- kartu transfer di atas kerangka .dok ---------------------------
   Ia memakai kelas .dok apa adanya; yang ditulis di sini cuma yang memang
   berbeda kenyataannya.

   Kartu DAFTAR ITEM tidak lagi ada di sini — sejak K-104 ia punya bentuknya
   sendiri (`.ukartu`, di bawah) — dan kartu ITEM RETUR menyusul ke sana pada
   K-114. Seluruh gaya `.dok--unit` DICABUT bersamanya: begitu sebuah keadaan
   tidak bisa lahir lagi, kodenya ikut hilang. Yang pernah dipelajarinya tetap
   tercatat di `prototipe/CLAUDE.md`. */
/* SELURUH kartu membuka dokumennya. Kepala, foto, dan kaki semuanya
   menerangkan satu hal yang sama, jadi tidak masuk akal kalau cuma sepertiga
   tengahnya yang bisa ditekan. Tombol di dalamnya tetap miliknya sendiri —
   penanganannya membuang penekanan yang lahir dari sebuah tombol. Dipakai
   kartu Daftar Komplain. */
.dok--klik{cursor:pointer;transition:border-color .14s}
.dok--klik:hover{border-color:var(--line-strong)}
.dok--klik:focus-visible{outline:2px solid var(--ink);outline-offset:2px}

/* ================= KARTU DAFTAR ITEM: fotonya yang mengenalkan (K-104) =====
   Diminta pemiliknya, dan ia menyebutkan sebabnya lebih dulu: "sulitnya
   membedakan halaman satu dengan halaman lain, awalnya saya mengira desain itu
   mutlak harus konsisten, ternyata ada batasannya."

   Ia benar, dan batasnya bisa disebut. Konsistensi menolong selama dua daftar
   menjawab pertanyaan yang SAMA. Daftar Pembelian, Penjualan, dan Servis
   memang begitu — ketiganya berisi DOKUMEN, dan yang dicari orang di sana nama
   pihaknya, tanggalnya, dan nilainya. Daftar Item tidak: yang berdiri di sana
   BARANG, dan barang dikenali dari gambarnya sebelum dari namanya. Kartu
   dokumen menaruh foto 58px di samping teks — ukuran yang cukup untuk
   mengatakan "ada fotonya", tidak cukup untuk mengenali HP-nya.

   Bentuknya karena itu bentuk katalog: foto selebar kartu di atas, nama di
   bawahnya, harga, lalu keterangan tempat dan keadaannya di kaki. Dan DUA
   LAJUR di lebar mana pun, telepon sekalipun (diminta pemiliknya) — kartu
   bergambar yang berdiri sendiri-sendiri memaksa menggulir dua kali lebih
   jauh untuk daftar yang sama. */
.ukartu{background:var(--surface);border:1px solid var(--line);border-radius:var(--radius);
  overflow:hidden;display:flex;flex-direction:column;cursor:pointer;transition:border-color .14s}
.ukartu:hover{border-color:var(--line-strong)}
.ukartu:focus-visible{outline:2px solid var(--ink);outline-offset:2px}
.ukartu.on{border-color:var(--ink);background:var(--surface-2)}
/* Fotonya 1:1 dan selebar kartunya penuh — tanpa jarak di kiri, kanan, dan
   atas. Nisbahnya dipatok supaya tinggi setiap kartu sama walau fotonya
   berbeda-beda bentuk; yang lebih tinggi atau lebih lebar dipotong di
   tengahnya (`object-fit:cover`), bukan digepengkan. */
.ukartu-foto{display:block;position:relative;width:100%;aspect-ratio:1/1;
  background:var(--surface-2);border-bottom:1px solid var(--line)}
.ukartu-foto img{width:100%;height:100%;object-fit:cover;display:block}
.ukartu-nofoto{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;color:var(--ink-3)}
/* KEADAAN BARANGNYA MENUMPANG DI POJOK KANAN ATAS FOTO (diminta pemiliknya).
   Di kaki kartu ia berebut lebar dengan nama lokasi — satu-satunya keterangan
   di baris itu yang dipakai mencari barang — sementara di atas foto tidak ada
   apa pun yang ia halangi. Latarnya dipadatkan menjadi warna kartu supaya ia
   tetap terbaca di atas foto seterang atau segelap apa pun; warna keadaannya
   tetap hidup di ikon, tulisan, dan garis tepinya. */
.ukartu-st{position:absolute;top:6px;right:6px;z-index:1;
  display:flex;flex-wrap:wrap;justify-content:flex-end;gap:4px;max-width:calc(100% - 12px)}
.ukartu-st .pill{background:var(--surface);box-shadow:0 1px 5px -1px rgba(0,0,0,.35)}
.ukartu-st .chipinfo{background:var(--surface);box-shadow:0 1px 5px -1px rgba(0,0,0,.35)}
/* CIP YANG MENYALA DI ATAS FOTO (K-275, dilaporkan pemiliknya dengan tangkapan
   layar: "kenapa ada card yang ada hitam2 di fotonya"). Aturan di atas
   memberi SETIAP cip latar `--surface`, sementara tulisan cip yang menyala
   `--on-ink` — terang di atas terang pada mode terang, gelap di atas gelap
   pada mode gelap: "Belum Ketemu" tidak terbaca di keduanya. Hitam PATOK,
   sama dengan tanda garansi di kartu etalase: foto tidak punya mode gelap. */
.ukartu-st .chipinfo--nyala{background:rgba(21,21,23,.86);border-color:transparent;color:#fff}
.ukartu-bd{padding:8px 9px 0;display:flex;flex-direction:column;gap:3px}
/* Nama barang DUA baris penuh lalu titik tiga, dan tingginya DIPATOK dua baris
   walau namanya cuma satu — kartu bergambar berjajar dua lajur, dan yang
   sebelah kiri tidak boleh berdiri lebih pendek daripada yang di kanannya. */
/* Nama barang TIDAK tebal (diminta pemiliknya, "samakan Shopee"): di kartu
   katalog yang berhak menonjol adalah HARGANYA — nama barangnya sudah dibaca
   lebih dulu karena ia berdiri tepat di bawah fotonya. */
.ukartu-nama{font-size:var(--f12);font-weight:400;line-height:17px;height:34px;overflow:hidden;
  color:var(--ink);display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}
/* Harga mepet kiri, batasnya kecil DI SEBELAH KANANNYA — satu baris, seperti
   harga dan cip diskon pada kartu Shopee yang dipakai pemiliknya sebagai
   contoh. Yang membuatnya muat di kartu selebar setengah layar telepon:
   sebutan "Batas" diganti IKONNYA (lima huruf itu persis yang tidak muat),
   dan angkanya tidak memakai huruf mesin ketik — mono 12 huruf sendirian
   sudah menghabiskan lebar kartunya.

   Barisnya TIDAK BOLEH MELIPAT (`nowrap`): yang muat pada satu kartu dan
   tidak muat pada kartu sebelahnya membuat tinggi keduanya berbeda, dan
   daftar yang tingginya berloncatan tidak bisa disusuri sambil menggulir
   cepat. Yang mengalah bila benar-benar sempit adalah BATASNYA, dan ia
   mengalah dengan titik-titik — bukan harga jualnya. */
.ukartu-hrg{display:flex;align-items:baseline;gap:4px;flex-wrap:nowrap;min-width:0;height:19px}
.ukartu-rp{flex:none;font-size:var(--f12);font-weight:700;letter-spacing:-.015em}
.ukartu-batas{flex:none;display:inline-flex;align-items:center;gap:1px;
  font-size:var(--f10);color:var(--ink-3);white-space:nowrap}
/* Tidak muat = tidak digambar (K-282) — diukur `pasBatas` di inv-item.js. */
.ukartu-hrg{overflow:hidden}
.ukartu-hrg--sesak .ukartu-batas{display:none}
.ukartu-batas svg{width:10px;height:10px;flex:none}
.ukartu-batas b{font-weight:600}
/* Batas yang berada DI BAWAH MODAL dicetak merah — penanda, bukan pintu.
   Menekannya membuka itemnya seperti bagian kartu yang lain. */
.ukartu-batas--rugi{color:var(--stop)}
/* Garis tipis memisahkan angkanya dari keterangan tempat dan waktunya. */
/* Tanggal masuk dan lokasinya SATU BARIS (diralat pemiliknya), tanpa kata
   "Masuk": ikon panah-ke-dalam sudah mengatakannya, dan kata itu memakan lebar
   yang dibutuhkan nama lokasinya. Yang mengalah bila sempit adalah NAMA
   LOKASINYA, dengan titik-titik — tanggalnya utuh, karena tanggal setengah
   tidak mengatakan apa-apa. */
.ukartu-kaki{margin-top:7px;padding:6px 9px 7px;border-top:1px solid var(--line);
  display:flex;align-items:center;gap:7px;min-width:0;font-size:var(--f10);color:var(--ink-3)}
.ukartu-kaki svg{width:12px;height:12px;flex:none}
.ukartu-tgl{flex:none;display:inline-flex;align-items:center;gap:3px;white-space:nowrap}
.ukartu-lok{flex:1 1 auto;min-width:0;display:inline-flex;align-items:center;gap:3px}
.ukartu-lok > span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* Mode Pilih: LENCANA KEADAAN ITULAH kotak centangnya (diminta pemiliknya).
   Kotak centang kedua di pojok kartu dicabut: ia benda seukuran kuku yang
   harus dibidik dua puluh kali berturut-turut, sementara lencana keadaan sudah
   berdiri di tempat yang sama pada setiap kartu — dan warnanya sudah menyebut
   barang yang mana yang sedang dipilih. */
.ukartu--pilih,.ukartu--pilih *{cursor:pointer}
/* Selama mode Pilih menyala, kartu yang berada di LOKASI LAIN dikelabukan —
   dan menekannya menyebutkan sebabnya, bukan diam. Ia tidak disembunyikan:
   barangnya memang ada, dan yang hilang dari daftar membuat orang mencari-cari
   ke mana perginya. Keadaan barangnya sendiri tidak lagi menahan (K-214). */
.ukartu--tolak{opacity:.5}
.ukartu--tolak,.ukartu--tolak *{cursor:not-allowed}
@media(max-width:430px){
  .ukartu-rp{font-size:var(--f12)}
}
/* KARTU ITEM RETUR (K-114) — kerangka `.ukartu` yang sama, isinya sendiri.
   Yang perlu gayanya sendiri cuma KAKINYA: di Daftar Item ia dua benda
   (tanggal dan lokasi) yang berbagi baris; di sini ia SATU, nomor pembelian
   asalnya, dan nomor itu memakai seluruh lebarnya lalu berpotong titik-titik.
   Nomor dokumen dibaca karakter demi karakter, jadi ia berhuruf mono — sama
   dengan setiap nomor dokumen lain di ERP ini. */
.ukartu-asal{flex:1 1 auto;min-width:0;display:inline-flex;align-items:center;gap:4px}
.ukartu-asal b{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  font-weight:500;font-size:var(--f10)}
/* KARTU TRANSFER: dua baris.

   Baris atas memuat waktu dan pelaksananya — bukan sebuah nama pihak, jadi ia
   TIDAK memakai ukuran judul 16px yang dipakai kartu lain. Ia keterangan, dan
   ukurannya keterangan; yang berhak besar di kartu ini adalah nama kedua
   lokasinya, dan keduanya berdiri di baris bawah.

   Baris bawah meminjam `.dhead-fakta` apa adanya — tiga petak berbagi lebar
   rata, dipisah garis tegak, melipat menjadi tumpukan di lebar telepon. Yang
   ditambahkan cuma label kecil di atas tiap nilainya, karena tanpa label
   "Warehouse Kediri | Outlet Kediri Kota" tidak menyebut mana yang asal. */
.dok--trf .dok-pihak{display:flex;align-items:center;gap:6px;flex-wrap:wrap;
  font-family:inherit;font-size:var(--f12);font-weight:400;color:var(--ink-3);letter-spacing:0;
  white-space:normal;overflow:visible}
.dok--trf .dok-pihak > i{font-style:normal;color:var(--ink-3)}
.dok--trf .trf-wkt{font-family:var(--f-angka);font-size:var(--f12);color:var(--ink-2)}
.dok--trf .trf-tiga{border-top:0;margin:0 -15px -13px;border-bottom-left-radius:var(--radius);
  border-bottom-right-radius:var(--radius);overflow:hidden}
.dok--trf .trf-tiga .dfakta{padding:10px 15px}
/* Petak "Item" hanya selebar isinya ("1 unit"); dua nama lokasi membagi sisa
   lebarnya. Dibagi rata bertiga, sepertiga lebar habis untuk dua kata pendek
   sementara "Outlet Kediri Kota" di sebelahnya terpotong — di layar telepon
   petak ketiga bahkan terdorong turun dan kartunya jadi tiga baris. Aturan
   ini berlaku di SEMUA lebar, termasuk di bawah 560px tempat `.dhead-fakta`
   biasanya menumpuk tegak: kartu ini memang dirancang dua baris. */
.dok--trf .trf-tiga{flex-direction:row;flex-wrap:nowrap;gap:0}
.dok--trf .trf-tiga .dfakta{flex:1 1 0;min-width:0}
.dok--trf .trf-tiga .dfakta:last-child{flex:0 0 auto}
.dok--trf .trf-tiga .dfakta + .dfakta{border-left:1px solid var(--line);border-top:0}
/* Jumlah unit tetap di petak ketiga, paling kanan, juga di telepon (diminta pemiliknya). */
@media(max-width:560px){
  .dok--trf .trf-tiga{margin-left:-13px;margin-right:-13px}
  .dok--trf .trf-tiga .dfakta{padding:9px 12px}
}

/* ---------- foto kartu SELALU 1:1 ----------
   Ditulis paling belakang dengan sengaja: aturan .pc-foto di atas
   meregangkan foto setinggi kartunya (align-items:stretch), sehingga barang
   yang sama terlihat lonjong di kartu yang kebetulan lebih tinggi — padahal
   fotonya sendiri tidak berubah. Yang menentukan tinggi foto adalah fotonya,
   bukan tetangganya. */
.pc-foto{align-self:flex-start;aspect-ratio:1/1;height:auto;min-height:0}

/* ---------- tahun dan jam di kartu daftar ----------
   Di lebar telepon kartu tidak muat "24 Ags 2026 · 14:20 · Outlet Nganjuk",
   dan yang selama ini terpotong adalah ujung kanannya — nama lokasi, satu-
   satunya butir yang benar-benar dipakai MENCARI barang. Yang dibuang justru
   dua butir yang paling jarang ditanyakan di depan daftar: tahunnya (seluruh
   isi daftar hampir selalu tahun yang sama) dan jamnya. Keduanya tetap
   lengkap di halaman detailnya.
   Titik pemisah ikut ke DALAM potongan jamnya, supaya yang tersembunyi tidak
   meninggalkan titik menggantung. */
.mtahun,.mlain{font-style:normal;opacity:inherit}
.dok-meta .mtahun{opacity:1}
/* !important dipakai dengan sadar: keduanya kelas PENYEMBUNYI yang ditempel
   ke dalam baris meta milik beberapa daftar yang berbeda, dan daftar itu
   sudah mengatur display anak-anaknya lewat pemilih yang lebih kuat
   (.dok-meta > span). Menandinginya satu per satu berarti
   daftar berikutnya nanti diam-diam tidak ikut. */
@media (max-width:560px){
  .mtahun,.mjam{display:none!important}
}

/* ---------- baris pengaturan di lebar telepon ----------
   Ditulis PALING BELAKANG dengan sengaja: setiap layar pengaturan menimpa
   lajurnya sendiri di dalam @media(max-width:900px) yang berdiri lebih bawah
   di berkas ini, jadi aturan yang ditulis lebih awal selalu kalah walau
   ambangnya lebih sempit.

   Yang diperbaiki: lajur "auto" untuk nomor urut berebut tempat dengan kolom
   isian yang melipat ke barisnya — lajur itu melar mengikuti isian terlebar,
   dan kolom uang di sebelahnya menyusut sampai yang terbaca cuma "Rp 8".
   Nomornya diberi barisnya sendiri, isiannya dibagi dua sama rata, dan
   tombol hapusnya turun ke barisnya sendiri di ujung kanan. */
@media(max-width:620px){
  .setbaris,.setbaris--harga,.setbaris--komp,.setbaris--tingkat,.setbaris--nilai,
  .setbaris--mode,.setbaris--field,.setbaris--dasar,.setbaris--hadir,
  .setbaris--oplok,.setbaris--opjadwal{grid-template-columns:1fr 1fr}
  .setbaris .setno{grid-column:1/-1;margin-top:0}
  .setbaris .setakt{grid-column:1/-1;justify-content:flex-end;padding-top:0}
  /* Baris rentang (K-295) cuma berisi nomor, SATU kolom, dan tombol hapus —
     muat sebaris di 390px. Ditumpuk seperti baris pengaturan lain, ia jadi
     tiga baris untuk satu angka. */
  .setbaris--rentang{grid-template-columns:auto 1fr auto}
  .setbaris--rentang .setno{grid-column:auto;margin-top:22px}
  .setbaris--rentang .setakt{grid-column:auto;padding-top:22px}
  /* Baris item Pembelian punya kebutuhan yang berbeda dari baris pengaturan:
     isinya cuma DUA kolom, dan yang pertama adalah nama barang yang ditulis
     apa adanya — dibagi dua sama rata, ia jadi kotak 160px yang memuat empat
     kata per baris. Jadi kolomnya bertumpuk penuh, sementara nomor urut dan
     tombol hapus naik SEBARIS di kepala itemnya: nomor di kiri, hapus di
     kanan. Angka "2" telanjang di tengah formulir tidak menerangkan apa pun;
     sebagai kepala satu barang, ia jelas menomori barang mana. */
  .setbaris--beli{grid-template-columns:1fr auto}
  /* `grid-row:1` WAJIB pada keduanya. Tanpa itu tombol hapus ditaruh menurut
     urutan tulisnya — sesudah kedua kolom yang membentang penuh — jadi ia
     mendarat di baris keempat, sendirian di bawah kolom Harga, jauh dari
     barang yang dihapusnya. */
  .setbaris--beli .setno{grid-column:1;grid-row:1;margin-top:0}
  .setbaris--beli .setakt{grid-column:2;grid-row:1;padding-top:0}
  .setbaris--beli .setsel{grid-column:1/-1}
  /* Kaki layar pengaturan: keterangan "sudah tersimpan" turun ke barisnya
     sendiri, tombolnya berjajar di bawahnya. Dipaksa satu baris, ketiganya
     terpotong bersama-sama dan tidak ada satu pun yang terbaca utuh. */
  .setkaki{flex-wrap:wrap}
  .setkaki .tumbuh{flex:1 0 100%;order:-1}
}

/* ---------- LAPORAN ----------
   Satu bentuk tabel untuk seluruh laporan: sebutan di kiri, angka rata kanan,
   baris kesimpulan lebih tebal di balik garisnya sendiri. Bentuknya sengaja
   sama dengan Ringkasan Keuangan di halaman dokumen — orang yang sudah hafal
   membaca yang itu tidak perlu belajar membaca yang ini. */
.lapkartu{margin-bottom:16px}
.lapbaris{display:flex;align-items:baseline;justify-content:space-between;gap:14px;
  padding:11px 0;border-bottom:1px solid var(--line)}
.lapbaris:last-child{border-bottom:0}
.lapbaris-t{min-width:0;font-size:var(--f12);color:var(--ink-2)}
/* Keterangan baris turun ke bawah sebutannya, bukan berdiri di sebelahnya:
   di sebelahnya ia berebut lebar dengan angka yang justru sedang dicari. */
.lapbaris-t i{display:block;margin-top:3px;font-style:normal;font-size:var(--f11);color:var(--ink-3)}
.lapbaris-v{font-family:var(--f-angka);font-variant-numeric:tabular-nums;
  font-size:var(--f13);font-weight:600;color:var(--ink);white-space:nowrap}
/* Baris kesimpulan sebuah seksi: garis di atasnya, hurufnya penuh, angkanya
   naik satu tingkat. Ia jawaban, bukan bahan. */
.lapbaris--kuat{border-top:1px solid var(--line-strong);border-bottom:0;margin-top:4px;padding-top:12px}
.lapbaris--kuat .lapbaris-t{font-size:var(--f13);font-weight:600;color:var(--ink)}
.lapbaris--kuat .lapbaris-v{font-size:var(--f14)}
/* Kesimpulan seluruh halaman berdiri di luar kartunya. */
.lapakhir{margin-top:2px}
.lapakhir span{font-family:var(--f-judul);font-size:var(--f13);font-weight:600}
.lapakhir b{font-family:var(--f-angka);font-variant-numeric:tabular-nums;
  font-size:var(--f18);font-weight:700;letter-spacing:-.02em}

/* Tabel berkolom: satu sebutan lalu angka-angka yang dibandingkan ke bawah.
   Lajur angkanya rata kanan dan berlebar sama, jadi mata menyusuri satu garis
   tegak alih-alih mencari ulang di setiap baris. */
.laptabel{display:flex;flex-direction:column}
.laprow{display:grid;grid-template-columns:minmax(0,1.6fr) 56px minmax(0,1fr) minmax(0,1fr) minmax(0,1fr);
  gap:10px;align-items:baseline;padding:10px 0;border-bottom:1px solid var(--line);font-size:var(--f12)}
.laptabel--dua .laprow{grid-template-columns:minmax(0,1.6fr) 56px minmax(0,1fr)}
/* Tanpa hak lihat-modal Persediaan cuma menghitung unit: dua lajur, bukan
   tiga dengan lajur Nilai yang kosong. */
.laptabel--satu .laprow{grid-template-columns:minmax(0,1.6fr) 56px}
.laprow > span:not(.laprow-t){text-align:right;font-variant-numeric:tabular-nums;white-space:nowrap}
.laprow-t{min-width:0;color:var(--ink);font-weight:500;overflow-wrap:anywhere}
.laprow-t i{display:block;margin-top:3px;font-style:normal;font-size:var(--f11);color:var(--ink-3);font-weight:400}
.laprow--kepala{border-bottom:1px solid var(--line-strong);padding-bottom:8px;
  font-size:var(--f10);font-weight:700;letter-spacing:.09em;text-transform:uppercase;color:var(--ink-3)}
.laprow--kepala > span{white-space:nowrap}
/* Baris yang punya rinciannya sendiri di baliknya (Report Per Lokasi,
   K-228). Yang menandainya kursor dan latar saat disentuh — bukan panah di
   ujung kanan, yang di tabel berlajur angka akan mendorong angkanya ke dalam
   dan membuat tepi kanannya tidak lagi lurus (aturan yang sama dengan
   `.ringkas-tanya`). */
.laprow--klik{cursor:pointer}
.laprow--klik:hover{background:var(--surface-2)}
.laprow--total{border-bottom:0;border-top:1px solid var(--line-strong);margin-top:2px;padding-top:12px;font-weight:600}
.laprow--total .laprow-t{font-weight:600}
/* Di lebar telepon lima lajur tidak muat. Yang dilepas adalah lajur yang bisa
   dihitung sendiri dari dua lajur lain — Modal — bukan angka yang dicari. */
@media(max-width:720px){
  .laprow{grid-template-columns:minmax(0,1.3fr) 40px minmax(0,1fr) minmax(0,1fr);gap:8px;font-size:var(--f12)}
  .laptabel--dua .laprow{grid-template-columns:minmax(0,1.3fr) 40px minmax(0,1fr)}
  .laptabel--satu .laprow{grid-template-columns:minmax(0,1.3fr) 40px}
  .laprow > span:nth-child(4):not(.laprow-t){display:none}
  .laptabel--dua .laprow > span:nth-child(4){display:revert}
}


/* ============================================================================
   PEMBELIAN DAN PENJUALAN DI LAYAR TELEPON

   Ditulis paling belakang dengan sengaja, sama alasannya dengan blok
   `.setbaris` di atasnya: beberapa aturan yang ditimpa di sini berdiri di
   dalam `@media(max-width:900px)` yang letaknya lebih bawah daripada tempat
   asalnya, jadi aturan yang ditulis lebih awal selalu kalah walau ambangnya
   lebih sempit.

   Dua modul ini dibaca bergantian sepanjang hari, jadi setiap aturan di sini
   berlaku untuk KEDUANYA — dan untuk Servis, yang meminjam bentuk yang sama.
   ========================================================================= */

/* ---- baris item yang dibelah satu garis (baris item Penjualan) ----
   `.irow--rapat` melipat di bawah 620px supaya angkanya bisa turun ke
   barisnya sendiri. Tetapi `.irow--belah` mengubah arah flexnya menjadi
   KOLOM, dan kolom yang boleh melipat adalah kolom berlajur banyak: anak-
   anaknya berhenti melebar mengikuti kartunya dan mulai melebar mengikuti
   isinya sendiri. Akibatnya seluruh baris item penjualan meluber 99px di
   layar 390px — nama barangnya tidak terpotong, harganya terpenggal di tepi,
   dan tidak ada satu pun tanda bahwa ada yang salah selain angka yang hilang
   separuh. */
@media(max-width:620px){
  .irow--belah{flex-wrap:nowrap}
  .irow--belah > .irow-atas,
  .irow--belah > .irow-bawah{max-width:100%}
  /* Garansi dan margin berhenti berebut satu baris selebar telepon. Diratakan
     sebaris, yang mengalah adalah garansinya — dan "Garansi Toko 3 B…" tidak
     mengatakan apa-apa. */
  .irow-bawah{flex-wrap:wrap;row-gap:4px}
  .irow-bawah-kiri{flex:1 1 100%;white-space:normal}
  .irow-bawah-kanan{margin-left:auto}
}

/* ---- kepala seksi Item ----
   Tombol Riwayat Komplain tetap SEBARIS dengan judulnya dan mentok kanan.
   `.sec-hd > div:first-child` memakai `flex-basis:260px`, dan di lebar telepon
   basis itu sendirian sudah melebihi lebar barisnya — jadi tombolnya selalu
   terlempar ke baris kedua walau isinya cuma dua kata. */
@media(max-width:620px){
  .sec-hd > div:first-child{flex:1 1 auto;min-width:0}
  .sec-hd > .irow-act{flex:none;margin-left:auto}
  .sec-hd h2{min-width:0}
  .sec-hitung{overflow:hidden;text-overflow:ellipsis}
}

/* ---- kepala kotak Ringkasan Keuangan ----
   Ikon petaknya dilepas di telepon. Ia tidak membedakan apa pun — cuma ada
   satu kotak bernama Ringkasan Keuangan pada halaman ini — sementara 34px
   yang dimakannya persis yang dibutuhkan judulnya supaya tidak pecah menjadi
   "Ringkasan / Keuangan" di sebelah tombol Catat Biaya. */
@media(max-width:560px){
  .ringkas-hd{gap:9px;padding:12px 13px 10px}
  .ringkas-hd > .ringkas-ik--hd{display:none}
  .ringkas-hd h2{white-space:nowrap}
}

/* ---- tindakan utama halaman ----
   Di layar telepon tombol utama berdiri selebar halamannya. Mengambang di
   pojok kanan atas sebuah baris yang tersisa kosong, ia jadi sasaran kecil di
   tempat yang paling sulit dijangkau ibu jari — dan barisnya sendiri toh
   sudah kosong. */
@media(max-width:560px){
  .page-head{gap:12px}
  .page-head > div:first-child{flex:1 1 100%}
  .head-actions{margin-left:0;width:100%}
  .head-actions > .btn--primary{flex:1 1 auto;justify-content:center}
}

/* ---- baris isian berlajur di dalam pop-up (Pembelian Baru, Jual Unit) ----
   Lebar kolom uang dipatok lewat kelas supaya ia bisa dilepas kembali di
   layar sempit. */
.field--harga{flex:0 0 170px}
.field--garansi{flex:0 0 240px}
@media(max-width:640px){
  .field--harga,.field--garansi{flex:1 1 100%}
  .srcline{row-gap:2px}
}

/* ---- kotak sisa tagihan di kepala pop-up pembayaran ----
   Sebutannya ("Kurang dibayar kepada Rudy Cell") mengalah menjadi satu baris
   penuh di atas, dan angkanya berdiri sebaris dengan tombol Bayar Lunas di
   bawahnya. Dipaksa sebaris bertiga di lebar telepon, sebutannya pecah
   menjadi empat baris satu-dua kata — "Kurang / dibayar / kepada / Rudy
   Cell" — di sebelah angka yang justru paling penting dibaca. */
@media(max-width:560px){
  .sisabayar{gap:9px 12px}
  .sisabayar-k{flex:1 1 100%}
  .sisabayar-v{margin-right:auto}
}

/* ============================================================================
   INVENTORY DAN SERVIS DI LAYAR TELEPON
   ========================================================================= */

/* ---- foto unit di kepala detail Item ----
   Fotonya 1:1 dan lajurnya dipatok 300px di layar lebar; di bawah 820px
   lajurnya luruh menjadi satu, jadi 1:1 berarti setinggi lebar layarnya —
   358px hanya untuk satu gambar, dan seluruh keterangan barangnya terdorong
   keluar layar pertama.

   Sempat dipatok TINGGINYA saja (`aspect-ratio:auto;height:230px`) dan itu
   SALAH: petaknya jadi 358×230, dan `object-fit:cover` memotong atas-bawah
   gambar untuk mengisinya. Barangnya jadi terlihat gepeng — dan foto HP yang
   dipotong pada bagian layarnya adalah bagian yang justru paling perlu
   dilihat.

   Yang benar: petaknya tetap PERSEGI, yang dibatasi LEBARNYA. Tingginya ikut
   turun sendiri ke angka yang sama (240px), keterangan barangnya tetap
   terlihat di layar pertama, dan tidak ada satu piksel gambar pun yang
   hilang. Ia berdiri di tengah karena di lebar telepon ia satu-satunya benda
   di barisnya. */
@media(max-width:640px){
  .itemtop{gap:14px;margin-bottom:14px}
  /* MEPET KIRI-KANAN, atas permintaan pemiliknya. Ia sempat dipatok 240px dan
     ditaruh di tengah supaya keterangan barangnya tetap terlihat di layar
     pertama — tetapi foto barang bekas adalah BUKTI KONDISI, dan lecet sebesar
     kuku tidak terlihat pada gambar 240px. Sekarang ia selebar layar penuh
     (`margin` negatif menembus jarak halaman), dan gesekan jari yang berpindah
     foto — bukan tombol panah 34px yang berdiri di atas barang yang sedang
     diperiksa. */
  .itemfoto-utama{aspect-ratio:1/1;height:auto;max-width:none;
    margin-left:calc(var(--pad-hal, 16px) * -1);margin-right:calc(var(--pad-hal, 16px) * -1);
    border-radius:0;border-left:0;border-right:0}
  /* Jejeran foto kecilnya ikut mepet, dan jarak halamannya dikembalikan di
     dalam supaya foto pertama tidak menempel di tepi layar. */
  .fotostrip{margin-left:calc(var(--pad-hal, 16px) * -1);margin-right:calc(var(--pad-hal, 16px) * -1);
    padding-left:var(--pad-hal, 16px);padding-right:var(--pad-hal, 16px)}
}

/* ---- baris keterangan di bawah nama item (.irow-sub) ----
   Titik pemisahnya adalah elemen tersendiri di dalam baris yang boleh
   melipat, jadi ia bisa mendarat di ujung baris pertama tanpa ada yang
   mengikutinya — "Masuk 25 Ags ·" lalu baris baru. Di lebar telepon baris
   ini memang tidak akan pernah muat, jadi titiknya dilepas dan jaraknya
   yang melebar: yang memisah tinggal ruang kosong, dan ruang kosong tidak
   bisa menggantung. Yang dilepas hanya titik anak LANGSUNG — titik di dalam
   `.mjam` ikut hilang bersama jamnya sendiri. */
@media(max-width:560px){
  .irow-sub{column-gap:14px}
  .irow-sub > i{display:none}
  .ringkasbaris{column-gap:14px}
  .ringkasbaris > i{display:none}
  .opnmeta{column-gap:14px}
  .opnmeta > i{display:none}
}

/* ============================================================================
   DAFTAR ITEM DI LAYAR TELEPON: yang dipakai bekerja selalu terjangkau
   ========================================================================= */

/* Pencarian, saringan, dan tombol Pilih MENEMPEL di atas. Daftar ini digulir
   jauh — tujuh puluh unit bukan hal aneh — dan saringan yang ikut hilang ke
   atas berarti menggulir balik ke puncak setiap kali orang ingin
   menyempitkan daftarnya. Latar belakangnya dipatok warna halaman, kalau
   tidak kartu yang lewat di belakangnya terlihat menembus. */
.stikatas{display:contents}
@media(max-width:820px){
  /* Menempel DI BAWAH baris kepala, bukan di puncak jendela: baris kepala
     sendiri menempel setinggi 58px, dan bilah saringan yang berhenti di y=0
     menutupinya — nama halaman, tombol kembali, dan tombol cari semuanya
     hilang begitu daftarnya digulir sejengkal. `z-index` di bawah baris kepala
     supaya urutan tumpuknya tidak bergantung pada urutan tulis di HTML. */
  .stikatas{display:block;position:sticky;top:58px;z-index:30;
    margin:0 calc(-1 * var(--pad-hal));padding:10px var(--pad-hal) 2px;background:var(--ground);
    box-shadow:0 6px 12px -10px rgba(0,0,0,.5)}
  /* SELALU RAPAT dengan baris kepala (diminta pemiliknya): bilahnya menelan
     jarak atas halaman (`--pad-atas`) supaya di posisi gulir nol pun ia
     sudah menempel di bawah baris kepala — bukan renggang dulu lalu rapat
     begitu digulir. Berlaku hanya bila ia memang benda pertama di halaman
     (kepala halaman di HP disembunyikan bila tanpa tombol). */
  .page > :is(.stikatas,.filterhead):is(:first-child,.page-head + *,.aksibar + *,.page-head + .aksibar + *,
    .page-head + :empty + *,:empty + *){margin-top:calc(-1 * var(--pad-atas))}
  .stikatas .filterhead{margin-bottom:8px}
  .stikatas .daftarhead{margin-bottom:8px}
  /* Baris saringan MENGGULIR KE SAMPING, tidak melipat ke baris kedua: jumlah
     saringan boleh bertambah tanpa menambah tinggi bilah yang menempel. Batang
     gulirnya disembunyikan — ia menambah 8px pada baris yang tingginya justru
     sedang dihemat. */
  .stikatas .filterhead{flex-wrap:nowrap;overflow-x:auto;scrollbar-width:none;
    margin-left:calc(-1 * var(--pad-hal));margin-right:calc(-1 * var(--pad-hal));padding-left:var(--pad-hal);padding-right:var(--pad-hal)}
  .stikatas .filterhead::-webkit-scrollbar{display:none}
  .stikatas .filterhead > *,.stikatas .filterhead .combo{flex:none}
}

/* Bilah Jual yang menempel di dasar layar. Menjual satu-satunya tindakan di
   seluruh ERP yang memasukkan uang, dan di daftar sepanjang ini tombolnya
   berada di kaki kartu yang kebetulan sedang terlihat — bukan di tempat yang
   selalu bisa dijangkau ibu jari. Di layar lebar ia tidak ada: di sana bilah
   tindakan di kepala daftar sudah selalu terlihat. */
/* `.aksibar` adalah bentuk yang sama untuk tombol utama halaman lain —
   Tambahkan Pembelian di Daftar Pembelian — dan di HP ia menggantikan tombol
   di kepala halaman, yang disembunyikan supaya satu tombol tidak berdiri
   dua kali. */
.jualbar,.aksibar{display:none}
@media(max-width:820px){
  .jualbar,.aksibar{display:flex;position:fixed;left:0;right:0;bottom:0;z-index:60;
    padding:10px 16px calc(10px + env(safe-area-inset-bottom));
    background:linear-gradient(to top, var(--ground) 62%, transparent);
    pointer-events:none}
  .jualbar > .btn,.aksibar > .btn{pointer-events:auto;flex:1 1 auto;justify-content:center;
    height:46px;font-size:var(--f13);border-radius:var(--radius);
    box-shadow:0 6px 18px -8px rgba(0,0,0,.45)}
  .jualbar > .btn svg,.aksibar > .btn svg{width:17px;height:17px}
  /* Bilah Pilih yang sudah menyala: empat tombol sebaris. Tiga yang sempit
     menumpuk ikon di atas katanya (seperti bilah tab aplikasi telepon),
     tombol Jual dua kali lebih lebar dan mendatar. */
  .jualbar-aksi{display:flex;gap:8px;width:100%;pointer-events:auto}
  .jualbar-aksi[hidden]{display:none}
  .jualbar-aksi > .btn{flex:1 1 0;min-width:0;height:48px;padding:0 4px;flex-direction:column;gap:2px;
    justify-content:center;font-size:var(--f11);line-height:1;border-radius:var(--radius);
    box-shadow:0 6px 18px -8px rgba(0,0,0,.45)}
  .jualbar-aksi > .btn svg{width:17px;height:17px}
  .jualbar-aksi > .jualbar-jual{flex:2 1 0;flex-direction:row;gap:7px;font-size:var(--f13)}
  .jualbar-aksi > .btn:disabled{opacity:.45}
  /* Tindakan pindah ke bilah bawah; baris hitungan atas tinggal jumlah
     terpilih dan centang Semua. */
  .daftarhead-aksi > .btn:not(.btn--pilihsemua),.daftarhead-aksi > .daftarhead-pisah{display:none}
  /* Tombol "Pilih Item" di baris saringan pun dilepas: bilah bawah sudah
     berbunyi "Pilih", dan satu tindakan yang berdiri di dua tempat membuat
     orang menekan yang satu lalu mencari yang lain. */
  .pilihitem{display:none}
  /* Kartu terakhir tidak boleh tertutup bilahnya. */
  .page:has(.jualbar),.page:has(.aksibar){padding-bottom:calc(104px + env(safe-area-inset-bottom))}
  .page:has(.aksibar) .page-head{display:none}
}
/* Belum ada yang dipilih: BERGARIS, dan menekannya menyalakan mode Pilih.
   Sudah ada: TERISI penuh beserta jumlahnya, dan menekannya membuka
   penjualannya. Dua pekerjaan yang berbeda harus punya dua rupa yang
   berbeda — kalau tidak, satu-satunya cara tahu apa yang akan terjadi adalah
   menekannya dan melihat. */
.btn--jual--kosong{background:var(--surface);color:var(--done);border-color:var(--done)}
.btn--jual--kosong:hover{background:var(--done-bg);border-color:var(--done);opacity:1}

/* SATU petak, dua tombol yang bergantian mengisinya. Halaman yang bisa
   dicapai dari menu memakai tombol MENU; halaman turunan memakai tombol
   KEMBALI, karena di situ yang dibutuhkan orang adalah jalan pulang, bukan
   daftar modul. Keduanya tidak pernah muncul bersamaan: dua tombol
   berdempetan di sudut yang paling sering ditekan ibu jari adalah dua peluang
   salah tekan.

   Petaknya berukuran tetap dan kedua tombolnya bertumpuk di dalamnya.
   SEJAK K-282 PERGANTIANNYA TANPA ANIMASI APA PUN (diminta pemiliknya:
   "hilangkan aja animasi hamburger sama animasi icon back ... yang muter2"):
   geseran naik-turunnya di dalam halaman dan putaran seperempatnya di antara
   halaman sama-sama dicabut — tombolnya langsung berganti. */
.navsel{position:relative;display:none;flex:none;width:34px;height:34px;overflow:hidden}
.navsel > *{position:absolute;inset:0;width:100%;height:100%}
.navsel > .backbtn{transform:translateY(100%);opacity:0}
.navsel--balik > .railtoggle{transform:translateY(-100%);opacity:0;pointer-events:none}
.navsel--balik > .backbtn{transform:none;opacity:1}
.navsel:not(.navsel--balik) > .backbtn{pointer-events:none}
/* TANPA pengurung. Kotak di sekeliling panah membuatnya seukuran dan sebentuk
   dengan tombol menu yang bergantian dengannya — dua benda berkotak sama besar
   di sudut yang sama, dan orang harus membaca isinya untuk tahu ia sedang di
   halaman utama atau bukan.

   Yang menggantikan kotaknya: panah BERBATANG (bukan chevron telanjang),
   digambar lebih besar dan sepenuh warna teks. Chevron sendirian terbaca
   sebagai "buka" atau "mundurkan sesuatu di dalam halaman"; panah berbatang
   yang menunjuk keluar ke kiri cuma punya satu arti di mana pun ia berdiri. */
.backbtn{display:inline-flex;align-items:center;justify-content:center;
  padding:0;border:0;border-radius:var(--radius);
  background:none;color:var(--ink);cursor:pointer}
.backbtn svg{width:21px;height:21px}
.backbtn:hover{color:var(--ink-2)}
.backbtn:focus-visible{outline:2px solid var(--ink);outline-offset:2px}
/* Ambangnya SAMA dengan ambang menu menjadi laci (960px). Beda sedikit
   saja, ada lebar di antaranya yang menyembunyikan tombol menu padahal
   menunya sudah tertutup — dan di situ tidak ada satu pun jalan
   membukanya. */
@media (max-width:960px){ .navsel{display:block} .navsel > .railtoggle{display:inline-flex} }

/* ============================================================================
   BARIS KEPALA DI LAYAR TELEPON: nama halaman, lalu pencariannya
   ============================================================================
   Di layar telepon baris kepala inilah kepala halaman. Isinya tiga benda dan
   tidak boleh lebih: tombol menu/kembali, NAMA HALAMANNYA, dan tombol cari.

   Yang dicabut di lebar ini ada tiga, dan ketiganya dicabut karena baris ini
   sudah mengatakan hal yang sama:
   · remah roti — jejaknya sudah diwakili tombol kembali di sebelah kiri, dan
     "Inventory / Daftar Item IN-002" memakan seluruh lebar layar untuk satu
     kata yang berguna;
   · judul besar di badan halaman — namanya sudah tercetak di baris kepala,
     dan judul kedua mendorong kartu pertama 60px lebih jauh ke bawah;
   · kolom pencarian di baris saringan — ia sekarang ada di baris kepala.
   Bertiga mereka memakan sepertiga layar sebelum satu kartu pun terlihat.

   Judul dan kolom pencarian BERTUMPUK di satu petak: kolomnya datang
   menggeser dari kanan dan judulnya keluar ke kiri, pola yang sama dengan
   tombol menu/kembali di sebelahnya. Menyembunyikan judul mendadak lalu
   menampilkan kolom di tempat yang sama membuat orang mengira halamannya
   berpindah. */
.topmid,.topcaribtn{display:none}
@media (max-width:960px){
  /* `overflow:hidden` WAJIB: kolom pencariannya menunggu di luar petak ini,
     digeser ke kanan sejauh lebarnya sendiri. Tanpa itu ia mendorong lebar
     halaman 300px ke kanan pada SETIAP halaman, dan seluruh ERP bisa digulir
     ke samping tanpa ada satu pun benda yang terlihat di sana. Karena
     petaknya memotong, kolomnya ditandai fokus lewat warna garis saja —
     lingkar cahaya di luar garis akan ikut terpotong. */
  /* UKURANNYA MENGIKUTI APLIKASI TELEPON PADA UMUMNYA (contoh pemiliknya:
     Shopee, lalu diturunkan sedikit karena huruf ERP ini memang lebih
     kecil): baris kepala 58px, tombol menu/kembali sasaran 44px dengan ikon
     24–26px di tepi kiri, nama halaman 18px tebal tepat di sebelahnya, ikon
     cari tanpa kotak. Yang lama 56px dengan ikon 16–21px terlalu kecil untuk
     ibu jari. */
  .topbar{height:58px;padding:0 10px 0 6px;gap:6px}
  .navsel{width:44px;height:44px}
  .navsel > .railtoggle{border:0;background:none;padding:0;color:var(--ink)}
  .navsel > .railtoggle svg{width:20px;height:20px}
  .backbtn svg{width:22px;height:22px}
  .topmid{position:relative;display:block;flex:1 1 auto;min-width:0;height:40px;overflow:hidden}
  .topjudul{position:absolute;inset:0;display:flex;flex-direction:column;align-items:flex-start;justify-content:center;
    font-family:var(--f-judul);font-size:16px;font-weight:700;color:var(--ink);
    white-space:nowrap;overflow:hidden;
    transition:transform .26s cubic-bezier(.22,.61,.36,1),opacity .18s ease}
  /* SATU NAMA SAJA (K-217). Baris kecil di atasnya — nama halaman induk —
     dicabut atas aturan tetap pemiliknya, dan karena tinggal satu baris
     hurufnya kembali penuh 18px. */
  .topjudul-t{display:block;max-width:100%;overflow:hidden;text-overflow:ellipsis;line-height:1.15}
  .topcari{position:absolute;inset:0;opacity:0;pointer-events:none;
    transform:translateX(calc(100% + 48px));
    transition:transform .26s cubic-bezier(.22,.61,.36,1),opacity .18s ease}
  .topcari input{width:100%;height:36px;padding:0 12px;border:1px solid var(--line);
    border-radius:var(--radius);background:var(--surface);color:var(--ink);font-size:var(--f13)}
  .topcari input::placeholder{color:var(--ink-3);opacity:1}
  .topcari input:focus{outline:0;border-color:var(--focus);border-width:1.5px}
  .topcari input::-webkit-search-cancel-button{-webkit-appearance:none;appearance:none}
  .topbar--cari .topjudul{transform:translateX(-28px);opacity:0}
  .topbar--cari .topcari{transform:none;opacity:1;pointer-events:auto}
  /* Tombolnya berganti isi dengan cara yang sama: yang keluar naik, yang
     masuk datang dari bawah. */
  .topcaribtn{position:relative;display:grid;place-items:center;flex:none;
    width:44px;height:44px;overflow:hidden;padding:0;cursor:pointer;
    border:0;border-radius:var(--radius);background:none;color:var(--ink)}
  .topcaribtn:hover{color:var(--ink);border-color:var(--line-strong)}
  .topcaribtn:focus-visible{outline:2px solid var(--ink);outline-offset:2px}
  .topcaribtn[hidden]{display:none}
  .topcaribtn-ik{position:absolute;inset:0;display:grid;place-items:center;
    transition:transform .22s cubic-bezier(.4,0,.2,1),opacity .16s ease}
  .topcaribtn-ik svg{width:20px;height:20px}
  .topcaribtn-x{transform:translateY(100%);opacity:0}
  .topbar--cari .topcaribtn-c{transform:translateY(-100%);opacity:0}
  .topbar--cari .topcaribtn-x{transform:none;opacity:1}
  /* Pencarian halaman sudah naik ke baris kepala, dan baris saringan yang
     tinggal berisi saringan saja ikut hilang bila memang tidak menyisakan
     apa pun. */
  .filterhead > .search{display:none}
  .filterhead:not(:has(> *:not(.search))){display:none}
  /* Judul besar dan keterangannya. Tombol tindakan di sebelah kanannya TETAP
     ADA — ia pekerjaan, bukan judul — jadi yang disembunyikan cuma petak
     kirinya, dan barisnya sendiri hilang hanya bila tidak ada tombol.

     HANYA DI DALAM KERANGKA ERP (`.page`), dan itu dibetulkan di K-176.
     Aturan ini berlaku karena judul halamannya NAIK ke baris kepala ERP
     (`.topjudul`) — jadi ia tidak hilang, ia pindah. Halaman ETALASE tidak
     punya baris kepala itu: kepalanya `.shophead`, yang cuma berisi lambang
     dan kolom cari. Tanpa batas `.page` di depannya, judul "Chat" dan nama
     toko yang sedang diajak bicara MENGHILANG BEGITU SAJA di layar telepon —
     tidak pindah ke mana pun, dan yang membacanya tidak punya satu pun cara
     tahu ia sedang berada di percakapan yang mana. */
  .page .page-head > div:first-child{display:none}
  .page .page-head:not(:has(.head-actions)){display:none}
}
@media (prefers-reduced-motion:reduce){ .topjudul,.topcari,.topcaribtn-ik{transition:none} }

/* ============================================================================
   BARIS KEPALA DI LAYAR LEBAR: bentuk telepon, tanpa kotaknya
   ============================================================================
   Tampilan tahap 1, diminta pemiliknya: "pada mode laptop, hilangkan kotak dan
   keterangan ini: Inventory / Daftar Item IN-002 ... di bagian paling atas
   langsung judulnya yaitu Daftar Item, sama kayak mode mobile, terus icon
   notifikasi di sisi paling kanan".

   Yang dicabut DUA: remah rotinya (sekarang tidak digambar di lebar mana pun)
   dan KOTAKNYA — bidang putih bergaris bawah yang memisahkan baris ini dari
   halamannya. Barisnya kini sewarna latar halaman, jadi yang terbaca judul di
   paling atas, bukan pita kosong berisi remah. Ia tetap menempel saat digulir
   dan tingginya tetap 56px: `.dhead` dan `.unitkiri` menempel tepat di
   bawahnya dengan angka itu.

   Judul besar di badan halaman ikut NAIK ke sini, sama dengan di telepon —
   dua judul yang sama berturut-turut adalah judul ganda (K-217). Tombol
   tindakan di sebelah kanannya tetap di tempatnya. Tombol cari TIDAK ikut
   naik: di layar lebar kolom pencariannya muat di baris saringan.

   Tombol MENU tidak ada di sini karena menu kirinya memang selalu terbuka;
   tombol KEMBALI ada, di halaman turunan saja — tanpa remah roti, dialah
   satu-satunya jalan pulang di layar ini. */
@media (min-width:961px){
  .topbar{background:var(--ground);border-bottom:0;padding:0 24px;gap:10px}
  .navsel--balik{display:block}
  .navsel > .railtoggle{display:none}
  .topmid{display:block;flex:1 1 auto;min-width:0}
  .topjudul{display:block;font-family:var(--f-judul);font-size:var(--f16);font-weight:600;color:var(--ink);
    white-space:nowrap;overflow:hidden}
  .topjudul-t{display:block;overflow:hidden;text-overflow:ellipsis}
  .topcari{display:none}
  .page .page-head > div:first-child{display:none}
  .page .page-head:not(:has(.head-actions)){display:none}
  #kerangka .topbar{background:var(--ground);border-bottom:0}
  #kerangka .page-head > div:first-child{display:none}
  /* KEPALA DAN SARINGAN TETAP DILEBUR (K-214): halaman yang judul besarnya
     naik ke baris kepala dan langsung disusul deretan tab berdiri rapat di
     bawah nama halamannya — yang memisah garis tabnya, bukan pita kosong
     setinggi jarak atas halaman. Yang ditarik barisnya, bukan jarak atas
     halamannya: `:has()` tidak boleh bersarang, dan "kepala TANPA tombol"
     sudah memakai satu. */
  .page > .page-head:not(:has(.head-actions)) + .stikatas .filterhead--tab{margin-top:calc(-1 * var(--pad-atas))}
}

/* ---- petak angka (Opname, Dashboard, HR) ----
   Tiga petak bertumpuk penuh menghabiskan 330px layar untuk tiga angka yang
   dua di antaranya nol. Melipat, sebutan dan angkanya berdiri sebaris dan
   keterangannya turun di bawahnya — tingginya separuh, isinya sama. */
@media(max-width:560px){
  .stat{flex-direction:row;flex-wrap:wrap;align-items:baseline;gap:4px 10px;padding:11px 13px}
  .stat > .stat-v{margin-left:auto;order:2}
  .stat > .stat-s{flex:1 1 100%;order:3}
}

/* ---- kepala dokumen: nama pihak mendapat lebarnya kembali ----
   Barisnya tidak melipat lagi, tetapi tanggal 12,5px dan nama 19px bersama-
   sama menyisakan 85px untuk nama pihaknya — "Hendra Wijaya" berhenti di
   "Hendr…". Yang dikecilkan adalah yang menerangkan, bukan yang dicari:
   tanggalnya turun ke 11px dan jaraknya dirapatkan, namanya ke 17px. */
@media(max-width:560px){
  .dhead-atas{gap:8px;padding:13px 14px 10px}
  /* Sejajar dengan tepi kiri baris di bawahnya, yang di lebar ini 14px. */
  .dhead-jenis{padding:9px 14px 0}
  .dhead-pihak{gap:9px}
  .avatarhuruf.dhead-ava{width:32px;height:32px;font-size:var(--f12)}
  .dhead-nm{font-size:var(--f14)}
  .dhead-tgl{font-size:var(--f11)}
  .dhead-kanan{gap:2px}
  .dhead-atas .pill{height:21px;padding:0 8px;font-size:var(--f11)}
  .mlain{display:none}
  /* Tiga keterangan dokumen berhenti menjadi tiga BARIS penuh. Masing-masing
     cuma berisi satu kata sampai satu nama pendek, jadi sebagai baris sendiri
     ketiganya menghabiskan 130px kepala dokumen untuk keterangan yang
     seluruhnya muat dalam dua baris. Sekarang mereka mengalir bersebelahan,
     dipisah garis tegak tipis, dan tetap bisa ditekan satu per satu. */
  /* Dua petak pertama berbagi baris pertama, setengah-setengah — lokasi di
     kiri, pembuatnya di kanan — dan nomor dokumen turun ke barisnya sendiri
     di bawah, rata kiri. Nomor dokumen 20 karakter tidak muat bersebelahan
     dengan apa pun di layar telepon, dan dipaksa ikut, ia yang dipotong
     titik-titik padahal justru nomor itulah yang mau disalin orang. */
  .dhead-fakta{flex-direction:row;flex-wrap:wrap;padding:8px 14px;gap:2px 0}
  .dfakta{flex:0 0 50%;min-width:0;padding:3px 9px;gap:5px}
  .dfakta:nth-child(odd){padding-left:0}
  .dfakta:nth-child(3){flex:0 0 100%;border-left:0;padding-top:6px}
  .dfakta + .dfakta{border-left:1px solid var(--line);border-top:0}
  .dfakta > svg{margin-left:2px;width:11px;height:11px}
  .dhead-kaki{padding:10px 14px}
}

/* ---------- Layar pengaturan yang bloknya bisa menguncup ----------
   Halaman Aturan Penggajian dulu menggambar keenam bloknya sekaligus: 108
   kolom isian setinggi 4,4 layar penuh, dan untuk tahu satu hal sederhana
   seperti "lembur nyala atau mati" orang harus menggulir empat layar.

   Barisnya sendiri MENYEBUTKAN JAWABANNYA, jadi yang menguncup bukan
   informasinya melainkan kolom isiannya — enam baris ini justru memuat lebih
   banyak keterangan daripada layar lama yang harus digulir. */
.setgrup--lipat{overflow:visible}
.setlipat{display:flex;align-items:center;gap:14px;width:100%;padding:14px 18px;
  border:0;background:var(--surface-2);text-align:left;cursor:pointer;
  font:inherit;color:inherit;transition:background .12s}
/* Menyentuhnya menguatkan garis blok, idiom yang sama dengan kartu dokumen
   dan baris item yang bisa ditekan — bukan latar kedua yang harus dipilih. */
.setgrup--lipat:hover{border-color:var(--line-strong)}
.setlipat .tumbuh{flex:1;min-width:0;display:flex;flex-direction:column;gap:3px}
.setlipat-judul{font-family:var(--f-judul);font-weight:700;font-size:var(--f13);line-height:1.3}
.setlipat-jawab{font-size:var(--f12);color:var(--ink-2);line-height:1.5;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.setlipat svg{flex:none;width:18px;height:18px;color:var(--ink-3);transition:transform .16s}
/* Baris jawaban HILANG begitu bloknya terbuka: angka yang sama tidak boleh
   berdiri dua kali pada satu layar, dan di sini ia berdiri persis di atas
   kolom yang memuatnya. Yang terbuka cukup judulnya. */
.setgrup--buka > .setlipat .setlipat-jawab{display:none}
.setgrup--buka > .setlipat{border-bottom:1px solid var(--line)}
.setgrup--buka > .setlipat svg{transform:rotate(90deg)}
/* Yang NONAKTIF tetap berdiri, cuma tenang — rule yang disembunyikan begitu
   dimatikan tidak akan pernah ditemukan lagi oleh yang tidak tahu ia ada. */
.setgrup--diam > .setlipat .setlipat-judul{color:var(--ink-2)}
.setgrup--diam > .setlipat .setlipat-jawab{color:var(--ink-3)}
.setgrup-ket{margin:0;padding:13px 18px 0;font-size:var(--f12);color:var(--ink-3);line-height:1.55}
/* GRUP HAK TAMBAHAN (K-167) menumpang bentuk lipat yang sama — baris yang
   menyebutkan jawabannya, dan isinya satu tekan di belakangnya.

   Bedanya satu dan ia perlu: isinya tetap DIGAMBAR lalu disembunyikan CSS.
   Panel Aturan Penggajian menggambar isinya hanya saat terbuka, dan di sana
   itu benar — isinya kolom yang dibaca dari `draf`. Di sini isinya CENTANG,
   yaitu keadaan yang sedang disunting; yang hilang bersama simpulnya hilang
   pula dari kiriman yang disimpan. */
.setgrup--lipat > .setgrup-isi{display:none}
.setgrup--buka > .setgrup-isi{display:block}
.hakisi{padding:12px}

/* ---------- Keuangan · kartu rekening ----------
   Saldo berdiri paling atas karena ia pertanyaan pertama orang yang membuka
   halaman Kas: uang kita sekarang berapa, dan di mana. Kartunya bisa ditekan
   dan menyaring daftar di bawahnya — kartu dan daftar menjawab pertanyaan yang
   sama dari dua sisi, jadi keduanya tidak boleh jadi dua halaman. */
.rekgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(228px,1fr));gap:12px;margin-bottom:16px}
.rekkartu{display:flex;flex-direction:column;gap:7px;padding:14px 16px;background:var(--surface);
  border:1px solid var(--line);border-radius:var(--radius);cursor:pointer;transition:border-color .14s}
.rekkartu:hover{border-color:var(--line-strong)}
.rekkartu--on{border-color:var(--ink);box-shadow:inset 0 0 0 1px var(--ink)}
/* Logo rekening di kiri, nama dan tipenya menumpuk di kanannya (K-120).
   Sebutan tipenya diberi kelasnya sendiri: sebagai `span` telanjang ia juga
   mengenai pembungkus teks yang baru — dan nama rekening yang mendadak
   11,5px kelabu tidak terbaca sebagai nama lagi. */
.rekkartu-nm{display:flex;align-items:center;gap:9px;font-family:var(--f-judul);font-size:var(--f13);font-weight:600;
  min-width:0;overflow:hidden}
.rekkartu-teks{display:flex;flex-direction:column;gap:2px;min-width:0;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.rekkartu-tipe{font-family:var(--f-isi);font-size:var(--f11);font-weight:400;color:var(--ink-3)}
.rekkartu-sd{font-family:var(--f-angka);font-size:var(--f16);font-weight:600;letter-spacing:-.01em}
.rekkartu-kk{display:flex;align-items:center;justify-content:space-between;gap:8px;
  min-height:30px;font-size:var(--f11);color:var(--ink-3)}
.rekkartu-kk > span{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* Yang dibatalkan tetap berdiri — jejaknya tidak pernah dihapus — tetapi
   angkanya dicoret supaya tidak terbaca sebagai uang yang bergerak. */
.kasrow--batal .irow-name,.kasrow--batal .irow-amt{color:var(--ink-3)}
.kasrow--batal .irow-amt{text-decoration:line-through}
/* Baris yang sudah termuat di saldo awal rekeningnya: angkanya ditenangkan,
   karena ia tidak ikut menggerakkan saldo hari ini maupun jumlah di kepala
   halaman. Ia tetap terbaca — pergerakannya sungguhan. */
.kasrow--pra .irow-amt{color:var(--ink-3)}

/* ---------- JARAK AMAN DI DASAR LAYAR TELEPON ----------
   Telepon menaruh tombol navigasinya (atau batang gesernya) di dasar layar,
   dan bilah yang menempel di situ berdiri PERSIS di bawahnya. Yang tertutup
   justru tombol yang paling sering ditekan: Jual, Simpan, dan Konfirmasi.

   `env(safe-area-inset-bottom)` menjawabnya, tetapi angkanya SELALU NOL selama
   halaman belum menyatakan `viewport-fit=cover` — dan itu dipasang dari erp.js,
   satu tempat untuk seluruh halaman.

   `100dvh` menggantikan `100vh` pada tinggi pop-up: `vh` memakai tinggi jendela
   yang PALING BESAR, jadi selama bilah alamat peramban masih terlihat, pop-up
   setinggi 100vh menjulur ke luar layar dan kakinya — tempat tombol simpannya
   berdiri — tidak pernah bisa dijangkau. */
.mdl{max-height:calc(100dvh - 88px)}
@media(max-width:960px){
  .mdl{max-height:calc(100dvh - 28px)}
  .mdl-ft,.panel-ft,.drw-ft{padding-bottom:calc(14px + env(safe-area-inset-bottom))}
  .pdp-aksi{padding-bottom:calc(10px + env(safe-area-inset-bottom))}
  .page{padding-bottom:calc(110px + env(safe-area-inset-bottom))}
  .toasts{bottom:calc(24px + env(safe-area-inset-bottom))}
  /* Laci menu setinggi 100vh menjulur ke balik bilah peramban dan tombol
     navigasi telepon — kakinya (nama orang, Pasang Aplikasi,
     Keluar) berdiri persis di tempat yang tertutup. dvh + jarak aman. */
  .rail{height:100dvh;padding-bottom:calc(16px + env(safe-area-inset-bottom))}
}

/* ------------------------------------------------- foto milik ERP, bukan
   milik peramban

   Menekan-tahan sebuah gambar di Chrome memunculkan menunya sendiri: "Buka
   gambar", "Salin gambar", "Unduh gambar", "Telusuri dengan Google Lens",
   "Bagikan gambar". Di layar telepon, menu itu muncul TEPAT saat orang hendak
   menggeser papan foto — jadi ia bukan sekadar mengganggu, ia merampas
   gerakan yang sedang dikerjakan.

   ERP ini sudah punya tombol unduhnya sendiri di penampil foto, jadi tidak ada
   satu pun kemampuan yang hilang. Yang dicabut cuma menu peramban di ATAS
   fotonya. Dipasang untuk SELURUH gambar, bukan satu halaman: foto ada di
   hampir setiap modul, dan aturan yang dipasang per halaman pasti terlewat di
   halaman berikutnya. */
img{
  -webkit-touch-callout:none;      /* menu tekan-tahan iOS */
  -webkit-user-drag:none;          /* seret gambar keluar */
  user-select:none;
  -webkit-user-select:none;
}

/* ------------------------------------------------- kebiasaan peramban yang
   mengganggu pekerjaan

   Dua bawaan peramban di telepon yang tidak pernah diminta siapa pun di ERP
   ini, dan keduanya merampas gerakan yang sedang dikerjakan orangnya:

   1. TARIK-KE-BAWAH UNTUK MEMUAT ULANG. Daftar di ERP ini digulir jauh —
      tujuh puluh unit bukan hal aneh — dan begitu orang menggulir balik ke
      puncak lalu meneruskan sedikit, halamannya dimuat ulang. Yang hilang
      bukan cuma tempatnya di daftar: formulir yang sedang diisi ikut hilang,
      tanpa satu pun pertanyaan.
   2. KETUK DUA KALI UNTUK MEMBESARKAN. Di daftar yang barisnya berdempetan,
      dua ketukan cepat pada dua tombol yang berbeda terbaca sebagai satu
      ketukan ganda — jadi tombol kedua tidak jalan dan layarnya justru
      membesar. `manipulation` hanya mencabut yang itu; menggulir dan mencubit
      untuk memperbesar tetap berjalan seperti biasa.

   Ditulis di sini, paling belakang, karena keduanya berlaku untuk seluruh ERP
   dan tidak boleh bisa ditimpa aturan halaman mana pun. */
html,body{
  /* `none`, bukan `contain`: contain cuma mencabut tarik-ke-bawah memuat
     ulang, sementara halamannya masih MELAR saat jari menggulir mentok
     (efek regang Chrome Android). Pemiliknya meminta yang itu dicabut juga. */
  overscroll-behavior:none;
  touch-action:manipulation;
}

/* ------------------------------------------------- halaman di belakang
   lapisan tidak ikut bergerak

   Dilaporkan pemiliknya: pop-up terbuka, tetapi halaman di belakangnya masih
   ikut tergulir saat jarinya menggeser — jadi yang sedang dibaca berpindah
   sendiri di balik pop-up, dan sesudah pop-upnya ditutup ia tidak lagi berada
   di tempat yang ia tinggalkan.

   `overflow:hidden` pada BODY, bukan `position:fixed`: keduanya menghentikan
   gulir, tetapi yang kedua membuang posisi gulirnya lalu harus
   mengembalikannya sendiri — dan setiap kali meleset satu piksel, halamannya
   melompat tepat pada saat pop-upnya ditutup. Bentuk ini pula yang sudah
   dipakai laci menu (`body.rail-on`) sejak awal.

   Isi lapisannya sendiri TETAP bisa digulir: `.ov--modal`, `.mdl-bd`,
   `.drw-bd`, dan `.panel-bd` semuanya mengurus gulirnya sendiri, dan
   ketiganya `position:fixed` sehingga tidak ikut terkunci.

   `scrollbar-gutter:stable` menahan tempat bilah gulirnya walau halamannya
   sedang tidak bisa digulir. Tanpa itu, setiap pop-up yang dibuka di layar
   lebar menggeser SELURUH halaman ~10px ke kanan pada detik ia muncul, lalu
   menggesernya kembali saat ditutup — dan yang terlihat orang bukan "bilah
   gulir hilang" melainkan halaman yang berkedut setiap kali sesuatu dibuka. */
html{scrollbar-gutter:stable}
body.lapis-on{overflow:hidden}

/* ------------------------------------------------- bilah gulir tidak
   digambar di layar sentuh

   Dilaporkan pemiliknya: "pada tampilan mobile hilangkan tampilan scroll yang
   ada di kanan". Aturan `::-webkit-scrollbar{width:10px}` di atas membuat
   Chrome menggambar bilah gulir BUATAN SENDIRI — dan bilah buatan sendiri
   tidak pernah mengambang lalu memudar seperti bilah bawaan telepon: ia
   berdiri terus di tepi kanan, di setiap kotak yang bisa digulir sekaligus.

   Di layar sentuh ia tidak menolong siapa pun: tidak ada yang menyeretnya
   dengan jari, dan yang mau menggulir memang langsung menggeser isinya.
   Di layar bertetikus ia TETAP DIGAMBAR — di sana bilah gulir sering
   satu-satunya tanda bahwa sebuah kotak masih ada isinya di bawah.

   YANG DICABUT CUMA BILAH HALAMAN — `html,body`, tidak lebih. Yang dikeluhkan
   pemiliknya adalah batang di tepi KANAN LAYAR, dan itu bilah halamannya
   sendiri. Dicabut menyeluruh dengan `*`, yang ikut hilang adalah bilah di
   dalam kotak-kotak yang menggulung sendiri — badan pop-up, badan laci,
   daftar pilihan, laci menu — dan di situ bilahnya justru satu-satunya tanda
   bahwa isinya masih ada di bawah. Ikut hilang pula bilah MENDATAR baris
   saringan (`.filters`, sengaja dibuat 6px) yang mengabarkan bahwa saringan
   di sebelah kanan masih bisa digeser.

   Ambangnya LEBAR LAYAR, bukan jenis penunjuk. Seluruh berkas ini memakai
   ambang lebar (960px, 820px, 640px, 560px) dan belum pernah sekali pun
   memakai `pointer:coarse`; memperkenalkan mekanisme kedua untuk pertanyaan
   yang sama membuat dua aturan yang harus dibaca bersama-sama setiap kali.

   Dua tuas ditulis berpasangan, idiom yang sama dengan `.tabs`,
   `.fotostrip`, `.roda`, dan `.stikatas .filterhead`: peramban baru membaca
   `scrollbar-width`, yang lama membaca `::-webkit-scrollbar`. */
@media (max-width:640px){
  html,body{scrollbar-width:none}
  html::-webkit-scrollbar,body::-webkit-scrollbar{display:none}
}

/* ------------------------------------------------- kerangka halaman (K-67)
   Disisipkan server sebelum skrip turun; memakai .app/.rail/.main/.topbar/
   .page yang sama dengan layar sungguhan, jadi tidak ada yang berpindah
   tempat saat isinya datang. Petaknya berkilau tenang; yang meminta gerak
   dikurangi mendapat petak diam. */
/* KERANGKA YANG DIAM, bukan yang berjalan (K-102, diminta pemiliknya:
   "loading berjalan yang berjalan dari kiri ke kanan itu dihilangkan saja,
   diganti loading skeleton"). Kilau yang menyapu dari kiri ke kanan dicabut
   dari SELURUH kerangka di ERP ini — di sini dan di `.skel` di atas.
   Sebabnya bukan cuma selera: petaknya hidup paling lama sepersekian detik,
   dan kilau yang tidak sempat menyelesaikan satu sapuan pun terbaca sebagai
   kedipan, bukan sebagai "sedang memuat". Yang mengabarkan "sedang dimuat"
   adalah BENTUKNYA — petak-petak seukuran isi yang akan menggantikannya. */
.krg{display:block;border-radius:6px;background:var(--surface-2)}
#kerangka .topbar{gap:12px}
.krg--ikon{width:34px;height:34px;border-radius:9px;flex:none}
.krg--nama{width:150px;height:18px}
.krg--judul{width:220px;height:28px;margin-bottom:6px}
.krg--tombol{width:150px;height:36px;border-radius:var(--radius)}
.krg--cari{width:240px;height:38px;border-radius:var(--radius)}
.krg--combo{width:140px;height:38px;border-radius:var(--radius)}
.krg--teks{height:13px}
.krg--pil{width:84px;height:22px;border-radius:999px}
.krg--foto{width:58px;height:58px;flex:none;border-radius:var(--radius)}
.krg--foto-kecil{width:44px;height:44px}
.krg--bulat{width:40px;height:40px;border-radius:50%;flex:none}
.krg--angka{width:60px;height:24px;margin-top:6px}
.krg-kartu,.krg-kotak{background:var(--surface);border:1px solid var(--line);border-radius:var(--radius);padding:14px 16px;margin-bottom:10px}
.krg-kartu{height:172px;display:flex;flex-direction:column;justify-content:space-between}
.krg-kotak--stat{height:80px;display:flex;flex-direction:column;justify-content:center;gap:4px}
.krg-baris{display:flex;justify-content:space-between;align-items:center;gap:12px;padding:6px 0}
.krg-item{display:flex;gap:11px;align-items:flex-start;padding:9px 0}
.krg-kolom{flex:1;display:flex;flex-direction:column;gap:8px;min-width:0}
/* Di telepon judul besar dan tombolnya tidak digambar (yang sungguhan pun
   begitu), dan baris saringannya satu baris yang terpotong di tepi —
   sama dengan `.stikatas .filterhead` yang menggulir ke samping. */
@media (max-width:960px){ #kerangka .topbar{height:58px} #kerangka .page-head{display:none} }
@media (max-width:820px){ #kerangka .filterhead{flex-wrap:nowrap;overflow:hidden;margin-top:6px} #kerangka .filterhead > .krg{flex:none} #kerangka .krg--cari{width:170px} }

/* ------------------------------------------- saringan dan tombol utama di HP (K-69)
   Diminta pemiliknya: "filter-filter di atas dirapetin, terutama di halaman
   yang belum diperbaiki", dan "tombol seperti Tambahkan Servis, +Opname
   diletakkan di bawah". Aturan yang dulu cuma milik Daftar Item, Pembelian,
   Penjualan, Servis, dan HR (`.stikatas`) kini berlaku untuk SETIAP baris
   saringan: satu baris yang menggulir ke samping, menempel di bawah baris
   kepala. Dan tombol di kepala halaman berdiri sebagai bilah di dasar layar —
   bentuk yang sama dengan Tambahkan Pembelian — pada setiap halaman. */
@media(max-width:820px){
  /* Bilah gulirnya TIDAK dicabut di sini (aturan "yang menggulung sendiri
     tetap punya bilahnya"); di layar sentuh ia memang tidak memakan tempat. */
  .page .filterhead,.page .filters{flex-wrap:nowrap;overflow-x:auto;scrollbar-width:thin;
    margin-left:calc(-1 * var(--pad-hal));margin-right:calc(-1 * var(--pad-hal));padding-left:var(--pad-hal);padding-right:var(--pad-hal)}
  .page .filterhead > *,.page .filterhead .combo,.page .filterhead--satu > .filters > *,.page .filters > *{flex:none}
  .page > .filterhead{position:sticky;top:58px;z-index:30;background:var(--ground);
    padding-top:8px;padding-bottom:8px;margin-bottom:8px;box-shadow:0 6px 12px -10px rgba(0,0,0,.5)}
  /* Rapat dengan baris kepala sejak gulir nol: aturannya satu dengan
     `.stikatas`, di blok itu. */
  /* Kepala halaman boleh berdiri di dalam pembungkus (#isi pada Absensi),
     jadi pemilihnya `.page .page-head`, bukan anak langsung. */
  .page .page-head{margin:0}
  .page .page-head > .head-actions{position:fixed;left:0;right:0;bottom:0;z-index:60;width:auto;margin:0;
    display:flex;gap:8px;flex-wrap:nowrap;padding:10px 16px calc(10px + env(safe-area-inset-bottom));
    background:linear-gradient(to top, var(--ground) 62%, transparent)}
  .page .page-head > .head-actions > .btn{flex:1 1 0;min-width:0;height:46px;padding:0 10px;justify-content:center;
    font-size:var(--f12);white-space:nowrap;border-radius:var(--radius);box-shadow:0 6px 18px -8px rgba(0,0,0,.45)}
  .page .page-head > .head-actions > .btn svg{width:17px;height:17px;flex:none}
  .page:has(.page-head > .head-actions){padding-bottom:calc(104px + env(safe-area-inset-bottom))}
}

/* Riwayat Lama (K-73): tombol "Muat N lagi" di kaki daftar. */
.arsip-kaki{display:flex;justify-content:center;padding:14px 0 4px}

/* ------------------------------------------- transisi navigasi berarah (K-71)
   Diminta pemiliknya: berpindah halaman terasa punya ARAH — masuk lebih
   dalam, halaman baru datang dari kanan; kembali, halaman lama keluar ke
   kanan; halaman sejajar cuma berganti tenang. ERP ini multi-halaman (setiap
   halaman berkas sendiri, dimuat penuh), jadi yang dipakai adalah transisi
   lintas-dokumen milik peramban (@view-transition): peramban memotret halaman
   lama, menahan potretnya sampai halaman baru siap digambar (kerangkanya,
   K-67), lalu menggeser keduanya. Tidak ada router baru, tidak ada halaman
   yang dimuat lewat skrip; riwayat peramban tetap riwayat yang asli.

   ARAHNYA diputuskan halaman LAMA saat ia ditinggalkan (`pasangArahNavigasi`
   di erp.js, dari kedalaman NAV dan remah roti — bukan dari alamatnya
   semata), dititipkan di sessionStorage, dan dibaca halaman BARU oleh satu
   skrip kecil di <head> yang disisipkan server (HalamanController::sajikan)
   menjadi `html[data-arah]` sebelum gambar pertamanya. Tanpa arah (muat
   ulang, dibuka langsung) tidak ada animasi.

   YANG BERGESER ADALAH SELURUH HALAMAN, dan itu perbaikan K-97.

   Dulu yang diberi nama transisi adalah `.main`, dan itulah sebabnya
   pemiliknya melaporkan halaman "kadang datang dari pojok kanan ATAS" dan
   "pasti ada kartu bertumpuk dari halaman belakang dan depannya". Sebabnya
   bisa diukur, bukan ditebak: `document.getAnimations()` di tengah transisi
   menyebutkan `::view-transition-group(isi)` menganimasikan
   **transform, width, DAN height**. Kotak `.main` memang berbeda ukurannya di
   tiap halaman — daftar panjang lawan detail pendek — jadi kotak grupnya
   MEMULAR dari ukuran lama ke ukuran baru. Isinya ikut serong (karena
   kotaknya berpindah sekaligus berubah besar) dan kedua potret halaman
   terlihat bertumpuk di dalam kotak yang sedang memular itu.

   Menamai `.main` berarti menjanjikan "benda ini sama di kedua halaman" —
   padahal yang sama cuma PERANNYA, bukan ukurannya. Yang benar-benar sama
   ukurannya di setiap halaman cuma satu: layarnya sendiri. Karena itu yang
   digeser sekarang AKAR, dan kotak grupnya dimatikan (`animation:none`)
   supaya tidak ada yang memular sama sekali.

   `mix-blend-mode:normal` wajib: bawaan peramban untuk potret lama dan baru
   adalah `plus-lighter` — dibuat untuk pudar-silang, dan pada dua halaman
   yang saling menggeser ia membuat keduanya tembus pandang satu sama lain.

   Yang dikecualikan dari geseran itu ada tiga, masing-masing dengan namanya
   sendiri: menu kiri (diam di komputer), NAMA HALAMAN di baris kepala (naik
   atau turun saling mengganti — diminta pemiliknya), dan tombol
   menu/kembali (berputar seperempat saat berganti rupa). */
@view-transition{navigation:auto}

/* 1 · YANG BERGESER CUMA HALAMANNYA — baris kepala DIAM DI TEMPAT.
   `.topbar` diberi namanya sendiri, jadi ia terangkat keluar dari potret
   akar: akar menggeser seluruh sisanya, dan baris kepala berdiri diam. */
.topbar{view-transition-name:topbar}
.rail{view-transition-name:rail}
/* Menu kiri diam pula — di komputer ia memang tidak pernah berpindah. */
::view-transition-group(rail){animation:none}
::view-transition-old(rail),::view-transition-new(rail){animation:none;mix-blend-mode:normal}
::view-transition-group(topbar){animation:none}
/* Keduanya TIDAK dianimasikan sama sekali — tidak digeser, tidak dipudarkan.
   Yang terlihat selama transisi adalah baris kepala HALAMAN BARU yang hidup,
   dan pada detik itu skripnya sudah menggambarnya; yang berganti di dalamnya
   bergerak sendiri (lihat blok 3 di bawah). Diukur: kotak `.topbar` berdiri
   di x:0 y:0 dari awal sampai akhir transisi, tidak bergeser sepiksel pun. */
::view-transition-old(topbar),::view-transition-new(topbar){animation:none;mix-blend-mode:normal}
/* KECUALI BILA IA TIDAK PUNYA PASANGAN (K-213). Detail Item tidak menggambar
   baris kepala di layar lebar, jadi berpindah ke sana meninggalkan potret
   baris kepala halaman LAMA tanpa penggantinya — dan `animation:none` di atas
   membuat potret itu berdiri penuh selama transisinya lalu hilang mendadak.
   Terukur sebelum aturan ini: remah roti "Inventory / Daftar Item" beserta
   loncengnya masih tergambar 369 ms sesudah kartunya ditekan, di atas halaman
   barang yang sudah masuk. Itu kedipan yang sama dengan yang dibereskan
   K-102, dari arah yang lain.

   `:only-child` itulah yang membedakan keduanya: potret yang berpasangan
   punya saudara di dalam `::view-transition-image-pair`, yang yatim tidak.
   Jadi yang berpasangan tetap DIAM seperti sejak K-102, dan yang yatim
   memudar — masuk maupun keluar. */
::view-transition-old(topbar):only-child{animation:vtPudarKeluar .1s ease both}
::view-transition-new(topbar):only-child{animation:vtPudarMasuk .1s ease both}

/* 2 · AKAR: kotaknya TIDAK BOLEH memular — di situlah kerusakan K-97 lahir.

   LAMANYA DIPENDEKKAN DI K-180, dan angkanya diukur bukan dikarang:
   pemiliknya menduga geseran inilah yang membuat ERP terasa lambat dimuat.
   Ia bukan — satu halaman butuh 1.374–1.853 ms sampai isinya berdiri di
   telepon, sementara geserannya 280 ms — tetapi seperlima tetap seperlima.
   HP 0,28 → 0,19 dtk, komputer 0,24 → 0,16 dtk. Mencabutnya SELURUHNYA
   sudah disiapkan pemiliknya sebagai jalan mundur (K-102) dan tidak
   terpakai: yang membuat perpindahan terasa punya ARAH adalah geseran ini
   sendiri. */
::view-transition-group(root){animation:none}
::view-transition-old(root),::view-transition-new(root){
  animation:none;mix-blend-mode:normal;height:100%;object-fit:cover;object-position:top center}
:root[data-arah="maju"]::view-transition-old(root){animation:vtKeluarKiri .16s cubic-bezier(.25,.7,.25,1) both}
:root[data-arah="maju"]::view-transition-new(root){animation:vtMasukKanan .16s cubic-bezier(.25,.7,.25,1) both}
:root[data-arah="mundur"]::view-transition-old(root){animation:vtKeluarKanan .16s cubic-bezier(.25,.7,.25,1) both}
:root[data-arah="mundur"]::view-transition-new(root){animation:vtMasukKiri .16s cubic-bezier(.25,.7,.25,1) both}
:root[data-arah="sejajar"]::view-transition-old(root){animation:vtPudarKeluar .1s ease both}
:root[data-arah="sejajar"]::view-transition-new(root){animation:vtPudarMasuk .1s ease both}
/* PUDAR-SILANG ETALASE ↔ PENCARIANNYA (K-281): yang lama memudar, yang baru
   timbul, bersamaan dan cepat — tanpa geseran di lebar mana pun. Arahnya
   dititipkan `Toko.pudarKe`. */
:root[data-arah="pudar"]::view-transition-old(root){animation:vtPudarKeluar .18s ease both}
:root[data-arah="pudar"]::view-transition-new(root){animation:vtPudarMasuk .18s ease both}
/* Komputer: subtil. */
@keyframes vtMasukKanan{from{transform:translateX(28px);opacity:0}to{transform:none;opacity:1}}
@keyframes vtKeluarKiri{from{transform:none;opacity:1}to{transform:translateX(-18px);opacity:0}}
@keyframes vtMasukKiri{from{transform:translateX(-28px);opacity:0}to{transform:none;opacity:1}}
@keyframes vtKeluarKanan{from{transform:none;opacity:1}to{transform:translateX(18px);opacity:0}}
@keyframes vtPudarMasuk{from{opacity:0}to{opacity:1}}
@keyframes vtPudarKeluar{from{opacity:1}to{opacity:0}}
/* HP: geseran selebar layar, LURUS dari kanan ke kiri. Halaman lama ikut
   tergeser sepertiga supaya terasa ada kedalaman. */
@media (max-width:820px){
  :root[data-arah="maju"]::view-transition-old(root){animation:vtHpKeluarKiri .19s cubic-bezier(.25,.7,.25,1) both}
  :root[data-arah="maju"]::view-transition-new(root){animation:vtHpMasukKanan .19s cubic-bezier(.25,.7,.25,1) both;box-shadow:-12px 0 24px -12px rgba(0,0,0,.35);z-index:2}
  :root[data-arah="mundur"]::view-transition-old(root){animation:vtHpKeluarKanan .19s cubic-bezier(.25,.7,.25,1) both;box-shadow:-12px 0 24px -12px rgba(0,0,0,.35);z-index:2}
  :root[data-arah="mundur"]::view-transition-new(root){animation:vtHpMasukKiri .19s cubic-bezier(.25,.7,.25,1) both}
  @keyframes vtHpMasukKanan{from{transform:translateX(100%)}to{transform:none}}
  @keyframes vtHpKeluarKiri{from{transform:none;opacity:1}to{transform:translateX(-33%);opacity:.55}}
  @keyframes vtHpMasukKiri{from{transform:translateX(-33%);opacity:.55}to{transform:none;opacity:1}}
  @keyframes vtHpKeluarKanan{from{transform:none}to{transform:translateX(100%)}}
}

/* 3 · YANG BERGANTI DI DALAM BARIS KEPALA BERGANTI DI TEMPATNYA SENDIRI.
   Nama halaman dan tombol menu/kembali TIDAK lagi punya nama transisi. Dulu
   punya, dan hasilnya justru kedipan yang dikeluhkan pemiliknya: yang
   dianimasikan masuk adalah petak abu-abu kerangka, lalu skripnya
   menggantinya dengan yang sungguhan — dua pergantian untuk satu
   perpindahan.

   Sekarang keduanya dianimasikan pada BENDA YANG SUNGGUHAN, sesudah
   transisinya habis (`erp.js` menunggu `viewTransition.finished`, lalu
   memasang `.topganti` pada baris kepalanya). Yang tidak berganti — lonceng,
   tombol cari, remah roti, dan baris kepalanya sendiri — tidak dianimasikan
   sama sekali: benda yang diam memang tidak perlu diberi gerakan. */
/* NAMA HALAMAN NAIK PANGKAT, TURUN PANGKAT (K-102, dijelaskan pemiliknya
   dengan contohnya sendiri): dari "Pembelian · Daftar Pembelian" menuju
   "Daftar Pembelian · Detail Pembelian", yang terjadi bukan dua baris yang
   berganti — melainkan "Daftar Pembelian" yang semula TEBAL DAN DI BAWAH
   NAIK KE ATAS menjadi kecil dan tipis, lalu judul barunya masuk dari bawah
   menempati tempat yang ia tinggalkan. Kembali, kebalikannya persis.

   Karena itu yang dianimasikan KEDUA BARISNYA sendiri-sendiri, bukan
   kotaknya: baris kecil datang dari tempat dan ukuran baris besar, dan
   sebaliknya. `transform-origin:left` supaya keduanya tumbuh dan menyusut
   dari tepi kiri yang sama — dari tengah, hurufnya melebar ke dua arah dan
   tidak ada satu tepi pun yang bisa disusuri mata.

   Angkanya bukan karangan: jarak 16px adalah selisih titik tengah kedua
   baris (10,5px + 16px beserta jaraknya di dalam kotak 40px), dan skala
   1,52 / 0,66 adalah nisbah kedua ukuran hurufnya. */
/* Sejak K-217 yang berganti TINGGAL SATU BARIS, jadi aturan dan gambar gerak
   yang dulu menggerakkan baris kecil di atasnya ikut dicabut — begitu sebuah
   keadaan tidak bisa lahir lagi, kodenya dihapus. Yang tersisa: maju, nama
   halamannya datang dari bawah; mundur, ia menyusut kembali ke kedudukan
   induknya; sejajar, ia cuma berganti tenang. */
.topmid{perspective:460px}
.topjudul .topjudul-t{transform-origin:left center}
/* Ikon di depan judul (K-286) — Detail Pembelian dan Detail Penjualan.
   Sebaris dengan hurufnya, setinggi huruf besarnya. */
.topjudul-ik{display:inline-flex;vertical-align:-.16em;margin-right:7px;color:var(--ink)}
.topjudul-ik svg{width:1.05em;height:1.05em}
.topbar--ganti .topjudul-t{animation:judulMasukBawah .2s cubic-bezier(.22,.7,.25,1)}
:root[data-arah="mundur"] .topbar--ganti .topjudul-t{animation-name:judulTurunPangkat}
:root[data-arah="sejajar"] .topbar--ganti .topjudul-t{animation-name:judulPudar;animation-duration:.14s}
@keyframes judulTurunPangkat{
  from{opacity:.2;transform:translateY(-16px) scale(.66)}
  to{opacity:1;transform:none}}
@keyframes judulMasukBawah{
  from{opacity:0;transform:translateY(115%) rotateX(-52deg)}
  to{opacity:1;transform:none}}
@keyframes judulPudar{from{opacity:0}to{opacity:1}}
/* TOMBOL CARI lahir dan hilang, tidak muncul begitu saja: ia tidak ada di
   halaman yang memang tidak punya pencarian, jadi ia berkedip setiap kali
   orang berpindah dari halaman yang punya ke yang tidak. */
.topcaribtn--lahir{animation:cariLahir .18s cubic-bezier(.22,.7,.25,1)}
@keyframes cariLahir{
  from{opacity:0;transform:scale(.55)}
  to{opacity:1;transform:none}}

@media (prefers-reduced-motion:reduce){
  :root[data-arah]::view-transition-old(root){animation:vtPudarKeluar .12s ease both}
  :root[data-arah]::view-transition-new(root){animation:vtPudarMasuk .12s ease both;box-shadow:none}
  .topbar--ganti .topjudul-t,
  .topcaribtn--lahir{animation:none}
}

/* ------------------------------------------- tarik untuk menyegarkan (K-70)
   Lingkaran yang ikut turun sejauh tarikan jari (tingginya diatur skrip),
   lalu berputar begitu dilepas melewati ambangnya. Ia MENDORONG isinya,
   bukan menutupinya — sama seperti contoh yang dikirim pemiliknya. */
.tariksegar{height:0;overflow:hidden;display:flex;align-items:flex-end;justify-content:center;transition:height .2s ease}
.tariksegar-ikon{display:grid;place-items:center;width:34px;height:34px;margin-bottom:10px;border-radius:50%;
  background:var(--surface);border:1px solid var(--line);box-shadow:var(--shadow);color:var(--ink-3);
  transform:rotate(var(--putar,0deg))}
.tariksegar-ikon svg{width:18px;height:18px}
.tariksegar--siap .tariksegar-ikon{color:var(--ink);border-color:var(--line-strong)}
.tariksegar--jalan .tariksegar-ikon{animation:tariksegar .8s linear infinite}
@keyframes tariksegar{to{transform:rotate(calc(var(--putar,0deg) + 360deg))}}

/* Kolom angka + tombol reset berikon, sebaris di lebar mana pun (Kalkulator). */
.srcline--reset{flex-wrap:nowrap}
.srcline--reset > .field{flex:1 1 auto;min-width:0}
.ikonbtn--isian{width:38px;height:38px;flex:none;border:1px solid var(--line);border-radius:var(--radius);background:var(--surface)}
.ikonbtn--isian svg{width:17px;height:17px}

/* ============ LEMBAR BAWAH DI LAYAR TELEPON (K-105) ========================
   Diminta pemiliknya, dengan Tokopedia sebagai contoh: "filternya dibikin
   kayak tokopedia yaitu muncul ngeslide dari bawah untuk mobile", dan
   "banyak sekali pop-up yang terlalu ke atas dan kejauhan dari jempol".

   Dua sebab, keduanya dari layar sungguhan:
   1. JEMPOL ADA DI BAWAH. Pop-up yang berdiri di sepertiga atas layar harus
      dijangkau dengan mengubah cara memegang HP-nya — dan tombol jawabannya
      justru yang paling jauh.
   2. Daftar pilihan yang jangkarnya di TEPI KANAN membuka melewati tepi
      layar; halamannya lalu melebar dan bergeser ke kiri untuk memberi
      tempat. Lembar bawah selalu selebar layarnya, jadi tidak ada tepi yang
      bisa dilewati.

   Ditulis PALING BELAKANG dengan sengaja: ia menimpa letak pop-up dan modal
   yang ditulis jauh di atas, dan aturan yang lebih awal selalu kalah. */
@media (max-width:640px){
  /* ---- pop-up (modal) naik dari dasar layar ---- */
  .ov--modal{align-items:flex-end;justify-content:center;padding:0;overflow:hidden}
  .mdl{width:100%;max-width:100%;max-height:calc(100dvh - 46px);
    border-radius:16px 16px 0 0;border-bottom:0;
    transform:translateY(100%);transition:transform .24s cubic-bezier(.22,.7,.25,1)}
  .ov.on .mdl{transform:none}
  /* Pegangan kecil di puncaknya: ia yang mengatakan "benda ini datang dari
     bawah dan bisa ditutup", tanpa satu kata pun. */
  .mdl-hd{position:relative;padding-top:20px}
  .mdl-hd::before{content:"";position:absolute;top:8px;left:50%;transform:translateX(-50%);
    width:38px;height:4px;border-radius:99px;background:var(--line-strong)}
  /* Kakinya menempel di dasar layar — di situlah jempolnya. */
  .mdl-ft{padding-bottom:calc(14px + env(safe-area-inset-bottom))}

  /* ---- RODA TANGGAL DIKECILKAN DI LAYAR TELEPON (K-119) ----
     Dilaporkan pemiliknya dengan tangkapan layarnya: "pemilihan tanggal
     belum bisa responsif, dan teksnya terlalu besar." Ia benar — 19px pada
     baris 44px dibuat untuk pop-up 460px di layar komputer; di lembar bawah
     selebar layar telepon, lima baris sebesar itu memakan 220px dari layar
     yang tingginya sudah dibagi dengan pop-up di bawahnya.

     Yang digeser cuma SATU angka: `--rd`. Seluruh ukuran roda diturunkan
     darinya, dan `pasangRoda` mengukurnya dari DOM — jadi tidak ada satu
     angka pun yang harus diganti di dua tempat. */
  .rodabar{--rd:38px;--rd-f:16.5px;grid-template-columns:.9fr 1.7fr 1.1fr}

  /* ---- SATU TOMBOL "FILTER" di ujung kanan baris saringan ----
     Ia MENEMPEL (`position:sticky`), jadi ia tidak ikut tergulir bersama
     cip-cip di sebelahnya: berapa pun saringan yang dipunyai halaman itu,
     jalan ke seluruhnya selalu terlihat di tempat yang sama. Bayangan di
     sisi kirinya yang mengatakan bahwa ada isi yang lewat di baliknya. */
  .saringhp{display:inline-flex!important;flex:none;position:sticky;right:0;z-index:2;
    background:var(--ground);box-shadow:-14px 0 14px -6px var(--ground);padding-left:10px}
  .saringhp svg{width:15px;height:15px}

  /* ---- daftar pilihan (combo, menu) pun naik dari dasar layar ---- */
  .pop-back{position:fixed;inset:0;z-index:119;background:rgba(8,9,10,.5);pointer-events:none}
  body.pop-lembar-on{overflow:hidden}
  .pop--lembar{position:fixed;left:0;right:0;bottom:0;top:auto;
    width:100%!important;max-width:100%;min-width:0;max-height:min(72dvh,540px);
    border-radius:16px 16px 0 0;border-bottom:0;
    box-shadow:0 -12px 34px -14px rgba(0,0,0,.55);
    display:flex;flex-direction:column;
    padding-bottom:env(safe-area-inset-bottom);
    animation:lembarNaik .24s cubic-bezier(.22,.7,.25,1)}
  .pop--lembar::before{content:"";display:block;flex:none;width:38px;height:4px;border-radius:99px;
    background:var(--line-strong);margin:8px auto 4px}
  /* Pilihannya diberi tinggi jempol, bukan tinggi kursor tetikus. */
  .pop--lembar .combo-opt,.pop--lembar .mi{min-height:46px;font-size:var(--f13)}
  .pop--lembar .combo-list{flex:1 1 auto}
  @keyframes lembarNaik{from{transform:translateY(100%)}to{transform:none}}
}
@media (max-width:640px) and (prefers-reduced-motion:reduce){
  .mdl{transition:none}
  .pop--lembar{animation:none}
}

/* ============ DETAIL ITEM: FOTONYA MENTOK KE BARIS KEPALA (K-105) ==========
   Diminta pemiliknya: "fotonya harusnya dimepetkan sampai mentok ke kotak area
   judul halaman, begitu pula pada web itu fotonya bahkan masih ngambang dan
   bisa ketarik keatas dikit, padahal memang seharusnya posisinya mentok diatas
   dan gak kescroll."

   Ia benar dua-duanya, dan sebabnya satu: jarak atas halaman. Di komputer
   kolom kirinya MENGGANTUNG pada 70px sementara ia mulai 24px di bawah baris
   kepala — jadi ia sempat bergerak naik 24px sebelum menempel, dan gerakan
   itulah yang terbaca sebagai "ngambang". Jarak atasnya dinolkan di halaman
   ini saja, dan menggantungnya dipatok pada tinggi baris kepala yang sama. */
.page:has(> .unitsplit){--pad-atas:0px}
.unitsplit{margin-top:0}
@media (min-width:961px){ .page:has(> .unitsplit){--pad-atas:20px} }
/* TIGA TINDAKAN DETAIL ITEM: Transfer dan Servis tinggal ikonnya, Jual paling
   kanan dan paling besar (K-211). Bentuknya sama persis dengan bilah Pilih di
   Daftar Item — yang paling sering ditekan yang paling lebar, dan ia berdiri
   di tempat yang sama di kedua halaman. */
.itemaksi{flex-wrap:nowrap}
@media (max-width:820px){
  /* TOMBOL TINDAKAN TURUN KE DASAR LAYAR (diminta pemiliknya). Jual, Servis,
     dan Transfer adalah pekerjaan, dan pekerjaan harus terjangkau jempol —
     bukan berada di kaki kolom kanan yang harus dicari dengan menggulir.
     Yang tertahan dokumen lain tetap DIGAMBAR lalu dimatikan, dengan sebabnya
     sebagai judul tetikusnya: yang hilang membuat orang mencari-cari ke mana
     perginya, yang mati mengatakan "belum sekarang". */
  .itemaksi{position:fixed;left:0;right:0;bottom:0;z-index:60;margin:0;
    padding:10px 16px calc(10px + env(safe-area-inset-bottom));
    background:linear-gradient(to top, var(--ground) 62%, transparent);
    display:flex;gap:8px;pointer-events:none}
  .itemaksi > .btn{pointer-events:auto;flex:1 1 0;min-width:0;justify-content:center;
    height:46px;font-size:var(--f13);border-radius:var(--radius);
    box-shadow:0 6px 18px -8px rgba(0,0,0,.45)}
  /* Yang tinggal ikonnya tidak ikut melar — kalau ikut, ketiganya kembali
     sama lebar dan Jual berhenti menonjol justru di layar tempat ia paling
     sering ditekan. */
  .itemaksi > .btn--ikon{flex:none;width:52px;padding:0}
  /* Di bilah mengambang Jual mengambil seluruh sisa lebarnya — di layar
     telepon ia satu-satunya tombol yang ditekan tanpa dibidik. */
  .itemaksi-jual{flex:1 1 auto}
  .itemaksi > .btn svg{width:17px;height:17px}
  .itemaksi > .btn:disabled{opacity:.45}
  .page:has(.itemaksi){padding-bottom:calc(78px + env(safe-area-inset-bottom))}
}

/* ---------- isi lembar Filter (K-106) ----------
   Satu blok per saringan: sebutannya di atas, pilihannya sebagai cip yang
   melipat di bawahnya. Cip, bukan daftar menurun — di lembar setinggi layar
   telepon, tiga saringan berisi lima pilihan masing-masing berarti lima belas
   baris yang harus digulir, sementara sebagai cip ketiganya muat sekali
   lihat. */
/* IKON CORONG DI UJUNG KANAN BARIS SARINGAN (K-250). Dulu ia cuma hidup di
   layar telepon — namanya masih menyebutkannya — dan di layar lebar seluruh
   saringan berjajar sebagai cip. Sejak pemiliknya meminta setiap daftar
   berbentuk seperti Daftar Item, ia berdiri di kedua lebar layar. Bentuknya di
   telepon diganti lagi oleh blok `@media` di atas: menempel di ujung kanan
   baris yang menggulir. IKON SAJA di baris bertab (Pembelian), bertulisan
   "Filter" di daftar lain; angka yang disembunyikannya (K-263) dicabut di
   K-271 — angkanya kini di tab yang menyala. `inline-flex` BUKAN `grid`: jebakan urutan yang
   sudah lima kali memakan korban di berkas ini. */
.saringhp{display:inline-flex;align-items:center;justify-content:center;gap:7px;padding:0 10px}
/* Tulisan "Filter" pada tombol yang berdiri SENDIRIAN (K-263, dipulihkan
   K-271 setelah pemiliknya meralat: ikon saja cuma di Pembelian dan
   Penjualan). */
.saringhp-t{font-size:var(--f12)}
/* Polos: tanpa kotak, tanpa latar — sama dengan tombol Filter di Daftar Item,
   yang memang benda LAIN (`.stattab-filter` di inv-item.js, bukan `.saringhp`)
   tetapi mengerjakan hal yang sama persis. Dua tombol begitu tidak boleh
   terbaca sebagai dua benda yang berbeda — dan di baris bertab keduanya
   memang sama: ikon saja. */
.filterhead--satu .filterhead-kanan .saringhp{border:0;background:none;color:var(--ink-3)}
@media (hover:hover){ .filterhead--satu .filterhead-kanan .saringhp:hover{background:var(--surface-2);color:var(--ink)} }
.filterhead--satu .filterhead-kanan .saringhp svg{width:16px;height:16px}
.saringlembar{display:flex;flex-direction:column;gap:16px}
.saringblok-k{font-size:var(--f11);font-weight:600;color:var(--ink-3);
  text-transform:uppercase;letter-spacing:.05em;margin-bottom:8px}
.saringblok-o{display:flex;flex-wrap:wrap;gap:7px}
.saringcip{display:inline-flex;align-items:center;min-height:36px;padding:0 13px;
  border:1px solid var(--line-strong);border-radius:99px;background:var(--surface);
  font:inherit;font-size:var(--f12);color:var(--ink-2);cursor:pointer;text-align:left;
  transition:border-color .14s,background .14s,color .14s}
.saringcip:hover{border-color:var(--ink-3);color:var(--ink)}
.saringcip.on{border-color:var(--ink);background:var(--ink);color:var(--on-ink);font-weight:600}
.saringcip:focus-visible{outline:2px solid var(--ink);outline-offset:2px}

/* ---------- LOGO REKENING (K-120) ----------
   Diminta pemiliknya: "kita cukup kesulitan ketika membedakan antar rekening
   — gimana jika setiap akun itu sebelah kirinya selalu ada logo seperti logo
   BCA, logo Mandiri, logo Cash."

   `object-fit:contain`, BUKAN `cover`. Logo bank hampir seluruhnya melebar,
   dan memotongnya di tengah membuang separuh namanya — kebalikan dari foto
   barang, yang justru dipotong persegi (K-117). Petaknya sendiri tetap
   persegi supaya seluruh baris berdiri sejajar berapa pun bentuk logonya.

   Latarnya `--surface-2`, bukan putih: logo berlatar tembus pandang harus
   tetap terbaca di tema gelap maupun terang, dan putih yang dipatok membuat
   petaknya menyala sendirian di antara baris gelap. */
.akunlogo{flex:none;display:grid;place-items:center;width:26px;height:26px;
  border-radius:6px;background:var(--surface-2);overflow:hidden}
.akunlogo img{width:100%;height:100%;object-fit:contain;display:block}
.akunlogo .avatarhuruf{font-size:var(--f10);font-weight:600;border-radius:0}

/* Di daftar pilihan ia sedikit lebih besar — di situ orang sedang MEMILIH,
   dan logonya yang dibaca lebih dulu daripada namanya. */
.combo-opt--ava{align-items:center}
.combo-opt--ava .akunlogo{width:28px;height:28px}
.combo-btn--ava{padding-left:8px}
/* Yang dipotong titik-titik harus NAMANYA, bukan logonya. Sejak logo berdiri
   sebagai anak pertama tombolnya, aturan `.combo-btn > span:first-child` yang
   sudah ada mengenai petak logo — dan nama rekening yang panjang melebarkan
   tombolnya alih-alih dipotong. */
.combo-btn--ava > .akunlogo + span{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* BARISNYA LEBIH TIPIS (diminta pemiliknya). Yang dikecilkan keterangan
   lokasinya, bukan nama akunnya: nama itulah yang dicari, dan nama yang ikut
   mengecil membuat seluruh baris terbaca sebagai keterangan. */
.combo-opt--ava .m{font-size:var(--f11);font-weight:400;color:var(--ink-3)}
.combo-btn--ava .sub{font-size:var(--f11)}

/* Kartu Master Data yang berlogo: logonya di kiri, nama dan keterangannya
   menumpuk di kanannya. Kartu lain tidak berubah sama sekali. */
.lc-sec--ava{display:flex;align-items:center;gap:11px}
.lc-sec--ava .akunlogo{width:36px;height:36px;border-radius:8px}
.lc-sec--ava .akunlogo .avatarhuruf{font-size:var(--f12)}
/* Pembungkusnya SELALU ada, juga pada kartu master yang tidak berlogo —
   satu bentuk untuk 55 halaman. `display:block` wajib: sebagai `span` inline
   yang berisi dua elemen blok, ia melahirkan kotak anonim dan tinggi barisnya
   bergeser sepiksel dari kartu yang berlogo. */
.lc-teks{display:block;min-width:0}
.lc-teks .lc-title{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* Kartu saldo di Buku Kas. */
.rekkartu-nm > .akunlogo{width:28px;height:28px;border-radius:7px}

/* Baris Logo di halaman detail Akun Keuangan. */
.logobaris .akunlogo{width:40px;height:40px;border-radius:9px}
.logobaris .akunlogo .avatarhuruf{font-size:var(--f13)}

/* Petak pilih logo di formulirnya. Bentuknya meniru petak Tambah Foto pada
   papan foto — garis putus-putus untuk yang belum ada isinya, jadi tempat
   logonya terlihat sebagai TEMPAT dan bukan sebagai perintah yang dicari. */
.logopilih{display:flex;align-items:center;gap:12px}
.logopetak{flex:none;display:grid;place-items:center;width:72px;height:72px;
  border-radius:10px;background:var(--surface-2);overflow:hidden}
.logopetak img{width:100%;height:100%;object-fit:contain;display:block}
.logopetak--kosong{border:1px dashed var(--line-strong);background:transparent;color:var(--ink-3)}
.logopetak--kosong svg{width:22px;height:22px}
.logoaksi{display:flex;flex-wrap:wrap;gap:8px}

/* ==========================================================================
   ETALASE PUBLIK (K-133)
   Hanya halaman yang dibuka PELANGGAN. Satu pun aturan di bawah ini tidak
   menyentuh layar yang dipakai pegawai.
   ========================================================================== */

/* ---------- kartu produk yang tingginya berbeda-beda ----------
   Diminta pemiliknya: "ukuran kartu kalau untuk pelanggan itu beda-beda,
   bukan karena teksnya panjang, tapi karena kontennya beda-beda."

   DIPAKAI LAJUR CSS (`columns`), BUKAN GRID. Pada grid, kartu yang pendek
   meninggalkan lubang kosong di bawahnya sampai setinggi kartu tertinggi di
   barisnya — dan justru lubang itulah yang membuat etalase terlihat rusak,
   bukan tingginya yang berbeda. Lajur menyusunnya menurun dan rapat, tanpa
   satu lubang pun.

   Yang dibayar: urutannya menjadi MENURUN per lajur, bukan mendatar. Untuk
   daftar yang dibaca sambil melihat-lihat itu tidak menghalangi apa pun —
   tetapi ia sebabnya kenapa cara ini TIDAK dipakai di daftar dalam ERP, yang
   dibaca sambil mencari satu barang tertentu. */
/* LAJUR MENGALIR DICABUT SELURUHNYA (K-176, keputusan pemiliknya).
   K-133 dulu menyusun kartu etalase dengan `columns`, supaya kartu yang
   tingginya berbeda-beda menumpuk rapat tanpa lubang. Pemiliknya
   membatalkannya: *"untuk saat ini komponennya juga belum banyak jadi saya
   rasa tidak mungkin panjang card bisa beda-beda, jadi tetap saat ini harus
   konsisten dulu ukurannya."*

   Jadi yang berlaku sekarang GRID BIASA di SEGALA lebar, dan barisnya rata
   dengan sendirinya. Lajur mengalirnya tidak disisakan "untuk nanti": ia
   justru mekanisme yang menghasilkan tepi bergerigi yang dilaporkannya, dan
   menyimpan kode yang hari ini cuma merusak berarti menyimpan kode mati.

   YANG DIJANJIKAN UNTUK NANTI tetap dicatat, tetapi BELUM DIBANGUN: begitu
   komponen yang benar-benar menarik lahir — bebas ongkir, toko khusus,
   garansi dobel — tinggi kartu boleh kembali berbeda-beda, DAN HANYA DI LAYAR
   TELEPON: *"tidak berlaku untuk mode desktop ya, jadi hanya berlaku untuk
   mode mobile."* Saat itu tiba ia satu media query, bukan satu rancangan. */
.shopgrid--alir{display:grid;grid-template-columns:repeat(auto-fill,minmax(196px,1fr));
  gap:12px;columns:auto}
/* DI LAPTOP LIMA, DAN ANGKANYA DIPUTUSKAN BUKAN DIHITUNG (K-260). Dilaporkan
   pemiliknya lalu diperjelasnya sendiri satu pesan kemudian: *"online shop
   yang ditampilkan ke pelanggan saat pakai mode laptop itu harusnya cardnya
   muat 5, bukan cuma 4"*, dan *"intinya card yang di laptop kebesaran"* —
   yang kedua menyebut penyakitnya, yang pertama gejalanya. Keduanya menunjuk
   satu halaman yang sama, dan itu DIUKUR: dari tiga halaman yang memakai
   petak ini, yang pernah menjawab EMPAT cuma yang berbilah saringan, dan di
   situ pula kartunya PALING BESAR — 237px di layar 1280 melawan 213px di
   layar 1440 yang lebih luas. Etalase yang kartunya MEMBESAR di layar yang
   lebih kecil, persis yang dilihatnya.

   YANG SALAH BUKAN ANGKANYA MELAINKAN TIDAK ADANYA ANGKA: `auto-fill`
   menjawab pertanyaan yang LAIN — "berapa kartu selebar 196px yang muat?" —
   dan jawabannya bergeser mengikuti lebar jendela, lebar bilah saringan,
   jarak antar kartu, dan padding halamannya. Karena itu ia menjawab EMPAT di
   1280px dan LIMA di 1440px tanpa seorang pun pernah memutuskan keduanya.
   Diukur: petaknya 984px di 1280 dan 1114px di 1440, dan 5x196+4x12 = 1028
   memang tidak muat di 984.

   SATU PERCOBAAN DITOLAK, DAN SEBABNYA DUA PIKSEL: menurunkan lantainya 196
   jadi 176 memang menghasilkan lima dari 1280 sampai 1920 — tetapi enam lajur
   menuntut 6x176+5x12 = 1116px sementara petak terlebarnya 1114px. Ia benar
   hari ini dengan selisih DUA PIKSEL, dan hari `--shop-pad`, jarak kartunya,
   atau lebar bilah saringannya bergeser sedikit saja, etalasenya diam-diam
   menjadi enam. Itu cacat yang sama persis dengan K-258.

   AMBANGNYA 1250px, dan itu BUKAN angka bulat yang enak dibaca melainkan
   batas yang diukur dari KARTUNYA: patokannya kartu di layar telepon, 183px
   (390px, dua lajur), dan di 1250px lima lajur menghasilkan 181px — di situ
   kartu laptopnya berhenti menyusut melewati kartu yang sudah dipakai
   pelanggan sehari-hari. Di bawahnya ia terus menyempit (179px di 1240px,
   161px di 1152px), dan etalase yang kartunya MENYEMPIT di layar yang lebih
   BESAR membaca seperti kerusakan — sama seperti yang barusan dilaporkan.
   Di bawah ambang ini `auto-fill` di atas tetap berlaku, dan jawabannya empat.

   DUA PIKSEL SISANYA TIDAK DIKEJAR, dan itu disengaja: angka pastinya
   bergantung pada lebar batang gulir perambannya — 181px di sini, lebih lebar
   sedikit di peramban yang batang gulirnya mengambang (Mac). Mengejar 183px
   persis berarti menyetel ambangnya pada satu peramban lalu meleset di
   peramban lain, dan itu jenis ketelitian yang sama yang baru saja ditolak di
   atas.

   `minmax(0,1fr)` BUKAN `1fr`, kali ketiga sesudah K-256 dan K-258: nama
   barang yang panjang tanpa spasi melebarkan lajurnya sendiri, dan petaknya
   mendorong halaman melebar ke samping.

   HALAMAN BERBILAH SARINGAN yang dilaporkannya, dan penunjuknya
   `.shoplayout` — itu satu-satunya yang pernah menjawab empat.

   DUA HALAMAN SISANYA MENYUSUL DI K-262, dan yang membawanya ke sini bukan
   selera melainkan ANGKA YANG SAMA. K-260 membiarkan halaman satu toko dan
   "Kamu Mungkin Juga Suka" karena keduanya tidak pernah menjawab empat;
   yang tidak ikut diukur waktu itu berapa LEBAR kartunya di tiap lebar
   jendela, dan begitu diukur penyakitnya persis penyakit yang dilaporkan:

     1152px  petak 1114  5 lajur  213px
     1250px  petak 1212  5 lajur  233px   <- paling besar
     1280px  petak 1242  6 lajur  197px
     1440px  petak 1372  6 lajur  219px

   Kartunya MEMBESAR saat jendelanya MENYUSUT dari 1280 ke 1250 — 197px
   menjadi 233px — dan 233px itu lebih besar daripada 219px di layar 1440px
   yang jauh lebih luas. Sebabnya sama persis: `auto-fill` menjawab "berapa
   kartu selebar 196px yang muat", bukan "berapa kartu yang kita mau".

   ENAM, dan ambangnya ambang YANG SAMA: di 1250px enam lajur menghasilkan
   192px, masih di atas kartu telepon (183px), jadi tidak ada alasan memakai
   angka kedua. Tujuh ditolak dengan ukuran, bukan dengan selera — di 1250px
   ia 163px, jauh di bawah kartu telepon, dan di situ nama barang beserta
   harganya mulai terpenggal. Kedua angkanya sengaja berdiri BERDAMPINGAN di
   satu blok supaya tidak ada yang menggeser salah satunya tanpa melihat yang
   lain; yang lebih rinci (`.shoplayout`) menang, dan itu memang urutannya.

   DI BAWAH 1250px KEDUANYA TIDAK DISENTUH — di situ `auto-fill` menjawab
   lima, dan memaksanya enam menjadikan kartunya 176px di 1152px: lebih
   sempit daripada kartu telepon, cacat yang baru saja dihindari di atas. */
@media(min-width:1250px){
  .shopgrid--alir{grid-template-columns:repeat(6,minmax(0,1fr))}
  .shoplayout .shopgrid--alir{grid-template-columns:repeat(5,minmax(0,1fr))}
}
.shopcard-jarak{font-style:normal;margin-left:auto;padding-left:8px;flex:none;
  color:var(--ink-3);font-variant-numeric:tabular-nums}
.shopcard .lok{display:flex;align-items:center;gap:4px}
/* BARIS LOKASI DIPAKU KE DASAR KARTUNYA. Petak grid sudah meregang sebaris,
   jadi yang tersisa cuma memastikan isinya ikut turun: tanpa ini kartu yang
   cipnya lebih sedikit menyisakan lubang di bawah barisnya, bukan di atas. */
.shopcard .lok{margin-top:auto}
@media(max-width:640px){
  .shopgrid--alir{grid-template-columns:repeat(2,minmax(0,1fr));gap:6px}
  .shopcard .bd{min-height:0}
}
/* KARTU ETALASE DIRAMPINGKAN (tahap 6c, butir I3: "kartu kebesaran — di HP
   jelas, di laptop sedikit"). JUMLAH LAJURNYA TIDAK DISENTUH — ia keputusan
   K-260/K-262, dan lajur lebih banyak di laptop justru membuat kartunya lebih
   sempit daripada kartu telepon. Yang dipangkas RUANG DI DALAMNYA: jarak
   isinya, tinggi judulnya, dan huruf harganya, sehingga satu kartu memakan
   tinggi lebih sedikit dan layar memuat lebih banyak barang. Di telepon
   lebih banyak daripada di laptop, sesuai laporannya. */
.shopcard .bd{padding:8px 10px 10px}
.shopcard h3{margin-bottom:4px;line-height:1.3;min-height:2.6em}
/* RAPAT ALA SHOPEE (tahap 8, butir I1: "jangan beri ampun space di tempat
   manapun"). Diukur di layar 320px: kartunya 149px, harga 94px + cip 50px +
   jarak 5px tidak muat di 131px sisanya, jadi cipnya terlempar ke baris
   bawah. Yang dipangkas cipnya (bukan harganya — harga tidak pernah boleh
   terpotong) dan tepi dalam kartunya. */
@media(max-width:640px){
  .shopgrid--alir{gap:5px}
  .shopcard .hrg{gap:2px 4px}
  .tandadisk{height:16px;padding:0 3px;gap:1px;font-size:var(--f10)}
  .tandadisk svg{width:10px;height:10px}
  .tandagaransi{top:5px;left:5px;height:19px;padding:0 7px 0 6px;gap:3px;font-size:var(--f10)}
  .tandagaransi svg{width:10px;height:10px}
  .shopcard .bd{padding:6px 6px 7px}
  .shopcard h3{font-size:var(--f12)}
  .shopcard .hrg b{font-size:var(--f13)}
  .shopcard .lok{font-size:var(--f11)}
}

/* ---------- KOTAK TOKO DI HALAMAN PRODUK, DI LAYAR TELEPON ----------
   BENTUK SHOPEE (K-274, contoh pemiliknya): baris pertama avatar, nama dan
   kotanya, lalu tombol Kunjungi di ujung kanan; baris kedua keempat angkanya
   SELEBAR KOTAK, dipisah garis tegak. Petak dua-dua K-255 (yang ada karena
   empat petak BERKOTAK tidak muat seperempat layar) dicabut: tanpa kotak,
   empat angka pendek muat berjajar di 360px. */
@media(max-width:640px){
  .pdp-toko{flex-wrap:wrap;padding:14px 12px;gap:14px 10px}
  .pdp-toko-atas{flex:1 1 0}
  .pdp-toko-stat{order:3;flex:1 0 100%;grid-template-columns:repeat(4,minmax(0,1fr))}
  .pdp-toko-stat > *{padding:2px 4px}
}

/* ---------- HALAMAN PRODUK DI LAYAR TELEPON (K-182) ----------
   DILAPORKAN PEMILIKNYA, dan ketiganya DIUKUR di layar 360px sebelum
   disentuh — tangkapan layar yang ia kirim semuanya Shopee (rujukan), jadi
   yang rusak harus dicari sendiri.

   1 · FOTO BESARNYA MEPET KE KIRI, dan 75px di kanannya kosong.
       Terukur: kotaknya 281 x 281, tepi kirinya di 4px, tepi kanannya di
       285px pada layar 360px. Itu persis "foto produk yang besar juga
       meleset terlalu ke kiri".

       Sebabnya DUA ATURAN YANG SALING MENIMPA, dan yang menang ditulis lebih
       belakang: K-177 menyetel `aspect-ratio:auto;height:min(78vw,42dvh)`
       supaya fotonya mengisi lebar dan dipotong tengahnya — lalu
       `.pdp-utama.itemfoto-utama{aspect-ratio:1/1}` yang berdiri jauh di
       bawahnya mengembalikannya menjadi PERSEGI. Tingginya terlanjur dipatok
       281px, jadi lebarnya ikut 281px; sisa lebar layarnya menganggur,
       sementara margin negatif warisan `.itemfoto-utama` (yang memang dibuat
       untuk halaman Detail Item, bukan untuk halaman ini) menariknya 16px ke
       kiri. Yang terlihat: foto yang meleset, dan halaman yang terasa tidak
       "fix".

       Ditambal DI SINI, paling belakang, supaya tidak ada aturan lain yang
       bisa menimpanya lagi — dan jejeran foto kecilnya ikut mepet, kalau
       tidak ia berdiri menjorok ke dalam di bawah foto yang mentok tepi.

   2 · BILAH TOMBOLNYA MENGGANTUNG 16px DI ATAS DASAR LAYAR.
       Terukur: tepi bawahnya di 784px pada layar setinggi 800px. Itu
       "tombol Hubungi lewat WhatsApp nggak pas di bawah, malah nggantung".

       Sebabnya bentuk yang sama: blok telepon menyetel `margin:0`, lalu
       `.pdp-aksi{margin-bottom:16px}` milik tata letak layar lebar — yang
       ditulis lebih belakang — mengembalikannya. Margin itu benar selama
       bilahnya mengalir di dalam halaman, dan salah begitu ia menempel di
       dasar layar.

   3 · "PRODUK LAIN DARI TOKO INI" BISA DIGULIR ATAS-BAWAH.
       Terukur: isinya 390px di dalam kotak 366px — 24px yang bisa digeser
       tegak, padahal ia baris yang mestinya cuma bergeser ke samping.

       Sebabnya aturan CSS yang jarang diingat: begitu satu sumbu diberi
       `auto`, sumbu yang lain BERHENTI menjadi `visible` dan ikut menjadi
       `auto`. Yang menonjol ke bawah bilah "Mau tanya-tanya dulu" (K-176),
       yang memang mengambang di luar kartunya.

       DITAMBAL DI PANGKALNYA, bukan dengan menahan gulirnya. `overflow-y`
       tidak bisa diberi `clip` di sini — begitu sumbu yang lain `auto`, CSS
       menghitung `clip` menjadi `hidden`, dan `hidden` MEMOTONG bilah itu di
       layar berkursor, tempat ia justru satu-satunya gunanya. Jadi yang
       diubah bilahnya sendiri: di layar sentuh ia tidak digambar sama sekali
       (`display:none`), dan di layar berkursor barisnya diberi ruang setinggi
       bilahnya. Tidak ada lagi yang menonjol, jadi tidak ada lagi yang bisa
       digulir tegak — di kedua jenis layar. */
/* ---------- FOTO PRODUKNYA PERSEGI, SAMA DENGAN DETAIL ITEM (K-220) ----------
   Dilaporkan pemiliknya: "halaman detail item pada online shop dari sisi
   pelanggan area bagian atas gak proper, harusnya persegi seperti detail item
   inventory gitu, tapi malah fotonya persegi panjang."

   Diukur di layar 390 x 844 sebelum disentuh, dan ia benar sampai ke
   pikselnya: Detail Item Inventory 390 x 390 (persegi), halaman produk
   390 x 304 (melintang). Angka 304 itu `min(78vw,42dvh)` yang dipasang K-177
   supaya harganya terlihat tanpa digulir — dan pada foto barang yang hampir
   selalu persegi, `object-fit:cover` lalu MEMOTONG atas dan bawahnya.

   INI MENCABUT SEPARUH K-177, dan itu disebut apa adanya: di sana pemiliknya
   sendiri yang berkata fotonya "kebesaran" saat persegi selebar layar. Yang
   mengubah jawabannya bukan selera melainkan sebuah halaman yang lahir
   sesudahnya — K-207 membuat Detail Item Inventory persegi selebar layar
   dengan kepala yang mengambang di atasnya, dan ia menyetujuinya. Sejak itu
   DUA halaman yang bentuknya sama berdiri dengan perbandingan yang berbeda,
   dan Consistency Above Everything menang atas tinggi yang dihemat.

   Yang dibayar: harganya turun 86px. Di layar setinggi 844px ia tetap
   terlihat tanpa digulir; di layar yang jauh lebih pendek ia tidak. Itu harga
   yang sama yang sudah dibayar Detail Item Inventory sejak K-207. */
@media(max-width:640px){
  .pdp-utama,.pdp-utama.itemfoto-utama{
    aspect-ratio:1/1;height:auto;max-width:none;
    margin-inline:calc(var(--shop-pad, 14px) * -1);
    border-radius:0;border-left:0;border-right:0}
  /* SAMPUL TOKO IKUT MENTOK KE TEPI (K-256), dengan alasan yang sama persis:
     kepalanya mengambang di atasnya, dan gambar yang menyisakan celah 8px di
     kiri-kanan sementara tombol Kembali berdiri DI ATASNYA terbaca sebagai
     dua benda yang tidak sengaja bertumpuk. Sudutnya ikut diluruskan —
     sudut membulat yang menempel di tepi layar tidak pernah benar. */
  .tokoprofil--sampul{margin-inline:calc(var(--shop-pad, 14px) * -1);border-radius:0}
  .tokoprofil--sampul .tokobanner{border-radius:0}
  .tokoprofil--sampul::after{border-radius:0}
  /* DERETAN FOTO KECIL DICABUT DI LAYAR TELEPON (K-251), diminta pemiliknya:
     *"saat pakai mode mobile, pada halaman detail item tolong jangan ada foto
     dibawah yang dijejer2, harusnya caranya adalah dengan slide slide cukup"*.

     Di layar telepon ia memang tidak menjawab apa pun yang belum dijawab:
     jarinya sudah bisa menggeser gambarnya sendiri, titik penandanya sudah
     mengatakan foto ke berapa dari berapa, dan sebaris petak 50px memakan
     tinggi yang seharusnya jadi milik harga barangnya. Di layar lebar ia
     TETAP — di sana tidak ada jari yang menggeser, dan petaknya tidak
     mendorong apa pun ke bawah karena keterangannya berdiri di sebelahnya.

     Yang menggantikannya di telepon: geseran jari, dan menekan gambarnya
     untuk membukanya besar di tengah. */
  .pdp-mini{display:none}
  .pdp-aksi{margin:0}
}

/* ---------- BILAH "MAU TANYA-TANYA DULU" (K-176) ----------
   Muncul saat kursor berada di atas kartunya, menempel di bawahnya, dan
   menekannya melempar ke WhatsApp. Ia MENGAMBANG di atas isi di bawahnya,
   tidak mendorongnya: bilah yang mendorong membuat seluruh daftar bergeser
   setiap kali kursor lewat, dan barang yang hendak ditekan orang berpindah
   tepat sebelum ia menekannya. */
/* SEL-nya yang menjadi petak grid, jadi ia yang diregangkan sebaris — dan
   kartunya harus ikut mengisi seluruh tingginya. Tanpa `flex:1` kartu yang
   cipnya lebih sedikit berhenti lebih tinggi daripada tetangganya, dan tepi
   bawah barisnya bergerigi. */
.shopcell{position:relative;display:flex;flex-direction:column}
.shopcell > .shopcard{flex:1 1 auto}
/* TINGGINYA SATU ANGKA YANG DIBACA DUA TEMPAT (K-258) — bilahnya sendiri,
   dan ruang yang disediakan baris geser di bawahnya. Dua angka yang ditulis
   sendiri-sendiri cepat atau lambat berbeda, dan K-182 sudah membuktikannya:
   ia mencadangkan 34px untuk bilah setinggi 38px, dan empat piksel itulah
   yang dilaporkan pemiliknya sebagai "bisa scroll atas bawah walaupun dikit"
   beserta produk yang "gerak2 gak jelas". Lihat bagiannya di
   prototipe/CLAUDE.md. */
.shoptanya{position:absolute;left:0;right:0;top:100%;z-index:5;
  height:var(--tanya-t);display:grid;place-items:center;text-align:center;text-decoration:none;
  background:var(--ink);color:var(--on-ink);font-size:var(--f12);font-weight:500;
  padding:0 10px;border-radius:0 0 var(--radius) var(--radius);
  opacity:0;transform:translateY(-6px);pointer-events:none;
  transition:opacity .13s,transform .13s}
/* HANYA DI LAYAR BERKURSOR. Di layar sentuh tidak ada keadaan "diarahkan ke
   sana", dan bilah yang muncul saat disentuh menelan ketukan yang sebenarnya
   dimaksudkan untuk membuka barangnya. */
@media (hover:hover){
  .shopcell:hover .shoptanya,
  .shopcell:focus-within .shoptanya{opacity:1;transform:translateY(0);pointer-events:auto}
  .shopcell:hover .shopcard{border-bottom-left-radius:0;border-bottom-right-radius:0}
}
@media (prefers-reduced-motion: reduce){ .shoptanya{transition:none} }
/* K-182 · IA BERHENTI MENEMPATI RUANG DI LAYAR SENTUH, bukan cuma
   disembunyikan. Catatan di atas sudah lama berkata "HANYA DI LAYAR
   BERKURSOR", tetapi yang dikerjakan selama ini cuma `opacity:0` — jadi di
   telepon ia tetap menonjol 24px di bawah kartunya, dan baris "Produk Lain
   Dari Toko Ini" yang mestinya cuma bergeser ke samping jadi bisa digulir
   atas-bawah. Di layar berkursor ia tetap ada, dan barisnya yang diberi
   ruang setinggi bilahnya.

   HARUS BERDIRI SESUDAH `.shoptanya` di atas: media query tidak menambah
   kekuatan pemilih, jadi yang ditulis lebih belakang yang menang — percobaan
   pertama ditaruh sebelum­nya dan tidak berlaku sama sekali. */
/* K-258 MENGUBAH BARIS "PRODUK LAIN" MENJADI PETAK DUA LAJUR DI TELEPON — dan
   DIRALAT pemiliknya di K-274: yang diminta dicabut dulu bukan geserannya
   melainkan batang gulir yang ikut bergeser. Petak, batas empat kartu, dan
   cadangan ruang bilah tanya di bawahnya dicabut seluruhnya; lihat blok
   `.barisgeser` di atas. */
@media (hover:none){ .shoptanya{display:none} }


/* ---------- LAYANAN KAMI (K-289) ----------
   Menggantikan kartu Tukar Tambah/Jual (K-176) dan bilah jempolnya (K-177),
   keduanya dicabut pemiliknya. Kotak menu ala aplikasi: ikon bulat di atas,
   namanya di bawah. Di telepon empat lajur (dua baris), di layar lebar
   delapan sebaris. */
.layanan{margin:12px 0 16px;padding:12px 10px 10px;border:1px solid var(--line);border-radius:var(--radius);
  background:var(--surface)}
.layanan h2{font-size:var(--f14);font-weight:600;letter-spacing:normal;margin:0 0 10px 2px}
.layanan-grid{display:grid;grid-template-columns:repeat(8,minmax(0,1fr));gap:8px 4px}
.layanan-b{display:flex;flex-direction:column;align-items:center;gap:6px;min-width:0;padding:4px 2px;
  border:0;border-radius:var(--radius);background:none;color:inherit;text-decoration:none;font:inherit;cursor:pointer}
.layanan-b:hover{background:var(--surface-2)}
.layanan-ik{flex:none;width:40px;height:40px;display:grid;place-items:center;border-radius:50%;
  background:var(--surface-2);border:1px solid var(--line);color:var(--ink)}
.layanan-ik svg{width:19px;height:19px}
.layanan-t{font-size:var(--f11);line-height:1.25;text-align:center;color:var(--ink-2);overflow-wrap:anywhere}
@media (max-width:640px){
  .layanan{margin:8px 0 14px;padding:10px 6px 8px}
  .layanan-grid{grid-template-columns:repeat(4,minmax(0,1fr));gap:10px 2px}
}
.layananlist{display:flex;flex-direction:column}
.layananlist-r{display:flex;align-items:center;gap:10px;padding:10px 0}
.layananlist-r + .layananlist-r{border-top:1px solid var(--line)}
.layananlist-bd{display:flex;flex-direction:column;min-width:0;flex:1 1 auto}
.layananlist-bd b{font-size:var(--f13);font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.layananlist-bd span{font-size:var(--f12);color:var(--ink-3)}
.layananlist-r .btn{flex:none}
.shopberanda{margin-top:12px}

/* ---------- SARINGAN ETALASE (K-176) ----------
   Dua wajah untuk satu daftar: kolom kiri yang MENGAMBANG di layar lebar,
   sebaris cip yang digeser di layar telepon. Diminta pemiliknya, dan
   bentuknya ia yang menunjukkan. */
.shoplayout{display:grid;grid-template-columns:232px minmax(0,1fr);gap:26px;align-items:start}
/* MENGAMBANG DAN SELALU IKUT — "sebelah kiri itu filter-filternya ngambang
   dan selalu ngikut". Puncaknya dipatok di bawah kepala halaman yang juga
   sticky (64px), jadi keduanya tidak pernah saling menutupi. */
.shopflt{position:sticky;top:80px;max-height:calc(100dvh - 100px);overflow:auto;
  scrollbar-width:thin}
.shopflt-in{border:1px solid var(--line);border-radius:var(--radius);background:var(--surface);padding:14px 15px}
.shopflt-hd{display:flex;align-items:center;gap:8px;padding-bottom:11px;margin-bottom:4px;
  border-bottom:1px solid var(--line)}
.shopflt-hd svg{width:15px;height:15px;color:var(--ink-3);flex:none}
.shopflt-hd h3{margin:0;font-family:var(--f-judul);font-size:var(--f12);font-weight:600;
  letter-spacing:.06em;text-transform:uppercase}
.shopflt-hd .linkbtn{margin-left:auto;font-size:var(--f12)}
.fltgrup{padding:12px 0 6px;border-bottom:1px solid var(--line)}
.fltgrup:last-child{border-bottom:0}
.fltgrup h4{margin:0 0 8px;font-family:var(--f-judul);font-size:var(--f12);font-weight:600}
.fltopt{display:flex;align-items:center;gap:9px;padding:5px 0;cursor:pointer;font-size:var(--f12)}
.fltopt input{width:15px;height:15px;flex:none;accent-color:var(--ink);cursor:pointer}
.fltopt-t{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.fltopt i{font-style:normal;flex:none;font-size:var(--f11);color:var(--ink-3);
  font-variant-numeric:tabular-nums}
.fltopt:hover .fltopt-t{color:var(--ink)}

/* SATU BARIS SARINGAN (K-177): cip urutan yang digeser, dan tombol Filter
   menempel di kanannya. Tidak ada lagi baris cip saringan terpisah di atasnya,
   dan tidak ada lagi kata "Urutkan" — cipnya sudah menanggung artinya. */
.urutbar{display:flex;align-items:center;gap:8px;margin:0 0 14px;
  padding:9px 12px;background:var(--surface-2);border-radius:var(--radius)}
.urutbar-cip{display:flex;gap:8px;flex:1 1 auto;min-width:0;overflow-x:auto;
  scrollbar-width:none;-ms-overflow-style:none}
.urutbar-cip::-webkit-scrollbar{display:none}
.urutopt{flex:none;border:1px solid var(--line);background:var(--surface);border-radius:7px;
  padding:6px 12px;font-size:var(--f12);cursor:pointer;color:var(--ink);
  font-family:inherit;white-space:nowrap;transition:border-color .12s,background .12s}
.urutopt:hover{border-color:var(--line-strong)}
.urutopt.on{background:var(--ink);border-color:var(--ink);color:var(--on-ink)}

/* Tombol Filter menempel di kanan baris urutan, dan ia tidak ikut tergeser —
   tombol yang hanyut keluar layar bersama cipnya tidak bisa ditemukan lagi.
   Tepi kirinya diberi bayangan landai supaya terbaca bahwa cipnya masih ada
   yang tersembunyi. */
.fltbtn{position:relative;flex:none;display:none;align-items:center;gap:6px;
  border:1px solid var(--line);border-radius:7px;background:var(--surface);
  padding:6px 11px;font-family:inherit;font-size:var(--f12);color:var(--ink);
  cursor:pointer;white-space:nowrap}
.fltbtn svg{width:15px;height:15px;flex:none}
/* Angka saringan yang menyala: keping kecil, supaya tetap terbaca di telepon
   yang tombolnya tinggal ikon (K-281). */
.fltbtn-n{min-width:17px;height:17px;padding:0 4px;border-radius:9px;background:var(--ink);color:var(--on-ink);
  font-size:var(--f10);font-weight:600;line-height:17px;text-align:center;font-variant-numeric:tabular-nums}
.fltbtn::before{content:"";position:absolute;right:100%;top:-9px;bottom:-9px;width:22px;
  pointer-events:none;background:linear-gradient(to right,transparent,var(--surface-2))}
.fltpanel .fltgrup:first-child{padding-top:0}

@media(max-width:900px){
  /* Kolom kiri DICABUT di lebar telepon dan tablet sempit — 232px di layar
     390px tidak menyisakan apa pun untuk barangnya. Tempatnya panel, dan
     pintunya tombol Filter di baris urutan. */
  .shoplayout{display:block}
  .shopflt{display:none}
  .fltbtn{display:flex}
  /* SARINGANNYA IKUT SAAT DIGULIR, sama seperti kolom cari di kepalanya —
     diminta pemiliknya: "fitur pencarian dan filter ngikut saat discroll ke
     bawah". Puncaknya dipatok tepat di bawah kepala halaman yang juga
     menempel, jadi keduanya tidak pernah saling menutupi. */
  /* Ia MENEMBUS jarak sisi halamannya supaya latarnya penuh selebar layar —
     dan angkanya dibaca dari `--shop-pad`, bukan diketik ulang (K-222).
     Diketik 14px, ia meleset 6px begitu celah etalase dipersempit, dan yang
     terjadi halaman yang bisa digulir ke samping tanpa satu benda pun
     terlihat di sana. */
  /* SEWARNA KEPALANYA DAN RAPAT KE KOTAK CARINYA (K-281, dilaporkan
     pemiliknya: "kok belang ya, harusnya area filter itu warnanya jangan
     dibikin gelap ... ketika kolom search dan filter ini bertemu, jangan
     dikasih gap"). Latarnya `--surface`, SAMA dengan kepala halaman, dan
     jarak atasnya dipangkas; garis bawah kepala dicabut di halaman yang
     punya baris ini, jadi saat keduanya bertemu mereka terbaca sebagai SATU
     bidang dengan cip yang mengambang di bawah kotak carinya. Bayangannya
     pindah ke tepi bawah baris ini. */
  .urutbar{position:sticky;top:var(--shophead-t,58px);z-index:30;gap:6px;padding:2px 10px 9px;
    margin-left:calc(var(--shop-pad) * -1);margin-right:calc(var(--shop-pad) * -1);
    padding-left:var(--shop-pad);padding-right:var(--shop-pad);
    border-radius:0;background:var(--surface);
    box-shadow:0 6px 14px -12px rgba(0,0,0,.5)}
  body:has(.urutbar) > .shophead:not(.shophead--layang){border-bottom-color:transparent}
  /* Di halaman hasil pencarian baris ini berdiri LANGSUNG di bawah kepalanya
     sejak awal — tidak ada apa pun di antaranya (K-281). */
  .shop-hasil > .shopmain{padding-top:0}
  .fltbtn::before{background:linear-gradient(to right,transparent,var(--surface))}
  .urutopt{padding:6px 11px;font-size:var(--f12)}
}

/* ---------- banner yang bergeser ---------- */
.bnr{position:relative;overflow:hidden;border-radius:var(--radius);margin:0 0 18px;background:var(--surface-2)}
.bnr-rel{display:flex;transition:transform .45s cubic-bezier(.3,.7,.3,1)}
.bnr-slide{flex:0 0 100%;display:block;aspect-ratio:1000/320;background:var(--surface-2)}
.bnr-slide img{width:100%;height:100%;object-fit:cover;display:block}
.bnr-titik{position:absolute;left:0;right:0;bottom:9px;display:flex;justify-content:center;gap:6px}
.bnr-titik i{width:6px;height:6px;border-radius:50%;background:#fff;opacity:.45;transition:opacity .2s,width .2s}
.bnr-titik i.on{opacity:1;width:16px;border-radius:3px}
@media (prefers-reduced-motion: reduce){ .bnr-rel{transition:none} }

/* ---------- deretan toko di kepala halaman ----------
   SATU BARIS YANG DIGESER MENYAMPING, bukan grid kartu. Bentuk lamanya —
   kartu besar berjajar — mendorong barang pertama dua layar penuh ke bawah,
   dan itu sebabnya dulu ia diturunkan ke kaki halaman. Sebagai cip setinggi
   64px ia muat di kepala tanpa mengusir apa pun. */
.tokolist{margin:0 0 16px}
.tokolist h2{font-family:var(--f-judul);margin:0 0 10px}
.tokolist-bar{display:flex;gap:9px;overflow-x:auto;padding-bottom:4px;
  scrollbar-width:none;-ms-overflow-style:none}
.tokolist-bar::-webkit-scrollbar{display:none}
/* SEMUA KARTU TOKO SAMA UKURANNYA (K-281, diminta pemiliknya dengan contoh
   kartu toko Shopee: "label tokonya ukurannya harus sama, adapun kalau
   namanya gak muat tinggal pakai '..'"). Dulu lebarnya mengikuti panjang
   namanya, jadi deretannya bergerigi. Sekarang lebarnya satu angka, logo
   bulat di kiri, dan nama yang kepanjangan dipotong titik-titik. Bentuknya
   kotak bersudut lancip seperti contohnya, bukan pil. */
.tokochip{flex:none;width:188px;display:flex;align-items:center;gap:10px;padding:10px 11px;
  border:1px solid var(--line);border-radius:var(--radius);background:var(--surface);
  text-decoration:none;color:inherit;transition:border-color .13s,box-shadow .13s}
.tokochip:hover{border-color:var(--line-strong);box-shadow:var(--shadow)}
@media (min-width:861px){ .tokochip{width:224px} }
.tokochip-av{width:40px;height:40px;border-radius:50%;flex:none}
.tokochip-bd{display:flex;flex-direction:column;flex:1 1 auto;min-width:0;line-height:1.3}
.tokochip-bd b{font-size:var(--f12);font-weight:600;white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis}
.tokochip-bd span{font-size:var(--f11);color:var(--ink-3);white-space:nowrap;font-variant-numeric:tabular-nums;
  overflow:hidden;text-overflow:ellipsis}

/* ---------- pengaturan banner di Kelola Toko ---------- */
.bnrbaris{grid-template-columns:auto 96px 1fr auto;align-items:center}
.bnrpetak{width:96px;height:34px;border-radius:7px;overflow:hidden;background:var(--surface-2);
  display:grid;place-items:center;font-size:var(--f11)}
.bnrpetak img{width:100%;height:100%;object-fit:cover;display:block}
.bnrisi{display:flex;flex-direction:column;gap:7px;min-width:0}
.bnrtaut{display:flex;gap:7px;flex-wrap:wrap}
.bnrtaut > span{flex:1 1 160px;min-width:0}
@media(max-width:900px){
  .bnrbaris{grid-template-columns:auto 1fr;row-gap:9px}
  .bnrpetak{width:100%;height:64px}
  .bnrbaris .bnrisi,.bnrbaris .irow-act{grid-column:1 / -1}
}

/* ---------- kotak QR di detail Tautan QR (K-164) ---------- */
/* QR-nya digambar sebesar yang bisa dipindai LANGSUNG DARI LAYAR: orang yang
   mau menempelkan posternya sering memindainya dulu dari monitor untuk
   memastikan tujuannya sudah benar. Latarnya dipatok PUTIH, bukan warna
   permukaan — QR gelap di tema gelap tidak pernah terbaca pembaca mana pun. */
.qrkotak{display:flex;flex-direction:column;align-items:flex-start;gap:10px;margin-top:4px}
.qrkotak > svg{width:172px;height:172px;background:#fff;padding:9px;border-radius:8px;
  border:1px solid var(--line)}

/* ------------------------------------------------------ SURAT (K-197) */
/* Kepingan penanda di formulir Jenis Surat: menekannya menuliskan penanda
   pada letak kursor — tidak ada kalimat panduan yang perlu menerangkan
   bentuk kurung sikunya. */
.penanda{display:flex;flex-wrap:wrap;gap:6px;margin-top:8px}
.penanda-btn{font:inherit;font-size:var(--f12);padding:3px 9px;border:1px solid var(--line-strong);border-radius:999px;
  background:var(--surface-2);color:var(--ink);cursor:pointer}
.penanda-btn:hover{border-color:var(--ink-3)}
.suratnaskah{margin:0;text-align:left;font:inherit;font-size:var(--f12);line-height:1.55;white-space:pre-wrap;word-wrap:break-word}
.suratnaskah--pra{border:1px dashed var(--line-strong);border-radius:var(--radius);padding:12px 14px;
  background:var(--surface-2);max-height:320px;overflow:auto}

/* ================================================================
   HALAMAN PRODUK: FOTONYA MENTOK ATAS, KEPALANYA MENGAMBANG (K-207)
   ================================================================
   Diminta pemiliknya dengan tangkapan layar Shopee: "mentok atas adalah
   langsung foto produk terus tombol back menimpa foto, terus seben di
   bagian atas itu adalah kolom search yang transparan dan semakin tampil
   saat discroll ke arah semakin bawah".

   SEJAK K-274 DI LAYAR LEBAR JUGA (diminta pemiliknya: "saat pakai laptop
   tolong samakan pada mobile, yaitu wallpaper foto langsung diposisikan
   mentok atas, dan tombol2nya itu menimpa dilapisan atas foto"). Alasan K-207
   menahannya di telepon tetap benar — di layar lebar fotonya cuma satu lajur,
   dan kepala yang mengambang di sebelahnya berdiri di atas TULISAN — dan
   dijawab tanpa dilanggar: lajur tulisannya diberi jarak atas setinggi
   kepalanya, jadi yang ditimpa tombol hanya fotonya. Chat dan keranjang
   tetap digambar di layar lebar; di telepon keduanya memang tidak ada.

   AMBANGNYA TINGGI FOTONYA, DIUKUR HIDUP, bukan angka yang diketik:
   tingginya sendiri `min(78vw,42dvh)`, jadi angka tetap apa pun akan salah
   pada separuh layar. `E.kepalaLayang` yang mengukurnya dan menuliskan
   `--hd-op`; Detail Item Inventory memakai mesin yang sama persis, lihat
   `.topbar--layang` di kaki berkas ini. */

/* Tombol bulat di kedua ujung kepala — Kembali di kiri, titik tiga di
   kanan. Digambar di lebar mana pun: yang berubah cuma latarnya. */
.shopbulat{position:relative;display:grid;place-items:center;flex:none;
  width:34px;height:34px;padding:0;border:0;border-radius:50%;
  background:none;color:var(--ink);cursor:pointer}
.shopbulat svg{position:relative;width:20px;height:20px}
.shopbulat:hover{background:var(--line)}

/* SEMUA LEBAR sejak K-274 (lihat kepala blok ini). */
@media all{
  /* Kepalanya keluar dari aliran halaman supaya fotonya benar-benar mulai
     di titik nol. `fixed`, bukan `sticky`: yang `sticky` tetap memakan
     tingginya sendiri, jadi fotonya berhenti 58px dari atas. */
  .shophead--layang{position:fixed;left:0;right:0;top:0;
    background:none;border-bottom:0}
  /* Latarnya DIGAMBAR LAPISAN TERSENDIRI, bukan `opacity` pada kepalanya:
     yang kedua ikut memudarkan tombol dan kotak carinya sekaligus, padahal
     tombol Kembali justru harus paling terbaca saat latarnya masih kosong. */
  .shophead--layang::before{content:"";position:absolute;inset:0;
    background:var(--surface);border-bottom:1px solid var(--line);
    opacity:var(--hd-op,0)}
  .shophead--layang .shopwrap{position:relative}
  /* Lambang dan butir Beranda TIDAK LAGI DISEBUT di sini: sejak K-222
     keduanya sudah tidak digambar di kepala mana pun, jadi menyembunyikannya
     berarti menyembunyikan sesuatu yang tidak ada. */
  .shophead--layang .shopwrap{flex-wrap:nowrap}
  /* Chat dan keranjang pun tidak, dan itu MENDEKATKAN pratinjau kepada yang
     sungguhan: di etalase publik keduanya memang tidak pernah ada (K-133),
     dan yang diminta pemiliknya di baris ini cuma tiga benda — Kembali,
     kotak cari, dan titik tiga. Keduanya tetap berdiri di setiap halaman
     etalase yang lain. */
  @media (max-width:640px){ .shophead--layang .shopchat{display:none} }
  /* Kotak carinya ikut terang bersama latarnya — itulah "semakin tampil
     saat discroll". */
  .shophead--layang .shopsearch{opacity:var(--hd-op,0)}
  /* KOTAK CARI YANG TIDAK TERLIHAT TIDAK BOLEH BISA DITEKAN. Benda tembus
     pandang tetap menangkap jari, dan yang menekan bagian atas foto
     barangnya akan terlempar ke halaman pencarian tanpa tahu ia menekan
     apa. Kelasnya dipasang `E.kepalaLayang`. */
  .shophead--layang.layang-tembus .shopsearch{pointer-events:none}

  /* Di atas foto, tombolnya putih beralas gelap — foto barang bekas bisa
     seterang atau segelap apa pun, dan ikon sewarna teks akan hilang ke
     dalam salah satunya. Begitu latarnya sudah padat, alasnya pergi dan
     ikonnya kembali sewarna teks.

     Dipindahkan pada AMBANG (kelas `shophead--padat`), bukan dipularkan
     mengikuti `--hd-op`: warna yang dipularkan menuntut `color-mix` dengan
     persen terhitung, dan yang gagal di situ tidak berbunyi seperti
     kerusakan — ikonnya cuma menghilang. */
  .shophead--layang .shopbulat{color:#fff;transition:color .18s}
  .shophead--layang .shopbulat:hover{background:none}
  .shophead--layang .shopbulat::before{content:"";position:absolute;inset:0;
    border-radius:50%;background:rgba(0,0,0,.46);transition:opacity .18s}
  .shophead--layang.layang-padat .shopbulat{color:var(--ink)}
  .shophead--layang.layang-padat .shopbulat::before{opacity:0}

  /* ---------- DAN SEJAK K-240 IA MENGIKUTI GULIRNYA, BUKAN AMBANGNYA ----------
     Dilaporkan pemiliknya: "tombol back dan tombol titik tiga … tolong juga
     ada transisi harusnya, bukan langsung tiba2 mati atau nyala".

     YANG SALAH BUKAN KETIADAAN TRANSISI, DAN ITU DIUKUR LEBIH DULU: kedua
     `transition .18s` di atas memang berjalan (alas gelapnya 1 → 0 dalam
     ~160 ms). Yang membuatnya terbaca "tiba-tiba" AMBANGNYA — pada `op` .549
     tombolnya masih putih beralas gelap penuh, pada .551 ia melompat ke
     keadaan akhirnya, sementara latar kepalanya sendiri baru 55% padat. Jadi
     tombolnya tidak pernah menempuh perjalanan yang sama dengan latar di
     belakangnya.

     Sekarang keduanya MEMULAR mengikuti `--hd-op` yang sama dengan latarnya,
     jadi tombol dan latarnya sampai bersama-sama.

     `transition` DICABUT di sini, dan itu bukan kelalaian: `--hd-op` ditulis
     ulang pada setiap peristiwa gulir, jadi transisi di atasnya membuat
     tombolnya tertinggal di belakang jari orangnya.

     DIPAGARI `@supports`, dan pagarnya memang dibutuhkan — K-207 menolak
     `color-mix` justru karena "yang gagal di situ tidak berbunyi seperti
     kerusakan, ikonnya cuma menghilang". Peramban yang tidak mengenalnya
     tetap memakai kedua ambang di atas, yang tidak disentuh sama sekali. */
  @supports (color: color-mix(in srgb, red 50%, blue)){
    .shophead--layang .shopbulat,
    .shophead--layang.layang-padat .shopbulat{
      color:color-mix(in srgb, var(--ink) calc(var(--hd-op,0) * 100%), #fff);
      transition:none}
    .shophead--layang .shopbulat::before,
    .shophead--layang.layang-padat .shopbulat::before{
      opacity:calc(1 - var(--hd-op,0));transition:none}
  }

  /* Jarak atas halamannya ditelan, jadi fotonya benar-benar mentok. */
  body:has(> .shophead--layang) > .shopmain{padding-top:0}
}
/* HALAMAN PRODUK DI LAYAR LEBAR: KEPALA BIASA (tahap 6b, ralat pemiliknya
   atas K-274 — "saat pakai mode laptop saat membuka detail produk itu di
   bagian atas ternyata tetap butuh kotak kolom search dan tombol lainnya ...
   dan gak perlu ada animasi transparan dan lain lain, terus detail produk bisa
   di turunkan"). `.shophead--hp` membatalkan seluruh mengambangnya di 641px ke
   atas: ia menempel dan memakan tingginya sendiri, latarnya padat sejak awal
   (`--hd-op` dipatok 1, jadi kotak cari, chat, dan keranjangnya tampil penuh),
   dan halamannya turun di bawahnya. Titik tiganya pindah ke kanan judul
   (`#pdpMenu`). Halaman TOKO tetap mengambang di lebar mana pun. */
@media (min-width:641px){
  .shophead--layang.shophead--hp{position:sticky;--hd-op:1 !important}
  .shophead--layang.shophead--hp.layang-tembus .shopsearch{pointer-events:auto}
  .shophead--hp #shopMenu{display:none}
  body:has(> .shophead--hp) > .shopmain{padding-top:24px}
}
.pdp-judul{display:flex;align-items:flex-start;gap:8px}
.pdp-judul h1{flex:1 1 auto;min-width:0}
.pdp-menu{margin-top:-4px}
@media (max-width:640px){ .pdp-menu{display:none} }

@media (prefers-reduced-motion: reduce){
  .shopbulat,.shopbulat::before{transition:none}
}

/* ---------- DETAIL ITEM INVENTORY: KEPALANYA IKUT MENGAMBANG (K-207) ----------
   Diminta pemiliknya bersama halaman produk: "sekalian pada inventory untuk
   internal juga mirip, tapi bedanya adalah tidak ada tombol tombol di pojok
   kanan atas".

   Jadi yang berdiri di baris ini tinggal DUA: tombol Kembali yang menimpa
   fotonya, dan nama halaman yang ikut terang saat digulir. Lonceng dan tombol
   cari tidak digambar — bukan dimatikan: keduanya tetap ada di setiap halaman
   lain, dan yang membuka satu barang memang sedang memeriksa barang itu, bukan
   sedang mencari barang berikutnya.

   Mesinnya `E.kepalaLayang`, sama persis dengan halaman produk — termasuk
   ambangnya. Dua halaman yang bentuknya sama tidak boleh memudar pada ambang
   yang berbeda. */
/* ---------- TITIK TIGA DETAIL ITEM (K-240) ----------
   Diminta pemiliknya: "semua tombol edit diletakkan di pojok kanan atas
   'titik tiga' yang kalau pakai android letaknya itu ada di menimpa foto di
   pojok kanan atas".

   DIGAMBAR DUA KALI, dan CSS yang memilih satu per lebar layar — bukan
   dipindah dengan JavaScript (pelajaran K-177). Ambangnya 960px, sama persis
   dengan ambang baris kepala menjadi kepala halaman (K-65) dan dengan ambang
   K-213 yang mencabut baris kepala Detail Item di 961px ke atas: di sana
   `.topbar` memang `display:none`, jadi titik tiga di dalamnya tidak akan
   pernah bisa ditekan siapa pun.

   `.itemmenu` berisi tombol yang SUNGGUHAN dan tidak pernah digambar — ia yang
   ditekan ulang oleh menunya (pola corong K-65, bentuk yang sama dengan
   `.absmenu` di K-203). `display:none` ditulis apa adanya: `[hidden]` bawaan
   peramban kalah oleh aturan layout mana pun yang berdiri di bawahnya, dan itu
   sudah beberapa kali memakan korban di berkas ini. */
.itemmenu{display:none}
.topmenu{position:relative;flex:none;display:grid;place-items:center;
  width:34px;height:34px;padding:0;border:0;border-radius:50%;
  background:none;color:var(--ink);cursor:pointer}
.topmenu svg{position:relative;width:19px;height:19px}
.topmenu:hover{background:var(--line)}
.itemjudul .itemkebab{flex:none;margin-top:2px}
@media (max-width:960px){ .itemkebab{display:none} }
@media (min-width:961px){ .topmenu{display:none} }

@media (max-width:640px){
  .topbar--layang{position:fixed;left:0;right:0;top:0;background:none;border-bottom:0}
  /* Latarnya lapisan tersendiri, bukan `opacity` pada kepalanya — yang kedua
     ikut memudarkan tombol Kembali, padahal ia justru harus paling terbaca
     saat latarnya masih kosong. */
  .topbar--layang::before{content:"";position:absolute;inset:0;
    background:var(--surface);border-bottom:1px solid var(--line);opacity:var(--hd-op,0)}
  .topbar--layang > *{position:relative}
  .topbar--layang .topmid{opacity:var(--hd-op,0)}
  .topbar--layang.layang-tembus .topmid{pointer-events:none}
  .topbar--layang .lonceng,
  .topbar--layang .topcaribtn{display:none}
  .topbar--layang .backbtn{color:#fff;transition:color .18s}
  .topbar--layang .backbtn::before{content:"";position:absolute;inset:5px;
    border-radius:50%;background:rgba(0,0,0,.46);transition:opacity .18s}
  .topbar--layang .backbtn svg{position:relative}
  .topbar--layang.layang-padat .backbtn{color:var(--ink)}
  .topbar--layang.layang-padat .backbtn::before{opacity:0}
  /* Titik tiganya ikut aturan yang sama: putih beralas gelap di atas foto,
     sewarna teks begitu latarnya padat. Dua tombol di baris yang sama tidak
     boleh memudar dengan cara yang berbeda. */
  .topbar--layang .topmenu{color:#fff;transition:color .18s}
  .topbar--layang .topmenu:hover{background:none}
  /* SAMA BESAR DENGAN TOMBOL KEMBALI (tampilan tahap 1, diminta pemiliknya:
     "tombol icon back pojok kiri atas dan tombol titik tiga kok ukurannya
     beda, harusnya sama"). Diukur: lingkaran Kembali 34px dengan panah 26px,
     titik tiga 28px dengan ikon 19px. Sekarang keduanya petak 44px, lingkaran
     34px, dan ikon 22px — dua benda berpasangan di sudut yang sama. */
  .topbar--layang .topmenu{width:44px;height:44px}
  .topbar--layang .topmenu svg,
  .topbar--layang .backbtn svg{width:20px;height:20px}
  .topbar--layang .topmenu::before{content:"";position:absolute;inset:5px;
    border-radius:50%;background:rgba(0,0,0,.46);transition:opacity .18s}
  .topbar--layang.layang-padat .topmenu{color:var(--ink)}
  .topbar--layang.layang-padat .topmenu::before{opacity:0}

  /* Memular mengikuti gulirnya, sama persis dengan halaman produk (K-240).
     Alasannya lengkap di blok `.shophead--layang` di atas; ditulis dua kali
     karena kedua kepala itu memang dua benda yang berbeda — yang tidak boleh
     berbeda AKIBATNYA, dan itulah yang dijaga uji. */
  @supports (color: color-mix(in srgb, red 50%, blue)){
    .topbar--layang .backbtn,
    .topbar--layang.layang-padat .backbtn{
      color:color-mix(in srgb, var(--ink) calc(var(--hd-op,0) * 100%), #fff);
      transition:none}
    .topbar--layang .backbtn::before,
    .topbar--layang.layang-padat .backbtn::before{
      opacity:calc(1 - var(--hd-op,0));transition:none}
    .topbar--layang .topmenu,
    .topbar--layang.layang-padat .topmenu{
      color:color-mix(in srgb, var(--ink) calc(var(--hd-op,0) * 100%), #fff);
      transition:none}
    .topbar--layang .topmenu::before,
    .topbar--layang.layang-padat .topmenu::before{
      opacity:calc(1 - var(--hd-op,0));transition:none}
  }
}

@media (prefers-reduced-motion: reduce){
  .topbar--layang .backbtn,.topbar--layang .backbtn::before,
  .topbar--layang .topmenu,.topbar--layang .topmenu::before{transition:none}
}

/* ==========================================================================
   DAFTAR ITEM: KEPALA DAN SARINGAN DILEBUR, KEADAAN BARANG SEBAGAI TAB (K-214)
   Diminta pemiliknya dengan tangkapan layar Shopee: "jangan dipisah dengan gap
   antara header dengan filter, dilebur jadi 1 … jangan model kotak, tapi yang
   polos kayak model shopee … kita gak pakai yang model gap-gap, mulai
   sekarang, bisa diganti garis atau apa gitu."

   Blok ini berdiri PALING BELAKANG di berkas ini dengan sengaja: aturan
   `.stikatas .filterhead > *` dan `.page .filterhead > *` di atasnya
   memaksa setiap anak baris saringan `flex:none`, dan media query tidak
   menambah kekuatan penyebut apa pun — yang ditulis lebih awal selalu kalah
   (jebakan yang sudah dicatat di K-201 dan di blok `.setbaris`).
   ========================================================================== */
/* Yang memisah GARIS, bukan jarak kosong. Dua garis saja: satu di bawah judul
   halaman, satu di bawah deretan tab. */
/* SARINGAN LOKASI DAN URUTAN tetap digambar sebagai combo yang sungguhan di
   dalam baris ini — `E.panelSaringan` menurunkan isi lembar Filter dari
   `[data-combo]` yang benar-benar berdiri di `.filterhead` (K-106) — dan cuma
   DISEMBUNYIKAN. `[hidden]` bawaan peramban tidak cukup di sini:
   `.filterhead--satu > .filters{display:contents}` penyebutnya lebih kuat dan
   akan memenangkannya, jadi combonya justru tetap tergambar. Jebakan yang
   sama sudah dua kali memakan korban di berkas ini (`.field[hidden]`,
   `.btn[hidden]`). */
.filterhead--tab > .filters[hidden]{display:none}
.page-head--lebur{margin-bottom:0;padding-bottom:12px}
.filterhead--tab{margin-bottom:0;padding:0;gap:0;
  border-top:1px solid var(--line);border-bottom:1px solid var(--line)}
.filterhead--tab > .search{flex:1 1 200px;margin:8px 12px 8px 0}
.daftarhead--lebur{margin-bottom:0;padding:8px 0;border-bottom:0}

/* DERETAN TAB. Polos, tanpa kotak dan tanpa latar; yang sedang berlaku
   ditandai tulisan hitam tebal beserta garis 2px di bawahnya — bentuk yang
   sama persis dengan butir Beranda di kepala etalase (K-209), supaya orang
   yang sudah mengenali satu tanda aktif tidak perlu belajar tanda kedua.
   Warnanya sengaja MONOKROM: warna di ERP ini cuma milik status dokumen, arah
   uang, kepekaan hak akses, dan tombol Jual. */
.stattab{display:flex;align-items:stretch;gap:0;overflow-x:auto;scrollbar-width:none}
.stattab::-webkit-scrollbar{display:none}
/* YANG MENGGULUNG KE SAMPING DERETAN TABNYA SENDIRI, bukan seluruh barisnya —
   dan itu menuntut penyebut yang cukup kuat, bukan sekadar ditulis paling
   belakang. `.stikatas .filterhead > *` dan `.page .filterhead > *` keduanya
   berkekuatan 0-2-0 dan memaksa `flex:none`; `.stattab` sendirian cuma 0-1-0,
   jadi ia KALAH berapa pun belakangnya ia ditulis. Ini ralat atas catatan di
   kepala blok ini: urutan cuma menolong penyebut yang SAMA kuatnya.

   Akibatnya kalau salah: deretan tabnya tidak pernah mengerut, jadi ia
   melebar melewati lebar layar dan BARISNYA yang menggulung — tab lewat di
   balik ikon kamera dan ikon Filter, dan menyembul lagi di celah kanannya
   ("kelihatan ada filter yang bergerak dari celah itu"). */
.filterhead--tab > .stattab{flex:1 1 auto;min-width:0}
.stattab-b{position:relative;flex:none;border:0;background:none;font:inherit;
  /* Ukuran tulisannya DISAMAKAN dengan ikon kamera di sebelahnya (diminta
     pemiliknya): keduanya berdiri di baris yang sama, dan dua benda sebaris
     yang ukurannya berbeda membuat barisnya terbaca miring. */
  font-size:var(--f12);font-weight:500;color:var(--ink-3);
  padding:11px 12px;cursor:pointer;white-space:nowrap;
  transition:color .14s}
.stattab-b:hover{color:var(--ink)}
.stattab-b.on{color:var(--ink);font-weight:700}
.stattab-b.on::after{content:"";position:absolute;left:12px;right:12px;bottom:0;
  height:2px;border-radius:2px;background:var(--ink)}

/* Ikon kamera dan tombol Filter berdiri di ujung kanan barisnya dan TIDAK
   ikut tergulir — bukan karena ia menempel (`position:sticky`), melainkan
   karena yang menggulung sekarang deretan tabnya sendiri. Keduanya benda
   biasa di ujung baris, dan tidak ada satu pun tab yang bisa lewat di
   baliknya.

   YANG MEMISAHKANNYA GARIS, bukan bayangan (aturan tetap pemiliknya). Bayangan
   hitam yang dulu berdiri di sini justru MEREDUPKAN tab terakhir — "Di Servis
   bagian paling kanan agak ketutupan sama bayangan hitam jadi kurang nyala" —
   dan bayangan yang meredupkan tulisan bukan pemisah, ia kerusakan. */
.filterhead--tab > .filterhead-kanan{flex:none;
  gap:2px;align-self:stretch;align-items:center;flex-wrap:nowrap;
  background:var(--ground);border-left:1px solid var(--line);padding-left:10px}
/* Ikon kamera dan ikon Filter satu ukuran dengan tulisan tabnya. */
.filterhead--tab .filterhead-kanan .btn{border:0;background:none;padding:0 9px;
  height:36px;color:var(--ink-3)}
/* SOROTAN KURSOR HANYA DI LAYAR BERKURSOR (K-275, dilaporkan pemiliknya: di
   telepon ikon Filter dan pembatasnya "kurang nyatu ... ada area yang gelap ada
   yang agak cerah"). Di layar sentuh `:hover` MENEMPEL sesudah ikonnya
   diketuk, jadi petak abu-abu sorotannya tertinggal di belakang ikon sampai
   orangnya mengetuk tempat lain. */
@media (hover:hover){ .filterhead--tab .filterhead-kanan .btn:hover{background:var(--surface-2);color:var(--ink)} }
.filterhead--tab .filterhead-kanan .btn svg{width:16px;height:16px}

/* Di layar telepon kepala halaman memang sudah disembunyikan (K-65), jadi
   garis atas deretan tab berdiri langsung di bawah baris kepala. Kolom
   pencariannya pun sudah tidak digambar di sana — ia naik ke baris kepala. */
@media(max-width:820px){
  /* BENAR-BENAR RAPAT dengan baris kepala: jarak atas bilah yang menempel
     ditiadakan, dan garis atas deretan tab dicabut — garis bawah baris kepala
     sudah berdiri persis di tempat itu, dan dua garis berdempetan terbaca
     sebagai satu garis yang tebalnya salah. */
  .page .stikatas:has(.filterhead--tab){padding-top:0}
  .stikatas .filterhead--tab{margin-bottom:0;border-top:0;
    padding-left:var(--pad-hal);padding-right:var(--pad-hal)}
  .stikatas .daftarhead--lebur{margin-bottom:0}
  /* TIDAK ADA BATANG GULIR DI BARIS INI. `.page .filterhead` di blok K-69
     sengaja membiarkannya (`scrollbar-width:thin`) untuk baris saringan yang
     memang menggulung sendiri — tetapi baris ini tidak menggulung lagi, yang
     menggulung deretan tab di dalamnya, dan batang gulir yang tergambar pada
     baris yang tidak bergerak cuma memakan tinggi. */
  .page .filterhead--tab,.stikatas .filterhead--tab{overflow:hidden;scrollbar-width:none}
  .page .filterhead--tab::-webkit-scrollbar{display:none}
  /* BARIS TINDAKAN TIDAK MENYISAKAN JARAK SELAGI KOSONG. Di layar telepon
     seluruh isinya memang tidak digambar sebelum mode Pilih menyala — tombol
     tindakannya sudah berdiri di bilah bawah — jadi yang tersisa cuma 35px
     kosong antara deretan tab dan kartu pertamanya ("antara filter dan card
     ga usah dikasih space hitam-hitam"). Begitu mode Pilih menyala ia berisi
     jumlah yang terpilih beserta centang "Semua", dan jaraknya kembali. */
  .stikatas .daftarhead--lebur:not(.daftarhead--pilih){display:none}
  .stikatas .daftarhead--lebur{padding:8px 0}

  /* SATU WARNA DENGAN BARIS KEPALA (diminta pemiliknya: "antara header Daftar
     Item dan area status, warnanya dibikin nyatu kayak Shopee aja, biar ringan
     dimata"). Baris kepala berdiri di atas `--surface`, deretan tab dulu di
     atas `--ground` — dua tingkat abu yang berdempetan, dan mata membaca
     batasnya sebagai satu benda lagi yang harus diurus.

     Sekarang keduanya satu bidang `--surface` yang tidak terputus, dan yang
     memisahkannya dari daftar di bawahnya PERGANTIAN BIDANG beserta satu garis
     — bukan bayangan, dan bukan jarak kosong. Karena itu garis bawah baris
     kepala ikut dipadamkan di halaman yang membawa baris ini: ia akan membelah
     bidang yang justru sedang disatukan. */
  body:has(.filterhead--tab) .topbar{border-bottom-color:transparent}
  /* Satu-satunya jarak yang tersisa di bawah bidang itu SAMA PERSIS dengan
     jarak antar-kartu (10px), jadi ia terbaca sebagai bagian dari irama
     kartunya — bukan sebagai pita kosong yang berdiri sendiri. */
  .stikatas:has(.filterhead--tab){background:var(--surface);padding-bottom:0;
    margin-bottom:10px;box-shadow:none}
  .stikatas .filterhead--tab,.filterhead--tab > .filterhead-kanan{background:var(--surface)}
}


/* ==========================================================================
   PEMINDAI LAYAR PENUH DI TELEPON (K-216)
   Diminta pemiliknya: "iya, biar area kamera besar". Di pop-up 480px gambarnya
   tidak pernah bisa lebih lebar daripada badan pop-up itu, dan aliran dari HP
   yang BERDIRI (1080×1920) menyisakan gambar selebar 306px di layar 390px —
   dus HP yang dibidik dari jarak sejengkal jatuh ke seratus titik saja.

   Polanya SAMA PERSIS dengan penampil foto (`.mdl--foto`): pop-upnya tidak
   naik dari bawah, ia MENGGANTIKAN layarnya. Ditulis paling belakang di berkas
   ini supaya ia menimpa lembar-bawah di `@media(max-width:640px)` — pemilih
   yang lebih lemah tidak pernah menang berapa pun belakangnya ia ditulis
   (jebakan yang sudah dicatat di K-201 dan K-215).

   SEJAK TAHAP 7 TIDAK ADA LAGI YANG BISA TERDORONG KELUAR LAYAR (inti K-149):
   kepala, tombol, dan keadaannya MENGAMBANG di atas gambarnya, dan kaki
   bertombolnya tidak ada lagi.
   ========================================================================== */
@media(max-width:820px){
  .ov:has(.pindai){padding:0;align-items:stretch;justify-content:stretch;
    background:#000;overflow:hidden}
  .ov .mdl:has(.pindai){width:100%;max-width:100%;height:100dvh;max-height:100dvh;
    border:0;border-radius:0;box-shadow:none;background:#000;color:#fff;transform:none}
  .ov.on .mdl:has(.pindai){transform:none}
  /* GAMBARNYA MEMENUHI LAYAR, KEPALANYA MENGAMBANG DI ATASNYA (tahap 7,
     ala Google Lens): judul dan tanda silang berdiri di atas gradasi gelap,
     bukan di baris hitam tersendiri. */
  .mdl:has(.pindai){position:relative}
  .mdl:has(.pindai) .mdl-hd{position:absolute;top:0;left:0;right:0;z-index:3;border-bottom:0;
    padding:10px 14px;background:linear-gradient(rgba(0,0,0,.55),transparent)}
  .mdl:has(.pindai) .mdl-hd::before{display:none}
  .mdl:has(.pindai) .mdl-x{color:#fff}
  .mdl:has(.pindai) .mdl-x:hover{background:rgba(255,255,255,.14);color:#fff}
  /* Badan pop-up menjadi satu lajur setinggi sisa layarnya, dan GAMBARNYA yang
     mengambil seluruh sisa itu — bukan angka yang ditebak. `min-height:0`
     wajib di setiap tingkatnya: tanpa itu lajur flex menolak mengerut di bawah
     tinggi isinya, dan yang terdorong keluar layar justru tombolnya. */
  .mdl:has(.pindai) .mdl-bd{padding:0;overflow:hidden;flex:1 1 auto;min-height:0;display:flex}
  .mdl:has(.pindai) .pindai{flex:1 1 auto;min-height:0;display:flex;width:100%}
  .mdl:has(.pindai) .pindai-layar{flex:1 1 auto;min-height:0;width:100%;height:100%}
  /* GAMBARNYA MENUTUPI SELURUH LAYAR (`cover`, tahap 7) — tanpa pita hitam
     sama sekali, seperti Google Lens. Yang terpotong cuma tepi kiri-kanan
     gambar yang berdiri, dan daerah yang DIBACA (90% × 55% tengahnya, lihat
     `BIDIK` di pindai.js) tetap berada di tengah layar. `rapatkanKotak` tidak
     mematok ukurannya di sini. */
  .mdl:has(.pindai) .pindai-video{width:100%;height:100%;max-width:none;max-height:none;
    border-radius:0;object-fit:cover}
  .mdl:has(.pindai) .pindai-kendali{top:calc(58px + env(safe-area-inset-top))}
  .mdl:has(.pindai) .pindai-status{bottom:calc(20px + env(safe-area-inset-bottom))}
  /* Di layar penuh kotaknya tetap setinggi layar walau gambarnya gagal, jadi
     pilnya tetap melayang di tempat biasanya. */
  .mdl:has(.pindai) .pindai-video[hidden] ~ .pindai-status{position:absolute;transform:translateX(-50%);margin:0}
}

/* ------------------------------------------------------ petak foto kosong
   SATU BENTUK UNTUK SELURUH ERP (K-224, `E.fotoKosongHTML`). Ia berdiri di
   petak yang ukurannya berbeda-beda — kartu etalase selebar setengah layar
   telepon, foto halaman produk selebar layar, kartu Inventory, dan baris
   rekomendasi 62px — jadi seluruh ukurannya ditulis di blok ini saja.

   DITULIS PALING BELAKANG dengan sengaja: petak-petak itu mengatur
   `place-items` dan warnanya sendiri di blok yang berdiri lebih bawah di
   berkas ini, dan aturan yang ditulis lebih awal selalu kalah walau
   pemilihnya sama kuat (jebakan yang sudah dicatat di K-201 dan K-215). */
.fotonanti{display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:5px;padding:6px;min-width:0;color:var(--ink-3);text-align:center}
.fotonanti i{font-style:normal;font-size:var(--f11);line-height:1.35;letter-spacing:.01em}
/* UKURAN IKONNYA DITULIS DI SINI SAJA. Aturan lama `.pdp-kosong svg`,
   `.rekbaris-ph svg`, dan `.ukartu-nofoto svg` DICABUT (tidak ada kode
   mati): ketiganya sama kuat penyebutnya dengan `.fotonanti svg`, dan blok
   ini ditulis lebih belakang — jadi mereka tidak akan pernah menang lagi,
   dan angka yang berdiri tanpa pernah berlaku adalah angka yang menyesatkan
   siapa pun yang menggesernya. */
.fotonanti svg{flex:none;width:30px;height:30px;opacity:.75}
/* Foto besar halaman produk dan Detail Item: petaknya selebar layar, jadi
   ikon 30px di tengahnya tenggelam. */
.pdp-kosong .fotonanti svg{width:44px;height:44px}
/* Petak yang memang tidak muat tulisan: ikonnya saja, dan ia tidak perlu
   ruang bernapas di sekelilingnya. */
.fotonanti--kecil{gap:0;padding:0}
.fotonanti--kecil svg{width:20px;height:20px}

/* ================ PEMILIH PROVINSI, KOTA, KECAMATAN (K-271) ================
   Tombolnya berupa satu kolom isian, sama tinggi dan sama garis dengan kolom
   lain di formulirnya. Yang kosong menulis NAMA kolomnya sendiri dengan warna
   hint — nama yang menanggung artinya, tanpa label di atasnya. */
.wilayahbtn{display:flex;align-items:center;gap:8px;width:100%;min-height:var(--tinggi-kendali);
  padding:6px 11px;border:1px solid var(--line);border-radius:var(--radius);background:var(--surface);
  font:inherit;font-size:var(--f12);color:var(--ink);text-align:left;cursor:pointer}
.wilayahbtn:hover{border-color:var(--line-strong)}
.wilayahbtn-t{flex:1 1 auto;min-width:0;overflow-wrap:anywhere}
.wilayahbtn--kosong .wilayahbtn-t{color:var(--ink-3)}
.wilayahbtn svg{flex:none;width:14px;height:14px;color:var(--ink-3)}
.wilayahbtn.err{border-color:var(--focus);box-shadow:inset 0 0 0 1px var(--focus)}

/* Halamannya. Di layar lebar sebuah pop-up bertinggi tetap — daftarnya yang
   menggulir, bukan kepalanya — dan di telepon ia MENGGANTIKAN layarnya,
   seperti halaman J&T yang jadi contohnya. Pemilihnya lebih kuat daripada
   `.mdl` di blok lembar-bawah (`@media(max-width:640px)` di atas), karena
   yang itu ditulis paling belakang dengan sengaja — pola `.mdl--foto`. */
.ov .mdl--wilayah{height:min(640px, calc(100dvh - 88px));display:flex;flex-direction:column}
.mdl--wilayah .mdl-bd{padding:0;display:flex;flex-direction:column;flex:1 1 auto;min-height:0;overflow:hidden}
.wlh-hd{display:flex;align-items:center;gap:10px;padding:12px 14px 6px}
.wlh-hd h3{font-size:var(--f14);font-weight:700;margin:0}
.wlh-kembali{display:inline-flex;align-items:center;justify-content:center;width:34px;height:34px;
  border:0;background:none;border-radius:var(--radius);color:var(--ink);cursor:pointer}
@media (hover:hover){ .wlh-kembali:hover{color:var(--ink-2)} }
.wlh-kembali svg{width:19px;height:19px}
.wlh-cari{padding:6px 14px 10px}
.wlh-cari .search{width:100%;max-width:none}
.wlh-isi{flex:1 1 auto;min-height:0;overflow-y:auto;overscroll-behavior:contain;
  background:var(--ground);padding:12px 14px calc(14px + env(safe-area-inset-bottom))}
.wlh-terpilih{display:flex;align-items:center;justify-content:space-between;margin-bottom:8px}
.wlh-terpilih b{font-size:var(--f12)}
.wlh-terpilih .linkbtn{font-size:var(--f12);font-weight:600;text-decoration:none}
.wlh-langkah{display:flex;flex-direction:column;gap:4px;margin-bottom:14px}
/* Titik bercincin: anak tangga yang sudah terpilih dan yang sedang menunggu
   memakai titik yang SAMA — yang menunggu cuma dibingkai. */
.wlh-titik{display:flex;align-items:center;gap:10px;min-height:36px;padding:0 12px;
  border:1px solid transparent;border-radius:var(--radius);background:none;
  font:inherit;font-size:var(--f12);color:var(--ink);text-align:left;cursor:pointer}
.wlh-titik i{flex:none;width:12px;height:12px;border-radius:50%;border:3px solid var(--ink);background:var(--surface)}
button.wlh-titik:hover{background:var(--surface-2)}
.wlh-titik--kini{border-color:var(--ink);background:var(--surface);cursor:default}
.wlh-sub{font-size:var(--f12);font-weight:700;margin-bottom:4px}
.wlh-daftar{display:flex;flex-direction:column}
.wlh-baris{display:flex;align-items:center;gap:14px;min-height:48px;padding:6px 6px;
  border:0;border-bottom:1px solid var(--line);background:none;
  font:inherit;font-size:var(--f13);color:var(--ink);text-align:left;cursor:pointer}
.wlh-baris:hover{background:var(--surface-2)}
.wlh-baris svg{flex:none;width:18px;height:18px;color:var(--ink-3)}
.wlh-baris span{min-width:0;overflow-wrap:anywhere}
/* Yang cocok dengan ketikan MENYALA — tebal dan sewarna tinta — tanpa garis
   bawah (diminta pemiliknya); sisanya sedikit redup supaya nyalanya terbaca. */
.wlh-baris span{color:var(--ink-2)}
.wlh-baris mark{background:none;color:var(--ink);font-weight:700;text-decoration:none}
.wlh-kosong{padding:18px 6px;font-size:var(--f12);color:var(--ink-3)}
@media (max-width:640px){
  .ov:has(.mdl--wilayah){padding:0;align-items:stretch;justify-content:stretch}
  .ov .mdl--wilayah{width:100%;max-width:100%;height:100dvh;max-height:100dvh;
    border:0;border-radius:0;box-shadow:none;transform:none}
  .ov.on .mdl--wilayah{transform:none}
}

/* ====== KOLOM BERGARIS DAN LABEL MENGAMBANG (K-271, tahap 4) ==============
   *"ketika kolomnya diklik maka hint-nya naik ke atas dan mengecil, sekalian
   tolong ubah semua model kolomnya, dari sebelumnya selalu mengandalkan kotak,
   diubah menjadi garis"* — dengan tangkapan layar Shopee sebagai contoh.

   GARIS UNTUK SEMUA KENDALI DI DALAM `.field` (kotak ketik, kotak teks,
   pilihan, kolom tanggal, pemilih wilayah), berjudul mengambang atau tidak.
   Yang BUKAN kolom formulir — kotak cari di kepala daftar, cip saringan —
   tidak berdiri di dalam `.field`, dan tidak disentuh.

   WARNANYA TETAP HITAM-PUTIH: garis yang sedang disentuh atau yang ditolak
   menebal dan menghitam, bukan memerah — pesan galat ERP ini sejak awal
   bertinta hitam (`.errmsg`), dan itu tidak diminta berubah. */
.field .inp,
.field .combo-btn,
.field .wilayahbtn,
.field .inp-tgl{border:0;border-bottom:1px solid var(--line-strong);border-radius:0;
  background:transparent;box-shadow:none;padding-left:0}
.field .combo-btn{padding-right:24px}
.field .combo-btn::after{right:4px}
.field .wilayahbtn,.field .inp-tgl{padding-right:0}
.field .inp:focus-within,
.field .combo-btn:focus-visible,
.field .wilayahbtn:focus-visible,
.field .inp-tgl:focus-visible{border-bottom-color:var(--ink);box-shadow:inset 0 -1px 0 var(--ink);outline:0}
.field .inp.err,.field .inp:has(.err),
.field .combo-btn.err,
.field .wilayahbtn.err,
.field .inp-tgl.err{border-bottom-color:var(--focus);box-shadow:inset 0 -1px 0 var(--focus)}
/* Kotak yang tidak bisa diubah: garisnya putus-putus, supaya tidak terbaca
   sebagai kolom yang menunggu diisi. */
.field .inp:has(> input[readonly]),.field .inp.inp--ro{border-bottom-style:dashed}

/* LABEL MENGAMBANG. Tingginya diukur dari satu baris isi: kendalinya
   mencadangkan 16px di atas untuk label kecil, dan label besar duduk tepat di
   baris isinya — jadi naiknya tidak menggeser apa pun di bawahnya. */
.field[data-hint]{position:relative}
.field[data-hint] .inp,
.field[data-hint] .combo-btn,
.field[data-hint] .wilayahbtn,
.field[data-hint] .inp-tgl{min-height:52px;height:auto;padding-top:20px;align-items:center}
.field[data-hint] .inp > textarea{padding-top:6px}
.field[data-hint] .combo-btn::after{top:auto;bottom:15px}
.field > label.lbl-apung{position:absolute;left:0;top:27px;z-index:1;margin:0;
  font-size:var(--f12);line-height:18px;color:var(--ink-3);pointer-events:none;
  transform-origin:left top;white-space:nowrap;max-width:100%;overflow:hidden;text-overflow:ellipsis;
  transition:top .16s ease, font-size .16s ease, color .16s ease}
.field[data-hint]:has(textarea) > label.lbl-apung{top:26px}
/* Selama label besar menempati barisnya, isi kosong kendalinya tidak
   digambar — kalau tidak, "Pilih…" dan labelnya bertumpuk. */
.field[data-hint] .combo-btn > .ph,
.field[data-hint] .wilayahbtn--kosong .wilayahbtn-t,
.field[data-hint] .inp-tgl-v.ph{visibility:hidden}
.field[data-hint] input::placeholder,
.field[data-hint] textarea::placeholder{color:transparent}
/* NAIK: disentuh atau terisi. Label yang naik berdiri 5px di bawah tepi
   atas kolomnya — MENDEKAT KE ISINYA, bukan menempel pada garis kolom di
   atasnya (diminta pemiliknya: "ketika labelnya naik kenapa mepet banget sama
   garis atasnya"). */
.field[data-hint]:focus-within > label.lbl-apung,
.field[data-hint]:has(input:not(:placeholder-shown)) > label.lbl-apung,
.field[data-hint]:has(textarea:not(:placeholder-shown)) > label.lbl-apung,
.field[data-hint]:has(.combo-btn > span:not(.ph):not(.sub)) > label.lbl-apung,
.field[data-hint]:has(.wilayahbtn:not(.wilayahbtn--kosong)) > label.lbl-apung,
.field[data-hint]:has(.inp-tgl-v:not(.ph)) > label.lbl-apung{top:5px;font-size:var(--f11);line-height:15px}
/* KOLOM BERAWALAN (telepon, Rp): labelnya tidak digambar — awalannya yang
   menyebut kolomnya ("Ongkir Rp"), lihat `labelJadiHint`. Ia tetap ada untuk
   pembaca layar. */
.field--awalan > label.lbl-apung{width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
.field--awalan[data-hint] .inp{padding-top:16px}
.field[data-hint]:focus-within > label.lbl-apung{color:var(--ink-2)}
/* Contoh isian baru tampak saat kolomnya disentuh dan masih kosong. */
.field[data-hint]:focus-within input::placeholder,
.field[data-hint]:focus-within textarea::placeholder{color:var(--ink-3)}
/* Label tanda "wajib" di dalam judulnya tidak ikut mengambang: pada label
   sekecil itu ia cuma merapatkan huruf. Kolom wajib yang kosong tetap
   ditolak saat Simpan, dengan pesan yang menyebut namanya. */
.field > label.lbl-apung .req{display:none}

/* ---- tahan foto: Simpan Foto / Simpan Semua Foto (tampilan tahap 1) ----
   Menu bawaan peramban DIPADAMKAN di atas foto yang bisa ditahan — tanpa itu
   Safari di iPhone memunculkan menunya sendiri berbarengan dengan milik ERP.
   Dan di telepon kedua tombol Unduh di kaki penampil foto tidak digambar:
   jalannya sekarang menahan fotonya (`Foto.pasangTahan`). */
.fototahan,.fototahan img{-webkit-touch-callout:none}
.fototahan img{-webkit-user-drag:none}
@media (max-width:640px){ .mdl--foto .lf-unduh{display:none} }

/* ==========================================================================
   PANEL DETAIL DI DAFTAR ITEM (K-273, tampilan tahap 2) — layar 1225px ke atas
   ==========================================================================
   Detailnya meluncur dari kanan SELEBAR DUA KARTU dan SETINGGI LAYAR (tahap
   4, ralat pemiliknya: "detail item itu memakan 2 card (bukan 3 card)", dan
   "icon pemberitahuan ikut geser ke kiri, sehingga detail produk bisa naik
   keatas"). Kartunya tetap di lajur yang tersisa SEUKURAN SEMULA
   (`--kartu-w` dan `--kartu-lajur` diukur sebelum panelnya dibuka), baris
   kepala mundur sejauh `--panel-sisi` supaya loncengnya tetap terlihat, dan
   baris saringan beserta baris tindakan Pilih Item menyempit selebar
   daftarnya (`--daftar-w`) — tidak ada lagi yang tertimbun di bawah panel.
   Letak dan lebar panelnya dihitung skripnya (`Panel.ukur`). Gerakan kartu
   dan tombol Pilih Item dikerjakan skripnya (FLIP); yang di sini cuma
   luncuran panelnya. */
.panelitem{position:fixed;top:0;bottom:0;z-index:45;display:flex;flex-direction:column;
  background:var(--surface);border-left:1px solid var(--line);
  box-shadow:-18px 0 32px -26px rgba(0,0,0,.4);
  transform:translateX(calc(100% + 40px));visibility:hidden;
  transition:transform .32s cubic-bezier(.22,.7,.25,1),visibility 0s linear .32s}
.panelitem.buka{transform:none;visibility:visible;
  transition:transform .32s cubic-bezier(.22,.7,.25,1),visibility 0s}
.panelitem-isi{flex:1 1 auto;min-height:0;overflow-y:auto;overscroll-behavior:contain;padding:18px}
/* TOMBOL LIPAT: lidah di tepi kiri panelnya, menjorok ke area daftar. */
.panellipat{position:absolute;top:50%;right:100%;display:grid;place-items:center;
  width:24px;height:56px;margin-top:-28px;padding:0;cursor:pointer;
  border:1px solid var(--line);border-right:0;border-radius:var(--radius) 0 0 var(--radius);
  background:var(--surface);color:var(--ink-3);box-shadow:-6px 0 14px -10px rgba(0,0,0,.35)}
.panellipat svg{width:16px;height:16px}
@media (hover:hover){ .panellipat:hover{color:var(--ink)} }
/* ISINYA BERBENTUK TELEPON (diminta pemiliknya: "tampilan detail item jadi
   mirip kayak pas pakai mode mobile"): satu lajur, foto selebar panelnya,
   dan fotonya tidak menggantung — panel ini menggulir dirinya sendiri. */
.panelitem .unitsplit{grid-template-columns:1fr;gap:16px}
.panelitem .unitkiri{position:static}
.panelitem .unitfoto-utama,.panelitem .fotostrip{max-width:none}
/* BILAH PINDAH ITEM DI DASAR DAFTARNYA: ‹ A · n / N · D ›. */
.panelnav{position:fixed;bottom:16px;z-index:36;display:none;align-items:center;justify-content:center;gap:4px;
  width:var(--daftar-w);pointer-events:none}
body.panel-buka .panelnav{display:flex;animation:navMasuk .24s ease}
@keyframes navMasuk{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
.panelnav > *{pointer-events:auto}
.panelnav-b{display:flex;align-items:center;gap:7px;height:40px;padding:0 12px;cursor:pointer;
  border:1px solid var(--line);border-radius:var(--radius);background:var(--surface);color:var(--ink-2);
  box-shadow:var(--shadow)}
@media (hover:hover){ .panelnav-b:hover{color:var(--ink);border-color:var(--line-strong)} }
.panelnav-ik{display:grid;place-items:center}
.panelnav-ik svg{width:16px;height:16px}
.panelnav-ik--kiri svg{transform:rotate(180deg)}
.panelnav kbd{display:grid;place-items:center;min-width:20px;height:20px;padding:0 5px;
  border:1px solid var(--line-strong);border-bottom-width:2px;border-radius:var(--radius-kcl);
  font:600 11px/1 var(--f-angka);color:var(--ink-2);background:var(--surface-2)}
/* LEBARNYA DIPATOK untuk "9999 / 9999" (diminta pemiliknya): jarak A dan D
   tidak boleh bergeser hanya karena angkanya menjadi ratusan atau ribuan. */
.panelnav-n{width:92px;flex:none;padding:0 4px;text-align:center;font-family:var(--f-angka);font-size:var(--f12);
  font-variant-numeric:tabular-nums;white-space:nowrap;color:var(--ink-2);pointer-events:none}
/* Kartu yang sedang terbuka di panel. */
.ukartu--lihat{outline:2px solid var(--ink);outline-offset:-1px}
body.panel-buka #list.daftarsempit--ubin{grid-template-columns:repeat(var(--kartu-lajur,3),var(--kartu-w));
  padding-bottom:64px}
body.panel-buka .stikatas > *{max-width:var(--daftar-w)}
/* TAB DETAIL ITEM (K-280): "Detail" · "Servis & Penjualan", di bawah harga. */
.itemtab{margin:6px 0 14px;border-bottom:1px solid var(--line)}
.itemtab-isi[hidden]{display:none}
/* Kartu yang digulir ke layar tidak berhenti di balik baris kepala atau bilah
   pindah item. */
body.panel-buka #list .ukartu{scroll-margin:72px 0 76px}
body.panel-buka .topbar{padding-right:calc(var(--panel-sisi) + 24px)}
.topbar{transition:padding-right .32s cubic-bezier(.22,.7,.25,1)}
@media (prefers-reduced-motion:reduce){ .panelitem,.panelitem.buka,.topbar{transition:none} .panelnav{animation:none} }
/* DETAIL ITEM LAYAR PENUH DI TELEPON (tahap 4). Satu lapisan selayar yang
   meluncur dari kanan, berisi halaman detail yang SAMA (`.page` +
   `gambarDetail`), jadi seluruh aturan halaman detail di telepon ikut
   berlaku. Kepalanya meniru `.topbar--layang` (K-207): Kembali dan titik tiga
   putih beralas gelap di atas foto, dan kepalanya memadat bersama namanya
   begitu fotonya lewat. Ia di atas bilah Jual daftar (60) dan di bawah
   pop-up (100). */
.layaritem{position:fixed;inset:0;z-index:70;display:flex;flex-direction:column;background:var(--ground);
  transform:translateX(100%);visibility:hidden;
  transition:transform .28s cubic-bezier(.22,.7,.25,1),visibility 0s linear .28s}
.layaritem.buka{transform:none;visibility:visible;
  transition:transform .28s cubic-bezier(.22,.7,.25,1),visibility 0s}
body.layar-buka{overflow:hidden}
.layaritem-isi{flex:1 1 auto;min-height:0;overflow-y:auto;overscroll-behavior:contain}
.layaritem-hd{position:absolute;left:0;right:0;top:0;z-index:5;height:58px;
  display:flex;align-items:center;gap:6px;padding:0 6px}
.layaritem-hd::before{content:"";position:absolute;inset:0;background:var(--surface);
  border-bottom:1px solid var(--line);opacity:0;transition:opacity .18s}
.layaritem-hd > *{position:relative}
.layaritem-b{display:grid;place-items:center;flex:none;width:44px;height:44px;padding:0;cursor:pointer;
  border:0;background:none;color:#fff;transition:color .18s}
.layaritem-b::before{content:"";position:absolute;inset:5px;border-radius:50%;
  background:rgba(0,0,0,.46);transition:opacity .18s}
.layaritem-b svg{position:relative;width:22px;height:22px}
.layaritem-t{flex:1 1 auto;min-width:0;font-family:var(--f-judul);font-size:var(--f14);font-weight:700;
  color:var(--ink);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;opacity:0;transition:opacity .18s}
.layaritem--padat .layaritem-hd::before,.layaritem--padat .layaritem-t{opacity:1}
.layaritem--padat .layaritem-b{color:var(--ink)}
.layaritem--padat .layaritem-b::before{opacity:0}
@media (prefers-reduced-motion:reduce){ .layaritem,.layaritem.buka{transition:none} }

/* PENCARIAN DAFTAR ITEM NAIK KE BARIS KEPALA JUGA DI LAYAR LEBAR (tahap 4,
   diminta pemiliknya: kolom cari yang lebar menjadi "1 ikon kaca pembesar
   yang menggeser judul 'Daftar Item'", cara kerjanya seperti di telepon —
   supaya tab keadaan tetap berdiri saat panel detailnya terbuka). Mesinnya
   `pasangCariAtas` yang SAMA; yang di sini cuma bentuk telepon yang
   diberlakukan di 961px ke atas, dan hanya di halaman yang menandai
   `<body>`-nya `cari-atas`. */
@media (min-width:961px){
  body.cari-atas .filterhead > .search{display:none}
  body.cari-atas .topmid{position:relative;height:40px;overflow:hidden}
  body.cari-atas .topjudul{position:absolute;inset:0;display:flex;align-items:center;
    transition:transform .26s cubic-bezier(.22,.61,.36,1),opacity .18s ease}
  body.cari-atas .topcari{display:block;position:absolute;inset:0;max-width:480px;opacity:0;pointer-events:none;
    transform:translateX(28px);
    transition:transform .26s cubic-bezier(.22,.61,.36,1),opacity .18s ease}
  body.cari-atas .topcari input{width:100%;height:36px;padding:0 12px;border:1px solid var(--line);
    border-radius:var(--radius);background:var(--surface);color:var(--ink);font-size:var(--f13)}
  body.cari-atas .topcari input::placeholder{color:var(--ink-3);opacity:1}
  body.cari-atas .topcari input:focus{outline:0;border-color:var(--focus);border-width:1.5px}
  body.cari-atas .topcari input::-webkit-search-cancel-button{-webkit-appearance:none;appearance:none}
  body.cari-atas .topbar--cari .topjudul{transform:translateX(-28px);opacity:0}
  body.cari-atas .topbar--cari .topcari{transform:none;opacity:1;pointer-events:auto}
  body.cari-atas .topcaribtn{position:relative;display:grid;place-items:center;flex:none;
    width:40px;height:40px;overflow:hidden;padding:0;cursor:pointer;
    border:0;border-radius:var(--radius);background:none;color:var(--ink)}
  body.cari-atas .topcaribtn[hidden]{display:none}
  body.cari-atas .topcaribtn-ik{position:absolute;inset:0;display:grid;place-items:center;
    transition:transform .22s cubic-bezier(.4,0,.2,1),opacity .16s ease}
  body.cari-atas .topcaribtn-ik svg{width:20px;height:20px}
  body.cari-atas .topcaribtn-x{transform:translateY(100%);opacity:0}
  body.cari-atas .topbar--cari .topcaribtn-c{transform:translateY(-100%);opacity:0}
  body.cari-atas .topbar--cari .topcaribtn-x{transform:none;opacity:1}
}

/* "PILIH ITEM" DI UJUNG KANAN BARIS TAB (K-273): tombol bergaris biasa di
   antara dua ikon polos — ia tindakan, bukan saringan — dan pekat saat mode
   Pilih menyala ("Batal Memilih"). Barisnya TIDAK LAGI MELIPAT: yang
   mengalah deretan tabnya, yang menggulung ke samping. */
.filterhead--tab{flex-wrap:nowrap}
.filterhead--tab .filterhead-kanan .pilihitem{height:32px;padding:0 12px;margin-right:6px;
  border:1px solid var(--line);background:var(--surface);color:var(--ink)}
.filterhead--tab .filterhead-kanan .pilihitem:hover{border-color:var(--line-strong);background:var(--surface)}
.filterhead--tab .filterhead-kanan .pilihitem.btn--primary{background:var(--ink);border-color:var(--ink);color:var(--on-ink)}
/* Baris tindakan di bawahnya tidak menyisakan jarak selagi mode Pilih mati —
   aturan yang sama dengan telepon, sekarang di setiap lebar: tombol Pilih
   Item sudah tidak tinggal di sana. */
.stikatas .daftarhead--lebur:not(.daftarhead--pilih){display:none}

/* ---- panduan geser halaman Detail Item (K-273), tujuh hari sekali ----
   Peraganya dua kartu kecil: yang satu keluar ke kiri, yang lain masuk dari
   kanan, didorong titik jari yang menghentak ke kiri. Berulang sampai
   ditutup. */
.panduangeser{position:fixed;inset:0;z-index:150;display:grid;place-items:center;padding:24px;
  background:rgba(8,9,10,.62);animation:pgMasuk .2s ease-out}
.panduangeser--tutup{opacity:0;transition:opacity .2s}
.panduangeser-kotak{width:min(300px,100%);display:flex;flex-direction:column;align-items:center;gap:16px;
  padding:22px 20px 18px;border-radius:18px;background:var(--surface);color:var(--ink);text-align:center}
.panduangeser-kotak p{margin:0;font-size:var(--f13);font-weight:600}
.panduangeser-kotak .btn{width:100%;height:42px}
.panduangeser-peraga{position:relative;width:170px;height:150px;overflow:hidden;border-radius:14px;
  background:var(--surface-2)}
.pg-kartu{position:absolute;top:14px;left:35px;width:100px;height:122px;display:flex;flex-direction:column;gap:7px;
  padding:8px;border-radius:10px;background:var(--surface);border:1px solid var(--line);
  box-shadow:0 6px 16px -10px rgba(0,0,0,.35)}
.pg-kartu i{display:block;height:62px;border-radius:6px;background:var(--line)}
.pg-kartu b{display:block;height:7px;border-radius:4px;background:var(--line)}
.pg-kartu b + b{width:60%}
.pg-kartu--a{animation:pgKeluar 2.4s cubic-bezier(.5,0,.3,1) infinite}
.pg-kartu--b{animation:pgDatang 2.4s cubic-bezier(.5,0,.3,1) infinite}
.pg-jari{position:absolute;top:84px;left:118px;width:26px;height:26px;border-radius:50%;
  background:rgba(21,21,23,.28);border:2px solid rgba(21,21,23,.55);animation:pgJari 2.4s cubic-bezier(.5,0,.3,1) infinite}
@keyframes pgMasuk{from{opacity:0}to{opacity:1}}
@keyframes pgKeluar{0%,30%{transform:none;opacity:1}62%,100%{transform:translateX(-150px);opacity:0}}
@keyframes pgDatang{0%,30%{transform:translateX(150px);opacity:0}62%,100%{transform:none;opacity:1}}
@keyframes pgJari{0%,18%{transform:none;opacity:0}28%{transform:none;opacity:1}
  58%{transform:translateX(-86px);opacity:1}72%,100%{transform:translateX(-86px);opacity:0}}
@media (prefers-reduced-motion:reduce){
  .pg-kartu--a,.pg-kartu--b,.pg-jari,.panduangeser{animation:none}
  .pg-kartu--a{display:none}
}

/* ---------- KEPALA SEKSI ITEM DI DALAM KOTAKNYA (K-286, rombak Pembelian R1)
   Diminta pemiliknya: "Item 0 dari 1 diterima" masuk ke DALAM kotak daftar
   itemnya, dan tombol-tombolnya (Nota, Kirim WhatsApp, Riwayat Komplain, …)
   berdiri DI ATAS kotaknya, di luar, SATU BARIS yang bisa digeser kiri-kanan
   bila tidak muat — bukan melipat ke baris kedua (ralat pemiliknya atas
   percobaan pertama yang menaruhnya sebaris dengan judul di dalam kotak).
   Detail Pembelian dan Detail Penjualan.

   Deretan tombolnya menempel ke KANAN lewat `margin-left:auto` pada anak
   pertamanya, bukan `justify-content:flex-end`: yang kedua memotong tombol
   paling kiri begitu barisnya meluap, dan potongan itu tidak bisa digulir. */
.irow-act.sec-akt{flex-wrap:nowrap;justify-content:flex-start;margin:0 0 8px;
  overflow-x:auto;scrollbar-width:none;-webkit-overflow-scrolling:touch}
.irow-act.sec-akt::-webkit-scrollbar{display:none}
.irow-act.sec-akt > *{flex:none;white-space:nowrap}
.irow-act.sec-akt > :first-child{margin-left:auto}
.sec-hd.sec-hd--kotak{flex-wrap:nowrap;align-items:center;margin:0;padding:9px 12px;
  border:1px solid var(--line);border-bottom:0;border-radius:var(--radius) var(--radius) 0 0;
  background:var(--surface)}
.sec-hd--kotak + .ilist{border-top-left-radius:0;border-top-right-radius:0}

/* ---------- KEADAAN PENERIMAAN DI BARIS ITEM PEMBELIAN (K-288, R2)
   Menggantikan serial di bawah nama inventory. "Sudah diterima ›" sebuah
   tombol teks yang membuka rincian penerimaannya; tiga keadaan lainnya cuma
   keterangan. Warnanya token keadaan yang sudah ada. */
.irow-terima{display:inline-flex;align-items:center;gap:4px;margin-top:4px;padding:0;border:0;
  background:none;font:inherit;font-size:var(--f12);font-weight:600;color:var(--ink-3);max-width:100%}
.irow-terima svg{width:13px;height:13px;flex:none}
.irow-terima--ok{color:var(--done)}
.irow-terima--stop{color:var(--stop)}
.irow-terima--tunggu{color:var(--ink-2);font-weight:500}
button.irow-terima{cursor:pointer}
button.irow-terima > svg:last-child{width:12px;height:12px;margin-left:-1px}
/* REKOMENDASI PENCARIAN SATU BARIS YANG DIGESER, DI TELEPON (K-289, diminta
   pemiliknya) — bukan cip yang melipat ke beberapa baris. Pencarian Terakhir
   tidak ikut. */
@media (max-width:640px){
  .carichips--geser{flex-wrap:nowrap;overflow-x:auto;scrollbar-width:none;-webkit-overflow-scrolling:touch;
    margin-inline:calc(var(--shop-pad, 8px) * -1);padding-inline:var(--shop-pad, 8px)}
  .carichips--geser::-webkit-scrollbar{display:none}
  .carichips--geser > .carichip{flex:none}
}

/* ---------- BARIS ITEM PEMBELIAN: TIGA BARIS SEJAJAR FOTO (K-290) ----------
   Nama · keadaan penerimaan · [komplain][Terima] … harga, tanpa garis
   melintang. Fotonya setinggi ketiga baris itu dan berdiri kokoh di kiri;
   baris ketiga TIDAK BOLEH melipat (tidak ada baris keempat): tombolnya
   tidak menyusut, harganya tidak dipotong, dan yang mengalah cuma nama
   di baris pertama (dipotong "…"). */
.irow.irow--beli3{flex-direction:row;flex-wrap:nowrap;align-items:stretch;gap:11px}
.irow--beli3 > .irowfoto--besar{width:76px;height:76px;flex:none;align-self:center;aspect-ratio:auto}
.irow--beli3 > .irow-main{flex:1 1 auto;min-width:0;display:flex;flex-direction:column;
  justify-content:space-between;gap:2px}
.irow--beli3 .irow-name{display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.irow--beli3 .irow-terima{margin-top:0}
.irow-aksibar.irow-aksibar--sebaris{margin:0;padding:0;border:0;gap:6px;flex-wrap:nowrap}
.irow-aksibar--sebaris > .irow-act{flex:none;order:0}
.irow-aksibar--sebaris .btn{height:30px}
.irow-aksibar--sebaris .btn--ikon{width:30px}
.irow-aksibar--sebaris > .irow-terimabtn{margin-left:0;padding:0 12px}
.irow-aksibar--sebaris > .irow-amt{flex:none;order:0;margin-left:auto;white-space:nowrap}
@media(max-width:620px){
  .irow.irow--beli3{flex-wrap:nowrap}
  .irow--beli3 > .irowfoto--besar{width:72px;height:72px}
}
/* Layar tersempit (320–360px) dengan harga delapan digit DAN tombol Terima:
   diukur meluap 3px — fotonya dan jaraknya yang mengalah, bukan harganya. */
@media(max-width:360px){
  .irow.irow--beli3{gap:9px}
  .irow--beli3 > .irowfoto--besar{width:66px;height:66px}
  .irow-aksibar.irow-aksibar--sebaris{gap:5px}
  .irow-aksibar--sebaris > .irow-terimabtn{padding:0 9px}
}
/* GARANSI · MASUK SEBARIS (K-290). Keduanya boleh menyusut dan dipotong
   titik-titik; garis tipis pendek di tengah sebagai pemisah. */
.asalbaris{display:flex;align-items:center;gap:8px;min-width:0;max-width:100%;flex:1 1 100%}
.asalbaris > .garansibawaan{margin:0;flex:0 1 auto;font-size:var(--f11)}
.asalbaris > .garansibawaan b{font-weight:500}
.asalbaris > .dhead-tgl{flex:0 1 auto;min-width:0;overflow:hidden}
.asalbaris > .dhead-tgl > span{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.asalbaris > .garansibawaan .hargaikon svg{width:12px;height:12px}
.asalgaris{flex:none;width:1px;height:11px;background:var(--line-strong)}
/* Kartu dokumen di dalam kotak Servis/Penjualan (K-290): tidak mewarisi
   `pre-wrap` catatan. */
.dwi-isi.dwi-isi--kartu{white-space:normal}
/* ---------- KOLOM BANYAK-BARIS TUMBUH MENGIKUTI ISINYA (K-292) ----------
   Dilaporkan pemiliknya (Request Customer, "dan ketidaksesuaian kolom
   pengisian ini juga terjadi dimana2"): kolom teks panjang dulu berdiri
   setinggi dua-tiga baris sejak kosong, jadi baris yang sedang diketik
   MELAYANG jauh di atas garis bawahnya, dan penghitung hurufnya menduduki
   pojoknya. Sekarang ia mulai SETINGGI SATU BARIS — sama dengan kolom biasa
   — dan tumbuh sendiri mengikuti isinya (paling tinggi delapan baris, lalu
   digulir). `field-sizing:content` di peramban yang mengenalnya; yang tidak,
   dibantu satu pendengar `input` di erp.js (`tumbuhkan`). Penghitung huruf
   turun ke BAWAH garisnya. Hanya kolom formulir `.field`; kotak catatan besar
   (`textarea.inp`) tidak disentuh. */
.field .inp > textarea{field-sizing:content;min-height:calc(1.45em + 12px);max-height:calc(8 * 1.45em + 12px);
  line-height:1.45;padding:6px 0;resize:none;overflow-y:auto}
.field[data-hint] .inp > textarea{padding-top:4px;padding-bottom:6px}
.field .inp--hitung{margin-bottom:16px}
.field .inp--hitung textarea{padding-bottom:6px}
.field .inp-hitung{top:calc(100% + 2px);bottom:auto;right:0;background:none;padding:0}
/* Kolom lokasi yang sudah pasti (K-292): terkunci, berikon pin. */
.field--pasti .inp{gap:6px}
.inp-pin{display:inline-flex;flex:none;color:var(--ink-3)}
.inp-pin svg{width:14px;height:14px}
/* LOKASI DI KANAN JUDUL PANEL (K-293). Yang tetap cuma tulisan berikon pin;
   yang boleh dipilih daftar pilihan ringkas di tempat yang sama. */
.panel--lembar .panel-hd > .panel-kanan{flex:none;min-width:0;max-width:50%}
.lokasitetap,.lokasipilih{display:inline-flex;align-items:center;gap:5px;min-width:0;font-size:var(--f13);color:var(--ink-2)}
.lokasitetap svg,.lokasipilih > svg{width:14px;height:14px;flex:none;color:var(--ink-3)}
.lokasitetap > span{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.lokasipilih .combo{min-width:0}
.lokasipilih .combo-btn{height:30px;min-height:0;padding:0 24px 0 8px;border:1px solid var(--line);
  border-radius:var(--radius);font-size:var(--f13);max-width:200px}
.lokasipilih .combo-btn::after{right:9px;top:50%;margin-top:-4px}

/* ---------- TIGA HARGA DETAIL ITEM, RINGKAS (K-293) ----------
   Diminta pemiliknya: dua harga kanan (batas harga jual, modal) bersama-sama
   SETINGGI satu harga kiri, supaya kotak yang mengelilinginya ringkas. Lajur
   kanan tanpa jarak dan barisnya 13px; harga besarnya setinggi dua baris itu.
   Garis di bawahnya tidak digambar di layar yang tombolnya menempel di dasar
   layar — di situ ia cuma membatasi ruang kosong. */
.itemharga{padding:10px 12px}
.itemharga > .hargautama{align-items:center}
.itemharga .hargasisi{gap:0}
.itemharga .hargasisi .hargakecil{line-height:13px}
.itemharga .hargasisi .hargaikon{width:13px;height:13px}
.itemharga .hargasisi .hargaikon svg{width:12px;height:12px}
.itemharga .hargabesar{line-height:26px}
@media (max-width:820px){ .itemharga > .hargagaris{display:none} }
/* Kotak serial, ikon label, dan "+N ›" SETINGGI SATU SAMA LAIN (K-293). */
.itemmeta .serialtag{display:inline-flex;align-items:center;height:22px;box-sizing:border-box;line-height:1}
.itemmeta .serialtag--ikon{width:28px;justify-content:center;padding:0}
.serialtag--lain{gap:2px;padding:0 4px 0 6px}
.serialtag--lain svg{width:11px;height:11px}
.nomorlain{display:flex;flex-direction:column}
.nomorlain-b{display:flex;align-items:center;gap:10px;padding:10px 2px;border:0;border-bottom:1px solid var(--line);
  background:none;font:inherit;color:inherit;text-align:left;cursor:pointer}
.nomorlain-b span{flex:none;min-width:64px;font-size:var(--f12);color:var(--ink-3)}
.nomorlain-b b{flex:1 1 auto;min-width:0;font-family:var(--f-angka);font-weight:500;overflow-wrap:anywhere}
.nomorlain-b svg{flex:none;width:14px;height:14px;color:var(--ink-3)}

/* HURUF DI TELEPON SATU ANAK TANGGA LEBIH KECIL (K-293, diminta pemiliknya:
   "font di hp, kalau laptop udah aman"). Yang kecil (10–12px) tetap —
   di bawahnya huruf tidak lagi terbaca; badan halaman 13→12px. Nama halaman
   di baris kepala tetap 16px (ditulis angka, bukan token). */
@media (max-width:640px){
  :root{--f13:12px; --f14:13px; --f16:14px; --f18:16px; --f22:18px}
}

/* ---------- KOTAK BIAYA DAN PEMBAYARAN DETAIL SERVIS (K-297)
   Servis beruang baru memisahkan CATATAN biaya dari UANG yang bergerak,
   masing-masing satu kotak berkepala `.sec-hd--kotak`. Isinya baris rinci
   yang sama dengan Detail Pembayaran (`.rincirow`), jadi kedua kotak dibaca
   sama seperti rinciannya. */
.kotakuang{border:1px solid var(--line);border-radius:0 0 var(--radius) var(--radius);
  background:var(--surface);padding:0 12px}
.kotakuang-kosong{margin:0;padding:14px 0;font-size:var(--f12)}
.kotakuang-aksi{margin:8px 0 0}
#secBiaya,#secBayar{margin-top:12px}

/* ---------- PETA PESAN ANTAR, LAYAR PENUH (K-298)
   Pin di tengah tidak bergerak; petanyalah yang digeser. Kepala dan kaki
   berdiri di atas peta sebagai bilah tipis. */
.petafull{position:fixed;inset:0;z-index:2000;display:flex;flex-direction:column;background:var(--surface)}
.petafull-hd{display:flex;align-items:center;gap:12px;padding:8px 12px;border-bottom:1px solid var(--line);background:var(--surface)}
.petafull-hd h2{margin:0;font-size:var(--f16);font-weight:600}
.petafull-peta{position:relative;flex:1 1 auto;min-height:0;background:var(--surface-2)}
.petafull-isi{position:absolute;inset:0}
.petafull-muat{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
  font-size:var(--f13);color:var(--ink-3)}
.petafull-pin{position:absolute;left:50%;top:50%;width:34px;height:34px;margin:-34px 0 0 -17px;
  color:var(--ink);pointer-events:none;z-index:2}
.petafull-pin svg{width:100%;height:100%;fill:currentColor;stroke:var(--surface);stroke-width:.8}
.petafull-kaki{display:flex;align-items:center;gap:10px;padding:10px 12px;border-top:1px solid var(--line);background:var(--surface)}
.petafull-cari{flex:1 1 auto;min-width:0}
.petafull-info{flex:1 1 auto;display:flex;flex-direction:column;gap:2px;font-size:var(--f12);color:var(--ink-3)}
.petafull-info b{font-size:var(--f16);color:var(--ink)}
html.petafull-buka{overflow:hidden}

/* ---------- PENGATURAN INVENTORY (tiga pilihan dalam satu halaman) ---------- */
.atur-baris{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:14px 16px;
  color:var(--ink);text-decoration:none;font-size:var(--f14)}
.atur-baris svg{width:14px;height:14px;flex:none;color:var(--ink-3)}

/* Ikon di dalam lencana keadaan (Retur): sebesar penanda `.mk` di sebelahnya. */
.pillik{display:inline-flex;flex:none;width:12px;height:12px}
.pillik svg{width:100%;height:100%}

/* SERVIS DAN PENJUALAN DI DETAIL ITEM: KARTUNYA LEPAS (diminta pemiliknya).
   Bukan kotak di dalam kotak: judul seksi berdiri sendiri, kartu dokumennya
   langsung di bawahnya. Dan tanpa gulir di dalamnya — tingginya mengikuti
   isi seluruhnya, karena satu-satunya yang boleh digulir halaman ini. */
.dwi-kolom--lepas{border:0;background:none;padding:0;border-radius:0}
.dwi-kolom--lepas .dwi-hd{padding:0 2px}
.dwi-isi.dwi-isi--kartu{max-height:none;overflow:visible;padding-right:0;min-height:0}

/* DETAIL ITEM DI TELEPON: NAMA BARANG DI BARIS KEPALA DIGANTI TOMBOL CARI
   (diminta pemiliknya). Ruangnya tetap dipakai (`visibility`, bukan
   `display`), supaya tombol Kembali tetap di kiri dan Cari + titik tiga tetap
   mepet kanan. Nama barangnya sudah ada di badan halaman. */
@media (max-width:960px){
  .topbar--layang .topmid{visibility:hidden}
}

/* MASUK DAN DAFTAR PELANGGAN ETALASE (K-301): satu kotak tengah, kolom satu. */
.akunkotak{max-width:400px;margin:24px auto;padding:20px;border:1px solid var(--line);border-radius:var(--radius);background:var(--surface);display:flex;flex-direction:column;gap:14px}
.akunkotak h1{font-size:var(--f16);margin:0}
.akunkotak-btn{width:100%;justify-content:center}
.akunkotak-baris{display:flex;justify-content:space-between;gap:10px;flex-wrap:wrap}
.akunkotak-tautan{background:none;border:0;padding:0;font:inherit;font-size:var(--f13);color:var(--ink);text-decoration:underline;cursor:pointer;text-align:center}
.akunkotak-tautan:disabled{color:var(--muted);text-decoration:none;cursor:default}
.akunkotak-kaki{text-align:center;font-size:var(--f13);color:var(--muted)}
.akunkotak-kaki a{color:var(--ink)}
.akunkotak-atau{display:flex;align-items:center;gap:10px;font-size:var(--f12);color:var(--muted)}
.akunkotak-atau::before,.akunkotak-atau::after{content:"";flex:1;border-top:1px solid var(--line)}
.akunkotak-google{display:flex;justify-content:center;min-height:44px}
.akunkotak [hidden]{display:none}
#bagKode{display:flex;flex-direction:column;gap:14px}
#bagKode[hidden]{display:none}
.akunkotak .kv-row{display:flex;justify-content:space-between;gap:12px;align-items:baseline}
.akunkotak .kv-row b{text-align:right;overflow-wrap:anywhere}
.akunkotak .notice{margin:0}

/* BIAYA DAN TABEL UANG DI BAWAH DAFTAR ITEM (K-307, rombak Pembelian R3). */
.biayabaris{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;padding:10px 14px;border-top:1px solid var(--line)}
.biayabaris:first-child{border-top:0}
.biayabaris-t{display:flex;flex-direction:column;gap:2px;min-width:0;overflow-wrap:anywhere;font-size:var(--f13)}
.biayabaris-t span{font-size:var(--f11);color:var(--ink-3)}
.biayabaris b{flex:none;font-family:var(--f-angka);font-variant-numeric:tabular-nums;font-size:var(--f13)}
.biayabaris--kosong{color:var(--ink-3);font-size:var(--f12)}
.ilist--uang{padding:6px 14px 4px}
.uangtabel .ringkas-baris:first-child{padding-top:6px}
.sec-hd.sec-hd--biaya{margin-top:14px}
.ilist.ilist--uang{margin-top:14px}

/* PANEL DAFTAR PEMBELIAN DI LAPTOP (≥1225px): halaman Detail Pembelian dalam bingkai di kanan, daftarnya
   menyempit di kiri. Dalam bingkai (`?bingkai=1`) menu kiri dan baris kepala tidak digambar. */
:root{--dp-w:620px}
.panelpembelian{right:0;width:var(--dp-w)}
.panelbingkai{flex:1 1 auto;min-height:0;width:100%;border:0;background:var(--ground)}
body.panel-beli .main{margin-right:var(--dp-w)}
html.bingkai .rail,html.bingkai .topbar,html.bingkai #kerangka{display:none}
html.bingkai .app{grid-template-columns:minmax(0,1fr)}

/* TAB KEADAAN YANG BERKENDALA: lingkaran penuh dan tulisan merah, sama dengan lencananya (`--stop`). */
.stattab-b--merah{color:var(--stop)}
.stattab-b--merah .mk{display:inline-block;margin-right:6px;background:currentColor;vertical-align:baseline}

/* STATUS ITEM MENEMPEL DI UJUNG JUDUL DETAIL ITEM: sesudah teks judul, sebaris, ikut melipat bersamanya. */
.itemjudul h1 .itemst{display:inline-flex;align-items:center;gap:6px;margin-left:8px;vertical-align:middle;font-weight:400;letter-spacing:normal}

/* ---------------------------------------------------------------- OPNAME (K-313)
   Kamera ditanam 1:1 di halaman (gambarnya dipotong persegi), dengan ikon di pojok kiri yang
   memperbesarnya: node yang SAMA berpindah ke puncak layar, persegi selebar layar (di laptop
   paling lebar 60% tinggi layar), dan daftar "Item yang belum diopname" mengisi sisa layar di bawahnya. */
.pindaitanam--persegi .pindai-video{width:100%;height:auto;aspect-ratio:1/1;max-height:none;object-fit:cover}
.pindaitanam--persegi{position:relative}
.pindai-bulat--kiri{position:absolute;top:22px;left:22px;z-index:3;line-height:normal}
body.opn-besar .pindai-bulat--kiri{top:10px;left:10px}
#opnKecil{display:none}
body.opn-besar #opnKecil{display:grid}
body.opn-besar #opnBesar{display:none}
.opn-besar-daftar{display:none}
body.opn-besar{overflow:hidden}
body.opn-besar .pindaitanam--persegi{position:fixed;top:0;left:0;right:0;z-index:70;margin:0;padding:0;border:0;border-radius:0;
  background:#000;display:flex;justify-content:center}
body.opn-besar .pindaitanam--persegi .pindai{width:min(100vw,60dvh)}
body.opn-besar .pindaitanam--persegi .pindai-video{border-radius:0}
body.opn-besar .opn-besar-daftar{display:block;position:fixed;left:0;right:0;top:min(100vw,60dvh);bottom:0;z-index:69;
  overflow:auto;background:var(--ground);padding:14px}
.opn-besar-judul{font-size:var(--f14);font-weight:600;margin:0 0 10px}
.sec-hd--kanan{justify-content:flex-end}
/* Baris item Opname: DUA baris teks — nama; lalu waktu masuk bersanding dengan serial — dan fotonya
   setinggi dua baris itu (kotak persegi mengikuti tinggi teksnya). */
.irow.irow--opn{--opn-lh:18px;--opn-foto:calc(var(--opn-lh) * 2 + 3px);min-height:0;display:flex;flex-direction:row;flex-wrap:nowrap;align-items:stretch;gap:11px;padding:10px 14px}
.irow--opn .irow-foto{position:relative;flex:none;align-self:center;width:var(--opn-foto);height:var(--opn-foto);min-width:0;overflow:hidden;display:block}
.irow--opn .irow-foto > *{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.irow--opn .irow-main{flex:1 1 auto;min-width:0;display:flex;flex-direction:column;justify-content:center;gap:3px}
.irow--opn .irow-name{display:block;line-height:var(--opn-lh);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.irow-sub--opn{margin-top:0;line-height:var(--opn-lh);display:flex;flex-wrap:nowrap;gap:8px;min-width:0;align-items:center}
.irow-sub--opn > *{flex:0 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.irow-serial-opn{font-variant-numeric:tabular-nums}
/* Ringkasan Selesaikan Opname: label dan angka dua lajur, angkanya rata KIRI. */
.opn-ringkas{display:grid;grid-template-columns:max-content 1fr;gap:10px 22px;align-items:baseline}
.opn-ringkas b{text-align:left;font-variant-numeric:tabular-nums}
.opn-ringkas-judul{font-size:var(--f13);font-weight:600;margin:16px 0 8px}
/* Lambang halaman Masuk sebagai latar CSS: berkas CSS-nya yang membawa penanda versi, bukan alamat gambarnya. */
.login-logo{display:block;width:100%;height:100%;background:url(login-logo.png) center/contain no-repeat}
/* Tombol "Laporkan Temuan" dirapatkan ke kotak kamera (K-322): jarak kamera → tombol → tab hanya 8px. */
.pindaitanam--persegi{margin-bottom:0}
.docsplit--pecah .sec-hd--kanan{margin:0 0 8px;padding:0}
.docsplit--opname .docsplit-kiri > .sec{margin-top:0}
@media (max-width:1224px){ .docsplit--pecah{row-gap:8px} }
