/*
 * style.css — tata letak dan bentuk. TIDAK ADA SATU PUN WARNA MENTAH di sini.
 *
 * Semua warna datang dari /theme.css yang dibuat server dari pengaturan, dan
 * dipasang dengan <link> SESUDAH berkas ini. Sorotan lembut memakai
 * rgba(var(--accent-rgb), .14) supaya tetap bisa disentuh tema.
 *
 * Warna yang hanya ada di dalam aturan CSS biasa tidak akan bisa diubah tema —
 * karena itu berkas ini sengaja tidak punya satu pun nilai hex, rgb(), atau
 * nama warna. Ada uji otomatis yang memeriksanya.
 */

/* ------------------------------------------------------------------ *
 * Dasar
 * ------------------------------------------------------------------ */

*,
*::before,
*::after {
  box-sizing: border-box;
}

:root {
  --lebar-isi: 1180px;
  --lebar-sempit: 720px;
  --sudut: 14px;
  --sudut-kecil: 9px;
  --sudut-besar: 22px;
  --jarak: 16px;
  --bayang: 0 1px 2px rgba(var(--text-rgb), 0.06), 0 6px 20px rgba(var(--text-rgb), 0.06);
  --bayang-kuat: 0 2px 6px rgba(var(--text-rgb), 0.1), 0 18px 44px rgba(var(--text-rgb), 0.12);
  --garis: 1px solid var(--border);
  --alur: 180ms cubic-bezier(0.2, 0.7, 0.3, 1);
  --font: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-angka: ui-monospace, "SF Mono", "Cascadia Mono", Consolas, monospace;

  /* Tinggi baris header. Dipakai DUA kali: oleh headernya sendiri, dan oleh
     tempat kosong yang menunggunya. Satu angka supaya keduanya tidak mungkin
     berselisih - kalau berselisih, halaman meloncat persis sebesar selisihnya. */
  --tinggi-kepala: 64px;

  /* Tinggi bilah hak cipta & versi di dasar layar. Dipakai dua kali: oleh
     bilahnya sendiri lewat isinya, dan oleh ruang yang disediakan body. */
  --tinggi-tanda: 30px;
  /* Tinggi bilah kirim di checkout. Dipaku dengan alasan yang sama seperti
     --tinggi-tanda: ruang yang disediakan body harus persis setinggi bilahnya,
     atau selisihnya menutupi isi halaman di ujung bawah. */
  --tinggi-bilah-kirim: 66px;
}

html {
  -webkit-text-size-adjust: 100%;
  /* Ruang bilah gulir SELALU disediakan, walau halamannya sedang pendek.
     Tanpa ini layar terasa bergetar: saat isi sebuah tab diganti, sesaat
     halamannya lebih pendek dari layar, bilah gulirnya hilang, dan seluruh
     halaman melebar 15px — lalu menyempit lagi begitu isinya datang. Diukur
     di panel Admin: 1385px -> 1400px -> 1385px dalam sekejap. */
  scrollbar-gutter: stable;
}

body {
  margin: 0;
  font-family: var(--font);
  font-size: 15px;
  line-height: 1.6;
  color: var(--text);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4 {
  margin: 0 0 0.5em;
  line-height: 1.25;
  font-weight: 700;
  letter-spacing: -0.01em;
}

h1 { font-size: clamp(1.7rem, 3.4vw, 2.5rem); }
h2 { font-size: clamp(1.3rem, 2.2vw, 1.7rem); }
h3 { font-size: 1.1rem; }

p { margin: 0 0 1em; }
p:last-child { margin-bottom: 0; }

a {
  color: var(--accent-link);
  text-decoration-thickness: 1px;
  text-underline-offset: 2px;
}
a:hover { text-decoration-thickness: 2px; }

img { max-width: 100%; height: auto; display: block; }

hr {
  border: 0;
  border-top: var(--garis);
  margin: 24px 0;
}

:focus-visible {
  outline: 3px solid rgba(var(--accent-rgb), 0.55);
  outline-offset: 2px;
  border-radius: 4px;
}

.isi {
  width: 100%;
  max-width: var(--lebar-isi);
  margin: 0 auto;
  padding: 0 20px;
}

.isi-sempit { max-width: var(--lebar-sempit); }

.utama { padding: 28px 0 64px; min-height: 60vh; }

.tumpuk { display: flex; flex-direction: column; gap: var(--jarak); }
.baris { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }

/* Kontrol yang berdiri langsung di dalam .baris tidak melebar penuh —
   kalau melebar, baris penyaring akan pecah menjadi beberapa baris. */
.baris > input:not([type="checkbox"]):not([type="radio"]),
.baris > select {
  width: auto;
  min-width: 150px;
  flex: 0 1 auto;
}
.baris-rapat { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }

/* Label yang menempel pada kolomnya. Dipakai di baris penyaring supaya kata
   seperti "dari" dan "sampai" ikut berpindah bersama kolom tanggalnya ketika
   barisnya melipat di layar sempit. */
.pasangan { display: inline-flex; align-items: center; gap: 6px; }

/* Atribut `hidden` bawaan HTML kalah oleh aturan display apa pun yang ditulis
   di sini — termasuk .baris-rapat di atas. Akibatnya elemen yang sudah diberi
   hidden lewat JavaScript tetap terlihat, dan itu tidak akan ketahuan dari
   pemeriksaan JavaScript (el.hidden tetap true). Satu aturan ini menutupnya
   untuk seluruh aplikasi. */
[hidden] { display: none !important; }
.dorong { margin-left: auto; }
.tengah { text-align: center; }
.kanan { text-align: right; }
.sembunyi { display: none !important; }

.redup { color: var(--text-muted); }
.kecil { font-size: 0.86rem; }
.tebal { font-weight: 700; }
.angka { font-variant-numeric: tabular-nums; }

/* ------------------------------------------------------------------ *
 * Header
 * ------------------------------------------------------------------ */

.kepala {
  position: sticky;
  top: 0;
  z-index: 40;
  background: var(--header-bg);
  border-bottom: var(--garis);
}

/* Halaman tidak pernah diperlihatkan setengah jadi.
 *
 * Judul, teks, header, dan footer semuanya disusun dari jawaban
 * /api/settings, jadi selama kira-kira 150ms pertama halaman ini baru
 * kerangka kosong. Kalau kerangka itu ikut terlihat, isinya seolah meloncat
 * masuk sekaligus: diukur di beranda, satu geseran tata letak sebesar 0,99 -
 * praktis setinggi satu layar penuh. Itulah sentakan yang terasa setiap kali
 * berpindah lewat menu.
 *
 * Yang ditahan hanya penampakannya, bukan tata letaknya: visibility, bukan
 * display, dan dikenakan pada anak-anak body supaya latar halamannya tetap
 * terlukis - jadi yang terlihat adalah halaman kosong berwarna benar, bukan
 * kilatan putih.
 *
 * Kelasnya dipasang oleh JavaScript, tidak ditulis di HTML. Kalau app.js
 * gagal dimuat sama sekali, tidak ada yang pernah menyembunyikan apa pun dan
 * halaman tetap tampil apa adanya. */
html.menunggu-kerangka body > * { visibility: hidden; }

/* Tempat header, sebelum JavaScript mengisinya.
 *
 * Header disusun dari jawaban /api/settings, jadi selama beberapa ratus
 * milidetik pertama div ini masih kosong dan setinggi nol. Begitu headernya
 * terpasang, SELURUH isi halaman terdorong turun 65px sekaligus - di setiap
 * perpindahan halaman, di setiap lebar layar. Itulah yang terlihat sebagai
 * layar menyentak. Tingginya disediakan lebih dulu, persis sebesar header yang
 * akan menempatinya: 64px baris isinya + 1px garis bawahnya.
 */
[data-kepala] {
  min-height: calc(var(--tinggi-kepala) + 1px);
}

.kepala-isi {
  display: flex;
  align-items: center;
  gap: 18px;
  min-height: var(--tinggi-kepala);
  padding: 8px 20px;
  max-width: var(--lebar-isi);
  margin: 0 auto;
}

.merek {
  display: flex;
  align-items: center;
  gap: 11px;
  text-decoration: none;
  color: var(--header-text);
  /* BOLEH MENYEMPIT, tapi tidak sampai hilang. Sejak penanda area ikut berdiri
     di luar menu lipat, baris header ponsel tegak memuat merek + penanda +
     keranjang + tombol menu sekaligus. Dengan flex-shrink:0 yang dulu, merek
     menolak menyempit dan yang meluber justru barisnya. min-width:0 itu yang
     mengizinkan tulisannya dipotong, bukan barisnya yang jebol. */
  flex-shrink: 1;
  min-width: 0;
}

.merek-nama,
.merek-sub {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.merek img {
  width: 40px;
  height: 40px;
  border-radius: 10px;
  object-fit: cover;
  box-shadow: var(--bayang);
}

/* min-width:0 WAJIB, dan tanpa itu ellipsis di bawah tidak pernah bekerja:
   bawaan sebuah item flex adalah min-width:auto, yang menolak menyempit lebih
   kecil daripada isinya. Akibatnya terukur — tulisan mereknya tidak terpotong,
   ia MELUAP ke bawah penanda area dan keduanya saling menimpa. */
.merek-teks { display: flex; flex-direction: column; line-height: 1.15; min-width: 0; }
.merek-nama { font-weight: 800; font-size: 1.06rem; letter-spacing: -0.02em; }
.merek-sub { font-size: 0.74rem; color: var(--header-muted); font-weight: 500; }

.menu { display: flex; align-items: center; gap: 2px; flex-wrap: wrap; }

.menu a {
  color: var(--header-text);
  text-decoration: none;
  padding: 8px 13px;
  border-radius: 999px;
  font-weight: 600;
  font-size: 0.92rem;
  transition: background var(--alur);
}

.menu a:hover { background: rgba(var(--accent-rgb), 0.12); }
.menu a[aria-current="page"] {
  background: rgba(var(--accent-rgb), 0.16);
  color: var(--accent-link);
}

.tombol-menu {
  display: none;
  background: transparent;
  border: var(--garis);
  border-radius: var(--sudut-kecil);
  padding: 8px 11px;
  cursor: pointer;
  color: var(--header-text);
  font-size: 1.1rem;
}

/* Lencana daftar harga khusus ("Harga Agen"), dipakai keranjang & checkout. */
.lencana-harga {
  background: rgba(var(--accent-rgb), 0.14);
  color: var(--accent-link);
  font-weight: 700;
}

/* Kelompok aksi header: penanda area + ikon keranjang. DUA-DUANYA DI LUAR
   menu lipat, jadi tetap terlihat di layar kecil. Dikelompokkan supaya jarak
   dan perataannya diatur di satu tempat, dan supaya keduanya tetap
   berpasangan saat menu-nya terlipat. */
.kepala-aksi {
  display: flex;
  align-items: center;
  gap: 10px;
  flex: none;
}

/* Ikon keranjang: DI LUAR menu lipat, jadi tetap terlihat di layar kecil.
   Keranjang adalah hal yang paling sering ditengok pembeli; menyembunyikannya
   di balik tombol menu membuatnya hilang justru saat paling dibutuhkan. */
.ikon-keranjang {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 42px;
  height: 42px;
  flex: none;
  border-radius: 999px;
  border: var(--garis);
  color: var(--header-text);
  text-decoration: none;
  transition: background var(--alur);
}

.ikon-keranjang:hover { background: rgba(var(--accent-rgb), 0.12); }
.ikon-keranjang[aria-current="page"] { background: rgba(var(--accent-rgb), 0.16); }
.ikon-keranjang-gambar { font-size: 1.15rem; line-height: 1; }

.lencana-keranjang {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 20px;
  height: 20px;
  padding: 0 6px;
  border-radius: 999px;
  background: var(--accent);
  color: var(--accent-contrast);
  font-size: 0.72rem;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}

/* Angka menempel di pojok ikon, bukan mendorong lebarnya. */
.ikon-keranjang .lencana-keranjang {
  position: absolute;
  top: -4px;
  right: -4px;
  border: 2px solid var(--surface);
}

/* 1100px, bukan 900px: di 901–1100px menunya tidak muat sebaris — "Masuk"
   turun ke baris kedua dan kepala halaman menjadi 100px. */
@media (max-width: 1100px) {
  .tombol-menu { display: block; }
  .menu {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    flex-direction: column;
    align-items: stretch;
    background: var(--surface);
    border-bottom: var(--garis);
    padding: 10px;
    gap: 2px;
    box-shadow: var(--bayang-kuat);
  }
  .menu.buka { display: flex; }
  /* CATATAN: JANGAN kembalikan `.kepala { position: relative }` di sini.
     Dulu barisnya ada, untuk menambatkan menu lipat yang absolut. Tapi
     `position: sticky` SUDAH elemen terposisi, jadi menu absolutnya tetap
     menambat ke header dengan benar tanpa itu — sementara `relative`
     MEMBATALKAN sticky-nya, dan headernya tergulir hilang di setiap halaman
     pada layar sempit. Justru di ponsel header itu paling dibutuhkan: di sana
     ikon keranjang dan tombol menu adalah satu-satunya jalan berpindah. */
  /* Menu lipat menutupi lebar penuh; penanda area dan keranjang tetap di
     barisnya. Yang didorong ke kanan KELOMPOKNYA, bukan keranjangnya sendiri:
     margin-left:auto pada keranjang akan mendorongnya menjauh dari penanda
     area dan memisahkan dua tombol yang justru harus berpasangan. */
  .kepala-aksi { margin-left: auto; }
}

/* ------------------------------------------------------------------ *
 * Hero
 * ------------------------------------------------------------------ */

.hero {
  background: linear-gradient(160deg, var(--hero-from), var(--hero-to));
  border-bottom: var(--garis);
  padding: 52px 0 56px;
  position: relative;
  overflow: hidden;
}

.hero::after {
  content: "";
  position: absolute;
  inset: auto -10% -60% 40%;
  height: 320px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(var(--surface-rgb), 0.75), transparent 70%);
  pointer-events: none;
}

/* Cerita perusahaan yang berputar di hero, dan lencana kepercayaannya. */
.hero-cerita {
  margin-top: 18px;
  max-width: 560px;
}

.hero-cerita-isi {
  background: rgba(var(--surface-rgb), 0.72);
  border: var(--garis);
  border-radius: var(--sudut);
  padding: 14px 16px;
  /* Tingginya dijaga supaya tombol di bawahnya tidak melompat tiap pergantian
     cerita — teks yang panjangnya berbeda akan menggeser tata letaknya. */
  /* Lantai untuk cerita yang sangat pendek. Tinggi sebenarnya ditentukan
     lapisan pengukur di bawah. */
  min-height: 96px;

  /* TINGGINYA TIDAK PERNAH BERUBAH — dan bukan dengan mematoknya.

     Dua lapisan ditumpuk di SATU sel kisi yang sama:

       .hero-cerita-ukuran    semua cerita sekaligus, tidak terlihat
       .hero-cerita-panggung  satu cerita yang sedang dibaca

     Lapisan pengukur memuat SEMUA cerita yang juga saling menumpuk, jadi
     tingginya sama dengan cerita yang PALING PANJANG. Karena ia ikut mengisi
     sel yang sama, kotak ini selalu setinggi itu — cerita mana pun yang
     sedang tampil.

     Yang menghitung peramban, bukan JavaScript. Itu sebabnya ia tetap benar
     waktu jendelanya diubah ukurannya, waktu hurufnya baru selesai dimuat,
     dan waktu pembacanya memperbesar tampilan — tiga keadaan yang semuanya
     mengubah jumlah baris teks, dan yang semuanya akan terlewat kalau
     tingginya diukur sekali lalu disimpan. */
  display: grid;
  align-items: center;
}

.hero-cerita-ukuran,
.hero-cerita-panggung {
  grid-area: 1 / 1;
  min-width: 0;
}

.hero-cerita-ukuran {
  visibility: hidden;
  display: grid;
  align-items: center;
}

.hero-cerita-ukuran > .hero-cerita-kartu { grid-area: 1 / 1; }

/* Tempat gambar di lapisan pengukur — kotak kosong seukuran fotonya, bukan
   fotonya sendiri. Memasang <img> yang sama dua kali berarti mengunduh setiap
   foto cerita dua kali di layar pertama yang dilihat pengunjung, dan ukurannya
   memang sudah dipatok 72px di .hero-cerita-kartu img. */
.hero-cerita-gambar-palsu { width: 72px; height: 72px; flex-shrink: 0; }

/* PERGANTIAN CERITA — dan angka di bawah ini SATU-SATUNYA tempat lamanya
   ditentukan. index.html membacanya kembali lewat getComputedStyle, bukan
   menuliskan angkanya sendiri: dua angka yang harus sama persis tapi tersimpan
   di dua berkas akan berselisih suatu hari, dan selisihnya terlihat sebagai
   kedipan — isinya tertukar waktu kotaknya belum sempat redup.

   Ini juga yang membuat `prefers-reduced-motion` bekerja tanpa satu baris pun
   tambahan: aturan di kaki berkas ini memangkas semua transisi menjadi
   0,001ms, halaman membaca angka itu, dan pergantiannya menjadi seketika. */
.hero-cerita-panggung { transition: opacity var(--alur), transform var(--alur); }

.hero-cerita-panggung.pudar {
  opacity: 0;
  /* Turun sedikit, bukan diam di tempat: gerak kecil ke satu arah membuat
     pergantiannya terbaca sebagai "berganti", bukan sebagai layar yang
     berkedip. Yang bergeser hanya isinya — kotaknya tidak ikut, karena
     tingginya dipegang lapisan pengukur. */
  transform: translateY(6px);
}

.hero-cerita-kartu {
  display: flex;
  gap: 14px;
  align-items: center;
}

/* Gambar yang bisa ditekan untuk diperbesar. Tombolnya polos: yang terlihat
   hanya gambarnya, tapi ia tetap tombol sungguhan supaya bisa dicapai papan
   ketik dan dibacakan pembaca layar. */
.gambar-bisa-besar {
  padding: 0;
  border: 0;
  background: none;
  cursor: zoom-in;
  border-radius: var(--sudut-kecil);
  line-height: 0;
  transition: transform var(--alur), box-shadow var(--alur);
}

.gambar-bisa-besar:hover { transform: scale(1.04); }
.gambar-bisa-besar:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

.lampu {
  border: 0;
  padding: 0;
  background: none;
  /* Menyusut mengikuti gambarnya. Tanpa ini <dialog> melebar sampai batas
     max-width, dan tombol tutup yang menempel di pojok kanan dialog melayang
     jauh dari gambarnya — terlihat seperti tombol yang bukan miliknya. */
  width: fit-content;
  max-width: 94vw;
  max-height: 94vh;
  margin: auto;
  overflow: visible;
}

.lampu::backdrop { background: rgba(var(--text-rgb), 0.78); }

.lampu img {
  display: block;
  max-width: 94vw;
  /* Sisakan ruang untuk keterangan di bawahnya. */
  max-height: 78vh;
  width: auto;
  height: auto;
  border-radius: var(--sudut);
  box-shadow: var(--bayang-kuat);
  background: var(--surface);
}

.lampu-ket {
  margin-top: 10px;
  padding: 10px 14px;
  border-radius: var(--sudut-kecil);
  background: var(--surface);
  color: var(--text);
  /* Dibatasi supaya keterangan yang panjang MELIPAT, bukan melebarkan
     dialognya melewati gambar. */
  max-width: min(94vw, 620px);
}

.lampu-tutup {
  position: absolute;
  top: -14px;
  right: -14px;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  border: 0;
  background: var(--surface);
  color: var(--text);
  box-shadow: var(--bayang-kuat);
  font-size: 1.3rem;
  line-height: 1;
  cursor: pointer;
}

.lampu-tutup:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

@media (max-width: 620px) {
  .lampu-tutup { top: -10px; right: -6px; }
}

.hero-cerita-kartu img {
  width: 72px;
  height: 72px;
  object-fit: cover;
  border-radius: var(--sudut-kecil);
  flex-shrink: 0;
  background: var(--surface-2);
}

.hero-cerita-kartu b { display: block; margin-bottom: 3px; }
.hero-cerita-kartu p { margin: 0; font-size: 0.9rem; color: var(--text-muted); }

.hero-cerita-titik {
  display: flex;
  gap: 7px;
  margin-top: 10px;
}

.hero-cerita-titik button {
  width: 9px;
  height: 9px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--border-strong);
  cursor: pointer;
  transition: background var(--alur), transform var(--alur);
}

