/* ==========================================================================
   Web Laundry - sistem tampilan v3.
   Diturunkan dari berkas desain: biru #004ac6, Plus Jakarta Sans, sudut
   membulat besar, kartu putih di atas latar biru pucat, ikon Material Symbols.
   ========================================================================== */

:root {
  /* --- warna inti --- */
  --primary: #004ac6;
  --on-primary: #ffffff;
  --primary-container: #2563eb;
  --on-primary-container: #eeefff;
  --primary-fixed: #dbe1ff;
  --primary-fixed-dim: #b4c5ff;
  --on-primary-fixed: #00174b;
  --on-primary-fixed-variant: #003ea8;

  --secondary: #576065;
  --on-secondary: #ffffff;
  --secondary-container: #dbe4ea;
  --on-secondary-container: #5d666b;

  --tertiary: #005a82;
  --on-tertiary: #ffffff;
  --tertiary-container: #0074a6;
  --on-tertiary-container: #e4f2ff;
  --tertiary-fixed: #c9e6ff;
  --tertiary-fixed-dim: #89ceff;
  --on-tertiary-fixed: #001e2f;
  --on-tertiary-fixed-variant: #004c6e;

  --error: #ba1a1a;
  --on-error: #ffffff;
  --error-container: #ffdad6;
  --on-error-container: #93000a;

  --background: #f8f9ff;
  --surface: #f8f9ff;
  --s-lowest: #ffffff;
  --s-low: #eff4ff;
  --s-cont: #e5eeff;
  --s-high: #dce9ff;
  --s-highest: #d3e4fe;
  --s-dim: #cbdbf5;
  --on-surface: #0b1c30;
  --on-surface-variant: #434655;
  --outline: #737686;
  --outline-variant: #c3c6d7;
  --inverse-surface: #213145;
  --inverse-on-surface: #eaf1ff;
  --wa: #25d366;
  --wa-gelap: #128c7e;

  /* garis tipis, dipakai di mana-mana */
  --garis: rgba(195, 198, 215, .5);
  --garis-tegas: #c3c6d7;

  /* --- jarak --- */
  --base: 4px; --xs: 8px; --sm: 12px; --md: 16px;
  --pad: 20px; --lg: 24px; --xl: 32px;
  --touch: 44px; --touch-lg: 56px;

  /* --- sudut --- */
  --r: 4px; --r-lg: 8px; --r-xl: 12px; --r-2xl: 16px; --r-3xl: 24px; --r-full: 9999px;

  /* --- bayang --- */
  --sh-sm: 0 1px 2px rgba(11, 28, 48, .05), 0 1px 3px rgba(11, 28, 48, .05);
  --sh-md: 0 2px 4px rgba(11, 28, 48, .05), 0 6px 16px -6px rgba(11, 28, 48, .12);
  --sh-lg: 0 4px 8px rgba(11, 28, 48, .06), 0 16px 32px -12px rgba(11, 28, 48, .18);
  --sh-primary: 0 8px 16px rgba(37, 99, 235, .25);

  --font: "Plus Jakarta Sans", "Segoe UI", system-ui, -apple-system, sans-serif;
  --sidebar-w: 256px;
  --topbar-h: 64px;
}

* { box-sizing: border-box; }
[hidden] { display: none !important; }
html, body { margin: 0; padding: 0; }
html { -webkit-text-size-adjust: 100%; }

body {
  background: var(--background);
  color: var(--on-surface);
  font-family: var(--font);
  font-size: 16px;
  line-height: 24px;
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
}

/* --- skala huruf, satu keluarga --------------------------------------- */
h1, h2, h3, h4 { margin: 0; font-weight: 700; letter-spacing: -.01em; }
h1 { font-size: 32px; line-height: 40px; }
h2 { font-size: 20px; line-height: 28px; }
h3 { font-size: 18px; line-height: 28px; }
p { margin: 0 0 var(--sm); }
p:last-child { margin-bottom: 0; }
a { color: var(--primary); text-decoration: none; }
a:hover { text-decoration: underline; }

.display { font-size: 40px; line-height: 48px; font-weight: 800; letter-spacing: -.02em; }
.harga-besar { font-size: 32px; line-height: 40px; font-weight: 700; letter-spacing: -.01em; }
.label-md { font-size: 14px; line-height: 20px; font-weight: 600; letter-spacing: .01em; }
.label-sm, .mini { font-size: 12px; line-height: 16px; font-weight: 500; }
.kecil { font-size: 14px; line-height: 20px; }
.body-lg { font-size: 18px; line-height: 28px; }
.label-atas {
  font-size: 12px; line-height: 16px; font-weight: 600;
  letter-spacing: .08em; text-transform: uppercase; color: var(--on-surface-variant);
}

.num, td.num, th.num, .nominal, .kode, input[type="number"], .uang {
  font-variant-numeric: tabular-nums; font-feature-settings: "tnum" 1;
}
.num, td.num, th.num { text-align: right; }
.minus { color: var(--error); }
.samar { color: var(--on-surface-variant); }
.pudar { color: var(--outline); }
.tebal { font-weight: 600; }
.tegas { font-weight: 700; }
.kanan { text-align: right; }
.tengah { text-align: center; }
.nowrap { white-space: nowrap; }
.tumbuh { flex: 1 1 auto; min-width: 0; }
.rapat { flex: 0 0 auto; }
.mb4 { margin-bottom: var(--md); }

/* --- ikon Material Symbols -------------------------------------------- */
.ms {
  font-family: "Material Symbols Outlined";
  font-weight: normal; font-style: normal; font-size: 24px; line-height: 1;
  letter-spacing: normal; text-transform: none; display: inline-block;
  white-space: nowrap; word-wrap: normal; direction: ltr;
  -webkit-font-feature-settings: "liga"; -webkit-font-smoothing: antialiased;
  font-variation-settings: "FILL" 0, "wght" 400, "GRAD" 0, "opsz" 24;
  flex: 0 0 auto; user-select: none;
}
.ms.isi { font-variation-settings: "FILL" 1, "wght" 400, "GRAD" 0, "opsz" 24; }
.ms.sm { font-size: 18px; }
.ms.md { font-size: 20px; }
.ms.lg { font-size: 28px; }
.ms.xl { font-size: 36px; }

/* ==========================================================================
   Kerangka
   ========================================================================== */
.rangka { display: flex; min-height: 100vh; min-height: 100dvh; }