.hero-cerita-titik button.aktif {
  background: var(--accent);
  transform: scale(1.35);
}

/* ------------------------------------------------------------------ *
 * Tentang Kami
 *
 * Halaman baca panjang, bukan halaman alat. Jadi yang diatur di sini lebar
 * baris, jarak antarbaris, dan irama antarbagian — tiga hal yang menentukan
 * apakah orang sampai ke kalimat terakhir.
 * ------------------------------------------------------------------ */

.tentang-kepala {
  margin-bottom: 26px;
  padding-bottom: 20px;
  border-bottom: var(--garis);
}

/* Nama perusahaan di atas judul: kecil, berjarak, dan REDUP — ia penanda
   tempat, bukan judulnya. Dibuat sekuat judul, keduanya berebut perhatian. */
.tentang-alis {
  margin: 0 0 6px;
  font-size: 0.74rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  color: var(--accent);
}

.tentang-kepala h1 { margin: 0; }

/* Ukuran dan jarak baris DINAIKKAN dari teks biasa aplikasi ini. Yang lain
   halaman alat — dibaca sekilas sambil mengerjakan sesuatu; yang ini dibaca
   bersambung dari atas ke bawah. */
.tentang p {
  margin: 0 0 16px;
  font-size: 1.02rem;
  line-height: 1.75;
}

.tentang-judul {
  margin: 34px 0 14px;
  font-size: 1.24rem;
  line-height: 1.35;
  /* Garis pendek berwarna aksen di atas judul: penanda bagian baru yang
     terlihat sambil menggulir cepat, tanpa menambah satu kata pun. */
  padding-top: 16px;
  border-top: 3px solid var(--accent);
  display: inline-block;
}

/* Kalimat yang sengaja berdiri sendiri. Bukan kutipan dari orang lain — ia
   kalimat penulisnya sendiri yang diberi ruang, jadi tanpa tanda kutip. */
.tentang-sorot {
  margin: 22px 0 24px;
  padding: 16px 0 16px 20px;
  border-left: 3px solid var(--accent);
  background: rgba(var(--accent-rgb), 0.05);
  border-radius: 0 var(--sudut-kecil) var(--sudut-kecil) 0;
}

.tentang-sorot p {
  margin: 0;
  font-size: 1.1rem;
  font-weight: 600;
  line-height: 1.55;
}

.tentang-sorot p + p { margin-top: 4px; }

/* Penutup. Satu-satunya blok berlatar penuh di halaman ini, dan memang harus
   sendirian: kalau ada dua, tidak ada yang menjadi penutup. */
.tentang-slogan {
  margin: 34px 0 0;
  padding: 26px 24px;
  border-radius: var(--sudut);
  background: linear-gradient(135deg, rgba(var(--accent-rgb), 0.14), rgba(var(--accent-rgb), 0.04));
  border: 1px solid rgba(var(--accent-rgb), 0.22);
  text-align: center;
  display: grid;
  gap: 6px;
}

.tentang-slogan-utama {
  font-size: 1.32rem;
  line-height: 1.3;
  color: var(--accent);
}

.tentang-slogan span { color: var(--text-muted); }

/* Baris terakhir biasanya tanda pagar. Dibuat menonjol tanpa membesar: ia
   penanda, bukan kalimat. */
.tentang-slogan span:last-child { font-weight: 600; letter-spacing: 0.01em; }

.tentang-lencana { margin-top: 26px; }

.tentang-ajakan {
  margin-top: 30px;
  padding-top: 24px;
  border-top: var(--garis);
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

@media (max-width: 560px) {
  .tentang-judul { font-size: 1.12rem; margin-top: 28px; }
  .tentang-slogan { padding: 22px 18px; }
  .tentang-slogan-utama { font-size: 1.16rem; }
  /* Tombol selebar layar di ponsel: dua tombol berdampingan pada lebar segitu
     menghasilkan dua tombol yang sama-sama terlalu sempit untuk dibaca. */
  .tentang-ajakan .tbl { width: 100%; }
}

/* ------------------------------------------------------------------ *
 * Tombol "Tentang Kami" di kepala halaman
 * ------------------------------------------------------------------ */

.tombol-tentang {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 7px 12px;
  border: var(--garis);
  border-radius: 999px;
  background: var(--surface);
  color: var(--text-muted);
  font-size: 0.82rem;
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
  transition: background var(--alur), color var(--alur), border-color var(--alur);
}

.tombol-tentang:hover,
.tombol-tentang.aktif {
  color: var(--accent);
  border-color: rgba(var(--accent-rgb), 0.45);
  background: rgba(var(--accent-rgb), 0.08);
}

.tombol-tentang-ikon { font-size: 1rem; line-height: 1; }

/* Di layar sempit tinggal ikonnya. Kepala halaman di ponsel tegak sudah memuat
   merek, penanda area, keranjang, dan tombol menu; satu kata lagi membuat
   nama merek terpotong. Namanya tidak hilang — ia tetap ada di aria-label dan
   di tautan kaki halaman. */
@media (max-width: 900px) {
  .tombol-tentang-teks { display: none; }
  /* Tanpa min-width, tombol yang tinggal ikonnya menyusut menjadi 25px —
     terukur, dan itu lebih sempit daripada ujung jempol. Tetangganya di kepala
     halaman ini 33px (penanda area) dan 42px (tombol menu); yang ini disamakan
     dengan mereka, bukan dibiarkan menjadi sasaran terkecil di layar. */
  .tombol-tentang {
    padding: 7px;
    min-width: 36px;
    justify-content: center;
  }
}

.hero-lencana {
  list-style: none;
  margin: 16px 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 8px 16px;
}

.hero-lencana li {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 0.87rem;
  font-weight: 650;
  color: var(--text-muted);
}

.hero-lencana-tanda {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--success);
  color: var(--success-contrast);
  font-size: 0.7rem;
  font-weight: 800;
}

@media (max-width: 620px) {
  .hero-cerita-kartu img { width: 56px; height: 56px; }
  .hero-cerita-isi { min-height: 0; }
}

.hero-isi {
  display: grid;
  grid-template-columns: 1.15fr 0.85fr;
  gap: 44px;
  align-items: center;
  position: relative;
  z-index: 1;
}

.hero-teks h1 { margin-bottom: 14px; }
.hero-teks p { font-size: 1.08rem; color: var(--text-muted); max-width: 52ch; }

.hero-gambar img {
  width: 100%;
  border-radius: var(--sudut-besar);
  box-shadow: var(--bayang-kuat);
  background: var(--surface);
}

@media (max-width: 860px) {
  .hero { padding: 34px 0 38px; }
  .hero-isi { grid-template-columns: 1fr; gap: 26px; }
  .hero-gambar { order: -1; max-width: 340px; }
}

/* ------------------------------------------------------------------ *
 * Tombol
 * ------------------------------------------------------------------ */

.tbl {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 10px 18px;
  border-radius: 999px;
  border: 1px solid transparent;
  background: var(--surface-2);
  color: var(--text);
  font: inherit;
  font-weight: 650;
  font-size: 0.94rem;
  cursor: pointer;
  text-decoration: none;
  transition: transform var(--alur), background var(--alur), box-shadow var(--alur), opacity var(--alur);
  white-space: nowrap;
}

.tbl:hover { transform: translateY(-1px); }
.tbl:active { transform: translateY(0); }

.tbl:disabled,
.tbl[aria-disabled="true"] {
  opacity: 0.5;
  cursor: not-allowed;
  transform: none;
}

.tbl-utama {
  background: var(--accent);
  color: var(--accent-contrast);
  box-shadow: 0 2px 10px rgba(var(--accent-rgb), 0.35);
}
.tbl-utama:hover { background: var(--accent-strong); }

.tbl-garis {
  background: transparent;
  border-color: var(--border-strong);
  color: var(--text);
}
.tbl-garis:hover { background: rgba(var(--accent-rgb), 0.1); }

.tbl-halus {
  background: rgba(var(--accent-rgb), 0.12);
  color: var(--accent-link);
}
.tbl-halus:hover { background: rgba(var(--accent-rgb), 0.2); }

.tbl-bahaya { background: var(--danger); color: var(--danger-contrast); }
.tbl-sukses { background: var(--success); color: var(--success-contrast); }
.tbl-kedua { background: var(--secondary); color: var(--secondary-contrast); }
.tbl-ingat { background: var(--warning); color: var(--warning-contrast); }

.tbl-kecil { padding: 6px 12px; font-size: 0.84rem; }
.tbl-besar { padding: 13px 26px; font-size: 1.02rem; }
.tbl-penuh { width: 100%; }

.tbl-teks {
  background: transparent;
  padding: 4px 8px;
  color: var(--accent-link);
  border-radius: var(--sudut-kecil);
}
.tbl-teks:hover { background: rgba(var(--accent-rgb), 0.12); transform: none; }

/* Tombol WhatsApp melayang */
.wa-melayang {
  position: fixed;
  right: 18px;
  bottom: 18px;
  z-index: 50;
  box-shadow: var(--bayang-kuat);
}

/* ------------------------------------------------------------------ *
 * Kartu & panel
 * ------------------------------------------------------------------ */

.kartu {
  background: var(--surface);
  border: var(--garis);
  border-radius: var(--sudut);
  padding: 20px;
  box-shadow: var(--bayang);
}

.kartu-rapat { padding: 14px; }
.kartu-datar { box-shadow: none; }

.panel {
  background: var(--surface);
  border: var(--garis);
  border-radius: var(--sudut);
  overflow: hidden;
}

.panel-kepala {
  padding: 14px 18px;
  border-bottom: var(--garis);
  background: var(--surface-2);
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}

.panel-kepala h2, .panel-kepala h3 { margin: 0; font-size: 1.02rem; }
.panel-isi { padding: 18px; }

.kisi { display: grid; gap: 18px; }
.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-auto { grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); }

/* KISI PRODUK — sama seperti .kisi-auto, tapi lebar terkecil kartunya datang
   dari pengaturan toko (produk_per_baris), bukan dipatok di sini.

   Yang diatur tetap LEBAR, bukan jumlah kolom, dan itu yang membuatnya aman:
   `auto-fill` menghitung sendiri berapa kartu yang muat, jadi layar sempit
   tetap melipat kartunya seperti biasa. Memaksa jumlah kolom akan membuat
   pilihan "5" tercetak juga di layar ponsel, lima kolom selebar jempol.

   250px -> empat sebaris pada isi selebar 1180px; 200px -> lima. */
.kisi-produk { grid-template-columns: repeat(auto-fill, minmax(var(--kartu-produk, 250px), 1fr)); }
.kisi-sisi { grid-template-columns: minmax(0, 1fr) 340px; align-items: start; }

@media (max-width: 980px) {
  .kisi-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* minmax(0, …), bukan 1fr: kata yang tidak bisa dipatahkan dulu melebarkan
     seluruh checkout menjadi 689px di layar 375px. */
  .kisi-sisi { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 700px) {
  .kisi-2, .kisi-3, .kisi-4 { grid-template-columns: 1fr; }
}

/* ------------------------------------------------------------------ *
 * Produk
 * ------------------------------------------------------------------ */

.kategori-judul {
  display: flex;
  align-items: center;
  gap: 11px;
  margin: 34px 0 16px;
}

.kategori-ikon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border-radius: 12px;
  background: rgba(var(--accent-rgb), 0.14);
  font-size: 1.25rem;
  flex-shrink: 0;
}

.produk {
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border: var(--garis);
  border-radius: var(--sudut);
  overflow: hidden;
  transition: transform var(--alur), box-shadow var(--alur), border-color var(--alur);
}

.produk:hover {
  transform: translateY(-3px);
  box-shadow: var(--bayang-kuat);
  border-color: var(--border-strong);
}

.produk-gambar {
  aspect-ratio: 4 / 3;
  background: linear-gradient(160deg, var(--hero-from), var(--hero-to));
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}

.produk-gambar img { width: 100%; height: 100%; object-fit: cover; }
.produk-gambar .kosong { font-size: 2.4rem; opacity: 0.5; }

/* PAKET HEMAT: pita jumlah di pojok gambar, dan hemat dalam warna sukses. */
/* Kotak persegi: poster tegak maupun melebar tetap terbaca. Gambarnya utuh
   (contain); latar buram dari gambar yang sama mengisi sisanya. */
.produk-paket .produk-gambar { position: relative; aspect-ratio: 1 / 1; }
.produk-paket .produk-gambar .latar-paket {
  position: absolute;
  inset: 0;
  object-fit: cover;
  filter: blur(18px) saturate(1.1);
  transform: scale(1.15);
  opacity: 0.55;
}
.produk-paket .produk-gambar .gambar-paket { position: relative; object-fit: contain; }
.pita-paket {
  position: absolute;
  z-index: 1;
  top: 10px;
  left: 10px;
  padding: 3px 10px;
  border-radius: 999px;
  background: var(--success);
  color: var(--success-contrast);
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.02em;
}
.hemat-paket { color: var(--success-link); font-weight: 600; }

.produk-isi { padding: 15px; display: flex; flex-direction: column; gap: 9px; flex: 1; }
.produk-nama { font-weight: 700; font-size: 1rem; line-height: 1.35; overflow-wrap: anywhere; }

.produk-meta {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  font-size: 0.79rem;
  color: var(--text-muted);
}

.produk-harga {
  font-size: 1.24rem;
  font-weight: 800;
  color: var(--accent-link);
  font-variant-numeric: tabular-nums;
}

.produk-satuan { font-size: 0.82rem; font-weight: 600; color: var(--text-muted); }

.tangga {
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: 9px 11px;
  border-radius: var(--sudut-kecil);
  background: rgba(var(--success-rgb), 0.13);
  font-size: 0.82rem;
}

/* ------------------------------------------------------------------ *
 * Pilihan wadah galon — tukar kosong, atau beli baru + isi
 *
 * Dibuat RINGKAS, bukan sebaris radio biasa: ia duduk di dalam kartu produk
 * yang berbagi satu baris kisi dengan kartu lain, dan tiap piksel tingginya
 * ikut menaikkan seluruh baris itu.
 * ------------------------------------------------------------------ */

.opsi-wadah {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 6px;
  margin: 10px 0 12px;
}

.opsi-wadah-pilih {
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding: 7px 9px;
  border: var(--garis);
  border-radius: var(--sudut-kecil);
  cursor: pointer;
  background: var(--surface);
  transition: border-color var(--alur), background var(--alur);
  min-width: 0;
}

/* Radionya disembunyikan dari MATA, bukan dari papan ketik: :focus-visible di
   bawah memakainya untuk menggambar cincin fokus pada kotaknya. Memakai
   display:none akan membuat pilihan ini mustahil dicapai tanpa tetikus. */
.opsi-wadah-radio {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
  pointer-events: none;
}

.opsi-wadah-nama {
  font-size: 0.78rem;
  font-weight: 650;
  line-height: 1.25;
  color: var(--text-muted);
}

.opsi-wadah-tambah { font-size: 0.72rem; color: var(--text-muted); }
/* Peringatan tukar galon: berwarna "ingat", karena ini syarat yang harus
   disiapkan pembeli sebelum kurir datang — bukan sekadar keterangan. */
.opsi-wadah-catatan {
  margin-top: 6px;
  padding: 6px 9px;
  font-size: 0.76rem;
  line-height: 1.4;
  border-left: 3px solid var(--warning);
  border-radius: var(--sudut-kecil);
  background: rgba(var(--warning-rgb), 0.12);
}

.opsi-wadah-pilih:hover { border-color: rgba(var(--accent-rgb), 0.45); }

.opsi-wadah-pilih:has(.opsi-wadah-radio:checked) {
  border-color: var(--accent);
  background: rgba(var(--accent-rgb), 0.08);
}

.opsi-wadah-pilih:has(.opsi-wadah-radio:checked) .opsi-wadah-nama { color: var(--accent); }

.opsi-wadah-pilih:has(.opsi-wadah-radio:focus-visible) {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

@media (max-width: 420px) {
  /* Di layar paling sempit dua kolom membuat tulisannya pecah per kata. */
  .opsi-wadah { grid-template-columns: 1fr; }
}

.tangga-baris { display: flex; justify-content: space-between; gap: 10px; }
.tangga-baris b { color: var(--success-link); font-variant-numeric: tabular-nums; }

.produk-aksi { margin-top: auto; display: flex; gap: 8px; align-items: center; }

.spek {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 3px 12px;
  font-size: 0.82rem;
  color: var(--text-muted);
}
.spek dt { font-weight: 600; }
.spek dd { margin: 0; }

/* ------------------------------------------------------------------ *
 * Form
 * ------------------------------------------------------------------ */

.bidang { display: flex; flex-direction: column; gap: 5px; margin-bottom: 15px; }
.bidang:last-child { margin-bottom: 0; }
/* Di dalam satu baris (mis. "Dari · Sampai · Terapkan"), jarak bawah itu ikut
   dihitung saat baris merapatkan isinya ke bawah — tombolnya lalu rata dengan
   JARAKNYA, bukan dengan kotaknya, dan tampak turun 16px. */
.baris > .bidang { margin-bottom: 0; }

label { font-weight: 650; font-size: 0.88rem; }
.wajib::after { content: " *"; color: var(--danger-link); }

input[type="text"], input[type="tel"], input[type="email"], input[type="number"],
input[type="password"], input[type="date"], input[type="datetime-local"], input[type="time"], input[type="search"],
input[type="url"], select, textarea {
  width: 100%;
  padding: 10px 13px;
  border: 1px solid var(--border-strong);
  border-radius: var(--sudut-kecil);
  background: var(--surface);
  color: var(--text);
  font: inherit;
  font-size: 0.95rem;
  transition: border-color var(--alur), box-shadow var(--alur);
}

textarea { min-height: 86px; resize: vertical; line-height: 1.55; }
select { cursor: pointer; }

input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(var(--accent-rgb), 0.22);
}

input[aria-invalid="true"], select[aria-invalid="true"], textarea[aria-invalid="true"] {
  border-color: var(--danger);
  box-shadow: 0 0 0 3px rgba(var(--danger-rgb), 0.18);
}

input::placeholder, textarea::placeholder { color: var(--text-muted); opacity: 0.75; }

input[type="file"] {
  width: 100%;
  padding: 9px;
  border: 1px dashed var(--border-strong);
  border-radius: var(--sudut-kecil);
  background: var(--surface-2);
  font: inherit;
  font-size: 0.88rem;
}

.pesan-galat { color: var(--danger-link); font-size: 0.83rem; font-weight: 600; }

.teks-bahaya { color: var(--danger-link); }
.petunjuk { color: var(--text-muted); font-size: 0.83rem; }

/* Petunjuk berlangkah yang muncul hanya ketika jalan pintasnya tidak bisa
   dipakai - misalnya tombol lokasi otomatis, yang diblokir browser di
   sambungan http://. Diberi kotak supaya terbaca sebagai satu petunjuk utuh
   dan bukan sebagai kalimat yang tercecer di bawah kolom isian. */
/* Satu temuan pemeriksaan data. Diberi garis pemisah supaya beberapa temuan
   di dalam satu panel tidak terbaca sebagai satu paragraf panjang. */
.periksa-temuan {
  margin-top: 10px;
  padding-top: 10px;
  border-top: var(--garis);
}

.petunjuk-langkah {
  margin-top: 8px;
  padding: 10px 12px;
  border: var(--garis);
  border-radius: var(--sudut-kecil);
  background: var(--bg-soft);
}

.petunjuk-langkah p { margin: 0 0 6px; }
.petunjuk-langkah p:last-child { margin-bottom: 0; }
.petunjuk-langkah ol { margin: 0 0 6px; padding-left: 1.4em; }
.petunjuk-langkah li { margin-bottom: 3px; }

.pilihan {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
}

.pilihan label {
  flex: 1;
  min-width: 170px;
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 12px 14px;
  border: 1px solid var(--border-strong);
  border-radius: var(--sudut-kecil);
  background: var(--surface);
  cursor: pointer;
  font-weight: 600;
  transition: border-color var(--alur), background var(--alur);
}

.pilihan label:hover { border-color: var(--accent); }
.pilihan input:checked + span { color: var(--accent-link); }
.pilihan label:has(input:checked) {
  border-color: var(--accent);
  background: rgba(var(--accent-rgb), 0.1);
}

/* Cara terima yang tidak berlaku di depot terpilih. Tetap TERLIHAT — pembeli
   harus tahu pilihan itu ada dan kenapa ia tidak bisa dipakai di cabang ini.
   Alasannya ditulis di #catatan-antar, tepat di bawah barisan pilihan. */
.pilihan label:has(input:disabled) {
  opacity: 0.5;
  cursor: not-allowed;
}

.pilihan label:has(input:disabled):hover { border-color: var(--border-strong); }

.pilihan input { margin-top: 3px; accent-color: var(--accent); flex-shrink: 0; }
.pilihan span { display: flex; flex-direction: column; gap: 2px; }
.pilihan small { font-weight: 500; color: var(--text-muted); }

.centang { display: flex; align-items: center; gap: 9px; font-weight: 600; cursor: pointer; }
.centang input { width: 17px; height: 17px; accent-color: var(--accent); cursor: pointer; }

.jumlah {
  display: inline-flex;
  align-items: center;
  border: 1px solid var(--border-strong);
  border-radius: 999px;
  overflow: hidden;
  background: var(--surface);
}

.jumlah button {
  width: 34px;
  height: 34px;
  border: 0;
  background: transparent;
  color: var(--text);
  font-size: 1.15rem;
  font-weight: 700;
  cursor: pointer;
  line-height: 1;
}

.jumlah button:hover { background: rgba(var(--accent-rgb), 0.14); }

.jumlah input {
  width: 52px;
  border: 0;
  text-align: center;
  padding: 6px 0;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  background: transparent;
}

.jumlah input:focus { box-shadow: none; outline: none; }

/* ------------------------------------------------------------------ *
 * Tabel
 * ------------------------------------------------------------------ */

.tabel-bungkus { overflow-x: auto; -webkit-overflow-scrolling: touch; }

/* KOLOM TOMBOL MENEMPEL DI KANAN. Tabel yang lebih lebar dari panelnya
   ("Pesanan" di 1024px: 1067px dalam 967px; "Pengguna" dengan nama depot
   panjang: 1450px dalam 1138px) dulu menaruh satu-satunya tombol — Buka,
   Ubah — di luar layar, dan barisnya sendiri tidak bisa ditekan. */
.tabel-bungkus td:last-child:has(> .tbl, > .aksi-tabel, > .baris-rapat) {
  position: sticky;
  right: 0;
  background: var(--surface);
  box-shadow: -8px 0 8px -8px var(--border-strong);
}

/* Kode pesanan, SKU, dan nama pengguna: huruf lebar-tetap, dan tidak pernah
   dipenggal. Di ponsel kolom KODE hanya kebagian 83px dan kode sepanjang
   QB-260906-CBT8 pecah menjadi tiga baris - satu baris tabel jadi setinggi
   111px, sementara kodenya sendiri jadi sulit dibaca sekali lihat. Tabelnya
   toh sudah bisa digeser ke samping, jadi biarkan lebar yang mengalah. */
.kode {
  font-family: var(--font-angka);
  white-space: nowrap;
}

/* Nilai pendek yang utuh sebagai satu kesatuan - tanggal, misalnya. Di ponsel
   "6 September 2026" pecah menjadi tiga baris dan sendirian membuat satu baris
   tabel setinggi 111px. */
.tanpa-penggal { white-space: nowrap; }

/* Keterangan bahwa tabelnya masih bisa digeser. Hanya muncul kalau memang
   tidak muat - dinyalakan dari JavaScript, bukan dari lebar layar, supaya
   tidak pernah menjanjikan kolom yang sebenarnya sudah kelihatan semua. */
.tabel-petunjuk {
  padding: 7px 12px;
  border-top: var(--garis);
  font-size: 0.78rem;
  color: var(--text-muted);
  background: var(--surface-2);
}

table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.9rem;
}

th, td {
  padding: 10px 12px;
  text-align: left;
  border-bottom: var(--garis);
  vertical-align: middle;
}

th {
  font-weight: 700;
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-muted);
  background: var(--surface-2);
  white-space: nowrap;
  position: sticky;
  top: 0;
  z-index: 1;
}

tbody tr:hover { background: rgba(var(--accent-rgb), 0.06); }

/* Urut & saring tabel — lihat pasangUrutSaring() di admin.js. */
.tabel-alat {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  padding: 10px 12px;
  border-bottom: var(--garis);
}
.tabel-alat input,
.tabel-alat select { width: auto; min-width: 150px; max-width: 260px; margin: 0; }
.tabel-alat input { flex: 1 1 200px; }
.tabel-hitungan:empty { display: none; }
th.bisa-urut { cursor: pointer; user-select: none; }
th.bisa-urut:hover,
th.bisa-urut:focus-visible { color: var(--text); }
th.bisa-urut::after { content: ' ↕'; opacity: 0.35; }
th.bisa-urut[aria-sort='ascending']::after { content: ' ▲'; opacity: 1; }
th.bisa-urut[aria-sort='descending']::after { content: ' ▼'; opacity: 1; }
@media (max-width: 560px) {
  .tabel-alat input,
  .tabel-alat select { max-width: none; flex: 1 1 100%; }
}
tbody tr:last-child td { border-bottom: 0; }

/* ------------------------------------------------------------------ *
 * BARIS BERWARNA — dipakai daftar "Perlu ditelepon" di Panel Sales.
 *
 * Warnanya SANGAT MUDA (0,07–0,10) dengan sengaja. Baris tabel yang diwarnai
 * pekat membuat tulisan di atasnya sulit dibaca dan membuat seluruh daftar
 * terbaca sebagai peringatan — padahal yang ingin ditunjukkan justru BEDA
 * antar barisnya. Lencana angkanya yang membawa warna penuh; barisnya cukup
 * memberi nada.
 *
 * Garis kiri yang tebal itu yang sebenarnya bekerja: ia terbaca bahkan waktu
 * layarnya dilihat sekilas, dan tidak bergantung pada kemampuan membedakan
 * warna — merah dan kuning adalah pasangan yang paling sering tertukar bagi
 * mata yang buta warna merah-hijau, jadi ketebalannya dibuat berbeda juga.
 * ------------------------------------------------------------------ */
tbody tr.baris-ingat td { background: rgba(var(--warning-rgb), 0.07); }
tbody tr.baris-ingat td:first-child { box-shadow: inset 3px 0 0 var(--warning-link); }
tbody tr.baris-bahaya td { background: rgba(var(--danger-rgb), 0.1); }
tbody tr.baris-bahaya td:first-child { box-shadow: inset 5px 0 0 var(--danger-link); }
tbody tr.baris-ingat:hover td,
tbody tr.baris-bahaya:hover td { filter: brightness(0.98); }

td.angka, th.angka { text-align: right; font-variant-numeric: tabular-nums; }

/* Kolom uang tidak boleh dipatahkan. "Rp 307.000" yang terbelah menjadi "Rp"
   lalu "307.000" di baris berikutnya membuat kolomnya terbaca dua kali lebih
   tinggi dari perlunya, dan angkanya sendiri jadi sulit disejajarkan dengan
   angka di baris atas-bawahnya. */
td.angka, th.angka { white-space: nowrap; }

/* SEPASANG TOMBOL KEPUTUSAN DI DALAM TABEL.

   Dulu keduanya hanya .baris-rapat yang boleh melipat: di kolom sempit "Terima"
   dan "Tolak" bertumpuk tegak, lebarnya mengikuti panjang katanya masing-masing,
   dan tiap baris tabel jadi setinggi dua tombol. Yang terlihat bukan sepasang
   pilihan, melainkan dua tombol yang kebetulan berdekatan.

   Sekarang: satu baris, tidak melipat, lebar sama, dan rata kanan sejajar
   dengan kolom keputusan di baris lain. */
.aksi-tabel {
  display: flex;
  gap: 6px;
  justify-content: flex-end;
  white-space: nowrap;
}

.aksi-tabel > .tbl { min-width: 74px; justify-content: center; }

/* Di layar sempit tabelnya digeser mendatar, bukan diperas — jadi pasangan ini
   tetap satu baris di sana. Yang melipat adalah tabelnya, dan itu memang
   perilaku yang sudah ada. */

/* Nama berkas bisa sepanjang "WhatsApp Image 2026-08-24 at 11.00.18 AM.jpeg".
   Dibiarkan utuh, ia memaksa kolom berkas melebar dan memeras kolom keputusan
   sampai tombolnya bertumpuk. Nama lengkapnya tetap terbaca lewat title. */
/* Nama berkas dan tombol Unduh TETAP SATU BARIS.

   Dibiarkan melipat, "Unduh" terlempar ke bawah nama berkas dan barisnya
   menjadi 111px sementara baris bernama pendek hanya 74px — tabel yang
   tingginya naik-turun tanpa sebab yang bisa dilihat pembacanya. Yang mengalah
   adalah nama berkasnya: ia dipotong, dan nama lengkapnya ada di title. */
.sel-berkas {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: nowrap;
}

.nama-berkas {
  max-width: 220px;
  min-width: 0;
  flex: 0 1 auto;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  display: inline-block;
  vertical-align: bottom;
}

/* Tombol Unduh tidak ikut menyusut — ia satu kata pendek, dan yang menyusut
   seharusnya nama berkas yang memang panjang. */
.sel-berkas > a { flex: 0 0 auto; }

/* ------------------------------------------------------------------ *
 * Lencana & status
 * ------------------------------------------------------------------ */

.lencana {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 0.76rem;
  font-weight: 700;
  white-space: nowrap;
  background: rgba(var(--text-rgb), 0.09);
  color: var(--text);
}

.lencana-accent { background: rgba(var(--accent-rgb), 0.16); color: var(--accent-link); }
.lencana-sukses { background: rgba(var(--success-rgb), 0.18); color: var(--success-link); }
.lencana-ingat { background: rgba(var(--warning-rgb), 0.2); color: var(--warning-link); }
.lencana-bahaya { background: rgba(var(--danger-rgb), 0.16); color: var(--danger-link); }
.lencana-kedua { background: rgba(var(--secondary-rgb), 0.18); color: var(--text); }