.sidebar {
  width: var(--sidebar-w); flex: 0 0 var(--sidebar-w);
  background: var(--s-lowest); border-right: 1px solid var(--garis);
  display: flex; flex-direction: column;
  position: sticky; top: 0; height: 100vh; height: 100dvh; overflow-y: auto;
  padding: var(--lg) var(--md);
}
.merek { display: block; padding: 0 var(--xs) var(--lg); text-decoration: none; }
.merek b {
  display: block; font-size: 28px; line-height: 34px; font-weight: 800;
  letter-spacing: -.02em; color: var(--primary);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.merek small { font-size: 14px; font-weight: 600; color: var(--on-surface-variant); }
.merek:hover { text-decoration: none; }

.nav { display: flex; flex-direction: column; gap: var(--base); }
.nav a {
  display: flex; align-items: center; gap: var(--md);
  padding: 12px var(--md); border-radius: var(--r-xl);
  color: var(--on-surface-variant); font-size: 14px; font-weight: 600;
  letter-spacing: .01em; text-decoration: none;
}
.nav a:hover { background: var(--s-low); color: var(--on-surface); text-decoration: none; }
.nav a.aktif {
  background: var(--primary-container); color: var(--on-primary-container);
  font-weight: 700; box-shadow: var(--sh-sm);
}
.nav a.aktif .ms { font-variation-settings: "FILL" 1; }
.nav a .hitung {
  margin-left: auto; font-size: 12px; font-weight: 700;
  background: var(--s-cont); color: var(--on-primary-fixed-variant);
  padding: 2px 8px; border-radius: var(--r-full); font-variant-numeric: tabular-nums;
}
.nav a.aktif .hitung { background: rgba(255,255,255,.22); color: #fff; }
.nav-grup { margin: var(--md) var(--md) var(--base); }

.sidebar-kaki { margin-top: auto; padding-top: var(--md); }
.siapa-kartu {
  display: flex; align-items: center; gap: var(--sm);
  padding: var(--sm); border-radius: var(--r-2xl); background: var(--s-low);
  margin-bottom: var(--xs);
}
.avatar {
  width: 40px; height: 40px; flex: 0 0 40px; border-radius: var(--r-full);
  background: var(--primary-fixed); color: var(--on-primary-fixed);
  display: grid; place-items: center; font-weight: 700; font-size: 16px;
}
.siapa-kartu .nm { font-size: 14px; font-weight: 700; }
.siapa-kartu .pr { font-size: 12px; color: var(--on-surface-variant); }

.panel-utama { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }

.topbar {
  position: sticky; top: 0; z-index: 30;
  min-height: var(--topbar-h);
  background: rgba(248, 249, 255, .88);
  backdrop-filter: saturate(180%) blur(10px);
  border-bottom: 1px solid var(--garis);
  display: flex; align-items: center; gap: var(--md);
  padding: var(--sm) var(--lg);
}
.topbar h1 { font-size: 24px; line-height: 32px; font-weight: 700; }
.topbar .sub { font-size: 14px; color: var(--on-surface-variant); margin-top: 2px; }
.topbar-aksi { display: flex; align-items: center; gap: var(--xs); flex: 0 0 auto; }

.cari-global { position: relative; flex: 0 1 320px; }
.cari-global input[type="search"] {
  height: 48px; padding: 0 var(--md) 0 48px; border-radius: var(--r-full);
  background: var(--s-lowest); box-shadow: var(--sh-sm);
}
.cari-global .ms {
  position: absolute; left: var(--md); top: 50%; transform: translateY(-50%);
  color: var(--outline); pointer-events: none;
}

.isi { padding: var(--lg); max-width: 1340px; width: 100%; }
.isi.lebar { max-width: none; }
.tabbar { display: none; }

/* ==========================================================================
   Kartu
   ========================================================================== */
.kartu {
  background: var(--s-lowest); border: 1px solid var(--garis);
  border-radius: var(--r-3xl); box-shadow: var(--sh-sm);
}
.kartu > .kepala {
  display: flex; align-items: center; justify-content: space-between;
  flex-wrap: wrap; gap: var(--xs) var(--sm);
  padding: var(--lg) var(--lg) var(--sm);
}
.kartu > .kepala.bergaris { border-bottom: 1px solid var(--garis); padding-bottom: var(--md); }
.kartu > .badan { padding: var(--lg); }
.kartu > .kepala + .badan { padding-top: var(--xs); }
.kartu > .kaki {
  padding: var(--md) var(--lg); border-top: 1px solid var(--garis);
  background: var(--s-low); border-radius: 0 0 var(--r-3xl) var(--r-3xl);
}
.kartu + .kartu { margin-top: var(--md); }
.kartu-judul { display: flex; align-items: center; justify-content: space-between; gap: var(--sm); margin-bottom: var(--sm); }

.kisi { display: grid; gap: var(--md); }
.kisi-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.kisi-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.kisi-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.kisi-sisi { grid-template-columns: minmax(0, 1.6fr) minmax(340px, .8fr); align-items: start; }
.tumpuk { display: flex; flex-direction: column; gap: var(--md); }

/* --- angka ringkas ----------------------------------------------------- */
.ringkas {
  background: var(--s-lowest); border: 1px solid var(--garis);
  border-radius: var(--r-3xl); padding: var(--lg); box-shadow: var(--sh-sm);
  display: flex; flex-direction: column; gap: var(--base);
}
.ringkas .atas { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--xs); }
.ringkas .label { font-size: 14px; font-weight: 600; color: var(--on-surface-variant); }
.ringkas .lencet {
  width: 40px; height: 40px; border-radius: var(--r-full); flex: 0 0 40px;
  background: var(--s-cont); color: var(--primary); display: grid; place-items: center;
}
.ringkas .nilai {
  font-size: 32px; line-height: 40px; font-weight: 700; letter-spacing: -.01em;
  font-variant-numeric: tabular-nums;
}
.ringkas .catatan { font-size: 12px; color: var(--outline); }
.ringkas.utama { background: var(--primary); border-color: var(--primary); color: #fff; box-shadow: var(--sh-primary); }
.ringkas.utama .label { color: rgba(255,255,255,.85); }
.ringkas.utama .catatan { color: rgba(255,255,255,.7); }
.ringkas.utama .lencet { background: rgba(255,255,255,.18); color: #fff; }
.ringkas.awas { border-color: var(--error-container); }
.ringkas.awas .nilai { color: var(--error); }
.ringkas.awas .lencet { background: var(--error-container); color: var(--on-error-container); }

/* ==========================================================================
   Tombol
   ========================================================================== */
.tombol {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--xs);
  height: var(--touch); padding: 0 var(--lg); border-radius: var(--r-full);
  font-family: var(--font); font-size: 14px; font-weight: 700; letter-spacing: .01em;
  line-height: 1; border: 1px solid var(--garis-tegas);
  background: var(--s-lowest); color: var(--on-surface);
  cursor: pointer; text-decoration: none; white-space: nowrap;
  transition: background-color .15s ease, border-color .15s ease, color .15s ease;
}
.tombol:hover { background: var(--s-low); border-color: var(--primary-fixed-dim); text-decoration: none; }
.tombol:active { transform: scale(.97); }
.tombol.utama {
  background: var(--primary); border-color: var(--primary); color: var(--on-primary);
  box-shadow: var(--sh-sm);
}
.tombol.utama:hover { background: var(--primary-container); border-color: var(--primary-container); }
.tombol.wadah {
  background: var(--primary-container); border-color: transparent; color: var(--on-primary-container);
}
.tombol.wadah:hover { background: var(--primary); color: #fff; }
.tombol.lembut { background: var(--s-cont); border-color: transparent; color: var(--on-primary-fixed-variant); }
.tombol.lembut:hover { background: var(--s-high); }
.tombol.bahaya { color: var(--error); border-color: var(--error-container); background: var(--s-lowest); }
.tombol.bahaya:hover { background: var(--error-container); }
.tombol.hantu { background: transparent; border-color: transparent; }
.tombol.hantu:hover { background: var(--s-low); }
.tombol.kecil { height: 36px; padding: 0 var(--md); font-size: 13px; gap: 6px; }
.tombol.besar { height: var(--touch-lg); padding: 0 var(--xl); font-size: 16px; border-radius: var(--r-2xl); }
.tombol.jumbo {
  height: 64px; padding: 0 var(--xl); font-size: 20px; font-weight: 700;
  border-radius: var(--r-2xl); box-shadow: var(--sh-md);
}
.tombol.lebar { width: 100%; }
.tombol[disabled], .tombol.mati { opacity: .45; cursor: not-allowed; box-shadow: none; }
.tombol[disabled]:active { transform: none; }
.tombol-baris { display: flex; flex-wrap: wrap; gap: var(--xs); }

.tombol-bulat {
  width: 40px; height: 40px; border-radius: var(--r-full); flex: 0 0 40px;
  display: grid; place-items: center; cursor: pointer;
  border: 1px solid var(--garis); background: var(--s-lowest); color: var(--on-surface-variant);
}
.tombol-bulat:hover { background: var(--s-cont); color: var(--on-surface); }
.tombol-bulat.bahaya:hover { background: var(--error-container); color: var(--on-error-container); }

/* ==========================================================================
   Formulir
   ========================================================================== */
label.bidang { display: block; margin-bottom: var(--md); }
label.bidang > span, .bidang-label {
  display: block; font-size: 14px; font-weight: 600; color: var(--on-surface-variant);
  margin-bottom: 6px;
}
input[type="text"], input[type="password"], input[type="number"], input[type="date"],
input[type="search"], input[type="tel"], select, textarea {
  width: 100%; height: 48px; padding: 0 var(--md);
  border: 1px solid var(--garis-tegas); border-radius: var(--r-xl);
  background: var(--s-lowest); color: var(--on-surface);
  font-family: var(--font); font-size: 16px;
}
select {
  appearance: none; padding-right: 40px;
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='18' viewBox='0 0 24 24' fill='none' stroke='%23737686' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 14px center;
}
textarea { height: auto; min-height: 96px; padding: var(--sm) var(--md); resize: vertical; border-radius: var(--r-2xl); }
input::placeholder, textarea::placeholder { color: var(--outline-variant); }
input:focus, select:focus, textarea:focus {
  outline: none; border-color: var(--primary); box-shadow: 0 0 0 3px rgba(0, 74, 198, .18);
}
a:focus-visible, button:focus-visible, summary:focus-visible, .ubin:focus-visible {
  outline: 3px solid rgba(0, 74, 198, .45); outline-offset: 2px;
}

.petunjuk { font-size: 13px; line-height: 18px; color: var(--outline); margin-top: 6px; }
.baris { display: flex; flex-wrap: wrap; gap: var(--sm); align-items: flex-end; }
.baris > * { flex: 1 1 170px; }
.baris > .rapat { flex: 0 0 auto; }
.baris.rata { align-items: center; }
.centang { display: flex; align-items: center; gap: var(--sm); font-size: 16px; font-weight: 600; cursor: pointer; }
.centang input { width: 20px; height: 20px; flex: 0 0 20px; accent-color: var(--primary); margin: 0; }

fieldset { border: 1px solid var(--garis); border-radius: var(--r-2xl); padding: var(--md) var(--lg); margin: 0 0 var(--md); }
legend { font-size: 12px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--on-surface-variant); padding: 0 var(--xs); }

/* ==========================================================================
   Tabel
   ========================================================================== */
.tabel-geser { overflow-x: auto; -webkit-overflow-scrolling: touch; }
/* Tabel di dalam wadah bergulir tidak boleh diperas sampai isinya terpotong.
   Kalau tidak muat, biar wadahnya yang digulir menyamping. */
.tabel-geser > table { min-width: max-content; }
table { width: 100%; border-collapse: collapse; font-size: 14px; }
th {
  text-align: left; font-size: 12px; font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase; color: var(--on-surface-variant);
  padding: var(--sm) var(--md); border-bottom: 1px solid var(--garis-tegas);
  white-space: nowrap; background: var(--s-low);
}
td { padding: var(--sm) var(--md); border-bottom: 1px solid var(--garis); vertical-align: middle; }
tbody tr:last-child td { border-bottom: 0; }
tbody tr:hover { background: var(--s-low); }
tfoot td { border-bottom: 0; border-top: 1px solid var(--garis-tegas); }
.kartu > .tabel-geser th:first-child, .kartu > .tabel-geser td:first-child { padding-left: var(--lg); }
.kartu > .tabel-geser th:last-child, .kartu > .tabel-geser td:last-child { padding-right: var(--lg); }
.kartu > .tabel-geser:last-child table tbody tr:last-child td { border-bottom: 0; }
.kode { font-weight: 700; font-variant-numeric: tabular-nums; }
a.kode { color: var(--primary); }

/* ==========================================================================
   Lencana tahap
   ========================================================================== */
.lencana {
  display: inline-flex; align-items: center; gap: 6px; padding: 4px 12px;
  border-radius: var(--r-full); font-size: 12px; font-weight: 700;
  white-space: nowrap; border: 1px solid transparent; line-height: 16px;
}
.s-diterima    { background: var(--s-cont);          color: var(--on-surface-variant); }
.s-dicuci      { background: var(--primary-fixed);   color: var(--on-primary-fixed-variant); }
.s-dikeringkan { background: var(--tertiary-fixed);  color: var(--on-tertiary-fixed-variant); }
.s-disetrika   { background: var(--tertiary-fixed-dim); color: var(--on-tertiary-fixed); }
.s-siap_ambil  { background: var(--primary);         color: #fff; }
.s-diambil     { background: var(--s-cont);          color: var(--outline); }
.s-batal       { background: var(--error-container); color: var(--on-error-container); }
.lencana.lunas { background: var(--primary-fixed);   color: var(--on-primary-fixed-variant); }
.lencana.utang { background: var(--error-container); color: var(--on-error-container); }
.lencana.netral { background: var(--s-cont);         color: var(--on-surface-variant); }

/* ==========================================================================
   Pil filter dan subnavigasi
   ========================================================================== */
.pil { display: flex; flex-wrap: wrap; gap: var(--xs); }
.pil a, .pil button {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 8px var(--md); border-radius: var(--r-full);
  border: 1px solid var(--garis-tegas); background: var(--s-lowest);
  font-family: var(--font); font-size: 14px; font-weight: 600;
  color: var(--on-surface-variant); text-decoration: none; cursor: pointer;
}
.pil a:hover { background: var(--s-cont); text-decoration: none; }
.pil a.aktif { background: var(--primary); border-color: var(--primary); color: #fff; font-weight: 700; }
.pil a .n {
  font-size: 12px; background: var(--s-cont); color: var(--on-primary-fixed-variant);
  padding: 0 7px; border-radius: var(--r-full); font-variant-numeric: tabular-nums;
}
.pil a.aktif .n { background: rgba(255,255,255,.22); color: #fff; }

.subnav {
  display: inline-flex; gap: var(--base); max-width: 100%; overflow-x: auto;
  margin-bottom: var(--md); background: var(--s-lowest); border: 1px solid var(--garis);
  padding: var(--base); border-radius: var(--r-full);
}
.subnav-bungkus { display: block; }
.subnav a {
  padding: 10px var(--md); border-radius: var(--r-full); font-size: 14px; font-weight: 600;
  color: var(--on-surface-variant); text-decoration: none; white-space: nowrap;
}
.subnav a:hover { background: var(--s-low); color: var(--on-surface); text-decoration: none; }
.subnav a.aktif { background: var(--primary-container); color: var(--on-primary-container); font-weight: 700; }

/* ==========================================================================
   Pesan sistem
   ========================================================================== */
.flash-tumpuk { display: flex; flex-direction: column; gap: var(--xs); margin-bottom: var(--md); }
.flash {
  display: flex; gap: var(--sm); align-items: flex-start;
  padding: var(--sm) var(--md); border-radius: var(--r-2xl); font-size: 15px;
  background: var(--primary-fixed); color: var(--on-primary-fixed);
  border: 1px solid transparent;
}
.flash .ms { margin-top: 1px; }
.flash.gagal { background: var(--error-container); color: var(--on-error-container); }
.flash.peringatan { background: var(--tertiary-fixed); color: var(--on-tertiary-fixed-variant); }
.flash.info { background: var(--s-cont); color: var(--on-surface-variant); }

.kosong { text-align: center; padding: var(--xl) var(--md); }
.kosong .gambar {
  width: 64px; height: 64px; margin: 0 auto var(--md); border-radius: var(--r-full);
  background: var(--s-cont); color: var(--primary); display: grid; place-items: center;
}
.kosong h3 { font-size: 18px; margin-bottom: 6px; }
.kosong p { color: var(--on-surface-variant); font-size: 14px; max-width: 440px; margin: 0 auto var(--md); }

/* ==========================================================================
   Layar kasir
   ========================================================================== */
.pos { display: grid; grid-template-columns: minmax(0, 1fr) 384px; gap: var(--md); align-items: start; }

.grid-layanan { display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: var(--md); }
.ubin {
  min-height: 140px; padding: var(--lg); cursor: pointer; text-align: left;
  background: var(--s-lowest); border: 1px solid var(--garis);
  border-radius: var(--r-2xl); box-shadow: var(--sh-sm);
  display: flex; flex-direction: column; justify-content: space-between; gap: var(--sm);
  font-family: var(--font); position: relative; overflow: hidden;
  transition: border-color .15s ease, box-shadow .15s ease, background-color .15s ease;
}
.ubin .ms { color: var(--on-surface-variant); }
.ubin .nm { font-size: 16px; font-weight: 600; line-height: 22px; color: var(--on-surface); }
.ubin .hg { font-size: 16px; font-weight: 700; font-variant-numeric: tabular-nums; color: var(--on-surface-variant); }
.ubin:hover { border-color: var(--primary-fixed-dim); box-shadow: var(--sh-md); }
.ubin:hover .ms { color: var(--primary); }
.ubin.dipilih {
  border: 2px solid var(--primary); box-shadow: var(--sh-md); padding: calc(var(--lg) - 1px);
}
.ubin.dipilih .ms { color: var(--primary); }
.ubin.dipilih .hg { color: var(--primary); }
.ubin .dipakai {
  position: absolute; top: var(--md); right: var(--md);
  min-width: 28px; height: 28px; padding: 0 var(--xs); border-radius: var(--r-full);
  background: var(--primary); color: #fff; font-size: 13px; font-weight: 700;
  font-variant-numeric: tabular-nums; display: none; place-items: center;
  box-shadow: var(--sh-sm);
}
.ubin.dipilih .dipakai { display: grid; }

/* keranjang */
.keranjang { position: sticky; top: calc(var(--topbar-h) + var(--md)); }
.keranjang .kartu {
  box-shadow: var(--sh-md); overflow: hidden;
  /* Kepala dan tombol simpan harus tetap terlihat walau isinya panjang,
     jadi kartunya dibatasi setinggi layar dan bagian tengahnya yang digulir. */
  display: flex; flex-direction: column;
  max-height: calc(100dvh - var(--topbar-h) - var(--xl));
}
.keranjang .krj-gulir { flex: 1 1 auto; overflow-y: auto; min-height: 0; }
/* .badan di keranjang bukan anak langsung .kartu, jadi paddingnya diatur di sini. */
.krj-gulir > .badan { padding: var(--lg); }
.krj-daftar { display: flex; flex-direction: column; gap: var(--sm); padding: 0 var(--lg); }
.krj-item {
  border: 1px solid var(--garis); border-radius: var(--r-2xl);
  padding: var(--md); background: var(--s-lowest); box-shadow: var(--sh-sm);
}
.krj-item .atas { display: flex; justify-content: space-between; align-items: flex-start; gap: var(--sm); margin-bottom: var(--sm); }
.krj-item .nm { font-size: 16px; font-weight: 600; line-height: 22px; }
.krj-item .bawah { display: flex; align-items: center; justify-content: space-between; gap: var(--sm); }
.krj-item .jml { font-size: 16px; font-weight: 700; font-variant-numeric: tabular-nums; }

.stepper {
  display: flex; align-items: center; height: 44px;
  border: 1px solid var(--garis-tegas); border-radius: var(--r-xl);
  overflow: hidden; background: var(--surface);
}
.stepper button {
  width: 42px; height: 100%; border: 0; background: transparent; cursor: pointer;
  color: var(--on-surface); display: grid; place-items: center;
}
.stepper button:hover { background: var(--s-high); }
.stepper button:first-child { border-right: 1px solid var(--garis); }
.stepper input {
  width: 58px; height: 100%; text-align: center; border: 0; border-radius: 0;
  background: transparent; font-size: 16px; font-weight: 700; padding: 0;
  font-variant-numeric: tabular-nums;
}
.stepper input:focus { box-shadow: none; }
.stepper .satuan {
  padding: 0 var(--sm); height: 100%; display: flex; align-items: center;
  font-size: 13px; color: var(--on-surface-variant);
  border-left: 1px solid var(--garis); border-right: 1px solid var(--garis);
  background: var(--s-lowest);
}
.krj-kosong { padding: var(--xl) var(--lg); text-align: center; color: var(--on-surface-variant); font-size: 14px; }
.krj-baris { display: flex; justify-content: space-between; gap: var(--sm); padding: 6px 0; font-size: 15px; }
.krj-baris .n { font-weight: 600; font-variant-numeric: tabular-nums; }
.krj-total { display: flex; justify-content: space-between; align-items: baseline; gap: var(--sm); }
.krj-total .lb { font-size: 20px; font-weight: 700; color: var(--on-surface-variant); }
.krj-total .n {
  font-size: 32px; line-height: 40px; font-weight: 700; letter-spacing: -.01em;
  color: var(--primary); font-variant-numeric: tabular-nums;
}
.putus { border-top: 1px solid var(--garis); margin: var(--md) 0; }

.cepat { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--xs); }
.cepat button {
  height: 48px; padding: 0 var(--base); cursor: pointer; white-space: nowrap;
  border: 1px solid var(--garis-tegas); border-radius: var(--r-xl);
  background: var(--surface); font-family: var(--font);
  font-size: 13px; font-weight: 600; font-variant-numeric: tabular-nums; color: var(--on-surface);
}
.cepat button:hover { border-color: var(--primary-fixed-dim); background: var(--s-high); }
.cepat button.pas { background: var(--primary-container); border-color: transparent; color: var(--on-primary-container); }
.cepat button.pas:hover { background: var(--primary); color: #fff; }

/* keranjang mengambang untuk layar HP */
.krj-apung { display: none; }
#tutup-keranjang { display: none; }

/* ==========================================================================
   Autocomplete
   ========================================================================== */
.saran-bungkus { position: relative; }
.saran {
  position: absolute; z-index: 40; left: 0; right: 0; top: calc(100% + 6px);
  background: var(--s-lowest); border: 1px solid var(--garis-tegas);
  border-radius: var(--r-2xl); box-shadow: var(--sh-lg); overflow: hidden;
  max-height: 300px; overflow-y: auto;
}
.saran button {
  display: flex; justify-content: space-between; align-items: center; gap: var(--sm);
  width: 100%; text-align: left; padding: var(--sm) var(--md);
  background: none; border: 0; border-bottom: 1px solid var(--garis);
  font-family: var(--font); font-size: 15px; cursor: pointer; color: var(--on-surface);
}
.saran button:last-child { border-bottom: 0; }
.saran button:hover, .saran button.sorot { background: var(--s-cont); }
.saran .hp { color: var(--on-surface-variant); font-size: 13px; font-variant-numeric: tabular-nums; }

/* ==========================================================================
   Papan cucian
   ========================================================================== */
.papan { display: grid; grid-template-columns: repeat(auto-fit, minmax(198px, 1fr)); gap: var(--sm); }
.kolom {
  background: var(--s-low); border: 1px solid var(--garis);
  border-radius: var(--r-3xl); display: flex; flex-direction: column; min-height: 240px;
}
.kolom > .kepala {
  display: flex; align-items: center; justify-content: space-between; gap: var(--xs);
  padding: var(--md) var(--md) var(--sm);
}
.kolom > .kepala .jd { display: flex; align-items: center; gap: var(--xs); font-size: 14px; font-weight: 700; }
.kolom > .kepala .n {
  font-size: 12px; font-weight: 700; background: var(--s-lowest); color: var(--on-surface-variant);
  padding: 2px var(--xs); border-radius: var(--r-full); font-variant-numeric: tabular-nums;
}
.kolom > .isi-kolom {
  padding: 0 var(--xs) var(--xs); display: flex; flex-direction: column; gap: var(--xs);
  overflow-y: auto; max-height: calc(100dvh - 260px); overscroll-behavior: contain;
}
.kolom.sorot { background: var(--primary-fixed); border-color: var(--primary-fixed-dim); }

.kartu-order {
  background: var(--s-lowest); border: 1px solid var(--garis);
  border-radius: var(--r-2xl); padding: var(--md); box-shadow: var(--sh-sm);
}
.kartu-order .atas { display: flex; align-items: center; justify-content: space-between; gap: var(--xs); }
.kartu-order .kode { font-size: 13px; font-weight: 700; }
.kartu-order .nm { font-size: 16px; font-weight: 700; line-height: 22px; margin-top: 4px; }
.kartu-order .mt {
  font-size: 12px; color: var(--on-surface-variant); display: flex; flex-direction: column;
  gap: 3px; margin-top: var(--xs);
}
.kartu-order .mt span { display: flex; align-items: center; gap: 5px; }
.kartu-order .uang-baris {
  display: flex; align-items: center; gap: 6px; margin-top: var(--sm);
  padding-top: var(--sm); border-top: 1px solid var(--garis);
  font-size: 14px; font-weight: 700; font-variant-numeric: tabular-nums;
}
.kartu-order form { margin-top: var(--sm); }
.kartu-order .tombol {
  height: 40px; font-size: 13px; padding: 0 var(--sm);
  white-space: normal; line-height: 1.25; text-align: center;
}
.kartu-order.telat { border: 2px solid var(--error); padding: calc(var(--md) - 1px); }
.tanda-telat {
  display: inline-flex; align-items: center; gap: 4px; padding: 2px var(--xs);
  border-radius: var(--r-full); background: var(--error); color: #fff;
  font-size: 11px; font-weight: 700;
}

/* ==========================================================================
   Tahap: rel mendatar dan garis waktu tegak
   ========================================================================== */
.rel { display: flex; gap: var(--base); flex-wrap: wrap; }
.rel .tahap {
  flex: 1 1 0; min-width: 104px; padding: var(--sm); border-radius: var(--r-xl);
  background: var(--s-low); text-align: center;
}
.rel .tahap .nm { display: block; font-size: 13px; font-weight: 700; color: var(--outline); }
.rel .tahap .kt { font-size: 11px; color: var(--outline); }
.rel .tahap.lewat { background: var(--primary-fixed); }
.rel .tahap.lewat .nm, .rel .tahap.lewat .kt { color: var(--on-primary-fixed-variant); }
.rel .tahap.sekarang { background: var(--primary); }
.rel .tahap.sekarang .nm, .rel .tahap.sekarang .kt { color: #fff; }

.jalur { list-style: none; margin: 0; padding: 0; position: relative; }
.jalur::before {
  content: ""; position: absolute; left: 19px; top: 20px; bottom: 20px;
  width: 4px; border-radius: var(--r-full); background: var(--s-high);
}
.jalur li { position: relative; display: flex; gap: var(--md); padding-bottom: var(--lg); }
.jalur li:last-child { padding-bottom: 0; }
.jalur .titik {
  width: 42px; height: 42px; flex: 0 0 42px; border-radius: var(--r-full);
  background: var(--s-high); color: var(--outline);
  display: grid; place-items: center; z-index: 1;
}
.jalur .isi-tahap { padding-top: 8px; }
.jalur .isi-tahap .nm { font-size: 16px; font-weight: 700; color: var(--on-surface-variant); }
.jalur .isi-tahap .wk { font-size: 13px; color: var(--outline); font-variant-numeric: tabular-nums; }
.jalur li.lewat .titik { background: var(--primary); color: #fff; box-shadow: 0 4px 10px rgba(0, 74, 198, .22); }
.jalur li.lewat .isi-tahap .nm { color: var(--on-surface); }
.jalur li.sekarang .titik {
  background: var(--primary); color: #fff;
  box-shadow: 0 0 0 4px var(--s-lowest), 0 6px 16px rgba(0, 74, 198, .3);
  animation: denyut 2.2s ease-in-out infinite;
}
.jalur li.sekarang .isi-tahap .nm { color: var(--primary); }
.jalur li.sekarang .isi-tahap .wk {
  color: var(--on-primary-fixed-variant); font-weight: 600;
  background: var(--primary-fixed); padding: 2px var(--xs); border-radius: var(--r);
  display: inline-block; margin-top: 2px;
}
.jalur li.belum { opacity: .5; }

@keyframes denyut {
  0% { box-shadow: 0 0 0 4px var(--s-lowest), 0 0 0 0 rgba(0, 74, 198, .35); }
  70% { box-shadow: 0 0 0 4px var(--s-lowest), 0 0 0 16px rgba(0, 74, 198, 0); }
  100% { box-shadow: 0 0 0 4px var(--s-lowest), 0 0 0 0 rgba(0, 74, 198, 0); }
}
@media (prefers-reduced-motion: reduce) {
  .jalur li.sekarang .titik { animation: none; }
  .tombol:active { transform: none; }
  * { transition: none !important; }
}

/* ==========================================================================
   Riwayat dan panel lipat
   ========================================================================== */
.riwayat { list-style: none; margin: 0; padding: 0; }
.riwayat li {
  display: flex; gap: var(--sm); padding: var(--sm) 0;
  border-bottom: 1px solid var(--garis); font-size: 14px; align-items: center;
}
.riwayat li:last-child { border-bottom: 0; }
.riwayat .waktu { flex: 0 0 132px; color: var(--outline); font-variant-numeric: tabular-nums; font-size: 12px; }

details.lipat { border: 1px solid var(--garis); border-radius: var(--r-xl); background: var(--s-lowest); }
details.lipat > summary {
  cursor: pointer; padding: var(--sm) var(--md); font-weight: 600; font-size: 14px;
  list-style: none; display: flex; align-items: center; justify-content: space-between; gap: var(--xs);
}
details.lipat > summary::-webkit-details-marker { display: none; }
details.lipat > summary::after { content: "+"; color: var(--outline); font-size: 18px; }
details.lipat[open] > summary::after { content: "\2212"; }
details.lipat > div { padding: 0 var(--md) var(--md); }

/* ==========================================================================
   Halaman masuk
   ========================================================================== */
.masuk-layar {
  min-height: 100vh; min-height: 100dvh; display: grid; place-items: center; padding: var(--lg) var(--md);
  background: linear-gradient(160deg, var(--primary-fixed), var(--background) 60%);
}
.masuk-kotak { width: 100%; max-width: 400px; }
.masuk-kartu {
  background: var(--s-lowest); border-radius: var(--r-3xl);
  padding: var(--xl) var(--lg); box-shadow: var(--sh-lg);
}
.masuk-merek { text-align: center; margin-bottom: var(--lg); }
.masuk-merek .lambang {
  width: 64px; height: 64px; margin: 0 auto var(--sm); border-radius: var(--r-full);
  background: var(--primary); color: #fff; display: grid; place-items: center;
  box-shadow: var(--sh-primary);
}
.masuk-merek b { display: block; font-size: 28px; font-weight: 800; letter-spacing: -.02em; color: var(--primary); }
.masuk-merek small { font-size: 14px; color: var(--on-surface-variant); }
.masuk-kaki { text-align: center; font-size: 13px; color: var(--on-surface-variant); margin-top: var(--md); }

.pesan-layar { min-height: 100vh; min-height: 100dvh; display: grid; place-items: center; padding: var(--lg); text-align: center; }
.pesan-layar .kotak { max-width: 480px; }
.pesan-layar .kode-galat { font-size: 64px; line-height: 1; font-weight: 800; letter-spacing: -.03em; color: var(--primary); }

/* ==========================================================================
   Halaman pelanggan
   ========================================================================== */
.lacak { max-width: 430px; margin: 0 auto;
  padding-bottom: calc(104px + env(safe-area-inset-bottom, 0px));
  min-height: 100vh; min-height: 100dvh; background: var(--background); }

.lacak-kepala {
  background: var(--s-lowest); padding: var(--lg);
  border-radius: 0 0 var(--r-3xl) var(--r-3xl); box-shadow: var(--sh-sm);
}
.lacak-kepala .atas { display: flex; align-items: center; justify-content: space-between; gap: var(--sm); margin-bottom: var(--lg); }
.lacak-kepala .outlet { font-size: 32px; line-height: 38px; font-weight: 800; letter-spacing: -.02em; color: var(--primary); }
.lacak-kepala .ket { font-size: 14px; color: var(--on-surface-variant); }
.lacak-kepala .lambang {
  width: 48px; height: 48px; flex: 0 0 48px; border-radius: var(--r-full);
  background: var(--primary-container); color: var(--on-primary-container);
  display: grid; place-items: center;
}
.lacak-nota { background: var(--surface); border: 1px solid var(--garis); border-radius: var(--r-2xl); padding: var(--md); }
.lacak-nota .baris {
  display: flex; justify-content: space-between; align-items: center; gap: var(--sm);
  padding: 6px 0;
}
.lacak-nota .baris + .baris { border-top: 1px solid var(--garis); padding-top: var(--sm); margin-top: 6px; }
.lacak-nota .kn { font-size: 12px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; color: var(--on-surface-variant); }
.lacak-nota .is { font-size: 15px; font-weight: 700; }
.lacak-nota .is.biru { color: var(--primary); font-variant-numeric: tabular-nums; }

.lacak-isi { padding: var(--lg) var(--lg) 0; display: flex; flex-direction: column; gap: var(--lg); }

.lacak-hero {
  text-align: center; padding: var(--xl) var(--lg);
  background: linear-gradient(150deg, var(--primary-fixed), var(--s-high));
  border-radius: var(--r-3xl); border: 1px solid rgba(0, 74, 198, .1); box-shadow: var(--sh-sm);
}
.lacak-hero .bulat {
  width: 80px; height: 80px; margin: 0 auto var(--lg); border-radius: var(--r-full);
  background: var(--primary); color: #fff; display: grid; place-items: center;
  box-shadow: 0 10px 20px rgba(0, 74, 198, .25);
  animation: denyut-hero 2.4s ease-in-out infinite;
}
@keyframes denyut-hero {
  0% { box-shadow: 0 10px 20px rgba(0,74,198,.25), 0 0 0 0 rgba(0, 74, 198, .3); }
  70% { box-shadow: 0 10px 20px rgba(0,74,198,.25), 0 0 0 18px rgba(0, 74, 198, 0); }
  100% { box-shadow: 0 10px 20px rgba(0,74,198,.25), 0 0 0 0 rgba(0, 74, 198, 0); }
}
@media (prefers-reduced-motion: reduce) { .lacak-hero .bulat { animation: none; } }
.lacak-hero h2 { font-size: 24px; line-height: 32px; font-weight: 700; }
.lacak-hero .estimasi {
  display: inline-block; margin-top: var(--sm); padding: 6px var(--md);
  background: rgba(255,255,255,.7); border: 1px solid #fff; border-radius: var(--r-full);
  font-size: 14px; color: var(--on-surface-variant);
}
.lacak-panel {
  background: var(--s-lowest); border: 1px solid var(--garis);
  border-radius: var(--r-3xl); padding: var(--lg); box-shadow: var(--sh-sm);
}
.lacak-panel h3 { font-size: 20px; font-weight: 700; margin-bottom: var(--md); }
.lacak-panel .baris-nota {
  display: flex; justify-content: space-between; align-items: center; gap: var(--sm);
  padding: var(--xs) 0; border-bottom: 1px solid var(--garis); font-size: 15px;
}
.lacak-panel .baris-nota:last-child { border-bottom: 0; }
.lacak-panel .baris-nota .n { font-weight: 700; font-variant-numeric: tabular-nums; }
.lacak-bayar {
  display: flex; justify-content: space-between; align-items: center; gap: var(--sm);
  background: var(--s-cont); padding: var(--md); border-radius: var(--r-2xl); margin-top: var(--md);
}
.lacak-bayar .lb { font-size: 15px; font-weight: 600; color: var(--primary); }
.lacak-bayar .nl {
  font-size: 18px; font-weight: 700; color: var(--primary); background: #fff;
  padding: 4px var(--sm); border-radius: var(--r-full); box-shadow: var(--sh-sm);
  font-variant-numeric: tabular-nums;
}
.lacak-bayar.utang .lb, .lacak-bayar.utang .nl { color: var(--on-error-container); }
.lacak-bayar.utang { background: var(--error-container); }
.lacak-rak {
  background: var(--primary); color: #fff; border-radius: var(--r-3xl);
  padding: var(--lg); text-align: center; box-shadow: var(--sh-primary);
}
.lacak-rak .kn { font-size: 12px; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; opacity: .85; }
.lacak-rak .nl { font-size: 40px; line-height: 48px; font-weight: 800; letter-spacing: -.02em; }
.lacak-wa {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 40;
  padding: var(--md) var(--md) calc(var(--md) + env(safe-area-inset-bottom, 0px));
  background: linear-gradient(to top, var(--background) 60%, transparent);
  max-width: 430px; margin: 0 auto;
}
.lacak-wa a {
  display: flex; align-items: center; justify-content: center; gap: var(--sm);
  width: 100%; height: var(--touch-lg); border-radius: var(--r-2xl);
  background: var(--wa); color: #fff; font-size: 16px; font-weight: 700;
  text-decoration: none; box-shadow: 0 8px 20px rgba(37, 211, 102, .3);
}
.lacak-wa a:hover { background: var(--wa-gelap); text-decoration: none; }
.lacak-kaki { text-align: center; font-size: 12px; color: var(--outline); padding: var(--lg); }

/* ==========================================================================
   Nota thermal 58mm
   ========================================================================== */
.nota-cetak {
  width: 58mm; margin: 0 auto; padding: 4mm 3mm; background: #fff; color: #000;
  font-family: var(--font); font-size: 11px; line-height: 1.35;
}
.nota-cetak .tengah { text-align: center; }
.nota-cetak h1 { font-size: 15px; font-weight: 800; margin: 0 0 2px; letter-spacing: 0; }
.nota-cetak .pisah { border-top: 1px dashed #000; margin: 5px 0; }
.nota-cetak table { width: 100%; font-size: 11px; }
.nota-cetak th, .nota-cetak td { padding: 1px 0; border: 0; background: none; font-size: 11px; text-transform: none; letter-spacing: 0; color: #000; }
.nota-cetak .num { text-align: right; font-variant-numeric: tabular-nums; }
.nota-cetak .total { font-size: 13px; font-weight: 700; }
.nota-cetak .kotak-rak {
  border: 2px solid #000; border-radius: 4px; padding: 4px;
  font-size: 26px; font-weight: 800; text-align: center; margin: 4px 0;
}
.nota-cetak img { display: block; margin: 5px auto 3px; width: 34mm; height: 34mm; }
.cetak-bar { max-width: 58mm; margin: var(--md) auto; display: flex; gap: var(--xs); }

@media print {
  @page { size: 58mm auto; margin: 0; }
  body { background: #fff; }
  .cetak-bar, .sidebar, .tabbar, .topbar { display: none !important; }
  .nota-cetak { width: 58mm; box-shadow: none; }
}

/* ==========================================================================
   Layar sempit
   ========================================================================== */
@media (max-width: 1180px) {
  .kisi-sisi { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 1100px) {
  .papan { grid-auto-flow: column; grid-template-columns: none;
           grid-auto-columns: minmax(250px, 1fr); overflow-x: auto; padding-bottom: var(--sm); }
  .pos { grid-template-columns: minmax(0, 1fr); }

  /* keranjang jadi lembar bawah yang ditarik dari tombol mengambang */
  .keranjang {
    position: fixed; left: 0; right: 0; bottom: 0; top: auto; z-index: 60;
    max-width: 520px; margin: 0 auto;
    transform: translateY(100%); transition: transform .3s cubic-bezier(.4, 0, .2, 1);
    max-height: 88vh; display: flex; flex-direction: column;
  }
  .keranjang.buka { transform: translateY(0); }
  .keranjang .kartu {
    border-radius: var(--r-3xl) var(--r-3xl) 0 0; border-bottom: 0;
    box-shadow: 0 -10px 40px rgba(11, 28, 48, .18);
    display: flex; flex-direction: column; max-height: 88vh;
  }
  .keranjang .krj-gulir { overflow-y: auto; flex: 1 1 auto; }
  .tirai {
    position: fixed; inset: 0; background: rgba(11, 28, 48, .5);
    -webkit-backdrop-filter: blur(2px); backdrop-filter: blur(2px);
    z-index: 55;                     /* di bawah lembar (60), saudara sekandungnya */
    animation: tirai-masuk var(--gerak-sedang) ease both;
  }
  @keyframes tirai-masuk { from { opacity: 0; } to { opacity: 1; } }

  /* Lembar keranjang harus punya latar sendiri yang pekat. Kalau mengandalkan
     latar kartu di belakangnya, isinya ikut terlihat redup di atas kelam. */
  .keranjang > .kartu { background: var(--s-lowest); }

  /* Bilah menu bawah dan bilah total ikut menyingkir saat lembar terbuka.
     Keduanya ada di luar stacking context lembar, jadi tidak bisa ditutup
     kelam; dibiarkan tampil, mereka menutupi tombol simpan. */
  body.keranjang-terbuka .tabbar,
  body.keranjang-terbuka .krj-apung.ada-isi {
    transform: translateY(150%);
    opacity: 0;
    pointer-events: none;
    transition: transform .3s cubic-bezier(.4, 0, .2, 1), opacity .2s ease;
  }

  /* Bilah atas juga di luar jangkauan kelam. Dibiarkan terang dan bisa ditekan,
     satu ketukan pada "Papan cucian" meninggalkan pesanan yang belum disimpan. */
  body.keranjang-terbuka .topbar {
    opacity: .4;
    pointer-events: none;
    transition: opacity var(--gerak-sedang) ease;
  }
  #tutup-keranjang { display: grid; }
  /* Duduk persis di atas bilah tab. Tingginya diukur skrip ke --tabbar-ruang
     karena berubah mengikuti ukuran huruf sistem dan tinggi garis home;
     angka cadangan dipakai sebelum skrip sempat mengukur. Lapisannya di atas
     bilah tab, supaya kalau toh bersentuhan, yang tertutup bukan nominalnya. */
  .krj-apung.ada-isi {
    display: block; position: fixed; left: 0; right: 0; z-index: 52;
    bottom: calc(var(--tabbar-ruang, 94px) + var(--sm));
    padding: 0 var(--pad);
    max-width: 520px; margin: 0 auto;
  }
  .krj-apung button {
    width: 100%; display: flex; align-items: center; justify-content: space-between;
    gap: var(--sm); padding: var(--base); padding-right: var(--md);
    background: var(--primary); color: #fff; border: 0; cursor: pointer;
    border-radius: var(--r-full); box-shadow: var(--sh-primary); font-family: var(--font);
  }
  .krj-apung .kiri { display: flex; align-items: center; gap: var(--sm); }
  .krj-apung .lingkar {
    width: 48px; height: 48px; border-radius: var(--r-full); position: relative;
    background: rgba(255,255,255,.2); display: grid; place-items: center;
  }
  .krj-apung .badge {
    position: absolute; top: -2px; right: -2px; min-width: 22px; height: 22px;
    padding: 0 5px; border-radius: var(--r-full); background: var(--error); color: #fff;
    font-size: 12px; font-weight: 700; display: grid; place-items: center;
    border: 2px solid var(--primary);
  }
  .krj-apung .teks { text-align: left; }
  .krj-apung .teks .lb { display: block; font-size: 12px; font-weight: 600; opacity: .9; }
  .krj-apung .teks .nl { display: block; font-size: 18px; font-weight: 700; font-variant-numeric: tabular-nums; }
  .krj-apung .kanan-pil {
    display: flex; align-items: center; gap: 4px; padding: var(--xs) var(--sm);
    background: rgba(255,255,255,.15); border-radius: var(--r-full);
    font-size: 14px; font-weight: 700;
  }
}

@media (max-width: 900px) {
  .sidebar { display: none; }
  .topbar { padding: var(--sm) var(--pad); gap: var(--sm); min-height: 56px; }
  .topbar h1 { font-size: 20px; line-height: 28px; }
  .isi { padding: var(--pad) var(--pad) 104px; }
  .kisi-2, .kisi-3, .kisi-4 { grid-template-columns: minmax(0, 1fr); }
  .kisi.duo-hp { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sm); }
  .kisi.duo-hp .ringkas { padding: var(--md); border-radius: var(--r-2xl); }
  .kisi.duo-hp .ringkas .nilai { font-size: 22px; line-height: 28px; }
  .kisi.duo-hp .ringkas .lencet { width: 32px; height: 32px; flex-basis: 32px; }
  .kisi.duo-hp .ringkas .lencet .ms { font-size: 18px; }
  .cari-global { display: none; }
  .grid-layanan { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sm); }
  .ubin { min-height: 120px; padding: var(--md); border-radius: var(--r-2xl); }
  .ubin.dipilih { padding: calc(var(--md) - 1px); }
  .rel .tahap { min-width: 88px; }

  /* --- bilah menu bawah --------------------------------------------------
     Bilahnya mengambang sedikit dari tepi layar, dan tab aktif ditandai pil
     yang bergeser dari tab lama ke tab baru, bukan muncul-hilang di tempat.
     Geserannya diatur skrip karena posisinya harus diukur dari tab yang
     sedang aktif. */
  .tabbar {
    display: flex; position: fixed; z-index: 50;
    left: var(--sm); right: var(--sm);
    bottom: calc(var(--sm) + env(safe-area-inset-bottom, 0px));
    background: var(--s-lowest);
    background: color-mix(in srgb, var(--s-lowest) 88%, transparent);
    -webkit-backdrop-filter: saturate(180%) blur(16px);
    backdrop-filter: saturate(180%) blur(16px);
    border: 1px solid var(--garis);
    border-radius: var(--r-3xl);
    padding: 6px;
    box-shadow: 0 6px 24px rgba(11, 28, 48, .12), 0 2px 6px rgba(11, 28, 48, .06);
    justify-content: space-around; align-items: center;
  }

  .tabbar-penanda {
    position: absolute; top: 0; left: 0; z-index: 0;
    border-radius: var(--r-full);
    background: var(--primary-container);
    opacity: 0; pointer-events: none;
    transition: transform .34s var(--pegas), width .34s var(--pegas),
                height .2s ease, opacity .2s ease;
  }

  .tabbar a {
    position: relative; z-index: 1;
    display: flex; flex-direction: column; align-items: center; gap: 3px;
    padding: 5px 4px; min-width: 62px; flex: 1 1 0;
    color: var(--on-surface-variant);
    font-size: 11px; font-weight: 600; text-decoration: none;
    transition: color .22s ease;
  }
  .tabbar a .lingkar {
    width: 58px; height: 30px; border-radius: var(--r-full);
    display: grid; place-items: center;
    transition: transform .3s var(--pegas);
  }
  .tabbar a .ms {
    transition: font-variation-settings .25s ease, transform .3s var(--pegas);
  }
  .tabbar a:active .lingkar { transform: scale(.9); }
  /* Label duduk di luar pil, jadi warnanya harus terbaca di atas latar bilah,
     bukan di atas pil. Yang memakai --on-primary-container hanya ikonnya. */
  .tabbar a.aktif { color: var(--primary); font-weight: 700; }
  .tabbar a.aktif .lingkar { color: var(--on-primary-container); }
  .tabbar a.aktif .ms { font-variation-settings: "FILL" 1; transform: translateY(-1px); }

  /* Label tab aktif sedikit lebih tegas, tanpa menggeser tab di sebelahnya. */
  .tabbar a::after {
    content: ""; position: absolute; bottom: 1px; left: 50%;
    width: 0; height: 2px; border-radius: var(--r-full);
    background: currentColor; transform: translateX(-50%);
    transition: width .28s var(--pegas);
  }
  .tabbar a.aktif::after { width: 16px; }

  @media (prefers-reduced-motion: reduce) {
    .tabbar-penanda, .tabbar a, .tabbar a .lingkar,
    .tabbar a .ms, .tabbar a::after { transition: none; }
  }
}

@media (max-width: 560px) {
  .riwayat .waktu { flex: 0 0 100px; }
  .krj-total .n { font-size: 26px; }
  .cepat { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* --- antrean di beranda -------------------------------------------------- */
.antrean { display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: var(--xs); }
.antrean a {
  display: block; padding: var(--md); border-radius: var(--r-2xl);
  background: var(--s-low); border: 1px solid transparent; text-decoration: none;
  color: var(--outline);
}
.antrean a:hover { text-decoration: none; border-color: var(--primary-fixed-dim); }
.antrean .ms { color: inherit; }
.antrean .n {
  display: block; font-size: 28px; line-height: 34px; font-weight: 800;
  letter-spacing: -.02em; font-variant-numeric: tabular-nums; margin-top: 2px;
}
.antrean .lb { font-size: 13px; font-weight: 600; }
.antrean a.ada { background: var(--primary-fixed); color: var(--on-primary-fixed-variant); }
.antrean a.tunggu { background: var(--primary); color: #fff; box-shadow: var(--sh-primary); }

/* --- pilihan mode kirim dan panel bot WhatsApp --------------------------- */
.pilih-mode { display: grid; gap: var(--xs); }
.pilih-mode label {
  display: flex; gap: var(--sm); align-items: flex-start; cursor: pointer;
  border: 1px solid var(--garis-tegas); border-radius: var(--r-2xl);
  padding: var(--md); background: var(--s-lowest);
}
.pilih-mode label:hover { border-color: var(--primary-fixed-dim); background: var(--s-low); }
.pilih-mode input { margin-top: 3px; accent-color: var(--primary); width: 20px; height: 20px; flex: 0 0 20px; }
.pilih-mode label:has(input:checked) {
  border-color: var(--primary); background: var(--primary-fixed);
  box-shadow: inset 0 0 0 1px var(--primary);
}
.pilih-mode .jd { display: block; font-size: 15px; font-weight: 700; }
.pilih-mode .ket { display: block; font-size: 13px; line-height: 19px; color: var(--on-surface-variant); margin-top: 2px; }

.bot-kisi { display: grid; grid-template-columns: 280px minmax(0, 1fr); gap: var(--lg); align-items: start; }
.bot-panggung { display: flex; flex-direction: column; gap: var(--sm); }

/* Dua cara menyambung, dipilih lewat sepasang tab kecil. */
.bot-cara {
  display: grid; grid-template-columns: 1fr 1fr; gap: 4px;
  background: var(--s-low); border-radius: var(--r-full); padding: 4px;
}
.bot-cara-tab {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  height: 36px; border: 0; border-radius: var(--r-full); cursor: pointer;
  background: transparent; color: var(--on-surface-variant);
  font: 600 13px/1 var(--font);
  transition: background-color .18s ease, color .18s ease;
}
.bot-cara-tab:hover { color: var(--on-surface); }
.bot-cara-tab.aktif {
  background: var(--s-lowest); color: var(--primary);
  box-shadow: var(--sh-sm);
}

.bot-qr {
  position: relative;
  width: 280px; height: 280px; border-radius: var(--r-2xl);
  border: 1px solid var(--garis); background: var(--s-low);
  display: grid; place-items: center; overflow: hidden;
}
.bot-qr img { width: 100%; height: 100%; object-fit: contain; background: #fff; }
.bot-kosong { text-align: center; color: var(--outline); padding: var(--md); }
.bot-kosong p { margin-top: var(--xs); }

/* Kode QR berganti tiap 20 detik. Pudar-masuk supaya pergantiannya tidak mengagetkan. */
.bot-qr img.segar { animation: qr-masuk .35s ease both; }
@keyframes qr-masuk {
  from { opacity: 0; transform: scale(.97); }
  to   { opacity: 1; transform: scale(1); }
}

.bot-sukses {
  position: absolute; inset: 0; display: grid; place-items: center;
  background: var(--primary-fixed); color: var(--primary);
}
.bot-sukses .ms { font-size: 84px; }
.bot-sukses.muncul { animation: sukses-masuk .45s cubic-bezier(.34, 1.4, .64, 1) both; }
.bot-sukses.muncul .ms { animation: sukses-cap .5s cubic-bezier(.34, 1.5, .64, 1) .06s both; }
@keyframes sukses-masuk { from { opacity: 0; } to { opacity: 1; } }
@keyframes sukses-cap {
  from { opacity: 0; transform: scale(.4); }
  to   { opacity: 1; transform: scale(1); }
}

/* Sisa umur kode QR, supaya pemilik tahu kapan harus menunggu kode berikutnya. */
.bot-umur { height: 4px; border-radius: var(--r-full); background: var(--s-low); overflow: hidden; }
.bot-umur-isi {
  height: 100%; width: 100%; border-radius: inherit; background: var(--primary);
  transition: width 1s linear, background-color .3s ease;
}
.bot-umur-isi[style*="width: 1"], .bot-umur-isi[style*="width: 2"] { background: var(--error); }

/* --- kode pairing 8 huruf ------------------------------------------------- */
.bot-kode-kotak {
  border: 1px solid var(--garis); border-radius: var(--r-2xl);
  background: var(--s-low); padding: var(--lg) var(--md);
  min-height: 132px; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: var(--xs);
}
.bot-kode { display: flex; align-items: center; gap: 5px; flex-wrap: wrap; justify-content: center; }
.bot-kode-huruf {
  display: grid; place-items: center;
  width: 34px; height: 44px; border-radius: var(--r-xl);
  background: var(--s-lowest); border: 1px solid var(--garis);
  font: 700 20px/1 var(--font); color: var(--on-surface);
  font-variant-numeric: tabular-nums; letter-spacing: .5px;
  animation: huruf-masuk .3s cubic-bezier(.34, 1.4, .64, 1) both;
}
.bot-kode-pisah { color: var(--outline); font-weight: 700; padding: 0 2px; }
@keyframes huruf-masuk {
  from { opacity: 0; transform: translateY(6px) scale(.9); }
  to   { opacity: 1; transform: none; }
}
.bot-pair-form { display: flex; flex-direction: column; gap: var(--sm); margin-top: var(--sm); }
.bot-pair-form .ladang { margin: 0; }

.langkah { margin: var(--md) 0 0; padding-left: var(--lg); font-size: 14px; line-height: 22px; }
.langkah li { margin-bottom: 6px; }
/* Langkah-langkah dimunculkan berurutan supaya kebaca sebagai urutan, bukan blok. */
.langkah:not([hidden]) li { animation: langkah-masuk .32s ease both; }
.langkah li:nth-child(1) { animation-delay: .02s; }
.langkah li:nth-child(2) { animation-delay: .07s; }
.langkah li:nth-child(3) { animation-delay: .12s; }
.langkah li:nth-child(4) { animation-delay: .17s; }
@keyframes langkah-masuk {
  from { opacity: 0; transform: translateX(-6px); }
  to   { opacity: 1; transform: none; }
}

@media (max-width: 720px) {
  .bot-kisi { grid-template-columns: minmax(0, 1fr); }
  .bot-qr { width: 100%; max-width: 320px; height: auto; aspect-ratio: 1; margin: 0 auto; }
  .bot-panggung { max-width: 360px; margin: 0 auto; width: 100%; }
}

/* --- status pembayaran ---------------------------------------------------- */
.b-lunas { background: var(--primary-fixed); color: var(--on-primary-fixed-variant); }
.b-dp    { background: var(--tertiary-fixed); color: var(--on-tertiary-fixed-variant); }
.b-belum { background: var(--error-container); color: var(--on-error-container); }

/* ==========================================================================
   Gerak
   --------------------------------------------------------------------------
   Animasi di sini semuanya kecil dan pendek: tugasnya menjelaskan apa yang
   baru berubah, bukan menghibur. Yang muncul dianimasikan sekali saat masuk,
   yang berubah nilainya dikedipkan sebentar, dan yang ditekan memberi balasan
   dalam sekitar seperlima detik. Semuanya dimatikan di blok
   prefers-reduced-motion paling bawah berkas ini.
   ========================================================================== */

:root {
  --gerak-cepat: .16s;
  --gerak-sedang: .28s;
  --gerak-lambat: .42s;
  --pegas: cubic-bezier(.34, 1.35, .64, 1);
  --halus: cubic-bezier(.4, 0, .2, 1);
}

/* --- masuk halaman -------------------------------------------------------- */
/* Kartu naik pelan berurutan supaya mata sempat menangkap urutannya. */
@keyframes naik-masuk {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}
@keyframes pudar-masuk {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* Kartu naik berurutan supaya mata sempat menangkap urutannya. Susunan tiap
   halaman berbeda-beda, jadi kartunya dipilih di kedalaman mana pun lalu
   kartu bersarang dikecualikan supaya tidak dianimasikan dua kali. */
.isi .kartu,
.isi .papan > .kolom,
.isi > .subnav-bungkus {
  animation: naik-masuk var(--gerak-sedang) var(--halus) both;
}
.isi .kartu .kartu { animation: none; }

.isi .kartu:nth-child(2), .isi .papan > .kolom:nth-child(2) { animation-delay: .05s; }
.isi .kartu:nth-child(3), .isi .papan > .kolom:nth-child(3) { animation-delay: .1s; }
.isi .kartu:nth-child(4), .isi .papan > .kolom:nth-child(4) { animation-delay: .15s; }
.isi .kartu:nth-child(n+5), .isi .papan > .kolom:nth-child(n+5) { animation-delay: .2s; }

/* --- pesan kilat ---------------------------------------------------------- */
/* Hasil tindakan muncul dari atas, arah yang sama dengan datangnya halaman. */
.flash { animation: flash-masuk var(--gerak-sedang) var(--pegas) both; }
.flash:nth-child(2) { animation-delay: .06s; }
.flash:nth-child(3) { animation-delay: .12s; }
@keyframes flash-masuk {
  from { opacity: 0; transform: translateY(-8px) scale(.99); }
  to   { opacity: 1; transform: none; }
}

/* --- tombol --------------------------------------------------------------- */
.tombol {
  transition: background-color var(--gerak-cepat) ease,
              border-color var(--gerak-cepat) ease,
              color var(--gerak-cepat) ease,
              box-shadow var(--gerak-cepat) ease,
              transform var(--gerak-cepat) var(--halus);
}
.tombol:not(:disabled):active { transform: scale(.97); }
.tombol.utama:not(:disabled):hover { box-shadow: var(--sh-primary); }
.tombol:disabled { transition: none; }

/* Tombol yang menunggu jawaban server: teksnya diganti, ikonnya berputar. */
.tombol.sibuk { pointer-events: none; opacity: .75; }
.tombol.sibuk .ms { animation: putar 1s linear infinite; }
@keyframes putar { to { transform: rotate(360deg); } }

.tombol-bulat { transition: background-color var(--gerak-cepat) ease, transform var(--gerak-cepat) var(--halus); }
.tombol-bulat:active { transform: scale(.9); }

/* --- navigasi ------------------------------------------------------------- */
/* Menu aktif ditandai garis yang menyapu masuk, bukan muncul mendadak. */
.nav a { position: relative; }
.nav a.aktif::before {
  content: ""; position: absolute; left: 0; top: 50%;
  width: 3px; height: 0; border-radius: var(--r-full); background: currentColor;
  transform: translateY(-50%); opacity: .55;
  animation: garis-tumbuh var(--gerak-sedang) var(--halus) .05s both;
}
@keyframes garis-tumbuh { to { height: 60%; } }
.nav a .ms { transition: transform var(--gerak-cepat) var(--pegas); }
.nav a:hover .ms { transform: translateX(1px) scale(1.06); }

/* --- ubin layanan di layar kasir ------------------------------------------ */
.ubin { transition: border-color var(--gerak-cepat) ease, box-shadow var(--gerak-cepat) ease,
                    background-color var(--gerak-cepat) ease, transform var(--gerak-cepat) var(--halus); }
.ubin:active { transform: scale(.97); }
.ubin .ms { transition: color var(--gerak-cepat) ease, transform var(--gerak-sedang) var(--pegas); }
.ubin:hover .ms { transform: translateY(-2px); }
/* Angka jumlah melompat kecil tiap kali nilainya benar-benar berubah. */
.ubin .dipakai.berubah { animation: hitung-naik var(--gerak-sedang) var(--pegas) both; }
@keyframes hitung-naik {
  from { opacity: 0; transform: scale(.5); }
  to   { opacity: 1; transform: scale(1); }
}

/* --- keranjang ------------------------------------------------------------ */
/* Baris baru masuk dari kanan, arah datangnya dari grid layanan di kirinya. */
.krj-item.baru { animation: item-masuk var(--gerak-sedang) var(--pegas) both; }
@keyframes item-masuk {
  from { opacity: 0; transform: translateX(12px); }
  to   { opacity: 1; transform: none; }
}
.krj-item .stepper button { transition: background-color var(--gerak-cepat) ease, transform var(--gerak-cepat) var(--halus); }
.krj-item .stepper button:active { transform: scale(.88); }

/* Nilai uang yang berubah dikedipkan sekali supaya perubahannya terlihat. */
.nilai-berubah { animation: nilai-kedip var(--gerak-lambat) ease both; }
@keyframes nilai-kedip {
  0%   { color: var(--primary); transform: translateY(-2px); }
  100% { color: inherit; transform: none; }
}

/* --- lencana dan status --------------------------------------------------- */
.lencana { transition: background-color var(--gerak-sedang) ease, color var(--gerak-sedang) ease; }
.lencana.kedip { animation: lencana-kedip var(--gerak-lambat) var(--pegas) both; }
@keyframes lencana-kedip {
  0%   { transform: scale(.88); opacity: .4; }
  60%  { transform: scale(1.06); opacity: 1; }
  100% { transform: scale(1); opacity: 1; }
}

/* Ikon penanda "sedang menunggu", dipakai saat penyambung belum menjawab. */
.berdenyut { animation: denyut-samar 1.8s ease-in-out infinite; }
@keyframes denyut-samar {
  0%, 100% { opacity: .35; }
  50%      { opacity: .85; }
}

/* --- tabel dan daftar ----------------------------------------------------- */
tbody tr { transition: background-color var(--gerak-cepat) ease; }
.kartu-order {
  transition: box-shadow var(--gerak-cepat) ease, transform var(--gerak-cepat) var(--halus),
              border-color var(--gerak-cepat) ease;
}
.kartu-order:hover { transform: translateY(-2px); box-shadow: var(--sh-md); }
/* --- garis waktu pesanan -------------------------------------------------- */
/* Tahap yang sudah lewat digambar dari atas ke bawah, seperti urutan aslinya. */
.jalur li { animation: tahap-masuk var(--gerak-sedang) var(--halus) both; }
.jalur li:nth-child(1) { animation-delay: .04s; }
.jalur li:nth-child(2) { animation-delay: .1s; }
.jalur li:nth-child(3) { animation-delay: .16s; }
.jalur li:nth-child(4) { animation-delay: .22s; }
.jalur li:nth-child(5) { animation-delay: .28s; }
.jalur li:nth-child(6) { animation-delay: .34s; }
@keyframes tahap-masuk {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; }
}
.jalur li.belum { animation-name: tahap-masuk-samar; }
@keyframes tahap-masuk-samar {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: .5; }
}

/* --- isian ---------------------------------------------------------------- */
.ladang input, .ladang select, .ladang textarea {
  transition: border-color var(--gerak-cepat) ease, box-shadow var(--gerak-cepat) ease,
              background-color var(--gerak-cepat) ease;
}
/* Daftar saran nama pelanggan turun dari kotak isiannya. */
.saran { animation: saran-turun var(--gerak-cepat) var(--halus) both; }
@keyframes saran-turun {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: none; }
}

/* --- lembar bawah di layar kecil ------------------------------------------ */
.tirai { transition: opacity var(--gerak-sedang) ease; }
.krj-apung { transition: transform var(--gerak-sedang) var(--pegas), box-shadow var(--gerak-cepat) ease; }
.krj-apung:active { transform: scale(.98); }

/* --- matikan semua kalau pengguna minta gerak dikurangi -------------------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
  .jalur li.belum { opacity: .5; }
  .nav a.aktif::before { height: 60%; }
  .tombol:active, .ubin:active, .tombol-bulat:active { transform: none; }
}

/* --- ganti isi tanpa muat ulang ------------------------------------------- */
/* Waktu isi halaman ditukar, kartu yang tidak berubah tidak ikut masuk ulang.
   Kalau semuanya dianimasikan lagi, perubahan yang sebenarnya jadi tenggelam. */
.isi.tanpa-masuk .kartu,
.isi.tanpa-masuk .papan > .kolom,
.isi.tanpa-masuk .kartu-order,
.isi.tanpa-masuk .jalur li,
.isi.tanpa-masuk .flash { animation: none !important; }

/* Kartu yang barusan pindah kolom disorot sebentar. */
.kartu-order.baru-pindah { animation: pindah-sorot 1s var(--halus) both; }
@keyframes pindah-sorot {
  0%   { transform: scale(.96); box-shadow: 0 0 0 3px var(--primary); }
  35%  { transform: scale(1); box-shadow: 0 0 0 3px var(--primary); }
  100% { transform: scale(1); box-shadow: 0 0 0 3px rgba(0, 74, 198, 0); }
}

/* ==========================================================================
   Sentuhan layar
   --------------------------------------------------------------------------
   Android dan iOS punya kebiasaan bawaan yang mengganggu di aplikasi kasir:
   kotak abu-abu berkedip tiap ketukan, jeda 300 milidetik sebelum ketukan
   diproses, tarik-untuk-muat-ulang yang tidak sengaja aktif saat menggulir
   papan, dan pembesaran otomatis saat isian disentuh. Semuanya dimatikan di
   sini. Ukuran huruf isian sengaja 16px karena di bawah itu Safari iOS
   memperbesar halaman sendiri begitu isian disentuh.
   ========================================================================== */

html {
  -webkit-tap-highlight-color: transparent;
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

/* Tarik-untuk-muat-ulang di tengah pekerjaan bikin isian yang belum disimpan
   hilang, jadi gerakan gulir ditahan di dalam halaman. */
body { overscroll-behavior-y: contain; }

a, button, .tombol, .tombol-bulat, .ubin, .kartu-order, label, summary,
input[type="checkbox"], input[type="radio"], select {
  touch-action: manipulation;
}

/* Kolom papan dan daftar panjang digulir sendiri tanpa menyeret halaman induk. */
.papan, .tabel-geser, .krj-gulir, .sidebar { overscroll-behavior: contain; }

/* Sasaran sentuh minimal 44px, ukuran yang dipakai pedoman Apple dan Android.
   Di layar sentuh tombol yang lebih kecil dari ini sering meleset. */
@media (pointer: coarse) {
  .tombol, .tombol-bulat, .tabbar a, .nav a { min-height: 44px; }
  .tombol.kecil { min-height: 40px; }
  /* Efek sorot mouse tidak berlaku di layar sentuh dan malah nyangkut
     setelah ketukan, jadi ditiadakan. */
  .ubin:hover { border-color: var(--garis); box-shadow: none; }
  .ubin:hover .ms { transform: none; color: var(--on-surface-variant); }
  .kartu-order:hover { transform: none; box-shadow: var(--sh-sm); }
  .ubin.dipilih:hover .ms { color: var(--primary); }
}

/* Bilah tab bawah menyisakan ruang untuk garis home iPhone. Halaman ikut
   diberi alas setinggi bilah supaya isi terakhir tidak tertutup. */
@media (max-width: 900px) {
  /* main.isi, bukan .ms.isi yang dipakai ikon. Alasnya seluas bilah tab plus
     satu jarak, supaya kartu terakhir tidak tertutup. */
  main.isi { padding-bottom: calc(var(--tabbar-ruang, 94px) + var(--lg)); }

  /* Kalau bilah total kasir sedang tampil, alasnya ditambah setinggi bilah itu
     juga. Tanpa ini ubin layanan terakhir tertutup dua bilah sekaligus. */
  main.isi:has(.krj-apung.ada-isi) {
    padding-bottom: calc(var(--tabbar-ruang, 94px) + 56px + var(--xl));
  }
}

/* Layar dengan poni: sisi kiri-kanan ikut dihindari saat HP dimiringkan. */
@media (orientation: landscape) {
  .rangka { padding-left: env(safe-area-inset-left, 0px); padding-right: env(safe-area-inset-right, 0px); }
  .lacak { padding-left: env(safe-area-inset-left, 0px); padding-right: env(safe-area-inset-right, 0px); }
}

/* --- garis kemajuan ------------------------------------------------------- */
/* Muncul di puncak layar selagi permintaan berjalan. Melaju cepat di awal lalu
   melambat mendekati ujung, karena lamanya jawaban server tidak diketahui. */
.kemajuan {
  position: fixed; top: 0; left: 0; height: 3px; width: 0;
  background: var(--primary); z-index: 90; opacity: 0;
  border-radius: 0 var(--r-full) var(--r-full) 0;
  box-shadow: 0 0 8px rgba(0, 74, 198, .5);
}
.kemajuan.jalan { opacity: 1; animation: kemajuan-maju 8s cubic-bezier(.1, .8, .3, 1) forwards; }
.kemajuan.selesai { opacity: 0; width: 100%; transition: width .18s ease, opacity .3s ease .1s; }
@keyframes kemajuan-maju {
  0%   { width: 0; }
  25%  { width: 55%; }
  60%  { width: 78%; }
  100% { width: 92%; }
}

/* --- ubin antrean di beranda ---------------------------------------------- */
.antrean a {
  transition: transform var(--gerak-cepat) var(--halus),
              box-shadow var(--gerak-cepat) ease, background-color var(--gerak-cepat) ease;
}
.antrean a:hover { transform: translateY(-2px); box-shadow: var(--sh-md); }
.antrean a:active { transform: translateY(0) scale(.98); }
.antrean a .n { transition: transform var(--gerak-sedang) var(--pegas); }
.antrean a:hover .n { transform: scale(1.06); }

/* --- baris tabel ---------------------------------------------------------- */
/* Baris pertama muncul lebih dulu, jadi tabel terbaca sebagai daftar yang
   terisi dari atas, bukan blok yang muncul sekaligus. */
.kartu tbody tr { animation: baris-masuk var(--gerak-cepat) var(--halus) both; }
.kartu tbody tr:nth-child(1) { animation-delay: .02s; }
.kartu tbody tr:nth-child(2) { animation-delay: .05s; }
.kartu tbody tr:nth-child(3) { animation-delay: .08s; }
.kartu tbody tr:nth-child(4) { animation-delay: .11s; }
.kartu tbody tr:nth-child(5) { animation-delay: .14s; }
.kartu tbody tr:nth-child(n+6) { animation-delay: .16s; }
@keyframes baris-masuk {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: none; }
}
.isi.tanpa-masuk .kartu tbody tr { animation: none !important; }

@media (prefers-reduced-motion: reduce) {
  .kemajuan.jalan { animation: none; width: 40%; }
}

/* --- topbar di layar sempit ------------------------------------------------ */
/* Judul dan tombol berbagi satu baris di layar lebar. Di HP tombolnya memakan
   hampir seluruh lebar dan menyisakan kolom selebar beberapa huruf untuk judul,
   sehingga keterangannya pecah jadi satu kata per baris. Di bawah 700px
   keduanya dipisah jadi dua baris. */
@media (max-width: 700px) {
  .topbar { flex-wrap: wrap; align-items: flex-start; }
  .topbar .tumbuh { flex: 1 1 100%; min-width: 0; }
  .topbar-aksi { flex: 1 1 100%; justify-content: flex-start; flex-wrap: wrap; }
  .topbar-aksi .tombol { flex: 1 1 auto; justify-content: center; }
  .topbar .sub { font-size: 13px; line-height: 19px; }
}

/* Kolom papan menyesuaikan isinya, tidak ikut setinggi kolom terpanjang.
   Di HP kolom kosong setinggi layar cuma bikin gulir jadi panjang. */
@media (max-width: 1100px) {
  .papan { align-items: start; }
  .kolom { min-height: 0; }
  .kolom:empty, .kolom > .isi-kolom:empty { min-height: 0; }
}

/* ==========================================================================
   Pindah halaman
   --------------------------------------------------------------------------
   Menu diambil alih skrip supaya isinya ditukar, bukan halaman dimuat ulang.
   Browser yang mendukung View Transitions menggarap silang-pudarnya sendiri,
   dan hasilnya lebih halus daripada animasi buatan tangan karena ia memotret
   keadaan lama dan baru lalu menyilangkannya di lapisan tersendiri.
   ========================================================================== */

main.isi { view-transition-name: isi-halaman; }
.sidebar { view-transition-name: bilah-sisi; }
.tabbar  { view-transition-name: bilah-tab; }
.topbar  { view-transition-name: bilah-atas; }

/* Isi halaman bergeser naik sedikit sambil berganti, arah yang sama dengan
   datangnya halaman baru. */
::view-transition-old(isi-halaman) {
  animation: isi-keluar .18s var(--halus) both;
}
::view-transition-new(isi-halaman) {
  animation: isi-masuk .28s var(--halus) both;
}
@keyframes isi-keluar {
  from { opacity: 1; transform: none; }
  to   { opacity: 0; transform: translateY(-6px); }
}
@keyframes isi-masuk {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}

/* Menu tetap diam. Ia tidak berpindah, jadi memudarkannya cuma bikin kedip. */
::view-transition-old(bilah-sisi), ::view-transition-new(bilah-sisi),
::view-transition-old(bilah-tab),  ::view-transition-new(bilah-tab) {
  animation: none; mix-blend-mode: normal;
}
::view-transition-old(bilah-atas) { animation: isi-keluar .14s var(--halus) both; }
::view-transition-new(bilah-atas) { animation: isi-masuk .22s var(--halus) both; }

/* Cadangan untuk browser tanpa View Transitions. */
main.isi.masuk { animation: isi-masuk .3s var(--halus) both; }

@media (prefers-reduced-motion: reduce) {
  ::view-transition-old(isi-halaman), ::view-transition-new(isi-halaman),
  ::view-transition-old(bilah-atas), ::view-transition-new(bilah-atas) {
    animation: none;
  }
  main.isi.masuk { animation: none; }
}

/* ==========================================================================
   Riak dan sentuhan kecil
   ========================================================================== */

/* Riak dibuat skrip di titik yang disentuh. Elemen yang bisa beriak dipotong
   di tepinya supaya lingkarannya tidak melimpah keluar bentuk tombol. */
.tombol, .tombol-bulat, .ubin, .tabbar a, .nav a, .antrean a,
.bot-cara-tab, .pilih-mode, .cepat button, .stepper button { overflow: hidden; }

.riak {
  position: absolute; border-radius: 50%; pointer-events: none;
  background: currentColor; opacity: .18; transform: scale(0);
  animation: riak-lebar .55s cubic-bezier(.2, .6, .3, 1) forwards;
}
.tombol.utama .riak, .tabbar a.aktif .lingkar .riak { background: #fff; opacity: .28; }
@keyframes riak-lebar {
  to { transform: scale(1); opacity: 0; }
}

/* --- isian ---------------------------------------------------------------- */
/* Kotak isian yang sedang dipakai diberi cincin tipis, bukan garis tebal, biar
   tata letaknya tidak bergeser satu piksel pun saat disentuh. */
input:focus, select:focus, textarea:focus {
  outline: none; border-color: var(--primary);
  box-shadow: 0 0 0 3px var(--primary-fixed);
}
.ladang span, label > span:first-child {
  transition: color var(--gerak-cepat) ease;
}
.ladang:focus-within > span:first-child { color: var(--primary); }

/* Panah pada daftar pilihan ikut berputar saat daftarnya dibuka. */
select { transition: background-image 0s, border-color var(--gerak-cepat) ease,
                     box-shadow var(--gerak-cepat) ease; }

/* Kotak centang dan pilihan bulat memberi balasan saat ditekan. */
input[type="checkbox"], input[type="radio"] {
  transition: transform var(--gerak-cepat) var(--pegas),
              background-color var(--gerak-cepat) ease,
              border-color var(--gerak-cepat) ease;
}
input[type="checkbox"]:active, input[type="radio"]:active { transform: scale(.85); }
input[type="checkbox"]:checked, input[type="radio"]:checked {
  animation: centang-pop var(--gerak-sedang) var(--pegas);
}
@keyframes centang-pop {
  0%   { transform: scale(.7); }
  60%  { transform: scale(1.12); }
  100% { transform: scale(1); }
}

/* Kartu pilihan mode ikut naik saat dipilih. */
.pilih-mode { transition: background-color var(--gerak-cepat) ease,
                          border-color var(--gerak-cepat) ease,
                          transform var(--gerak-cepat) var(--halus); }
.pilih-mode:active { transform: scale(.995); }

/* --- tautan --------------------------------------------------------------- */
/* Garis bawah tumbuh dari kiri, bukan muncul sekaligus. */
.isi a:not(.tombol):not(.kode):not(.merek):not(.pil a):not(.lencana) {
  background-image: linear-gradient(currentColor, currentColor);
  background-size: 0% 1px; background-position: 0 100%;
  background-repeat: no-repeat;
  transition: background-size var(--gerak-sedang) var(--halus);
  text-decoration: none;
}
.isi a:not(.tombol):not(.kode):not(.merek):not(.pil a):not(.lencana):hover {
  background-size: 100% 1px;
}
/* Chip pemilih kategori berbentuk pil, garis bawah di situ salah tempat. */
.pil a { text-decoration: none; background-image: none; }

/* --- kartu dan tabel ------------------------------------------------------ */
.kartu { transition: box-shadow var(--gerak-sedang) ease; }
.ringkas { transition: transform var(--gerak-cepat) var(--halus), box-shadow var(--gerak-cepat) ease; }
.ringkas:hover { transform: translateY(-2px); box-shadow: var(--sh-md); }
tbody tr:hover { background: var(--s-low); }

/* Nomor nota melebar sedikit saat disorot, penanda bahwa ia bisa diklik. */
.kode { transition: color var(--gerak-cepat) ease, letter-spacing var(--gerak-cepat) ease; }
a.kode:hover { letter-spacing: .01em; }

/* --- keadaan kosong ------------------------------------------------------- */
/* Ikon melayang pelan supaya halaman kosong tidak terasa mati. */
.kosong .gambar { animation: melayang 4s ease-in-out infinite; }
@keyframes melayang {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-5px); }
}

/* --- fokus papan tik ------------------------------------------------------ */
/* Penanda fokus untuk yang berpindah dengan Tab, tanpa mengganggu pemakai tetikus. */
:focus-visible {
  outline: 2px solid var(--primary); outline-offset: 2px;
  border-radius: var(--r-xl);
}

@media (prefers-reduced-motion: reduce) {
  .riak { display: none; }
  .kosong .gambar { animation: none; }
  .isi a:not(.tombol):not(.kode):not(.merek):not(.pil a):not(.lencana) { transition: none; }
  .ringkas:hover { transform: none; }
}