.jejak { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0; }

.jejak li {
  position: relative;
  padding: 0 0 16px 24px;
  border-left: 2px solid var(--border);
}

.jejak li:last-child { border-left-color: transparent; padding-bottom: 0; }

.jejak li::before {
  content: "";
  position: absolute;
  left: -6px;
  top: 5px;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 0 3px rgba(var(--accent-rgb), 0.2);
}

.langkah {
  display: flex;
  gap: 14px;
  align-items: flex-start;
}

/* Alur "Cara Memesan": kartu bergambar, satu langkah per kartu. */
/*
 * SATU KOLOM LEBAR, BUKAN LIMA KOLOM SEMPIT.
 *
 * Dulu lima langkah berdiri sejajar pada kolom selebar ~190px, yang di layar
 * sedang menyusut jadi sekitar 110px. Kalimat panjang di kolom selebar itu
 * patah menjadi belasan baris berisi 3-4 kata. Justru pembaca yang paling
 * membutuhkan panduan ini — orang yang belum pernah memesan — yang paling
 * dilelahkan bentuk itu.
 *
 * Satu kolom juga berarti bentuk ini tidak perlu ditata ulang untuk ponsel:
 * yang berubah cuma lebarnya.
 */
.langkah-alur {
  list-style: none;
  margin: 18px 0 0;
  padding: 0;
  display: grid;
  gap: 10px;
  /* Dibatasi supaya barisnya tidak jadi terlalu panjang untuk dibaca. Ukuran
     ini kira-kira 75 huruf per baris pada tulisan seukuran ini — di atas itu
     mata kehilangan awal baris berikutnya. */
  max-width: 760px;
}

.langkah-baris {
  background: var(--surface);
  border: var(--garis);
  border-radius: var(--sudut);
  box-shadow: var(--bayang);
  padding: 16px 18px;
  display: flex;
  gap: 14px;
  align-items: flex-start;
}

.langkah-teks h3 {
  margin: 1px 0 3px;
  font-size: 1rem;
}

.langkah-teks p { margin: 0; }

.langkah-nomor {
  flex-shrink: 0;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: var(--accent);
  color: var(--accent-contrast);
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 800;
  font-size: 0.95rem;
}

/* ------------------------------------------------------------------ *
 * Cara membayar — nominal dan rekening yang bisa disalin
 *
 * Pelanggan di halaman ini SUDAH memutuskan membeli. Yang ia butuhkan tinggal
 * dua hal, dan keduanya dipakai di aplikasi LAIN (aplikasi banknya): berapa,
 * dan ke mana. Jadi keduanya dibuat besar, terbaca sekilas, dan bisa disalin
 * dengan satu ketukan — yang mengetik ulang dari ingatan akan salah satu digit
 * cepat atau lambat.
 * ------------------------------------------------------------------ */

/* Nominalnya berdiri di atas latar polos, TANPA kotak sendiri: kalau ia ikut
   berkotak, dua kotak bertumpuk di satu panel dan tidak ada lagi yang menonjol.
   Yang perlu menonjol angkanya, dan ukuran hurufnya sudah mengerjakan itu. */
.bayar-nominal {
  margin-bottom: 14px;
}

.bayar-angka {
  font-size: 1.9rem;
  font-weight: 800;
  color: var(--accent-link);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
}

/* Kartu rekening: BERWARNA dan bergaris putus-putus.
   Warnanya memisahkannya dari isi panel yang lain, dan garis putus-putus
   membacanya sebagai "sesuatu untuk disalin" — bukan sebagai kotak isian yang
   menunggu diketik. Di panel yang isinya hampir semuanya formulir, perbedaan
   itu yang membuat mata menemukannya lebih dulu. */
.bayar-rekening {
  margin-bottom: 10px;
  background: rgba(var(--accent-rgb), 0.06);
  border: 1px dashed rgba(var(--accent-rgb), 0.45);
}

/* Nomor rekening: RENGGANG dan bersatuan lebar.
   Deretan angka panjang tanpa jeda adalah deretan yang salah dibaca; jarak
   antarhuruf memberi mata tempat berpijak, dan angka yang lebarnya sama
   membuat dua rekening berjajar bisa dibandingkan sekilas. */
.bayar-nomor {
  /* Tidak dipatahkan di tanda hubung ("…-1234-" / "5678" terbaca sebagai dua
     nomor): satu baris, mengecil di layar sempit, dan bisa digeser kalau
     nomornya memang sangat panjang. */
  font-size: clamp(1rem, 4.6vw, 1.3rem);
  white-space: nowrap;
  overflow-x: auto;
  font-weight: 800;
  letter-spacing: 0.09em;
  font-variant-numeric: tabular-nums;
  margin: 2px 0 1px;
}

/* ------------------------------------------------------------------ *
 * KARTU QRIS di halaman pesanan.
 *
 * LATAR GAMBARNYA SELALU PUTIH, juga di tema gelap. QRIS dibaca kamera, bukan
 * mata: kode hitam di atas latar gelap kehilangan kontras yang dibutuhkan
 * pemindai, dan tema gelap yang membuat halaman nyaman dibaca justru membuat
 * kodenya gagal dipindai. Bingkai putihnya juga memberi "zona sunyi" di
 * sekeliling kode — ruang kosong yang memang disyaratkan agar QR terbaca.
 *
 * Lebarnya dibatasi 280 px: cukup besar untuk dipindai dari HP lain yang
 * dipegang di depan layar, dan tidak menjadi raksasa di layar laptop.
 * ------------------------------------------------------------------ */
.bayar-qris {
  display: grid;
  justify-items: center;
  gap: 10px;
  margin-bottom: 10px;
  text-align: center;
  background: rgba(var(--accent-rgb), 0.06);
  border: 1px dashed rgba(var(--accent-rgb), 0.45);
}
.bayar-qris-gambar {
  width: 100%;
  max-width: 280px;
  height: auto;
  padding: 12px;
  background: var(--latar-pindai);
  border-radius: var(--sudut-kecil);
  box-shadow: 0 1px 4px rgba(var(--text-rgb), 0.08);
}
.bayar-qris-nama { font-size: 1rem; }
/* Peringatan penipuan di langkah bayar (QRIS no. 3 dan catatan transfer bank).
   --danger-link: merah yang ditakar untuk TEKS di atas surface, bukan --danger
   (lihat .hitung-mundur). */
.awas-penipuan { color: var(--danger-link); }
.awas-penipuan b { font-weight: 800; }
.bayar-awas { margin: 10px 2px 0; line-height: 1.5; }
.bayar-qris-langkah {
  text-align: left;
  margin: 0;
  padding-left: 1.2em;
  max-width: 34em;
  display: grid;
  gap: 3px;
}

/* QRIS di panel admin: dipisah dari rekening di atasnya dengan garis, dan
   pratinjaunya memakai latar putih yang sama dengan yang dilihat pembeli —
   supaya yang dinilai admin adalah persis apa yang akan dipindai. */
.bagian-qris {
  margin-top: 26px;
  padding-top: 18px;
  border-top: var(--garis);
}
.bagian-qris h3 { margin: 0 0 10px; }
.qris-kotak {
  display: flex;
  align-items: center;
  min-height: 60px;
}
.qris-pratinjau {
  width: 180px;
  height: auto;
  padding: 8px;
  background: var(--latar-pindai);
  border: var(--garis);
  border-radius: var(--sudut-kecil);
}

/* Pemilih berkas: input aslinya disembunyikan DARI MATA, bukan dari papan
   ketik. `display:none` akan membuatnya tidak bisa difokus sama sekali dan
   labelnya tidak lagi bisa dicapai dengan Tab.

   PEMILIHNYA HARUS MENYEBUT input[type="file"], bukan kelasnya saja. Aturan
   umum `input[type="file"]` di berkas ini berkekuatan (0,1,1) — pemilih atribut
   DITAMBAH nama elemen — sedangkan `.berkas-asli` sendirian cuma (0,1,0). Jadi
   `width: 100%` dari aturan umum itu MENANG, dan input yang dikira selebar satu
   piksel sebenarnya selebar panelnya.

   Akibatnya terukur: elemennya menjulur sampai 1193px pada layar 1024px, dan
   halaman pesanan bisa digeser ke kanan sejauh 169px tanpa ada yang terlihat di
   sana. */
input[type="file"].berkas-asli {
  position: absolute;
  width: 1px;
  height: 1px;
  min-width: 0;
  padding: 0;
  margin: 0;
  border: 0;
  overflow: hidden;
  /* Dipotong habis, bukan sekadar dibuat tembus pandang: sebagian browser
     tetap menyediakan tempat untuk isi yang meluap dari kotak sekecil ini. */
  clip-path: inset(50%);
  opacity: 0;
  pointer-events: none;
}

.pilih-berkas {
  display: block;
  text-align: center;
  cursor: pointer;
  border-style: dashed;
}

.berkas-asli:focus-visible + .pilih-berkas {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* ------------------------------------------------------------------ *
 * Panduan kerja (SOP) di tab Bantuan
 *
 * Bentuknya sama dengan langkah "Cara Memesan" di beranda, dan itu disengaja:
 * orang yang sudah membaca satu tidak perlu belajar membaca yang lain.
 * ------------------------------------------------------------------ */

.sop-langkah {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 10px;
  /* Dibatasi supaya barisnya tidak jadi terlalu panjang untuk dibaca. */
  max-width: 820px;
}

.sop-baris {
  display: flex;
  gap: 13px;
  align-items: flex-start;
  padding: 14px 16px;
  border: var(--garis);
  border-radius: var(--sudut);
  background: var(--surface-2);
}

.sop-nomor {
  flex-shrink: 0;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--accent);
  color: var(--accent-contrast);
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 800;
  font-size: 0.88rem;
}

.sop-isi { min-width: 0; }
.sop-isi h4 { margin: 3px 0 6px; font-size: 0.97rem; }
.sop-isi ul { margin: 0; padding-left: 18px; }
.sop-isi li { margin-bottom: 5px; line-height: 1.55; }
.sop-isi li:last-child { margin-bottom: 0; }

/* Kotak isian yang angkanya ditentukan sistem, bukan diketik orang. Dibuat
   TERLIHAT terkunci: kotak yang tampak seperti kotak isian biasa tapi menolak
   diketik terasa seperti halaman yang rusak, bukan seperti aturan. */
/* PEMILIHNYA HARUS MENYEBUT input[type="text"], sama seperti .berkas-asli di
   bawah dan dengan alasan yang sama: aturan umum di baris 818 berkekuatan
   (0,1,1), jadi `.nilai-terkunci` sendirian (0,1,0) kalah dan kotaknya tetap
   tergambar putih seperti kotak isian biasa. Terukur di layar sebelum baris
   ini ditulis. */
input[type="text"].nilai-terkunci {
  background: var(--surface-2);
  color: var(--text-muted);
  cursor: default;
}
input[type="text"].nilai-terkunci:focus {
  outline: none;
  box-shadow: none;
  border-color: var(--border);
}

.sop-catatan { margin-top: 14px; }
.sop-catatan ul { margin: 6px 0 0; padding-left: 18px; }
.sop-catatan li { margin-bottom: 4px; }

/* SATU PANDUAN = SATU BAGIAN YANG BISA DILIPAT.
   Dipasang di atas <details>/<summary> bawaan, jadi yang diatur di sini hanya
   tampilannya: membuka, menutup, papan ketik, dan pembaca layar sudah ditangani
   peramban. */
.sop-kepala {
  cursor: pointer;
  user-select: none;
  /* Segitiga bawaan dibuang di kedua mesin peramban — Firefox lewat
     list-style, Safari/Chrome lewat ::-webkit-details-marker — lalu diganti
     tanda panah sendiri yang ikut berputar. Kalau salah satu baris ini hilang,
     yang muncul DUA tanda, bukan satu. */
  list-style: none;
}
.sop-kepala::-webkit-details-marker { display: none; }
.sop-kepala:hover { background: var(--surface-3, var(--surface-2)); }
.sop-kepala::after {
  content: '';
  flex: none;
  margin-left: auto;
  width: 8px;
  height: 8px;
  border-right: 2px solid var(--text-muted);
  border-bottom: 2px solid var(--text-muted);
  transform: rotate(45deg) translate(-2px, -2px);
  transition: transform var(--alur);
}
.sop-panel[open] > .sop-kepala::after { transform: rotate(-135deg) translate(-2px, -2px); }
/* Ringkasan turun ke baris kedua: ia yang memberi tahu isi bagian yang sedang
   tertutup, jadi ia harus terbaca justru saat bagiannya belum dibuka. */
.sop-ringkas {
  flex-basis: 100%;
  /* ::after selalu menjadi anak TERAKHIR, jadi tanpa order ini tanda panahnya
     terdorong ke bawah ringkasan dan menempati baris ketiga sendirian — paling
     kelihatan di layar ponsel, tempat ringkasannya memang selalu pecah. */
  order: 1;
}
.sop-panel > .panel-isi { padding-top: 16px; }

/* ------------------------------------------------------------------ *
 * Pemberitahuan
 * ------------------------------------------------------------------ */

.info {
  padding: 12px 15px;
  border-radius: var(--sudut-kecil);
  border-left: 4px solid var(--accent);
  background: rgba(var(--accent-rgb), 0.1);
  font-size: 0.9rem;
}

.info-sukses { border-left-color: var(--success); background: rgba(var(--success-rgb), 0.12); }

/* ------------------------------------------------------------------ *
 * KARTU DEPOT di checkout — tepat di bawah titik lokasi.
 *
 * Satu kotak tipis, bukan kotak berwarna penuh: di atasnya sudah ada kotak
 * jarak dan ongkir dari titik lokasi, dan dua kotak tebal bertumpuk membaca
 * sebagai dua peringatan. Garis kirinya menyamai kartu .info supaya terbaca
 * sebagai "keterangan", bukan "masalah".
 *
 * Jaraknya yang paling besar, karena itulah yang ingin diketahui pembeli
 * sesudah menaruh titiknya; alamat depotnya sesudah itu, lebih kecil.
 * ------------------------------------------------------------------ */
.kartu-depot {
  margin-top: 8px;
  padding: 10px 14px;
  border-radius: var(--sudut-kecil);
  border: 1px solid rgba(var(--accent-rgb), 0.18);
  border-left: 4px solid var(--accent);
  background: rgba(var(--accent-rgb), 0.04);
  display: grid;
  gap: 2px;
}
.kartu-depot-jarak { font-size: 1rem; }
/* Belum ada jarak: yang tertulis kalimat petunjuk, bukan angka — jadi ukurannya
   ukuran petunjuk, bukan ukuran jawaban. */
.kartu-depot-jarak.kartu-depot-menunggu { font-size: inherit; }
/* Blok depot dipindah-pindah checkout: ke ujung bagian antar (di bawah titik
   lokasi), atau ke awal bagian ambil. Di ujung ia menjadi :last-child dan
   kehilangan jarak bawahnya, sehingga kartunya menempel ke "Tanggal
   pengiriman". Id-nya mengalahkan aturan .bidang:last-child. */
#bidang-depot { margin-bottom: 15px; }
.info-ingat { border-left-color: var(--warning); background: rgba(var(--warning-rgb), 0.14); }
.info-bahaya { border-left-color: var(--danger); background: rgba(var(--danger-rgb), 0.11); }

/* Sisa waktu bayar. Dipisah ke barisnya sendiri dan diberi angka bergaya
   monospasi: angka detik yang berubah tiap detik dengan lebar huruf yang
   berbeda-beda membuat seluruh baris bergoyang ke kiri-kanan. */
.sisa-waktu { margin-top: 6px; }
.hitung-mundur {
  font-family: var(--font-angka);
  /* --danger-link, BUKAN --danger. Yang pertama warna merah yang memang
     ditakar untuk TEKS di berkas ini (dipakai juga oleh .pesan-galat dan
     .lencana-bahaya); yang kedua untuk garis dan bidang, dan terlalu muda
     dibaca sebagai huruf. */
  color: var(--danger-link);
  /* BESAR DAN TEBAL — dan ini bukan selera.

     Angkanya duduk di atas kotak .info-ingat, yaitu warna warning 14% di atas
     surface. Yang dijamin themes.js hanya kontras danger-link terhadap surface
     POLOS, jadi semburat kuning itu memakannya. Diukur di keenam tema:

         kertas 5.80   malam 4.67   brand/tosca/daun 4.53   laut 4.14

     Tema "laut" jatuh di bawah 4.5, ambang AA untuk teks biasa. Di atas
     18.66px DAN tebal, ambangnya 3.0 — dan yang paling tipis pun, 4.14, ada
     jauh di atasnya. Jadi ukuran ini yang membuat merahnya boleh dipakai.

     1.25rem = 20px. Menurunkannya ke bawah 18.66px mengembalikan cacatnya
     tanpa satu pun tanda di layar. */
  font-size: 1.25rem;
  font-weight: 700;
  line-height: 1.2;
}

.pesan-layar {
  position: fixed;
  right: 16px;
  bottom: 16px;
  z-index: 100;
  display: flex;
  flex-direction: column;
  gap: 8px;
  max-width: min(400px, calc(100vw - 32px));
}

.pesan {
  padding: 12px 16px;
  border-radius: var(--sudut-kecil);
  background: var(--surface);
  border: var(--garis);
  border-left: 4px solid var(--accent);
  box-shadow: var(--bayang-kuat);
  font-size: 0.9rem;
  font-weight: 600;
  animation: masuk var(--alur);
}

.pesan-sukses { border-left-color: var(--success); }
.pesan-galat { border-left-color: var(--danger); }

@keyframes masuk {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: translateY(0); }
}

.kosong {
  text-align: center;
  padding: 44px 20px;
  color: var(--text-muted);
}

.kosong-ikon { font-size: 2.6rem; margin-bottom: 10px; opacity: 0.6; }

.memuat {
  display: inline-block;
  width: 18px;
  height: 18px;
  border: 2px solid rgba(var(--accent-rgb), 0.3);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: putar 0.7s linear infinite;
}

@keyframes putar { to { transform: rotate(360deg); } }

/* ------------------------------------------------------------------ *
 * Ringkasan biaya
 * ------------------------------------------------------------------ */

.ringkasan { display: flex; flex-direction: column; gap: 9px; }

.ringkasan-baris {
  display: flex;
  justify-content: space-between;
  gap: 14px;
  font-size: 0.93rem;
}

/* ANAK LANGSUNG (">"): dulu turunan mana pun, sehingga nama barang tanpa
   baris tambahan ikut tebal sementara yang lain tidak. */
.ringkasan-baris > span:last-child { font-variant-numeric: tabular-nums; font-weight: 650; }
/* Nominal di kanan tidak dipatahkan: "Rp" di satu baris dan angkanya di baris
   berikutnya terbaca sebagai dua angka. Yang boleh melipat teks di kirinya. */
.ringkasan-baris > span:last-child { white-space: nowrap; }
.ringkasan-baris > span:first-child { min-width: 0; overflow-wrap: anywhere; }
/* BARIS KETERANGAN (alamat, wilayah, catatan) BUKAN NOMINAL: boleh melipat.
   Dulu ikut "nowrap" di atas, dan alamat panjang terpotong di tepi panel —
   1317px di baris selebar 298px. */
.ringkasan-baris.baris-teks > span:last-child {
  white-space: normal;
  overflow-wrap: anywhere;
  text-align: right;
  min-width: 0;
}
/* ...sementara labelnya ("Alamat", "Catatan") tetap utuh di kiri. */
.ringkasan-baris.baris-teks > span:first-child { flex-shrink: 0; white-space: nowrap; }

.ringkasan-total {
  display: flex;
  justify-content: space-between;
  gap: 14px;
  padding-top: 11px;
  border-top: 2px solid var(--border-strong);
  font-size: 1.15rem;
  font-weight: 800;
}

.ringkasan-total span:last-child { color: var(--accent-link); font-variant-numeric: tabular-nums; }

/* Potongan voucher: hijau, supaya terbaca sebagai sesuatu yang DIDAPAT, bukan
   biaya lain yang ikut ditagih. */
.ringkasan-voucher span { color: var(--success-link); }

/* Kotak voucher di ringkasan checkout: garis putus-putus, seperti kupon —
   bentuk yang langsung dikenali pembeli tanpa perlu dibaca. */
.kotak-voucher {
  margin-top: 14px;
  padding: 10px 12px;
  border: 1px dashed rgba(var(--success-rgb), 0.55);
  border-radius: var(--sudut-kecil);
  background: rgba(var(--success-rgb), 0.06);
}
.kotak-voucher input { flex: 1; min-width: 0; }

/* Daftar centang produk di formulir voucher: dibatasi tingginya dan bisa
   digulir, supaya toko dengan puluhan produk tidak membuat dialognya
   memanjang melewati layar. */
.kotak-produk-voucher {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 4px 12px;
  max-height: 220px;
  overflow-y: auto;
  padding: 8px 10px;
  border: var(--garis);
  border-radius: var(--sudut-kecil);
}

.sisi-lengket { position: sticky; top: 84px; }

/* ------------------------------------------------------------------ *
 * Baris keranjang
 * ------------------------------------------------------------------ */

.item {
  display: grid;
  grid-template-columns: 76px minmax(0, 1fr) auto;
  gap: 14px;
  align-items: center;
  padding: 14px 0;
  border-bottom: var(--garis);
}
/* Isi kolom boleh menyempit: nama tanpa spasi dulu melebarkan barisnya sampai
   tombol Hapus terdorong ke luar layar. */
.item > * { min-width: 0; overflow-wrap: anywhere; }

.item:last-child { border-bottom: 0; }

.item-gambar {
  width: 76px;
  height: 76px;
  border-radius: var(--sudut-kecil);
  object-fit: cover;
  background: var(--surface-2);
}

/* Baris pada rincian pesanan tidak punya gambar produk — hanya teks. */
.item-tanpa-gambar { grid-template-columns: minmax(0, 1fr) auto; }

.item-kanan { text-align: right; display: flex; flex-direction: column; gap: 6px; align-items: flex-end; }
/* Nominal di kolom kanan tidak dipatahkan ("Rp" dan angkanya di dua baris). */
.item-kanan > .angka { white-space: nowrap; }

@media (max-width: 620px) {
  .item { grid-template-columns: 56px minmax(0, 1fr); }
  /* Baris tanpa gambar harus ikut dinolkan kolom gambarnya di sini juga.
     Aturan .item di atas datang belakangan dengan kekhususan yang sama, jadi
     tanpa baris ini ia menang dan menyisakan kolom 56px yang kosong — teks
     nama produk lalu diperas ke lebar 56px dan pecah satu kata per baris. */
  .item-tanpa-gambar { grid-template-columns: minmax(0, 1fr); }
  .item-gambar { width: 56px; height: 56px; }
  .item-kanan { grid-column: 1 / -1; flex-direction: row; align-items: center; justify-content: space-between; }
}

/* ------------------------------------------------------------------ *
 * Tab panel Admin
 * ------------------------------------------------------------------ */

.tab-bar {
  display: flex;
  gap: 2px;
  /* MELIPAT, bukan digeser mendatar. Panel ini punya 14 tab; dengan geser
     mendatar hampir 300px di antaranya tersembunyi di balik bilah gulir yang
     mudah tidak terlihat — tab yang tidak kelihatan sama saja dengan tab yang
     tidak ada. Melipat memang bisa memakan satu baris lagi, tapi tidak pernah
     menyembunyikan apa pun. */
  flex-wrap: wrap;
  row-gap: 4px;
  padding: 5px 0;
  border-bottom: var(--garis);
}

/* Layar sempit tetap digeser: melipat 14 tab di ponsel akan memakan hampir
   sepertiga layar sebelum isinya kelihatan. */
@media (max-width: 700px) {
  .tab-bar {
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: thin;
  }
}

.tab-bar button {
  border: 0;
  background: transparent;
  /* 11px, bukan 12: seluruh 14 tab kelebihan tepat 11px dari lebar isi 1180px,
     dan memangkas 1px per sisi menutupnya tanpa membuat tombolnya terasa
     sempit. Kalau nanti ada tab lagi, .tab-bar akan melipat dengan rapi. */
  padding: 7px 11px;
  border-radius: 999px;
  font: inherit;
  font-weight: 650;
  font-size: 0.86rem;
  color: var(--text-muted);
  cursor: pointer;
  white-space: nowrap;
  transition: background var(--alur), color var(--alur);
}

.tab-bar button:hover { background: rgba(var(--accent-rgb), 0.1); color: var(--text); }
/* Tanda angka di tautan "Panel Admin" kepala situs — di halaman mana pun. */
.tanda-angka {
  display: inline-block;
  min-width: 1.35em;
  margin-left: 6px;
  padding: 1px 6px;
  border-radius: 999px;
  background: var(--danger);
  color: var(--danger-contrast);
  font-size: 0.72rem;
  font-weight: 800;
  line-height: 1.45;
  text-align: center;
}
/* Tanda angka di tab: pesanan Baru / bukti transfer yang belum ditanggapi. */
.tab-bar .tanda-tab {
  display: inline-block;
  min-width: 1.35em;
  margin-left: 6px;
  padding: 1px 6px;
  border-radius: 999px;
  background: var(--danger);
  color: var(--danger-contrast);
  font-size: 0.72rem;
  font-weight: 800;
  line-height: 1.45;
  text-align: center;
  vertical-align: 1px;
}

.tab-bar button[aria-selected="true"] {
  background: var(--accent);
  color: var(--accent-contrast);
}

/* MENU BERKELOMPOK: tiap kelompok membawa judul kecil di atas tabnya, dan
   kelompok dipisah JARAK, bukan garis — garis pemisah ikut terbawa ke awal
   baris begitu kelompoknya melipat. Judulnya sengaja redup dan kecil — ia
   penunjuk arah, bukan tombol. */
.tab-bar.tab-bar-berkelompok {
  align-items: flex-start;
  column-gap: 26px;
  row-gap: 10px;
  padding: 6px 0 10px;
}
.tab-kelompok {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.tab-kelompok-judul {
  padding: 0 11px;
  font-size: 0.68rem;
  font-weight: 750;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
  white-space: nowrap;
  opacity: 0.85;
}
.tab-kelompok-isi { display: flex; flex-wrap: wrap; gap: 2px; }
/* Pemilih menu ponsel: hanya di layar sempit, menggantikan bilah berkelompok. */
.tab-pilih { display: none; }
@media (max-width: 700px) {
  .tab-bar.tab-bar-berkelompok { display: none; }
  .tab-pilih {
    display: block;
    width: 100%;
    margin-top: 16px;
    padding: 11px 14px;
    border: var(--garis);
    border-radius: 12px;
    background: var(--surface);
    color: var(--text);
    font: inherit;
    font-weight: 700;
  }
}

/* ------------------------------------------------------------------ *
 * Bilah bagian di dalam sebuah tab (dipakai halaman Laporan)
 *
 * SENGAJA LEBIH TENANG daripada bilah tab utama di atasnya: ia bagian dari
 * satu tab, bukan saudaranya. Dua bilah yang tergambar sama kuat membuat
 * pembacanya harus berpikir dulu mana yang membawanya ke mana.
 * ------------------------------------------------------------------ */

.bilah-bagian {
  border-bottom: 0;
  margin-bottom: 4px;
  gap: 4px;
  /* Menempel saat digulir: tabel laporan bisa sepanjang beberapa layar, dan
     bilah yang hilang di atas membuat orang menggulir balik hanya untuk
     pindah bagian. */
  position: sticky;
  top: 0;
  z-index: 3;
  background: var(--bg);
  padding-top: 8px;
}

.bilah-bagian button {
  font-size: 0.82rem;
  padding: 6px 12px;
  background: var(--surface-2);
  border: var(--garis);
}

.bilah-bagian button:hover { background: rgba(var(--accent-rgb), 0.12); }

.bilah-bagian button[aria-selected="true"] {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-contrast);
}

/* Isi bagian diberi tinggi minimum supaya berpindah bagian tidak membuat
   halaman melompat-lompat saat tingginya berbeda jauh. */
.bagian-isi { min-height: 50vh; }

/* KELOMPOK BIDANG di dalam satu panel pengaturan.

   Dua belas kolom berderet tanpa pemisah memaksa orang membaca semuanya untuk
   menemukan satu. Garis tipis di atas tiap kelompok memberi tahu di sebelah
   mana ia berada tanpa menambah satu panel pun — panel baru berarti satu layar
   gulungan lagi, dan itu justru keluhan yang sedang diperbaiki. */
.kelompok-bidang + .kelompok-bidang {
  margin-top: 22px;
  padding-top: 18px;
  border-top: var(--garis);
}

.kelompok-bidang > h4 { margin: 0 0 2px; font-size: 0.95rem; }
.kelompok-bidang > p { margin: 0 0 12px; }

/* Pemisah untuk satu judul yang berdiri sendiri, bukan sekelompok kolom. */
h4.kelompok-pisah {
  margin: 26px 0 12px;
  padding-top: 18px;
  border-top: var(--garis);
  font-size: 0.95rem;
}

/* Tinggi minimum supaya halaman tidak mengerut saat isi tab sedang dimuat.
   Yang dicegah di sini pergeseran TEGAK-nya; pergeseran mendatarnya dicegah
   scrollbar-gutter di atas. */
.tab-isi {
  padding-top: 18px;
  min-height: 60vh;
}

.statistik {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 12px;
}

.statistik-kotak {
  padding: 15px 17px;
  border-radius: var(--sudut);
  border: var(--garis);
  background: var(--surface);
}

.statistik-nilai {
  /* Nominal ratusan juta ("Rp 6.989.244.642") dulu meluber 17px ke kartu
     sebelah: ukurannya kini menyesuaikan kartu, dan yang masih terlalu
     panjang dipatahkan di dalam kartunya sendiri. */
  font-size: clamp(1.15rem, 2.2vw, 1.7rem);
  overflow-wrap: anywhere;
  min-width: 0;
  font-weight: 800;
  line-height: 1.15;
  font-variant-numeric: tabular-nums;
  color: var(--accent-link);
}

.statistik-label { font-size: 0.8rem; color: var(--text-muted); font-weight: 600; }

/* Di ponsel keenam kotak ini memakan hampir seluruh layar sebelum tab pertama
   bisa disentuh - diukur pada layar 812px: 530px habis sebelum bilah tabnya.
   Angkanya diperkecil secukupnya supaya nilai rupiah terpanjang tetap muat
   dalam satu baris, sehingga tinggi keenam kotaknya sekalian menjadi rata. */
@media (max-width: 560px) {
  .statistik {
    gap: 8px;
    grid-template-columns: repeat(auto-fit, minmax(138px, 1fr));
  }
  .statistik-kotak { padding: 10px 12px; }
  .statistik-nilai { font-size: 1.2rem; }
  .statistik-label { font-size: 0.74rem; }
}

/* ------------------------------------------------------------------ *
 * Dialog
 * ------------------------------------------------------------------ */

dialog {
  border: var(--garis);
  border-radius: var(--sudut);
  padding: 0;
  background: var(--surface);
  color: var(--text);
  box-shadow: var(--bayang-kuat);
  max-width: min(680px, calc(100vw - 32px));
  width: 100%;
  /* Setinggi-tingginya selayar. Peramban memang sudah membatasi tinggi dialog
     sendiri, dan tanpa batas yang kita akui isinya menyembul melewati kotak
     dialognya lalu terpotong. */
  max-height: calc(100vh - 24px);
  max-height: calc(100dvh - 24px);
}

/* Dialog disusun tegak supaya isinya yang mengalah, bukan tombolnya.
 *
 * Sebelum ini kepala, isi, dan kaki hanya ditumpuk begitu saja: pada pesanan
 * dengan enam tombol aksi di layar ponsel, kakinya setinggi 205px dan ujungnya
 * jatuh 19px di luar dialog - tombol terakhir terpotong dan tidak bisa
 * disentuh. Dengan susunan ini kepala dan kaki selalu utuh, dan bagian isinya
 * yang menyusut lalu digulir.
 */
dialog[open] {
  display: flex;
  flex-direction: column;
}

.dialog-kepala,
.dialog-kaki { flex: none; }

dialog::backdrop { background: rgba(var(--text-rgb), 0.45); }

.dialog-kepala {
  padding: 15px 20px;
  border-bottom: var(--garis);
  display: flex;
  align-items: center;
  gap: 10px;
}

.dialog-kepala h3 { margin: 0; }
.dialog-isi {
  padding: 20px;
  max-height: 66vh;
  overflow-y: auto;
  /* Boleh menyusut di bawah tinggi isinya kalau dialognya sudah mentok. */
  flex: 0 1 auto;
  min-height: 0;
}

/* Pratinjau bukti transfer. Foto struk biasanya potret dan tinggi, jadi yang
   dibatasi tingginya — lebarnya mengikuti supaya tidak terpotong. */
.pratinjau-bukti {
  display: block;
  max-width: 100%;
  max-height: 54vh;
  margin: 0 auto;
  object-fit: contain;
  border: var(--garis);
  border-radius: var(--sudut-kecil);
  background: var(--surface-2);
}

/* Foto struk yang lebih kecil dari kotaknya ditampilkan seukuran aslinya —
   dipaksa selebar dialog hanya membuatnya buram. */
img.pratinjau-bukti { width: auto; }
iframe.pratinjau-bukti { width: 100%; height: 54vh; }

.dialog-kaki {
  padding: 14px 20px;
  border-top: var(--garis);
  display: flex;
  gap: 9px 14px;
  /* Dibungkus, bukan meluber: sebuah pesanan bisa punya banyak tombol sekaligus
     (perpindahan status, pembayaran, pesan, cetak).

     DUA KELOMPOK, bukan satu deret. Dulu seluruhnya satu deret dengan
     justify-content: flex-end — tujuh tombol berbaris tanpa urutan yang berarti,
     dan yang terakhir terlempar sendirian ke baris kedua, rata kanan, seolah
     tidak sengaja. Sekarang pembungkusannya jatuh di ANTARA kelompok. */
  flex-wrap: wrap;
  align-items: center;
  background: var(--surface-2);
}

.kaki-alat,
.kaki-aksi {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  align-items: center;
}

/* Perkakas di kiri, keputusan di kanan. Yang mengubah data tidak boleh
   bertetangga dengan yang cuma membuka nota. */
.kaki-aksi { margin-left: auto; }

@media (max-width: 620px) {
  /* Di ponsel keduanya menjadi dua baris penuh, dan yang MENGUBAH DATA di
     bawah — paling dekat dengan jempol, dan terbaca terakhir. */
  .dialog-kaki { flex-direction: column-reverse; align-items: stretch; }
  .kaki-alat, .kaki-aksi { margin-left: 0; justify-content: flex-start; }
}

/* Di ponsel tombol-tombol ini melipat menjadi empat baris, dan karena rata
   kanan ujung kirinya bertangga - terbaca berantakan, dan tombol sempit di
   tengah tumpukan sulit disentuh dengan tepat. Dibiarkan melar supaya tiap
   baris terisi penuh dan rata. */
@media (max-width: 560px) {
  .dialog-kaki { justify-content: stretch; }
  .dialog-kaki > .tbl { flex: 1 1 auto; }
}

/* ------------------------------------------------------------------ *
 * Footer
 * ------------------------------------------------------------------ */

.kaki {
  border-top: var(--garis);
  background: var(--surface);
  padding: 34px 0 26px;
  margin-top: 44px;
}

.kaki-isi {
  display: grid;
  grid-template-columns: 1.4fr 1fr 1fr;
  gap: 30px;
}

.kaki-sponsor {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  margin-top: 26px;
  padding-top: 18px;
  border-top: var(--garis);
}
.kaki-sponsor-logo { height: 44px; width: auto; display: block; }

.kaki h4 { font-size: 0.82rem; text-transform: uppercase; letter-spacing: 0.05em; color: var(--text-muted); }
.kaki ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.kaki a { color: var(--text); text-decoration: none; font-size: 0.9rem; }
.kaki a:hover { color: var(--accent-link); text-decoration: underline; }


/* Bilah hak cipta & versi yang menempel di dasar layar, di semua halaman.
 *
 * Setinggi satu baris dan tidak pernah lebih: ia menemani halaman, bukan ikut
 * memperebutkan tempatnya. Tingginya disediakan lewat padding pada body supaya
 * tidak pernah ada isi halaman yang tertutup di ujung bawah — termasuk tombol
 * terakhir sebuah formulir panjang. */
.tanda-tetap {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 45;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 14px;
  /* Tingginya DIPAKU ke angka yang sama dengan ruang yang disediakan body.
     Kalau keduanya boleh berbeda, selisihnya menutupi isi halaman di ujung
     bawah — dan selisih dua piksel tidak akan pernah terlihat sampai ada
     tombol yang tidak bisa ditekan. */
  height: var(--tinggi-tanda);
  box-sizing: border-box;
  overflow: hidden;
  white-space: nowrap;
  padding: 0 16px;
  font-size: 0.74rem;
  letter-spacing: 0.02em;
  color: var(--text-muted);
  background: var(--surface);
  border-top: var(--garis);
}

/* Layar sempit hanya muat satu baris pendek. Yang paling tidak dibutuhkan
   pergi duluan, supaya hak cipta dan nomor versi tidak pernah terpotong —
   nomor versi justru yang paling sering perlu disebut saat bertanya. */
.tanda-sponsor { display: inline-flex; align-items: center; gap: 6px; }
.tanda-sponsor a { display: inline-flex; }
/* Logonya muat di dalam bilah setinggi --tinggi-tanda, tidak melebarkannya. */
.tanda-sponsor-logo { height: 20px; width: auto; display: block; }

@media (max-width: 460px) {
  .tanda-tetap { gap: 10px; }
  .tanda-tetap .tanda-npwp,
  .tanda-tetap .tanda-oleh { display: none; }
}
/* Layar paling sempit: logonya tetap, kalimatnya mengalah. */
@media (max-width: 360px) {
  .tanda-tetap .tanda-sponsor-teks { display: none; }
}

body { padding-bottom: var(--tinggi-tanda); }

/* ------------------------------------------------------------------ *
 * BILAH KIRIM — aksi utama yang tidak pernah tergulir hilang
 *
 * Formulir checkout panjangnya dua layar penuh, dan tombol "Kirim Pesanan"
 * dulu hanya ada di kartu ringkasan kanan atas. Pembeli mengisi kolom
 * terakhirnya, lalu menatap layar yang tidak punya tombol apa pun — aksi
 * utamanya menghilang tepat pada saat ia dibutuhkan, dan ia harus menggulir
 * NAIK untuk mencarinya.
 *
 * Bilah ini membawa TOTALNYA SEKALIGUS TOMBOLNYA. Tombol saja tidak cukup:
 * orang menekan "kirim" sesudah memastikan angkanya, jadi angka yang dipastikan
 * harus ada di tempat yang sama dengan tombolnya.
 *
 * Di ponsel ini wajib; di layar lebar tetap berguna karena formulirnya memang
 * panjang. Kartu ringkasan di kanan tetap ada — yang pindah hanya tombolnya.
 * ------------------------------------------------------------------ */
.bilah-kirim {
  position: fixed;
  left: 0;
  right: 0;
  /* DI ATAS bilah hak cipta, bukan menimpanya. */
  bottom: var(--tinggi-tanda);
  z-index: 44;
  height: var(--tinggi-bilah-kirim);
  box-sizing: border-box;
  background: var(--surface);
  border-top: var(--garis);
  box-shadow: var(--bayang-kuat);
}

.bilah-kirim-isi {
  max-width: var(--lebar-isi);
  height: 100%;
  margin: 0 auto;
  padding: 0 20px;
  display: flex;
  align-items: center;
  gap: 14px;
}

.bilah-kirim-total {
  display: flex;
  flex-direction: column;
  line-height: 1.2;
  min-width: 0;
}

.bilah-kirim-angka {
  font-size: 1.25rem;
  font-weight: 800;
  color: var(--accent-link);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* Tombolnya tidak ikut menyempit: aksi utama yang terpotong separuh lebih
   buruk daripada angka yang terpotong. */
.bilah-kirim .tbl {
  margin-left: auto;
  flex: none;
}

/* Ruang untuk bilahnya, supaya kolom terakhir formulir tidak tertutup — dan
   yang melayang di sudut bawah ikut naik lagi supaya tidak duduk di atasnya. */
body.ada-bilah-kirim { padding-bottom: calc(var(--tinggi-tanda) + var(--tinggi-bilah-kirim)); }
body.ada-bilah-kirim .wa-melayang { bottom: calc(18px + var(--tinggi-tanda) + var(--tinggi-bilah-kirim)); }
body.ada-bilah-kirim .pesan-layar { bottom: calc(16px + var(--tinggi-tanda) + var(--tinggi-bilah-kirim)); }

/* Layar sempit: keterangan "Perkiraan total" boleh pergi, angkanya tidak. */
@media (max-width: 420px) {
  .bilah-kirim-isi { padding: 0 13px; gap: 10px; }
  .bilah-kirim-total .kecil { display: none; }
}


/* Yang melayang di sudut bawah ikut naik, supaya tidak duduk di atas bilahnya. */
.wa-melayang { bottom: calc(18px + var(--tinggi-tanda)); }

/* LAYAR SEMPIT: "Hubungi Kami" selebar ~170px menutupi tombol Tambah kartu
   yang sedang berada di bawah layar. Di HP ia menjadi tombol bulat berikon
   (namanya tetap dibaca pembaca layar lewat aria-label), dan body memberi
   ruang supaya isi terbawah bisa digulir sampai di atasnya. */
@media screen and (max-width: 760px) {
  .wa-melayang {
    width: 52px;
    height: 52px;
    padding: 0;
    border-radius: 50%;
    justify-content: center;
    font-size: 1.45rem;
    right: 14px;
  }
  .wa-melayang .wa-teks { display: none; }
  body.ada-wa { padding-bottom: calc(var(--tinggi-tanda) + 80px); }
  body.ada-wa.ada-bilah-kirim { padding-bottom: calc(var(--tinggi-tanda) + var(--tinggi-bilah-kirim) + 80px); }
}
.pesan-layar { bottom: calc(16px + var(--tinggi-tanda)); }

/* Dua kelompok: hak cipta di kiri, versi dan pembuat aplikasi di kanan. */

/* Tanda versi di panel Admin, yang footernya tidak dipasang. */

@media (max-width: 760px) {
  .kaki-isi { grid-template-columns: 1fr; gap: 22px; }
}

/* ------------------------------------------------------------------ *
 * Cetak — invoice & surat jalan A4
 * ------------------------------------------------------------------ */

.dokumen {
  max-width: 210mm;
  margin: 20px auto;
  padding: 16mm 15mm;
  background: var(--surface);
  border: var(--garis);
  border-radius: var(--sudut);
  box-shadow: var(--bayang);
}

.dok-kop {
  display: flex;
  gap: 16px;
  align-items: flex-start;
  padding-bottom: 14px;
  border-bottom: 2px solid var(--border-strong);
  margin-bottom: 18px;
}

.dok-kop img { width: 64px; height: 64px; object-fit: contain; }
.dok-kop-nama { font-size: 1.3rem; font-weight: 800; line-height: 1.2; }
.dok-judul { text-align: right; margin-left: auto; }
.dok-judul h1 { font-size: 1.5rem; margin: 0; }

.dok-blok { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; margin-bottom: 18px; }
.dok-blok h4 { font-size: 0.75rem; text-transform: uppercase; color: var(--text-muted); margin-bottom: 4px; }

.ttd {
  margin-top: 40px;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 40px;
  text-align: center;
  font-size: 0.85rem;
}

.ttd-kotak { padding-top: 62px; border-bottom: 1px solid var(--text); }

/* Kaki dokumen: rekening & catatan di kiri, ringkasan angka di kanan. */
.dok-kaki { display: flex; gap: 24px; margin-top: 18px; align-items: flex-start; }
.dok-kaki > :first-child { flex: 1; }
.dok-kaki .ringkasan { min-width: 250px; }

/* Di layar ponsel, lembar A4 tidak boleh memaksa halaman bergeser mendatar.
   Padding 15mm memakan 114px dari lebar 375px, dan sisanya tidak cukup untuk
   tabel barang. Geometri A4-nya sendiri tidak diubah — itu diatur @media print
   di bawah, jadi hasil cetaknya tetap sama. */
@media (max-width: 620px) {
  .dokumen { margin: 12px auto; padding: 18px 14px; }
  .dok-blok { grid-template-columns: 1fr; gap: 14px; }
  .ttd { grid-template-columns: 1fr; gap: 24px; }
  /* Kop dan kaki dokumen ditumpuk. Dibiarkan berdampingan, kolomnya tinggal
     seratusan piksel dan teksnya pecah satu kata per baris. */
  .dok-kop { flex-wrap: wrap; }
  .dok-judul { margin-left: 0; width: 100%; text-align: left; }
  .dok-kaki { flex-direction: column; }
  .dok-kaki .ringkasan { min-width: 0; width: 100%; }
  /* Tabel barang diberi lebar minimum supaya kolomnya tidak diperas sampai
     nama produk pecah per kata. Yang lebih panjang digeser di dalam
     .tabel-bungkus. Aturan ini tidak berlaku saat mencetak: lebar kertas A4
     jauh di atas 620px, jadi media query ini tidak ikut. */
  .dokumen .tabel-bungkus table { min-width: 520px; }
}

/* ------------------------------------------------------------------ *
 * TANDA "UJI COBA"
 *
 * Tiga sifat di bawah ini yang membuatnya berguna, bukan mengganggu —
 * dan ketiganya sama pentingnya:
 *
 *   pointer-events: none   kliknya TEMBUS. Tanpa ini, elemen ini menjadi
 *                          selembar kaca tak terlihat yang menutupi seluruh
 *                          aplikasi, dan tidak satu tombol pun bisa ditekan.
 *   z-index: 90            di bawah .pesan-layar (100) dan di bawah <dialog>
 *                          yang selalu di lapisan teratas. Jadi notifikasi
 *                          dan kotak konfirmasi tetap bersih.
 *   opacity rendah         terbaca sebagai latar, bukan sebagai isi halaman.
 *
 * `position: fixed` + `inset: 0`: selalu selayar penuh, tidak ikut bergulir,
 * dan tidak menambah tinggi halaman satu piksel pun.
 * ------------------------------------------------------------------ */
.tanda-uji {
  position: fixed;
  inset: 0;
  z-index: 90;
  pointer-events: none;
  user-select: none;
  -webkit-user-select: none;
  opacity: 0.07;
  background-repeat: repeat;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='330' height='190'%3E%3Ctext x='165' y='100' fill='%23000' font-family='system-ui,-apple-system,Segoe UI,Roboto,sans-serif' font-size='40' font-weight='700' letter-spacing='3' text-anchor='middle' transform='rotate(-24 165 100)'%3EUJI COBA%3C/text%3E%3C/svg%3E");
  /* Latar belakang yang tercetak biasanya dibuang peramban demi tinta. Di sini
     justru itu isinya: nota dari salinan latihan HARUS terlihat berbeda dari
     nota sungguhan, termasuk sesudah dicetak. */
  print-color-adjust: exact;
  -webkit-print-color-adjust: exact;
}

@media print {
  .kepala, .kaki, .wa-melayang, .tanpa-cetak, .pesan-layar, .bilah-kirim { display: none !important; }
  /* Tandanya TETAP tercetak — lihat alasannya di atas — tapi lebih tipis,
     supaya angka di bawahnya tidak ikut kabur. */
  .tanda-uji { opacity: 0.09; }
  /* Ruang untuk bilah yang menempel tidak ada gunanya di atas kertas. */
  body { background: none; font-size: 11pt; padding-bottom: 0; }
  /* Disebut TERPISAH, bukan digabung ke pemilih di atas. `body.ada-bilah-kirim`
     lebih kuat daripada `body` saja, jadi tanpa baris ini ruang untuk bilah
     kirim tetap tercetak sebagai sejengkal kosong di kaki kertas — sementara
     menggabungkannya ke atas akan membuat penjaga di uji 11 kehilangan aturan
     `body {}` yang ia cari. */
  body.ada-bilah-kirim, body.ada-wa, body.ada-wa.ada-bilah-kirim { padding-bottom: 0; }
  /* Kaki invoice (pembayaran + subtotal…total) tidak dibelah dua halaman:
     dulu invoice berbaris banyak mencetak "Subtotal" di halaman 1 dan "Total"
     sendirian di halaman 2. */
  .dok-kaki { break-inside: avoid; page-break-inside: avoid; }
  .dokumen {
    margin: 0;
    padding: 0;
    border: 0;
    border-radius: 0;
    box-shadow: none;
    max-width: none;
  }
  .utama { padding: 0; }
  /* Bungkus geser hanya berguna di layar. Di atas kertas ia harus lenyap,
     supaya tabel yang lebih lebar dari kolomnya tidak terpotong diam-diam. */
  .tabel-bungkus { overflow: visible; }
  /* Panduan yang tertutup tetap tercetak. Di layar melipatnya menolong; di atas
     kertas ia hanya menghilangkan isi yang justru ingin dibawa orang. */
  .sop-panel > .panel-isi { display: block !important; }
  .sop-kepala::after { display: none; }
  a { text-decoration: none; color: inherit; }
  table { font-size: 10pt; }
  th { background: none; border-bottom: 1pt solid var(--text); }
  @page { size: A4; margin: 14mm; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    transition-duration: 0.001ms !important;
  }
}

/* ------------------------------------------------------------------ *
 * Pemilih area
 *
 * Hanya muncul kalau toko melayani lebih dari satu area. Kartunya sengaja
 * besar dan bisa ditekan seluruh badannya: ini pilihan pertama yang diambil
 * pengunjung, sering dengan satu tangan sambil memegang galon kosong.
 * ------------------------------------------------------------------ */

.kisi-area {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: var(--jarak);
}

.kartu-area {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
  padding: 20px;
  background: var(--surface);
  border: var(--garis);
  border-radius: var(--sudut);
  box-shadow: var(--bayang);
  color: inherit;
  text-decoration: none;
  transition: transform var(--alur), box-shadow var(--alur), border-color var(--alur);
}

.kartu-area:hover,
.kartu-area:focus-visible {
  transform: translateY(-2px);
  box-shadow: var(--bayang-kuat);
  border-color: var(--accent);
}

.kartu-area.aktif {
  border-color: var(--accent);
  background: rgba(var(--accent-rgb), 0.08);
}

/* Kode area (BPP, SMD) dipakai sebagai lencananya. Ia sudah ada di data dan
   sudah dicetak di kode pesanan, jadi tidak ada gambar baru yang perlu
   disiapkan tiap kali area baru dibuka. */
.kartu-area-tanda {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 42px;
  height: 28px;
  padding: 0 10px;
  margin-bottom: 6px;
  border-radius: 999px;
  background: rgba(var(--accent-rgb), 0.14);
  color: var(--accent);
  font-weight: 700;
  font-size: 0.82rem;
  letter-spacing: 0.06em;
}

.kartu-area-nama {
  font-size: 1.15rem;
  font-weight: 700;
}

.kartu-area-alamat {
  font-size: 0.86rem;
  opacity: 0.7;
  line-height: 1.45;
}

.kartu-area-kini {
  margin-top: 8px;
  font-size: 0.78rem;
  font-weight: 700;
  color: var(--accent);
}

/* Penanda di header: keterangan, bukan hiasan. Harga dan ongkir yang dilihat
   pembeli bergantung padanya, jadi ia harus terbaca sekilas di tiap halaman. */
.penanda-area {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 12px;
  border-radius: 999px;
  border: 1px solid var(--accent);
  color: var(--accent);
  font-weight: 600;
  font-size: 0.88rem;
  text-decoration: none;
  white-space: nowrap;
}

/* Tidak ikut menyempit: nama area yang terpotong separuh lebih buruk daripada
   merek yang terpotong — merek masih dikenali dari logonya, area tidak. */
.penanda-area { flex: none; }

/* Yang panjang dulu; yang pendek baru muncul di layar sempit. */
.penanda-area-pendek { display: none; }

.penanda-area:hover,
.penanda-area:focus-visible {
  background: rgba(var(--accent-rgb), 0.12);
}

/* Belum memilih: ia harus menarik mata, karena tidak ada harga yang bisa
   ditampilkan sebelum ditekan. */
.penanda-area.perlu {
  background: var(--accent);
  color: var(--accent-contrast);
}

/*
 * PONSEL TEGAK: yang tampil KODE AREANYA, bukan namanya.
 *
 * Di lebar 390px, baris header memuat merek, penanda area, ikon keranjang, dan
 * tombol menu sekaligus. "BALIKPAPAN" menghabiskan ruang yang tersisa dan
 * mendorong mereknya sampai tinggal logo; "BPP" muat dengan longgar.
 *
 * Diganti, bukan dipotong dengan ellipsis: "BALIKP..." dan "BALIKPAPAN TIMUR"
 * terlihat sama di layar, dan pembeli yang salah area tidak punya cara tahu.
 * Kode areanya pendek karena memang dibuat untuk dibaca sekilas.
 */
@media (max-width: 560px) {
  .kepala-isi { gap: 10px; padding: 8px 13px; }
  .kepala-aksi { gap: 7px; }
  .penanda-area-panjang { display: none; }
  .penanda-area-pendek { display: inline; }
  .penanda-area {
    padding: 5px 10px;
    gap: 4px;
    font-size: 0.82rem;
    letter-spacing: 0.01em;
  }
  /* Pin-nya ikut mengecil: di ruang sesempit itu ia keterangan, bukan hiasan. */
  .penanda-area-pin { font-size: 0.78rem; }

  /* JARING PENGAMAN untuk area yang TIDAK diberi kode: yang dipakai namanya,
     dan nama seperti "PENAJAM PASER UTARA" akan menjebol baris header karena
     penandanya sengaja tidak menyempit.
     Dipotong di sini, walau di atas ditulis "diganti, bukan dipotong" — dan
     kedua-duanya benar. Mengganti selalu lebih baik, tapi itu menuntut areanya
     punya kode; kalau tidak ada, pilihannya tinggal terpotong atau header yang
     jebol, dan header jebol membuat tombol menu tak bisa ditekan sama sekali.
     Kodenya sendiri 3-4 huruf, jadi batas ini tidak pernah menyentuhnya. */
  .penanda-area-pendek {
    max-width: 10ch;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
}

/*
 * PONSEL PALING SEMPIT (320px, iPhone SE dan sejenisnya).
 *
 * Di lebar itu anggarannya habis: logo 40px, ikon keranjang 42px, tombol menu
 * 39px, dan sisa ruangnya harus dibagi tulisan merek dengan penanda area.
 * Terukur dengan nama area 27 huruf tanpa kode — penandanya memakan 116px dan
 * MEREKNYA TINGGAL SATU HURUF, "Q" saja.
 *
 * Jadi di sini penandanya yang mengalah lebih dulu. Ia tetap terbaca sebagai
 * sebuah nama, sementara merek yang tinggal satu huruf tidak terbaca sebagai
 * apa pun. Kode area 3-4 huruf tetap tidak tersentuh batas ini.
 */
@media (max-width: 400px) {
  .penanda-area-pendek { max-width: 6ch; }
  /* SEBELUM AREA DIPILIH tulisannya "Pilih area" utuh — itu tombol pertama yang
     harus ditekan pembeli baru, dan "Pilih …" tidak terbaca sebagai apa pun. */
  .penanda-area.perlu .penanda-area-pendek { max-width: none; }
}

.panel-area {
  padding: 26px;
}

/* Bagian pemilih area di halaman pembuka. */
.sambutan-area {
  margin-top: 40px;
  padding: 26px;
  background: var(--surface);
  border: 1px solid var(--accent);
  border-radius: var(--sudut-besar);
  box-shadow: var(--bayang-kuat);
}

/* ------------------------------------------------------------------ *
 * RASA DAPUR RUMAH — tampilan bawaan toko
 *
 * Huruf bulat (yang tersedia di perangkat pembeli — CSP hanya mengizinkan
 * font dari server sendiri), sudut lebih lembut, dan gumpalan warna di sudut
 * hero seperti di logo. Tetap tanpa satu pun warna mentah: semuanya dari tema.
 * ------------------------------------------------------------------ */

:root {
  --font: "Nunito", "Quicksand", "Varela Round", ui-rounded, "SF Pro Rounded", "Segoe UI", system-ui,
    -apple-system, Roboto, "Helvetica Neue", Arial, sans-serif;
  --sudut: 18px;
  --sudut-kecil: 12px;
  --sudut-besar: 28px;
}

h1, h2 {
  font-weight: 800;
  letter-spacing: -0.015em;
}

h2::after {
  /* Garis kecil kuning di bawah judul bagian — seperti goresan spatula. */
  content: "";
  display: block;
  width: 44px;
  height: 5px;
  margin-top: 8px;
  border-radius: 99px;
  background: var(--accent);
}

.hero h1::after,
.sambutan-area h2::after,
.panel h2::after,
.dialog h2::after,
.po-kartu h2::after {
  display: none;
}

.tbl {
  border-radius: 999px;
}

.hero::before {
  /* Gumpalan di pojok kanan atas, bentuk yang sama dengan logo. */
  content: "";
  position: absolute;
  width: 360px;
  height: 300px;
  top: -150px;
  right: -110px;
  border-radius: 58% 42% 46% 54% / 55% 48% 52% 45%;
  background: rgba(var(--accent-rgb), 0.55);
  pointer-events: none;
}

.hero::after {
  /* ...dan pasangannya di pojok kiri bawah. */
  inset: auto auto -170px -120px;
  width: 340px;
  height: 300px;
  border-radius: 46% 54% 58% 42% / 52% 45% 55% 48%;
  background: rgba(var(--accent-rgb), 0.4);
}

.hero-gambar img {
  background: var(--surface);
  padding: 14px;
  transform: rotate(-1.5deg);
}

.produk-gambar {
  background: var(--surface-2);
}

/* ------------------------------------------------------------------ *
 * OPEN PO
 * ------------------------------------------------------------------ */

.po-kisi {
  display: grid;
  gap: 20px;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 520px), 1fr));
}

.po-kartu {
  background: var(--surface);
  border: 2px solid var(--accent);
  border-radius: var(--sudut-besar);
  box-shadow: var(--bayang);
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

.po-kepala {
  display: grid;
  grid-template-columns: 150px minmax(0, 1fr);
  gap: 18px;
  padding: 18px 18px 6px;
  align-items: start;
}

.po-sampul {
  position: relative;
  aspect-ratio: 1 / 1;
  border-radius: var(--sudut);
  overflow: hidden;
  background: var(--surface-2);
}

.po-sampul img { width: 100%; height: 100%; object-fit: cover; }

.po-pita {
  position: absolute;
  left: 8px;
  top: 8px;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 0.75rem;
  font-weight: 800;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  background: var(--secondary);
  color: var(--secondary-contrast);
}

.po-judul { min-width: 0; overflow-wrap: anywhere; }
.po-judul h3 { font-size: 1.25rem; font-weight: 800; margin-bottom: 4px; }
.po-judul p { margin: 0 0 10px; font-size: 0.92rem; }

.po-jam {
  display: inline-flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
  padding: 6px 14px;
  border-radius: 999px;
  background: var(--accent);
  color: var(--accent-contrast);
  font-size: 0.92rem;
  margin-bottom: 10px;
}

.po-jam-segera {
  background: var(--surface-2);
  color: var(--text);
  border: var(--garis);
}

.po-hitung { font-variant-numeric: tabular-nums; }

.po-fakta { display: flex; flex-wrap: wrap; gap: 6px; }
.po-fakta .lencana { white-space: normal; }

.po-daftar-menu {
  list-style: none;
  margin: 8px 0 0;
  padding: 0 18px 12px;
}

.po-menu {
  display: grid;
  grid-template-columns: 64px minmax(0, 1fr) auto;
  gap: 14px;
  align-items: center;
  padding: 12px 0;
  border-top: 1px dashed var(--border-strong);
}

.po-menu-gambar {
  width: 64px;
  height: 64px;
  border-radius: var(--sudut-kecil);
  overflow: hidden;
  background: var(--surface-2);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.6rem;
}

.po-menu-gambar img { width: 100%; height: 100%; object-fit: cover; }
.po-menu-nama { font-weight: 800; line-height: 1.3; }
.po-menu-aksi { display: flex; gap: 8px; align-items: center; }
.po-menu-aksi input[type="number"] { width: 64px; }

.po-catatan {
  margin: 0 18px 16px;
  padding: 12px 14px;
  border-radius: var(--sudut);
  background: rgba(var(--accent-rgb), 0.14);
  border: 1px solid var(--accent);
}

.po-catatan p { margin: 0 0 10px; }

.po-pita-info {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  padding: 12px 16px;
  margin-bottom: 16px;
  border-radius: var(--sudut);
  background: rgba(var(--accent-rgb), 0.14);
  border: 2px dashed var(--accent);
}

.po-pita-ikon { font-size: 1.6rem; line-height: 1; }

.lencana-po {
  background: var(--secondary);
  color: var(--secondary-contrast);
}

@media (max-width: 640px) {
  .po-kepala { grid-template-columns: 84px minmax(0, 1fr); gap: 12px; padding: 14px 14px 4px; }
  .po-judul h3 { font-size: 1.08rem; }
  .po-pita { font-size: 0.62rem; padding: 2px 7px; left: 5px; top: 5px; }
  .po-jam { font-size: 0.85rem; padding: 5px 11px; }
  .po-daftar-menu { padding: 0 14px 8px; }
  .po-menu { grid-template-columns: 52px minmax(0, 1fr); }
  .po-menu-gambar { width: 52px; height: 52px; }
  .po-menu-aksi { grid-column: 1 / -1; justify-content: flex-end; }
  .po-catatan { margin: 0 14px 14px; }
  .hero::before { width: 220px; height: 190px; top: -100px; right: -90px; }
  .hero::after { width: 200px; height: 180px; bottom: -110px; left: -90px; }
}

/* ------------------------------------------------------------------ *
 * HURUF — disimpan di server sendiri (CSP: font-src 'self').
 * Fredoka untuk judul (bulat, senada huruf di logo), Nunito untuk teks.
 * Lisensi OFL ada di public/assets/font/.
 * ------------------------------------------------------------------ */

@font-face {
  font-family: "Fredoka";
  src: url("/assets/font/fredoka-latin-wght.woff2") format("woff2");
  font-weight: 300 700;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Nunito";
  src: url("/assets/font/nunito-latin-wght.woff2") format("woff2");
  font-weight: 200 1000;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Nunito";
  src: url("/assets/font/nunito-latin-wght-italic.woff2") format("woff2");
  font-weight: 200 1000;
  font-style: italic;
  font-display: swap;
}

:root {
  --font: "Nunito", ui-rounded, "Segoe UI", system-ui, -apple-system, Roboto, Arial, sans-serif;
  --font-judul: "Fredoka", "Nunito", ui-rounded, "Segoe UI", system-ui, sans-serif;
}

h1, h2, h3, h4,
.tbl,
.produk-nama,
.merek-nama,
.po-menu-nama,
.produk-harga {
  font-family: var(--font-judul);
}

h1, h2 { font-weight: 600; letter-spacing: -0.01em; }
h3, h4 { font-weight: 600; }
.tbl { font-weight: 600; letter-spacing: 0.01em; }

/* ------------------------------------------------------------------ *
 * BERANDA
 * ------------------------------------------------------------------ */

/* Pita Open PO di paling atas: cokelat logo, satu baris di layar lebar. */
.pita-po-atas {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 4px 14px;
  padding: 10px 20px;
  background: var(--secondary);
  color: var(--secondary-contrast);
  font-size: 0.92rem;
  text-decoration: none;
}

.pita-po-atas:hover .pita-po-ajak { text-decoration: underline; }

.pita-po-label {
  padding: 2px 10px;
  border-radius: 999px;
  background: var(--accent);
  color: var(--accent-contrast);
  font-family: var(--font-judul);
  font-weight: 600;
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.pita-po-nama { font-family: var(--font-judul); font-weight: 600; }
.pita-po-ajak { font-family: var(--font-judul); font-weight: 700; color: var(--accent); }

/* Hero */
/* clip, bukan hidden: wadah overflow:hidden bisa TERGULIR di dalamnya saat
   fokus atau lompatan tautan mengenai rantang, menyisakan pita kosong. */
.sambut { padding: 34px 0 0; border-bottom: 0; overflow: clip; }

.sambut-isi {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
  gap: 40px;
  align-items: center;
  padding-bottom: 34px;
  position: relative;
  z-index: 1;
}

.sambut-sapa {
  display: inline-block;
  margin: 0;
  padding: 6px 16px;
  border-radius: 999px;
  background: var(--surface);
  box-shadow: var(--bayang);
  font-family: var(--font-judul);
  font-weight: 600;
  color: var(--accent-link);
  transform: rotate(-1.5deg);
}

.sambut h1 {
  margin: 16px 0 14px;
  font-size: clamp(2.4rem, 6vw, 4.1rem);
  line-height: 1.02;
  letter-spacing: -0.02em;
  color: var(--secondary);
}

.sambut h1::after { display: none; }

.sambut #hero-tagline { font-size: 1.12rem; max-width: 46ch; color: var(--text); }

.sambut-aksi {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px 22px;
  margin-top: 24px;
}

.tautan-wa {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-weight: 800;
  color: var(--secondary);
  text-decoration: underline;
  text-decoration-style: wavy;
  text-decoration-color: var(--accent);
  text-underline-offset: 6px;
}

.tautan-wa svg { width: 22px; height: 22px; }

.sambut .hero-lencana { margin-top: 22px; }

.sambut-gelombang {
  display: block;
  width: 100%;
  height: 46px;
  margin-top: -1px;
  color: var(--bg);
  position: relative;
  z-index: 1;
}

/* RANTANG HARI INI */
.rantang-panggung {
  position: relative;
  margin: 0;
  justify-self: center;
  width: min(100%, 440px);
  padding-top: 132px;
}

.gelembung {
  position: absolute;
  top: 6px;
  right: 0;
  z-index: 3;
  margin: 0;
  max-width: 230px;
  padding: 9px 16px;
  border: 3px solid var(--secondary);
  border-radius: 20px 20px 4px 20px;
  background: var(--surface);
  color: var(--secondary);
  font-family: var(--font-judul);
  font-weight: 600;
  line-height: 1.25;
  transform: rotate(2deg);
  box-shadow: var(--bayang);
}

.rantang {
  position: relative;
  margin-left: 44px;
  color: var(--secondary);
}

/* Dua batang penjepit di kiri-kanan, menyatu dengan gagangnya. */
.rantang::before,
.rantang::after {
  content: "";
  position: absolute;
  top: -2px;
  bottom: 10px;
  width: 11px;
  border-radius: 6px;
  background: var(--secondary);
}

.rantang::before { left: calc(6% - 5px); }
.rantang::after { right: calc(6% - 5px); }

.rantang-gagang {
  position: absolute;
  left: 0;
  top: -92px;
  width: 100%;
  height: 94px;
  overflow: visible;
}

.rantang-uap {
  position: absolute;
  top: -70px;
  left: 50%;
  display: flex;
  gap: 16px;
  transform: translateX(-50%);
  pointer-events: none;
}

.rantang-uap i {
  display: block;
  width: 12px;
  height: 40px;
  border-left: 4px solid rgba(var(--text-rgb), 0.28);
  border-radius: 50%;
  animation: rantang-uap 3s ease-in-out infinite;
}

.rantang-uap i:nth-child(2) { animation-delay: 0.9s; height: 48px; }
.rantang-uap i:nth-child(3) { animation-delay: 1.8s; }

.rantang-tutup {
  position: relative;
  height: 30px;
  margin: 0 9%;
  border-radius: 60% 60% 10px 10px / 100% 100% 10px 10px;
  background: var(--secondary);
}

.rantang-tutup::after {
  content: "";
  position: absolute;
  top: -10px;
  left: 50%;
  width: 30px;
  height: 14px;
  border: 3px solid var(--secondary);
  border-radius: 9px;
  background: var(--accent);
  transform: translateX(-50%);
}

.rantang-isi {
  display: flex;
  flex-direction: column;
  gap: 7px;
  margin-top: 6px;
}

.rantang-susun {
  position: relative;
  display: grid;
  grid-template-columns: 58px minmax(0, 1fr) auto;
  gap: 12px;
  align-items: center;
  margin: 0 8%;
  padding: 10px 14px 10px 10px;
  border: 3px solid var(--secondary);
  border-radius: 14px;
  background: var(--surface);
  color: var(--text);
  text-decoration: none;
  box-shadow: inset 0 -7px 0 rgba(var(--text-rgb), 0.06);
  transition: transform var(--alur), box-shadow var(--alur);
  animation: rantang-turun 0.55s cubic-bezier(0.2, 0.8, 0.3, 1.15) both;
  animation-delay: calc(var(--urut, 0) * 130ms + 120ms);
}

.rantang-susun:nth-child(1) { background: var(--accent); color: var(--accent-contrast); }
.rantang-susun:nth-child(3) { background: var(--bg-soft); }

.rantang-susun:hover,
.rantang-susun:focus-visible {
  transform: translateX(6px) rotate(-0.6deg);
  box-shadow: inset 0 -7px 0 rgba(var(--text-rgb), 0.06), var(--bayang);
}

.rantang-foto {
  width: 58px;
  height: 58px;
  border-radius: 50%;
  overflow: hidden;
  border: 3px solid var(--secondary);
  background: var(--surface-2);
}

.rantang-foto img { width: 100%; height: 100%; object-fit: cover; }

.rantang-teks { min-width: 0; line-height: 1.2; }
.rantang-teks b { display: block; font-family: var(--font-judul); font-weight: 600; font-size: 1.02rem; text-wrap: balance; }
.rantang-teks span { font-size: 0.85rem; opacity: 0.85; }

.rantang-harga { font-family: var(--font-judul); font-weight: 600; white-space: nowrap; }

.rantang-alas {
  height: 14px;
  margin: 6px 12% 0;
  border-radius: 0 0 14px 14px;
  background: var(--secondary);
}

.rantang-mama {
  position: absolute;
  left: -14px;
  bottom: -10px;
  z-index: 2;
  width: 132px;
  transform: rotate(-4deg);
  filter: drop-shadow(0 6px 10px rgba(var(--text-rgb), 0.18));
}

@keyframes rantang-turun {
  from { opacity: 0; transform: translateY(-28px); }
  to { opacity: 1; transform: none; }
}

@keyframes rantang-uap {
  0% { opacity: 0; transform: translateY(14px) scaleY(0.7); }
  40% { opacity: 1; }
  100% { opacity: 0; transform: translateY(-20px) scaleY(1.1); }
}

@media (prefers-reduced-motion: reduce) {
  .rantang-uap i { animation: none; opacity: 0.6; }
  .rantang-susun { animation: none; }
}

/* Tiga cara menerima masakan */
.cara-terima { padding: 4px 0 6px; }

.judul-kecil { text-align: center; font-size: 1.2rem; }
.judul-kecil::after { margin: 8px auto 0; }

.cara-terima-kisi {
  list-style: none;
  margin: 16px 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 14px;
}

.cara-terima-kisi li {
  display: grid;
  grid-template-columns: 56px minmax(0, 1fr);
  column-gap: 14px;
  align-items: start;
  padding: 18px;
  border: 2px solid var(--border);
  border-radius: var(--sudut-besar);
  background: var(--surface);
}

.cara-terima-kisi b { font-family: var(--font-judul); font-weight: 600; font-size: 1.15rem; color: var(--secondary); }
.cara-terima-kisi li > span:last-child { grid-column: 2; color: var(--text-muted); font-size: 0.95rem; line-height: 1.45; }

.cara-ikon {
  grid-row: span 2;
  display: grid;
  place-items: center;
  width: 56px;
  height: 56px;
  border-radius: 46% 54% 52% 48% / 55% 45% 55% 45%;
  background: var(--accent);
  color: var(--accent-contrast);
}

.cara-ikon svg { width: 32px; height: 32px; }

/* Bagian-bagian di bawahnya */
.beranda .utama { padding-top: 40px; }
.bagian-beranda { margin: 0 0 60px; }
.bagian-beranda h2 { margin: 0 0 6px; }
.bagian-ket { margin: 0 0 18px; max-width: 60ch; }
.bagian-kepala { align-items: flex-end; margin-bottom: 16px; }

.alis {
  margin: 0 0 2px;
  font-family: var(--font-judul);
  font-weight: 600;
  font-size: 1rem;
  color: var(--accent-link);
}

/* Kenalan sama Mama */
.kenalan {
  display: grid;
  grid-template-columns: 240px minmax(0, 1fr);
  gap: 36px;
  align-items: center;
  margin: 0 0 60px;
  padding: 32px;
  border: 2px dashed var(--border-strong);
  border-radius: var(--sudut-besar);
  background: var(--surface);
}

.kenalan-gambar {
  display: grid;
  place-items: center;
  aspect-ratio: 1 / 1;
  border-radius: 58% 42% 46% 54% / 55% 48% 52% 45%;
  background: rgba(var(--accent-rgb), 0.38);
}

.kenalan-gambar img { width: 74%; }
.kenalan h2 { margin: 0 0 12px; }
.kenalan-teks p { max-width: 62ch; }

.kenalan blockquote {
  margin: 16px 0;
  padding: 4px 0 4px 16px;
  border-left: 5px solid var(--accent);
  font-family: var(--font-judul);
  font-size: 1.2rem;
  line-height: 1.35;
  color: var(--secondary);
}

.kenalan-ttd {
  display: block;
  width: max-content;
  margin: 0 0 18px;
  font-family: var(--font-judul);
  font-weight: 600;
  font-size: 1.45rem;
  color: var(--accent-link);
  transform: rotate(-3deg);
}

/* Penutup: ajakan chat */
.penutup {
  display: grid;
  grid-template-columns: 140px minmax(0, 1fr);
  gap: 26px;
  align-items: center;
  margin: 0;
  padding: 30px 34px;
  border-radius: var(--sudut-besar);
  background: var(--secondary);
  color: var(--secondary-contrast);
}

.penutup h2 { color: inherit; margin: 0 0 8px; }
.penutup h2::after { background: var(--accent); }
.penutup p { margin: 0 0 16px; max-width: 58ch; }

.penutup-mama {
  width: 140px;
  padding: 10px;
  border-radius: 50%;
  background: var(--surface);
}

@media (max-width: 860px) {
  .sambut { padding-top: 24px; }
  .sambut-isi { grid-template-columns: minmax(0, 1fr); gap: 18px; padding-bottom: 20px; }
  .rantang-panggung { padding-top: 112px; }
  .cara-terima-kisi { grid-template-columns: minmax(0, 1fr); gap: 10px; }
  .cara-terima-kisi li { padding: 14px; }
  .kenalan { grid-template-columns: minmax(0, 1fr); padding: 24px 20px; gap: 18px; }
  .kenalan-gambar { width: 170px; justify-self: center; }
  .penutup { grid-template-columns: minmax(0, 1fr); text-align: center; padding: 26px 20px; }
  .penutup-mama { width: 110px; justify-self: center; }
  .penutup h2::after { margin: 8px auto 0; }
  .penutup p { margin-left: auto; margin-right: auto; }
  .penutup .baris { justify-content: center; }
  .pita-po-siap { display: none; }
}

@media (max-width: 1100px) {
  .pita-po-siap { display: none; }
}

@media (max-width: 420px) {
  .rantang { margin-left: 34px; }
  .rantang-susun { grid-template-columns: 48px minmax(0, 1fr); row-gap: 0; margin: 0 7%; padding: 8px 12px 8px 8px; }
  .rantang-foto { width: 48px; height: 48px; grid-row: span 2; }
  .rantang-harga { grid-column: 2; font-size: 0.9rem; }
  .rantang-mama { width: 96px; left: -10px; }
  .gelembung { max-width: 190px; font-size: 0.92rem; }
}

/* ------------------------------------------------------------------ *
 * FITUR DAPUR: spanduk tutup, label menu, catatan, kabari, testimoni
 * ------------------------------------------------------------------ */

.spanduk-tutup {
  padding: 10px 20px;
  text-align: center;
  background: var(--danger);
  color: var(--danger-contrast);
  font-size: 0.95rem;
}

.produk-label {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
  margin: 2px 0 8px;
}

.lencana-label {
  background: rgba(var(--accent-rgb), 0.22);
  color: var(--text);
}

.catatan-menu-baris {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin-top: 8px;
}

input.catatan-menu {
  padding: 7px 11px;
  font-size: 0.9rem;
  border-style: dashed;
}

.kabari-po {
  display: grid;
  gap: 12px;
  padding: 18px 20px;
  border: 2px dashed var(--accent);
  border-radius: var(--sudut-besar);
  background: rgba(var(--accent-rgb), 0.12);
}

.kabari-po-teks { display: flex; flex-direction: column; gap: 2px; }
.kabari-po-teks b { font-family: var(--font-judul); font-weight: 600; font-size: 1.1rem; color: var(--secondary); }

.kabari-po-isian {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr) auto;
  gap: 8px;
}

.testimoni-kisi {
  display: grid;
  gap: 18px;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 280px), 1fr));
}

.testimoni { margin: 0; }

.testimoni-gelembung {
  position: relative;
  margin: 0 0 12px;
  padding: 14px 16px;
  border-radius: 18px 18px 18px 4px;
  background: var(--surface);
  border: 2px solid var(--border);
  box-shadow: var(--bayang);
  line-height: 1.5;
}

.testimoni figcaption { padding-left: 6px; font-size: 0.92rem; }

@media (max-width: 760px) {
  .kabari-po-isian { grid-template-columns: minmax(0, 1fr); }
}

/* ------------------------------------------------------------------ *
 * KATERING — pesan untuk acara (/katering) dan ajakannya di beranda
 * ------------------------------------------------------------------ */

/* Ajakan di beranda: kartu kecil, bukan bagian penuh — ia jalan samping,
   bukan jualan utama. Garis putus-putus seirama dengan "Kenalan sama Mama". */
.katering-ajakan {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px 24px;
  margin: 0 0 60px;
  padding: 22px 26px;
  border: 2px dashed rgba(var(--accent-rgb), 0.7);
  border-radius: var(--sudut-besar);
  background: rgba(var(--accent-rgb), 0.12);
}

.katering-ajakan-ikon { font-size: 2.2rem; line-height: 1; }
.katering-ajakan-teks { flex: 1 1 300px; }
.katering-ajakan h2 { margin: 0 0 4px; font-size: 1.3rem; }
.katering-ajakan p { margin: 0; color: var(--text-muted); }

.katering-form { margin-top: 18px; }
.katering-sub { margin: 4px 0 12px; font-size: 1.1rem; }
.katering-sub:not(:first-child) { margin-top: 22px; }

.katering-usulan {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin: -6px 0 16px;
}

.katering-usulan-menu {
  padding: 4px 11px;
  border: var(--garis);
  border-radius: 999px;
  background: var(--surface);
  color: var(--text);
  font: inherit;
  font-size: 0.85rem;
  cursor: pointer;
}

.katering-usulan-menu:hover { border-color: var(--accent); color: var(--accent-link); }

.katering-terkirim { margin-top: 18px; }
.katering-terkirim h2 { margin: 0 0 8px; }

.katering-ringkas {
  display: grid;
  gap: 6px;
  margin: 16px 0 20px;
  padding: 14px 16px;
  border-radius: var(--sudut);
  background: var(--surface-2);
}

.katering-ringkas-baris { display: grid; grid-template-columns: 120px minmax(0, 1fr); gap: 10px; }
.katering-ringkas dt { color: var(--text-muted); }
.katering-ringkas dd { margin: 0; font-weight: 600; overflow-wrap: anywhere; }
.katering-aksi { gap: 10px; flex-wrap: wrap; }

@media (max-width: 520px) {
  .katering-ajakan { padding: 18px; }
  .katering-ringkas-baris { grid-template-columns: minmax(0, 1fr); gap: 0; }
}

/* Siap jualan: langkah pemasangan yang belum beres, di atas dasbor panel. */
.siap-jualan { border-left: 4px solid var(--accent); }
.siap-jualan-daftar { margin: 0; padding-left: 18px; display: grid; gap: 10px; }
.siap-jualan-daftar .tbl { margin-top: 6px; }

/* Ulasan sesudah pesanan selesai ("Gimana rasanya?"). Bintangnya label
   radio: tetap bisa dipilih dengan papan ketik dan terbaca pembaca layar. */
.ulasan-kartu h2 { font-size: 1.15rem; }
.bintang-pilih { display: inline-flex; gap: 2px; }
.bintang {
  position: relative;
  cursor: pointer;
  font-size: 1.9rem;
  line-height: 1;
  color: var(--border-strong);
  padding: 2px;
  border-radius: var(--sudut-kecil);
  transition: transform 0.1s ease;
}
.bintang:hover { transform: scale(1.12); }
.bintang.nyala { color: var(--warning); }
.bintang:has(.bintang-radio:focus-visible) { outline: 2px solid var(--accent); outline-offset: 2px; }
input.bintang-radio {
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
  min-width: 0;
  padding: 0;
  margin: 0;
  pointer-events: none;
}
.bintang-baca { font-size: 1.4rem; letter-spacing: 2px; color: var(--warning); }
.ulasan-panel-baris { padding: 10px 0; border-bottom: 1px solid var(--garis); }
.ulasan-panel-baris:last-child { border-bottom: 0; }

/* Nama dan foto kartu menu menuju halaman menunya (/menu/:id). */
a.produk-nama { color: inherit; text-decoration: none; }
a.produk-nama:hover,
a.produk-nama:focus-visible { color: var(--accent-link); text-decoration: underline; }
a.produk-gambar { text-decoration: none; }

/* Halaman satu menu: foto besar di kiri, cerita dan tombol beli di kanan;
   bertumpuk di layar sempit. */
.menu-detail-remah { margin: 4px 0 14px; color: var(--text-muted); }
.menu-detail {
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
  gap: 28px;
  align-items: start;
}
.menu-detail-foto {
  aspect-ratio: 4 / 3;
  border-radius: var(--sudut-besar);
  overflow: hidden;
  background: var(--surface-2);
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: var(--bayang);
}
.menu-detail-foto img { width: 100%; height: 100%; object-fit: cover; }
.menu-detail-foto .kosong { font-size: 4rem; opacity: 0.5; }
.menu-detail-isi { display: grid; gap: 10px; min-width: 0; }
.menu-detail-nama { margin: 0; overflow-wrap: anywhere; }
.menu-detail-harga .produk-harga { font-size: 1.7rem; }
.menu-detail-aturan { margin: 4px 0; padding-left: 18px; color: var(--text-muted); display: grid; gap: 4px; }
.menu-detail-cerita { margin: 0 0 12px; line-height: 1.6; white-space: pre-line; }

@media (max-width: 760px) {
  .menu-detail { grid-template-columns: minmax(0, 1fr); gap: 18px; }
}

/* Pilihan varian dan pilihan tanpa beda harga di kartu menu. */
.produk-pilihan { display: grid; gap: 6px; margin: 6px 0 4px; }
.produk-pilihan-baris { display: grid; grid-template-columns: minmax(84px, auto) 1fr; align-items: center; gap: 8px; font-size: 0.9rem; }
.produk-pilihan-baris select { padding: 6px 10px; }

/* Ongkir wilayah ojol ("dibayar ke driver...") boleh melipat di layar sempit. */
td.angka.sel-ojol { white-space: normal; min-width: 7em; text-align: left; }

/* Di kartu menu, label pilihan di atas dan pilihannya selebar kartu:
   "Biasa — Rp 38.000" terpotong di kartu empat kolom. */
.produk .produk-pilihan-baris { grid-template-columns: 1fr; gap: 2px; }
.produk .produk-pilihan-baris select { width: 100%; }
