/* Tepuk — satu stylesheet untuk semua halaman.

   Tema gelap, rapat, tanpa ornamen. Ini alat kerja yang dibuka sambil melayani
   pembeli, bukan halaman pemasaran: yang penting angka kebaca dalam sekali
   lirik, dan tombol yang salah tidak gampang kepencet.

   Font diambil dari berkas sendiri, bukan CDN: hosting murah kadang lambat ke
   luar negeri, dan halaman ini harus tetap enak dibuka dari HP di dalam
   restoran. Satu berkas 27 KB, disimpan browser setelah unduhan pertama. */

@font-face {
  font-family: 'Tepuk Sans';
  font-style: normal;
  /* Satu berkas variabel 400–800: semua ketebalan tanpa unduhan tambahan. */
  font-weight: 400 800;
  font-display: swap;
  src: url('/assets/fonts/plus-jakarta-sans-latin.woff2') format('woff2');
}

:root {
  color-scheme: dark;

  --bg: #0a0d0c;
  --bg-2: #0d1110;
  --surface: #131817;
  --surface-2: #19211f;
  --surface-3: #202927;

  --line: #242b29;
  --line-2: #1b2220;

  --ink: #eef2ef;
  --ink-2: #a2adaa;
  --ink-3: #6e7975;

  --accent: #35cf95;
  --accent-ink: #04160f;
  --accent-soft: rgba(53, 207, 149, .12);
  --accent-line: rgba(53, 207, 149, .32);

  --warn: #e6b264;
  --warn-soft: rgba(230, 178, 100, .11);
  --warn-line: rgba(230, 178, 100, .3);

  --danger: #f0857b;
  --danger-soft: rgba(240, 133, 123, .1);
  --danger-line: rgba(240, 133, 123, .3);

  /* Empat warna Google. Dipakai hanya sebagai garis tipis dan bingkai kartu:
     itu bahasa yang sudah dikenali orang, dan langsung memberi tahu bahwa
     kartu ini soal ulasan Google — tanpa perlu logo resmi. */
  --g-blue: #4285f4;
  --g-red: #ea4335;
  --g-yellow: #fbbc05;
  --g-green: #34a853;
  --g-bar: linear-gradient(90deg,
            var(--g-blue) 0 25%, var(--g-red) 25% 50%,
            var(--g-yellow) 50% 75%, var(--g-green) 75%);

  --r: 14px;
  --r-sm: 10px;
  --r-lg: 20px;

  --sans: 'Tepuk Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
          'Helvetica Neue', Arial, sans-serif;
  --mono: ui-monospace, 'SF Mono', 'Cascadia Mono', 'JetBrains Mono', Menlo,
          Consolas, monospace;
}

* { box-sizing: border-box; }

/* Atribut hidden harus menang atas kelas yang menyetel display. Tanpa ini
   .pick { display:flex } membuat blok "usaha terpilih" tetap tampil walau
   elemennya diberi hidden. */
[hidden] { display: none !important; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  min-height: 100vh;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 15px;
  line-height: 1.55;
  /* Plus Jakarta Sans punya spasi sangat sempit (0.17 em, font lain 0.26+),
     jadi "1 kartu" terbaca "1kartu". Tambahan ini mengembalikan jarak kata
     ke ukuran normal tanpa mengubah jenis hurufnya. */
  word-spacing: .06em;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* Garis empat warna di puncak halaman. Satu-satunya hiasan tetap di seluruh
   aplikasi: cukup untuk memberi tahu "ini soal Google", tidak sampai jadi
   pelangi yang berebut perhatian dengan isi. */
body::before {
  content: "";
  position: fixed;
  inset: 0 0 auto;
  height: 3px;
  background: var(--g-bar);
  z-index: 30;
  pointer-events: none;
}

/* Reset form controls but keep specificity at zero so component classes win. */
:where(button, input, textarea, select) {
  font: inherit;
  color: inherit;
  margin: 0;
}

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; text-underline-offset: 3px; }

h1, h2, h3 {
  font-weight: 700;
  letter-spacing: -.03em;
  line-height: 1.12;
  margin: 0;
}

p { margin: 0; }

::selection { background: var(--accent); color: var(--accent-ink); }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 4px;
}

/* ------------------------------------------------------------------ shell */

.wrap {
  max-width: 940px;
  margin: 0 auto;
  padding: 0 20px 88px;
}

.topbar {
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  height: 58px;
  margin-bottom: 30px;
  padding: 0 20px;
  margin-left: -20px;
  margin-right: -20px;
  background: rgba(10, 13, 12, .82);
  -webkit-backdrop-filter: saturate(140%) blur(12px);
  backdrop-filter: saturate(140%) blur(12px);
  border-bottom: 1px solid var(--line);
}

.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  text-decoration: none;
  color: var(--ink);
  min-width: 0;
}

.brand:hover { text-decoration: none; }

/* Tanda: kotak mikro dengan busur NFC. Digambar CSS + SVG, bukan berkas
   gambar — satu permintaan lebih sedikit, dan tetap tajam di semua layar. */
.brand-mark {
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  flex: none;
  border-radius: 9px;
  background: linear-gradient(160deg, var(--accent), #1c8a63);
  color: var(--accent-ink);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .35);
}

.brand-mark svg { width: 17px; height: 17px; display: block; }

.brand-text {
  display: flex;
  align-items: baseline;
  gap: 8px;
  min-width: 0;
}

.brand-text b {
  font-size: 16px;
  font-weight: 650;
  letter-spacing: -.02em;
}

.brand-text i {
  font-style: normal;
  font-size: 12px;
  color: var(--ink-3);
  white-space: nowrap;
}

/* Pratinjau merek di /admin/merek.php. Meniru topbar supaya yang diketik di
   kolom atas terlihat persis seperti yang nanti muncul di kepala halaman. */
.brand-preview {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--surface-2);
}
.brand-preview .brand-text b { font-size: 16px; font-weight: 650; letter-spacing: -.02em; }
.brand-preview .brand-text i { font-size: 12px; color: var(--ink-3); font-style: normal; }

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

.topnav a {
  font-size: 13.5px;
  color: var(--ink-2);
  text-decoration: none;
  padding: 7px 12px;
  border-radius: 8px;
  transition: background .14s, color .14s;
}

.topnav a:hover { background: var(--surface-2); color: var(--ink); }

.topnav a[aria-current="page"] {
  background: var(--surface-2);
  color: var(--ink);
  font-weight: 600;
}

.topnav a:last-child { color: var(--ink-3); }

/* ------------------------------------------------------------------ heads */

.page-head { margin-bottom: 22px; }

.page-head h1 { font-size: 25px; }

.page-head p {
  color: var(--ink-2);
  font-size: 14px;
  margin-top: 7px;
  max-width: 58ch;
  line-height: 1.55;
}

.page-head .note { max-width: 58ch; }

/* Judul dan tombol aksi dalam satu baris: di layar lebar tombolnya menempel
   kanan, di HP turun sendiri ke bawah judul. */
.head-row {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 14px 18px;
  flex-wrap: wrap;
  margin-bottom: 22px;
}

.head-row .page-head { margin-bottom: 0; }
.head-row .head-actions { display: flex; gap: 8px; flex-wrap: wrap; }

.narrow { max-width: 520px; margin-left: auto; margin-right: auto; }

/* ------------------------------------------------------------------ hero */

/* Halaman depan: satu kalimat, satu tombol, satu contoh kartu. Kartunya
   digambar dengan CSS, jadi tidak ada berkas gambar yang perlu diunduh dan
   tampilannya tetap tajam di layar apa pun. */
.hero {
  display: grid;
  grid-template-columns: 1.05fr .95fr;
  align-items: center;
  gap: 48px;
  padding: 34px 0 20px;
}

.hero h1 {
  font-size: 40px;
  font-weight: 800;
  letter-spacing: -.045em;
  line-height: 1.06;
}

.hero p {
  color: var(--ink-2);
  font-size: 16px;
  line-height: 1.55;
  margin-top: 14px;
  max-width: 42ch;
}

.hero-actions {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  margin-top: 26px;
}

.hero-points {
  list-style: none;
  padding: 0;
  margin: 30px 0 0;
  display: grid;
  gap: 11px;
}

.hero-points li {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 13.5px;
  color: var(--ink-2);
}

.hero-points svg { width: 16px; height: 16px; flex: none; color: var(--accent); }

.hero-art { display: flex; justify-content: center; }

/* ------------------------------------------------------- kartu ulasan (gcard) */

/* Bingkai gradasi empat warna Google, isi gelap, QR putih di tengah. Ini
   tiruan kartu yang dipegang pelanggan di meja — sama persis di layar depan,
   di halaman aktivasi, dan di halaman kartu admin. */
.gcard {
  position: relative;
  width: 268px;
  padding: 2px;
  border-radius: 24px;
  background: linear-gradient(155deg,
              var(--g-red) 0%, var(--g-yellow) 34%,
              var(--g-green) 66%, var(--g-blue) 100%);
  box-shadow: 0 24px 60px -24px rgba(0, 0, 0, .9);
}

.gcard-in {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0;
  padding: 22px 20px 18px;
  border-radius: 22px;
  background: #0f1413;
  text-align: center;
}

.gcard-lead {
  font-size: 12px;
  font-weight: 500;
  color: #9aa6a2;
  letter-spacing: .01em;
}

/* Huruf Google satu per satu: G biru, o merah, o kuning, g biru, l hijau,
   e merah. Ditulis sebagai teks, bukan logo gambar — tetap tajam, tetap
   ringan, dan tidak perlu izin pakai berkas logo. */
.g-wordmark {
  display: flex;
  font-size: 33px;
  font-weight: 700;
  letter-spacing: -.045em;
  line-height: 1.25;
  margin-top: 2px;
}

.g-wordmark i { font-style: normal; }
.g-wordmark i:nth-child(1) { color: var(--g-blue); }
.g-wordmark i:nth-child(2) { color: var(--g-red); }
.g-wordmark i:nth-child(3) { color: var(--g-yellow); }
.g-wordmark i:nth-child(4) { color: var(--g-blue); }
.g-wordmark i:nth-child(5) { color: var(--g-green); }
.g-wordmark i:nth-child(6) { color: var(--g-red); }

.gcard-stars {
  display: block;
  margin-top: 1px;
  color: var(--g-yellow);
  font-size: 15px;
  letter-spacing: .12em;
  /* Bintang teks, bukan SVG: tidak menambah permintaan berkas dan tetap
     terbaca walau halaman dicetak hitam putih. */
}

/* QR selalu putih dengan modul hitam: kamera HP butuh kontras itu. Bingkai
   tipis berwarna di luarnya cuma hiasan, tidak mengubah area yang dipindai. */
.gcard-qr {
  margin-top: 16px;
  padding: 2px;
  border-radius: 18px;
  background: var(--g-bar);
}

.gcard-qr > div {
  padding: 12px;
  border-radius: 16px;
  background: #fff;
  line-height: 0;
}

.gcard-qr canvas, .gcard-qr img {
  display: block;
  width: 152px;
  height: 152px;
  image-rendering: pixelated;
}

.gcard-scan {
  margin-top: 14px;
  font-size: 14px;
  font-weight: 650;
  color: #fff;
  letter-spacing: -.01em;
}

.gcard-foot {
  margin-top: 13px;
  padding-top: 12px;
  border-top: 1px solid #202826;
  width: 100%;
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: #6e7975;
}

.gcard-foot b { color: #a2adaa; font-weight: 700; }

/* Kartu ukuran besar di halaman aktivasi: satu-satunya hal yang dilihat
   pemilik usaha setelah kodenya tersimpan. */
.gcard.is-lg { width: 320px; }
.gcard.is-lg .gcard-qr canvas,
.gcard.is-lg .gcard-qr img { width: 186px; height: 186px; }

.gcard-wrap { display: flex; justify-content: center; }

/* Tanda centang besar sebagai penutup alur aktivasi: satu-satunya saat
   halaman ini memakai warna hijau penuh, supaya "berhasil" langsung terbaca
   tanpa membaca kalimatnya. */
.done-badge {
  width: 46px;
  height: 46px;
  margin: 0 auto 16px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--accent-soft);
  border: 1px solid var(--accent-line);
  color: var(--accent);
}

.done-badge svg { width: 22px; height: 22px; }

/* Kalimat tunggal di bawah kartu hasil aktivasi, lalu dua tombol. */
.done-hint {
  margin: 20px 0 0;
  text-align: center;
  font-size: 13px;
  color: var(--ink-3);
}

.done-actions { justify-content: center; margin-top: 14px; }

.lbl-opt { font-weight: 400; color: var(--ink-3); }

.form-foot {
  font-size: 12px;
  color: var(--ink-3);
  margin-top: 14px;
  text-align: center;
}

/* ------------------------------------------------------------------ panel */

.panel {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r);
  padding: 20px;
}

.panel + .panel { margin-top: 14px; }

.panel-title {
  font-size: 13px;
  font-weight: 650;
  letter-spacing: .01em;
  color: var(--ink);
  margin-bottom: 16px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--line-2);
}

/* ------------------------------------------------------------------ forms */

.field { margin-bottom: 18px; }
.field:last-child { margin-bottom: 0; }

.field label {
  display: block;
  font-size: 13px;
  font-weight: 600;
  color: var(--ink);
  margin-bottom: 7px;
}

.field .hint {
  font-size: 12.5px;
  color: var(--ink-3);
  margin-top: 7px;
  line-height: 1.5;
}

.input {
  display: block;
  width: 100%;
  padding: 11px 13px;
  background: var(--bg-2);
  color: var(--ink);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  font-size: 16px; /* 16px: mencegah iOS memperbesar halaman saat fokus */
  transition: border-color .14s, box-shadow .14s, background .14s;
}

.input:hover { border-color: #303a37; }

.input:focus {
  outline: none;
  background: var(--bg);
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}

.input::placeholder { color: var(--ink-3); }

/* Kolom tautan yang sudah terkunci di admin. URL-nya panjang, jadi dibiarkan
   turun baris. Aturan ini sengaja tidak menempel di semua input readonly:
   kolom kode kartu juga readonly, dan gayanya beda jauh. */
.input-url[readonly] {
  color: var(--ink-2);
  background: var(--surface-2);
  border-style: dashed;
  /* URL panjang harus turun baris, bukan terpotong di tengah jalan. */
  overflow-wrap: anywhere;
  font-family: var(--mono);
  font-size: 13px;
}

/* Lipatan opsional di dalam form: judulnya saja yang kelihatan sampai diketuk.
   Dipakai untuk kolom yang jarang dipakai, supaya form tidak terasa panjang. */
.adv {
  margin: 0 0 18px;
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: var(--bg-2);
}

.adv > summary {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 11px 13px;
  font-size: 13px;
  font-weight: 600;
  color: var(--ink-2);
  cursor: pointer;
  list-style: none;
  border-radius: var(--r-sm);
  transition: color .14s, background .14s;
}

.adv > summary::-webkit-details-marker { display: none; }

/* Judul dua baris: baris pertama nama kolomnya, baris kedua kapan dipakai.
   Tanpa baris kedua, orang tidak tahu ini jalan alternatif dan mengira form
   cuma punya satu cara. */
.adv-txt {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.adv-t { font-size: 13px; font-weight: 600; color: var(--ink-2); }

.adv-s {
  font-size: 11.5px;
  font-weight: 500;
  line-height: 1.35;
  color: var(--ink-3);
}

.adv > summary:hover .adv-t,
.adv[open] > summary .adv-t { color: var(--ink); }

/* Tanda plus/minus kecil di kanan: satu-satunya petunjuk bahwa ini bisa dibuka. */
.adv > summary::after {
  content: '';
  width: 7px;
  height: 7px;
  margin-left: auto;
  border-right: 1.5px solid var(--ink-3);
  border-bottom: 1.5px solid var(--ink-3);
  transform: rotate(45deg) translate(-2px, -2px);
  transition: transform .16s;
}

.adv[open] > summary::after { transform: rotate(225deg) translate(-2px, -2px); }

.adv > summary:hover { color: var(--ink); background: var(--surface-2); }

.adv > summary:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.adv[open] > summary {
  color: var(--ink);
  border-bottom: 1px solid var(--line-2);
  border-radius: var(--r-sm) var(--r-sm) 0 0;
}

.adv > .field { padding: 14px 13px; margin-bottom: 0; }

.input-code {
  font-family: var(--mono);
  font-size: 22px;
  font-weight: 600;
  letter-spacing: .28em;
  text-align: center;
  text-transform: uppercase;
  padding: 15px 14px 15px 20px;
  background: var(--surface-2);
}

/* Kode dari tautan QR terkunci. Kursor teks diganti panah supaya kolomnya
   tidak terbaca seperti masih bisa diketik. */
.input-code[readonly] {
  cursor: default;
}

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 10px 17px;
  min-height: 40px;
  border: 1px solid transparent;
  border-radius: var(--r-sm);
  background: var(--accent);
  color: var(--accent-ink);
  font-size: 13.5px;
  font-weight: 640;
  letter-spacing: -.005em;
  cursor: pointer;
  text-decoration: none;
  white-space: nowrap;
  transition: filter .14s, background .14s, border-color .14s;
}

.btn:hover { filter: brightness(1.08); text-decoration: none; }
.btn:active { filter: brightness(.95); }

.btn[disabled] {
  background: var(--surface-3);
  color: var(--ink-3);
  cursor: not-allowed;
  filter: none;
}

.btn-quiet {
  background: var(--surface-2);
  border-color: var(--line);
  color: var(--ink-2);
  font-weight: 560;
}

.btn-quiet:hover { background: var(--surface-3); color: var(--ink); filter: none; }

.btn-danger {
  background: transparent;
  border-color: var(--line);
  color: var(--danger);
  font-weight: 560;
}

.btn-danger:hover {
  background: var(--danger-soft);
  border-color: var(--danger-line);
  filter: none;
}

.btn-sm { padding: 6px 12px; min-height: 32px; font-size: 12.5px; }
.btn-block { width: 100%; }

/* ------------------------------------------------------------------ notes */

.note {
  padding: 12px 14px;
  border-radius: var(--r-sm);
  font-size: 13px;
  line-height: 1.55;
  border: 1px solid var(--line);
  background: var(--surface-2);
  color: var(--ink-2);
}

.note b { color: inherit; font-weight: 640; }

.note-ok {
  background: var(--accent-soft);
  border-color: var(--accent-line);
  color: #b6efd6;
}

.note-warn {
  background: var(--warn-soft);
  border-color: var(--warn-line);
  color: #f2d3a2;
}

.note-err {
  background: var(--danger-soft);
  border-color: var(--danger-line);
  color: #f8c0ba;
}

.note .code { color: inherit; }

.note + .note { margin-top: 10px; }

/* ------------------------------------------------------------------ stats */

/* Satu permukaan dengan sekat 1px, bukan empat kartu terpisah. Lebih tenang,
   dan angkanya jadi satu blok yang bisa dibandingkan sekilas. */
.stats {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
  border-radius: var(--r);
  overflow: hidden;
  margin-bottom: 18px;
}

.stat {
  background: var(--surface);
  padding: 14px 16px 15px;
  min-width: 0;
}

.stat b {
  display: block;
  font-size: 26px;
  font-weight: 640;
  letter-spacing: -.03em;
  line-height: 1.05;
  font-variant-numeric: tabular-nums;
}

.stat span {
  display: block;
  font-size: 12px;
  color: var(--ink-3);
  margin-top: 5px;
  line-height: 1.3;
}

.stat.is-brand b { color: var(--accent); }

/* ------------------------------------------------------------------ table */

.table-wrap {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r);
  overflow: hidden;
}

table { width: 100%; border-collapse: collapse; }

th {
  text-align: left;
  font-size: 12px;
  font-weight: 600;
  color: var(--ink-3);
  padding: 11px 14px;
  background: var(--bg-2);
  border-bottom: 1px solid var(--line);
  white-space: nowrap;
}

td {
  padding: 13px 14px;
  border-bottom: 1px solid var(--line-2);
  font-size: 14px;
  vertical-align: middle;
}

tr:last-child td { border-bottom: 0; }
tbody tr { transition: background .12s; }
tbody tr:hover { background: var(--surface-2); }

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

.code {
  font-family: var(--mono);
  font-size: 13.5px;
  font-weight: 600;
  letter-spacing: .08em;
  color: var(--ink);
}

.biz { color: var(--ink); font-weight: 500; }
.biz small {
  display: block;
  color: var(--ink-3);
  font-weight: 400;
  font-size: 12px;
  margin-top: 2px;
}

.pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 11.5px;
  font-weight: 600;
  padding: 4px 10px 4px 8px;
  border-radius: 100px;
  white-space: nowrap;
  border: 1px solid transparent;
}

.pill::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
  flex: none;
}

.pill-blank     { background: var(--surface-2); color: var(--ink-3); border-color: var(--line); }
.pill-active    { background: var(--accent-soft); color: var(--accent); border-color: var(--accent-line); }
.pill-unclaimed { background: var(--warn-soft); color: var(--warn); border-color: var(--warn-line); }
.pill-disabled  { background: var(--danger-soft); color: var(--danger); border-color: var(--danger-line); }

.empty {
  padding: 52px 24px;
  text-align: center;
  color: var(--ink-3);
  font-size: 14px;
  line-height: 1.6;
}

.empty b { color: var(--ink-2); font-weight: 600; }

/* ------------------------------------------------------------------ filter */

.filters {
  display: flex;
  gap: 8px;
  margin-bottom: 14px;
  flex-wrap: wrap;
}

.filters .input { flex: 1; min-width: 170px; padding: 9px 12px; font-size: 14px; min-height: 40px; }

.filters select {
  padding: 9px 30px 9px 12px;
  min-height: 40px;
  font-size: 13.5px;
  border-radius: var(--r-sm);
  border: 1px solid var(--line);
  background-color: var(--surface);
  color: var(--ink-2);
  appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, var(--ink-3) 50%),
                    linear-gradient(135deg, var(--ink-3) 50%, transparent 50%);
  background-position: right 15px center, right 10px center;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
}

.filters select:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}

/* Satuan "scan" hanya muncul saat tabel berubah jadi kartu di layar sempit. */
.c-scan-unit { display: none; }

/* ------------------------------------------------------------------ activation */

.act-grid {
  display: grid;
  grid-template-columns: 1.15fr .85fr;
  gap: 16px;
  align-items: start;
}

.steps { counter-reset: s; list-style: none; padding: 0; margin: 0; }
.steps li {
  counter-increment: s;
  position: relative;
  padding-left: 32px;
  margin-bottom: 14px;
  font-size: 13.5px;
  color: var(--ink-2);
  line-height: 1.5;
}
.steps li:last-child { margin-bottom: 0; }
.steps li::before {
  content: counter(s);
  position: absolute;
  left: 0; top: 1px;
  width: 21px; height: 21px;
  border-radius: 7px;
  background: var(--surface-2);
  border: 1px solid var(--line);
  color: var(--ink-2);
  font-size: 11px;
  font-weight: 700;
  display: grid;
  place-items: center;
  font-variant-numeric: tabular-nums;
}

/* ------------------------------------------------------------ kartu admin */

/* Satu kartu: kartu fisiknya di kiri, pekerjaannya di kanan. Yang tampil bukan
   tiruan — markupnya sama dengan lembar cetak 85 × 85 mm — jadi yang dilihat
   penjual di layar persis yang dipegang pelanggan. */
.k-title {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin: 0;
}

.k-code {
  font-family: var(--mono);
  font-size: 23px;
  font-weight: 650;
  letter-spacing: .13em;
  line-height: 1.1;
}

.k-caption {
  margin-top: 12px;
  text-align: center;
  font-size: 12px;
  color: var(--ink-3);
}

.k-caption b { font-weight: 600; color: var(--ink-2); }

.k-body {
  margin: 0;
  font-size: 13.5px;
  line-height: 1.55;
  color: var(--ink-2);
}

/* Baris keterangan di dalam panel: label kecil di atas, isinya di bawah. */
.k-row {
  margin-top: 20px;
  padding-top: 18px;
  border-top: 1px solid var(--line-2);
}

.k-row-t {
  margin-bottom: 9px;
  font-size: 12px;
  font-weight: 600;
  color: var(--ink-3);
}

.k-danger .panel-title { color: var(--danger); }

.act-grid .sq-show { margin-top: 0; }

/* ---------------------------------------------------------- pemilih usaha */

/* Kolom cari + daftar hasil, meniru dropdown Google Maps: nama tebal di atas,
   alamat dan rating sebagai baris kedua. Daftarnya mengalir di dalam halaman,
   bukan melayang di atasnya — di HP keyboard menutup separuh layar, dan
   daftar yang melayang jadi tidak bisa digulir. */
.picker { position: relative; }

/* Tinggi daftar mengikuti isi sampai batas 50vh. Satu halaman hasil Google
   berisi 20 tempat; dengan tinggi tetap 268px hanya sekitar empat baris yang
   terlihat dan sisanya tersembunyi tanpa tanda apa pun. */
.picker-list {
  list-style: none;
  margin: 8px 0 0;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: var(--surface);
  max-height: min(50vh, 420px);
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
}

/* Daftar yang bisa digulir memotong baris terakhir tepat di tengah teks, dan
   itu terbaca seperti daftar rusak. Fade tipis di bawah hanya dipasang kalau
   memang masih ada isi (kelas .is-more dari JS), jadi daftar pendek tetap
   tampil utuh tanpa bayangan palsu. */
.picker-list.is-more {
  -webkit-mask-image: linear-gradient(#000 calc(100% - 24px), transparent);
  mask-image: linear-gradient(#000 calc(100% - 24px), transparent);
}

/* Penghitung hasil di atas daftar: menjawab "cuma segini?" tanpa perlu
   menggulir sampai bawah. */
.picker-count {
  margin-top: 8px;
  padding: 0 2px 6px;
  font-size: 12px;
  font-weight: 600;
  color: var(--ink-3);
}

.picker-count[hidden] { display: none; }

/* Daftar langsung menempel di bawah penghitung, bukan 8px lagi. */
.picker-count:not([hidden]) + .picker-list { margin-top: 0; }

.picker-item {
  padding: 10px 13px;
  border-bottom: 1px solid var(--line-2);
  cursor: pointer;
  line-height: 1.35;
  transition: background .1s;
}

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

.picker-item b {
  display: block;
  font-size: 14px;
  font-weight: 600;
  color: var(--ink);
}

.picker-item span {
  display: block;
  font-size: 12px;
  color: var(--ink-3);
  margin-top: 3px;
}

.picker-item:hover,
.picker-item[aria-selected="true"] { background: var(--surface-2); }

.picker-item[aria-selected="true"] { box-shadow: inset 2px 0 0 var(--accent); }

.picker-msg {
  font-size: 12.5px;
  color: var(--ink-3);
  margin-top: 8px;
  min-height: 0;
  line-height: 1.5;
}

.picker-msg:empty { display: none; }

/* Usaha yang sudah dipilih menggantikan kolom cari, jadi yang terlihat tinggal
   keputusan akhirnya — bukan teks yang tadi diketik. */
.pick {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 11px 13px;
  border: 1px solid var(--accent-line);
  border-radius: var(--r-sm);
  background: var(--accent-soft);
}

.pick-text { flex: 1; min-width: 0; }

.pick-text b {
  display: block;
  font-size: 14px;
  font-weight: 620;
  color: #c9f4e1;
  overflow-wrap: anywhere;
}

.pick-text span {
  display: block;
  font-size: 12px;
  color: #7fb9a3;
  margin-top: 3px;
  line-height: 1.4;
}

.pick .btn {
  flex: none;
  background: transparent;
  border-color: var(--accent-line);
  color: #c9f4e1;
}
.pick .btn:hover { background: rgba(53, 207, 149, .18); }

/* ------------------------------------------------------------------ scan landing (jika JS mati) */

.fallback {
  max-width: 420px;
  margin: 12vh auto 0;
  text-align: center;
  padding: 30px 24px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r);
}

.fallback h1 { font-size: 21px; margin-bottom: 10px; }
.fallback p { color: var(--ink-2); font-size: 14px; margin-bottom: 20px; line-height: 1.6; }
.fallback .code { font-size: 15px; }

/* ------------------------------------------------------------------ print card */

/* Kartu yang akan dicetak. Tampil juga di layar sebagai pratinjau, jadi
   ukurannya harus sama enak di dua tempat — dan tetap kertas putih walau
   aplikasinya gelap: yang dilihat di sini adalah hasil cetaknya. */
.print-card {
  /* Variabel lokal: di dalam kartu ini semua warna kembali ke tinta gelap di
     atas kertas putih. */
  --ink: #101614;
  --ink-2: #4a544f;
  --ink-3: #78837d;
  --line: #dfe4e0;

  background: #fff;
  color: var(--ink);
  border: 1px solid #101614;
  border-radius: 12px;
  padding: 26px 22px;
  text-align: center;
  max-width: 320px;
  margin-left: auto;
  margin-right: auto;
}

.print-card h2 { font-size: 19px; margin-bottom: 3px; letter-spacing: -.01em; }
.print-card .pc-biz { font-size: 12px; color: var(--ink-2); margin-bottom: 18px; }

.print-card canvas, .print-card img {
  display: block;
  margin: 0 auto;
  width: 168px;
  height: 168px;
  image-rendering: pixelated;
}

.print-card .pc-code {
  font-family: var(--mono);
  font-size: 13px;
  letter-spacing: .24em;
  margin-top: 16px;
  color: var(--ink);
}

.print-card .pc-note {
  font-size: 11px;
  color: var(--ink-3);
  margin-top: 5px;
  line-height: 1.4;
}

/* ------------------------------------------------------------------ sheet kartu kosong */

/* Lembar isi 10 kartu (2 kolom x 5 baris) di A4. Ukuran di layar sama dengan
   ukuran cetak supaya pratinjaunya bisa dipercaya. */
.sheet {
  display: grid;
  grid-template-columns: repeat(2, 85mm);
  gap: 4mm;
  justify-content: center;
  padding: 4mm 0;
}

.card-blank {
  --ink: #101614;
  --ink-2: #4a544f;
  --ink-3: #78837d;

  border: 1px dashed #4a544f;
  border-radius: 3mm;
  padding: 3.5mm 4mm;
  /* 85 x 50 mm: 2 kolom x 5 baris = 10 kartu per A4 dengan margin 10 mm
     (250 mm + jarak = masih di bawah 277 mm ruang cetak). */
  height: 50mm;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-between;
  text-align: center;
  background: #fff;
  color: var(--ink);
}

.cb-head { line-height: 1.2; }
.cb-head b { display: block; font-size: 8pt; font-weight: 600; }
.cb-google {
  font-size: 9pt;
  font-weight: 700;
  letter-spacing: -.02em;
  /* Warna huruf Google, bukan logo: tidak perlu gambar dan tetap aman cetak. */
  background: linear-gradient(90deg, #4285f4 0 25%, #ea4335 25% 50%, #fbbc05 50% 75%, #34a853 75%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

/* Dua cara memakai kartu, bersebelahan: tempel HP (NFC) dan scan QR. */
.cb-mid {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6mm;
  flex: 1;
}

/* Label kedua kolom duduk di garis yang sama walau tingginya beda: ikon NFC
   lebih pendek dari QR, jadi isinya didorong ke bawah. */
.cb-nfc, .cb-scan {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  gap: 1mm;
  height: 21mm;
  font-size: 5.5pt;
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--ink-2);
}

.cb-nfc-svg { width: 12mm; height: 12mm; fill: currentColor; color: var(--ink); }

.cb-qr canvas, .cb-qr img {
  display: block;
  width: 18mm;
  height: 18mm;
  image-rendering: pixelated;
}

.cb-id { font-family: var(--mono); font-size: 9pt; letter-spacing: .16em; line-height: 1.1; }
.cb-id b { font-weight: 700; }
.cb-foot { font-size: 5pt; color: var(--ink-3); letter-spacing: .01em; }

/* ------------------------------------------------------------------ kartu persegi */

/* 85 x 85 mm, 4 per A4. Bentuk yang paling dikenal orang sebagai "kartu
   ulasan Google": bingkai empat warna, panel putih di tengah. Bidangnya lebih
   lega dari kartu nama, jadi QR-nya bisa 26 mm — terbaca dari jarak tangan
   tanpa perlu mendekat. */
.sheet-square {
  display: grid;
  grid-template-columns: repeat(2, 85mm);
  gap: 4mm;
  justify-content: center;
  padding: 4mm 0;
}

.card-sq {
  /* Bingkai empat warna digambar sebagai empat kotak latar, bukan berkas
     gambar: tetap tajam di 300 dpi dan tidak ada yang perlu diunduh. */
  position: relative;
  width: 85mm;
  height: 85mm;
  padding: 5.5mm;
  border-radius: 4mm;
  background:
    linear-gradient(#4285f4, #4285f4) left top / 50% 50% no-repeat,
    linear-gradient(#ea4335, #ea4335) right top / 50% 50% no-repeat,
    linear-gradient(#34a853, #34a853) left bottom / 50% 50% no-repeat,
    linear-gradient(#fbbc05, #fbbc05) right bottom / 50% 50% no-repeat;
  -webkit-print-color-adjust: exact;
  print-color-adjust: exact;
}

.cs-panel {
  height: 100%;
  border-radius: 3mm;
  background: #fff;
  color: #111614;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: 4mm 4.5mm 3mm;
  overflow: hidden;
}

/* Sebuah .card-sq selalu benda cetak 85 mm. Di layar sesudah aktivasi kartunya
   perlu lebih besar — di situlah pemilik usaha memeriksa hasilnya sebelum
   ditempel — tapi markupnya satu, jadi pembesarannya lewat font-size: semua
   ukuran di dalam panel memakai em, dan 10.5pt ≈ 85 mm. Yang tidak ikut em
   (bingkai, padding panel, QR mm) diatur ulang di sini. */
.sq-show {
  display: flex;
  justify-content: center;
  margin: 22px 0 6px;
}

.sq-show .card-sq {
  width: 300px;
  height: 300px;
  padding: 19px;
  border-radius: 14px;
  font-size: 10.5pt;
  /* Bayangan tipis, bukan gelap pekat: kartunya putih di atas latar hampir
     putih, jadi yang dibutuhkan cuma pemisah halus — bayangan hitam berat
     di sini terbaca seperti kotak kotor. */
  box-shadow: 0 20px 44px -24px rgba(0, 0, 0, .30), 0 1px 3px rgba(0, 0, 0, .06);
}

.sq-show .cs-panel {
  border-radius: 10px;
  padding: 14px 16px 11px;
  gap: 0;
}

.sq-show .cs-logo svg { width: 42px; height: 42px; }
.sq-show .cs-kicker { margin-top: 6px; font-size: .62em; }
.sq-show .cs-title { font-size: 1.43em; }
.sq-show .cs-dots { gap: 4px; margin-top: 6px; }
.sq-show .cs-dots i { width: 6px; height: 6px; }
.sq-show .cs-mid { gap: 18px; }
.sq-show .cs-nfc, .sq-show .cs-scan { gap: 5px; font-size: .44em; }
.sq-show .cs-nfc-svg { width: 39px; height: 39px; }
.sq-show .cs-or { font-size: .42em; }
.sq-show .sq-qr canvas, .sq-show .sq-qr img { width: 92px; height: 92px; }
.sq-show .cs-foot { padding-top: 7px; font-size: .44em; gap: 8px; }
.sq-show .cs-foot b { font-size: 1.04em; }

.cs-logo svg { display: block; width: 12mm; height: 12mm; }

.cs-kicker {
  margin-top: 1.6mm;
  font-size: 6.5pt;
  font-weight: 500;
  letter-spacing: .01em;
  color: #4a544f;
}

.cs-title {
  font-size: 15pt;
  font-weight: 750;
  letter-spacing: -.025em;
  line-height: 1.1;
  color: #111614;
}

/* Lima titik warna, bukan bintang: pada 85 mm bintang abu-abu terbaca seperti
   noda cetak, sedangkan lima titik tetap rapi. */
.cs-dots {
  display: flex;
  gap: 1.1mm;
  margin-top: 1.8mm;
}
.cs-dots i { width: 1.7mm; height: 1.7mm; border-radius: 50%; display: block; }

/* Ikon NFC dan QR tingginya beda jauh (11 mm vs 26 mm). Kalau dirata-bawah,
   ikon NFC menggantung rendah dan "atau" jatuh sendirian di bawah. Rata-tengah
   membuat keduanya terbaca sebagai dua pilihan yang setara. */
.cs-mid {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 5mm;
  margin-top: auto;
  width: 100%;
}

.cs-nfc, .cs-scan {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.4mm;
  font-size: 4.6pt;
  font-weight: 650;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: #4a544f;
}

.cs-nfc-svg { width: 11mm; height: 11mm; fill: currentColor; color: #111614; }

/* Sejajar dengan tengah QR, bukan dengan tepi bawahnya. */
.cs-or {
  align-self: center;
  font-size: 4.4pt;
  font-weight: 650;
  letter-spacing: .1em;
  color: #98a29d;
}

.sq-qr canvas, .sq-qr img {
  display: block;
  width: 26mm;
  height: 26mm;
  image-rendering: pixelated;
}

.cs-foot {
  margin-top: auto;
  width: 100%;
  padding-top: 2mm;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 2mm;
  font-size: 4.6pt;
  color: #78837d;
}
.cs-foot b {
  font-family: var(--mono);
  font-size: 4.8pt;
  font-weight: 600;
  letter-spacing: .12em;
  color: #4a544f;
}

/* Penanda "chip NFC sudah ditulis" di /admin/nfc.php. Bukan lencana penting —
   cuma supaya waktu menulis 40 kartu berturut-turut kelihatan mana yang
   terlewat, tanpa harus mengingat-ingat. */
.nfc-done {
  display: inline-block;
  margin-top: 4px;
  padding: 1px 7px;
  border: 1px solid var(--line);
  border-radius: 999px;
  font-size: 11px;
  letter-spacing: .02em;
  color: var(--ink-3);
}

/* ------------------------------------------------------------------ tenda meja */

/* Tenda untuk restoran dan hotel: nomor meja dan QR jadi satu benda.
   90 x 125 mm, 4 per A4. Warnanya bukan tema gelap aplikasi — ini benda cetak
   yang duduk di meja makan, jadi putih bersih dengan satu pita warna. */
.sheet-tent {
  display: grid;
  grid-template-columns: repeat(2, 90mm);
  gap: 6mm;
  justify-content: center;
  padding: 4mm 0;
}

.tent {
  /* --tent-accent diisi dari halaman cetak; ini cadangan kalau kosong. */
  --tent-accent: #b3352c;

  position: relative;
  width: 90mm;
  height: 125mm;
  /* 14 mm di bawah = tinggi pita, supaya isi tidak pernah ketiban pita. */
  padding: 8mm 7mm 14mm;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  background: #fff;
  color: #111614;
  border: 1px dashed #9aa39f;   /* garis potong */
  border-radius: 2mm;
  overflow: hidden;
}

.tt-top { width: 100%; }
.tt-client {
  font-size: 11pt;
  font-weight: 700;
  letter-spacing: -.01em;
  line-height: 1.15;
  color: #111614;
}
.tt-kicker {
  margin-top: 1mm;
  font-size: 6pt;
  font-weight: 600;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: #6b7570;
}

/* Nomornya yang harus kebaca dari seberang ruangan: itu satu-satunya alasan
   tenda ini ada di meja. */
.tt-num {
  margin: 6mm 0 0;
  font-size: 72pt;
  font-weight: 800;
  line-height: .95;
  letter-spacing: -.035em;
  color: var(--tent-accent);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
/* "Kamar 101" dan "Meja Tap 12" jauh lebih panjang dari "Meja 4". Tanpa
   undakan ukuran, yang panjang meluber keluar tenda. */
.tt-num-md { font-size: 50pt; }
.tt-num-sm { font-size: 34pt; }
.tt-num-empty {
  font-family: var(--mono);
  font-size: 22pt;
  letter-spacing: .1em;
  color: #111614;
}

/* QR didorong ke bawah supaya sisa ruang jatuh di antara nomor dan QR, bukan
   menganga di bawah keterangan. Nomor di atas, kode di bawah: itu urutan yang
   dibaca orang saat tenda ini menyapa dari seberang meja. */
.tt-qr-wrap {
  margin-top: auto;
  padding: 2.5mm;
  border: 1.2mm solid var(--tent-accent);
  border-radius: 3mm;
  background: #fff;
}
.tt-qr canvas, .tt-qr img {
  display: block;
  width: 32mm;
  height: 32mm;
  image-rendering: pixelated;
}

.tt-cta {
  display: flex;
  align-items: center;
  gap: 1.6mm;
  margin-top: 3mm;
  font-size: 7.5pt;
  font-weight: 650;
  color: #111614;
}
.tt-nfc { width: 6mm; height: 6mm; fill: currentColor; }

/* Pita di kaki tenda: satu-satunya bidang berwarna penuh. Kalau warnanya
   terlalu muda, teks putih tidak terbaca — karena itu pilihannya gelap. */
.tt-band {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 12mm;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 7mm;
  background: var(--tent-accent);
  color: #fff;
  font-size: 8pt;
  font-weight: 700;
  letter-spacing: .02em;
}
/* Tenda klien tidak mencetak ID, jadi tanpa ini nama merek menggantung di kiri
   dan separuh pita jadi bidang warna kosong. Tengahkan saja. */
.tt-band-solo { justify-content: center; }

.tt-band em {
  font-family: var(--mono);
  font-style: normal;
  font-size: 6.5pt;
  font-weight: 500;
  letter-spacing: .12em;
  opacity: .85;
}

/* ------------------------------------------------------------------ misc */

.muted { color: var(--ink-3); font-size: 13px; }

.backlink { margin-top: 16px; font-size: 13px; }
.backlink a { color: var(--ink-3); }
.backlink a:hover { color: var(--ink); }

.row-actions { display: flex; gap: 8px; flex-wrap: wrap; }

/* Tiga tombol per baris (Aktivasi / Buka / Hapus) tidak muat sebaris di kolom
   tabel selebar 940px. Tetap satu baris di desktop, dan yang paling sering
   dipakai — Buka — ditaruh paling kanan supaya sejajar antar baris. */
.row-act {
  display: flex;
  gap: 6px;
  justify-content: flex-end;
  flex-wrap: wrap;
}

/* Kotak centang pilih. Ukurannya dinaikkan: ini tombol yang mematikan kartu
   orang, dan kotak 13px bawaan browser terlalu kecil untuk jempol. */
.c-pick { width: 1px; padding-right: 0; }
.c-pick input[type="checkbox"] {
  width: 18px;
  height: 18px;
  margin: 0;
  accent-color: var(--accent);
  cursor: pointer;
  vertical-align: middle;
}

#pick-all { margin-left: 1px; }

/* Bilah "N dipilih" menempel di atas tabel selama ada yang dipilih, supaya
   tombol hapus massal tidak perlu dicari ke bawah pada daftar 129 kartu. */
.bulkbar {
  position: sticky;
  top: 8px;
  z-index: 30;
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  padding: 10px 12px;
  margin-bottom: 10px;
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--r);
  box-shadow: 0 10px 24px rgba(0, 0, 0, .35);
}

.bulkbar-n { font-size: 13px; color: var(--ink-2); margin-right: auto; }
.bulkbar-n b { color: var(--ink); font-size: 15px; }

/* Jalur "ikut hapus kartu aktif": satu baris sendiri di bawah tombol, selalu
   kelihatan supaya jalan keluarnya ketemu, tapi redup sampai dicentang.
   Kolom kata kuncinya mati sebelum dicentang. */
.bulk-force {
  flex: 1 0 100%;
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  padding-top: 10px;
  border-top: 1px dashed var(--line);
}

.bulk-check {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  color: var(--ink-2);
  cursor: pointer;
  user-select: none;
}
.bulk-check input { accent-color: var(--danger); }
.bulkbar.is-force .bulk-check { color: var(--danger); font-weight: 600; }

.bulk-word {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  color: var(--ink-3);
}
.bulk-word b { color: var(--danger); letter-spacing: .06em; }
.bulk-word .input {
  width: 96px;
  padding: 5px 9px;
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: .08em;
}
.bulk-word .input:disabled { opacity: .45; }

/* Kolom tautan + tombol Salin di halaman kartu. */
.copy-row { display: flex; gap: 8px; }
.copy-row .input { flex: 1; min-width: 0; }
.copy-row .btn { flex: none; }

.form-inline { display: inline; }

/* ------------------------------------------------------------------ print */

@media print {
  :root { color-scheme: light; }

  body { background: #fff; color: #000; }
  .topbar, .no-print, .page-head p, .backlink { display: none !important; }
  .wrap { max-width: none; padding: 0; }
  .panel {
    border: 0;
    background: transparent;
    padding: 0;
    color: #000;
  }
  .act-grid { grid-template-columns: 1fr; }

  .print-card {
    border: 1px solid #000;
    border-radius: 12px;
    padding: 24px;
    max-width: 78mm;
    page-break-inside: avoid;
  }
  .print-card h2 { font-size: 17px; }
  .print-card .pc-biz { font-size: 11px; margin-bottom: 14px; }
  .print-card canvas, .print-card img { width: 42mm; height: 42mm; }
  .print-card .pc-code { font-size: 12px; margin-top: 12px; }
  .print-card .pc-note { font-size: 10px; }

  /* Lembar kartu kosong: garis putus-putus di layar jadi garis potong tipis
     saat dicetak, dan tiap 10 kartu pindah halaman. */
  @page { size: A4; margin: 10mm; }
  .sheet {
    grid-template-columns: repeat(2, 85mm);
    gap: 4mm;
    padding: 0;
    page-break-after: always;
  }
  .card-blank {
    border: 1px solid #999;
    page-break-inside: avoid;
  }

  /* Kartu kotak: 2 x 2 per A4, ukuran sama dengan kartu nama jadi grid-nya
     ikut aturan di atas. Bingkainya warna, bukan garis — printer tidak boleh
     menipiskannya. */
  .sheet-square {
    gap: 4mm;
    padding: 0;
    page-break-after: always;
  }
  .card-sq {
    page-break-inside: avoid;
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }
  .card-sq .cs-dots i,
  .card-sq .cs-logo svg {
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }

  /* Tenda: 2 x 2 per A4. Garis potong tetap dicetak supaya bisa dipotong
     lurus, tapi tipis saja — 1 px hitam pekat ikut terlihat di tepi tenda. */
  .sheet-tent {
    grid-template-columns: repeat(2, 90mm);
    gap: 6mm;
    padding: 0;
    page-break-after: always;
  }
  .tent {
    border: 1px solid #b9c0bd;
    page-break-inside: avoid;
    /* Warna pita harus benar-benar tercetak, bukan ditipiskan printer. */
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }
  .tt-band {
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }
}

/* ------------------------------------------------------------------ responsive */

@media (max-width: 720px) {
  .wrap { padding: 0 16px 72px; }

  /* Di HP, merek dan menu tidak muat sebaris: begitu nama merek diisi enam
     sampai delapan huruf, menu "Kartu" tertimpa teks merek — dan yang paling
     awal justru yang paling sering dipakai. Jadi topbar turun jadi dua baris:
     merek di atas, menu menggulir mendatar di bawahnya kalau masih sempit. */
  .topbar {
    flex-wrap: wrap;
    height: auto;
    padding: 10px 16px 0;
    margin-left: -16px;
    margin-right: -16px;
    row-gap: 2px;
  }
  .brand { padding-bottom: 8px; }
  .topnav {
    order: 3;
    width: 100%;
    overflow-x: auto;
    scrollbar-width: none;
    padding-bottom: 4px;
  }
  .topnav::-webkit-scrollbar { display: none; }
  .page-head h1 { font-size: 22px; }
  .panel { padding: 17px; }
  .stats { grid-template-columns: repeat(2, 1fr); }
  .act-grid { grid-template-columns: 1fr; }
  .hide-sm { display: none; }
  th, td { padding: 10px 12px; }

  /* Lembar cetak bersatuan milimeter dan tidak boleh dikecilkan: kalau
     dikecilkan, pratinjau di HP tidak lagi sama dengan hasil printer. Jadi
     di layar sempit lembarnya sendiri yang jadi area gulir, rata kiri —
     dengan perataan tengah, kelebihan lebarnya tumpah ke kiri dan kolom
     pertama jadi tidak bisa dijangkau sama sekali. */
  .sheet, .sheet-square, .sheet-tent {
    justify-content: start;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    padding-bottom: 10px;
  }
  .brand-text i { display: none; }
  .topnav a { padding: 7px 9px; }

  /* Halaman depan di HP: teks dulu, contoh kartu di bawahnya. Dua kolom
     berdesakan di 390px dan judulnya jadi pecah tiga baris. */
  .hero { grid-template-columns: 1fr; gap: 34px; padding: 18px 0 0; text-align: center; }
  .hero h1 { font-size: 30px; }
  .hero p { margin-left: auto; margin-right: auto; font-size: 15px; }
  .hero-actions { justify-content: center; }
  .hero-actions .btn { flex: 1; min-width: 150px; }
  .hero-points { text-align: left; max-width: 300px; margin-left: auto; margin-right: auto; }
  .hero-art { order: -1; }
  .gcard { width: 240px; }
  .gcard-qr canvas, .gcard-qr img { width: 136px; height: 136px; }
}

@media (max-width: 420px) {
  .topnav { gap: 0; }
  .topnav a { font-size: 13px; padding: 7px 8px; }
  .filters .btn { flex: 1; }
}

/* Tabel daftar kartu di layar sempit.

   Enam kolom tidak akan pernah muat di 360px, dan membiarkannya meluber
   membuat tombol "Buka" — satu-satunya jalan masuk ke sebuah kartu —
   terpotong di tepi kanan. Jadi di bawah 720px tabelnya berhenti jadi tabel:
   tiap baris jadi satu kartu kecil, dan tombolnya pindah ke dalam kartu. */
@media (max-width: 720px) {
  .table-wrap {
    background: transparent;
    border: 0;
    border-radius: 0;
    overflow: visible;
  }

  table, tbody, tr, td { display: block; }
  thead { display: none; }

  tbody tr {
    display: grid;
    /* Kolom pertama selebar kotak centang saja, sisanya untuk kode dan isi.
       Tanpa kolom khusus, centang dan kode saling menimpa di baris pertama. */
    grid-template-columns: auto 1fr auto;
    align-items: center;
    gap: 3px 10px;
    padding: 13px 14px;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--r);
    margin-bottom: 9px;
  }

  tbody tr:last-child { margin-bottom: 0; }

  /* Latar hover baris tidak berarti lagi setelah jadi kartu terpisah. */
  tbody tr:hover { background: var(--surface); }

  tbody td {
    padding: 0;
    border: 0;
    font-size: 14px;
  }

  .c-pick   { grid-column: 1; grid-row: 1; width: auto; justify-self: start; }
  .c-pick input[type="checkbox"] { width: 20px; height: 20px; }
  .c-code   { grid-column: 2; grid-row: 1; }
  .c-status { grid-column: 3; grid-row: 1; justify-self: end; }
  .c-biz    { grid-column: 2 / -1; grid-row: 2; margin-top: 1px; }
  .c-scan   { grid-column: 2; grid-row: 3; text-align: left; margin-top: 6px;
              font-size: 13px; color: var(--ink-3); }
  .c-act    { grid-column: 3; grid-row: 3; justify-self: end; margin-top: 6px; }
  .c-act .row-act { flex-wrap: nowrap; }

  /* Di HP tombol per baris mengecil tapi jangan sampai jadi sasaran jempol
     yang salah: tinggi minimal tetap 34px dan jaraknya dilebarkan. */
  .c-act .btn-sm { min-height: 34px; padding: 6px 11px; }

  /* Bilah pilih menempel ke bawah layar, bukan ke atas: di HP jempol ada di
     bawah, dan topbar yang ikut menggulir membuat `top` jadi tidak menentu. */
  .bulkbar {
    position: sticky;
    top: auto;
    bottom: 10px;
    box-shadow: 0 -6px 20px rgba(0, 0, 0, .4);
  }
  .bulkbar-n { margin-right: 0; width: 100%; }
  .bulkbar .btn { flex: 1; }

  .c-scan, .c-scan-unit { display: inline; }
  .c-scan { font-variant-numeric: tabular-nums; }

  /* Baris saring: kolom cari selebar layar, tombol di baris sendiri supaya
     tidak berdesakan dengan select. */
  .filters { display: grid; grid-template-columns: 1fr auto; align-items: center; }
  .filters .input { grid-column: 1 / -1; min-width: 0; }
  .filters select { min-width: 0; }
  .filters > a.btn { grid-column: 1 / -1; }
}

/* Kertas A4 selebar ~190 mm setelah margin, jadi blok 720px di atas ikut
   berlaku saat mencetak. Di kertas tidak ada yang bisa digulir: lembar harus
   kembali rata tengah dan tanpa area gulir. */
@media print {
  .sheet, .sheet-square, .sheet-tent { justify-content: center; overflow: visible; padding-bottom: 0; }
}

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
}

/* ==================================================================
   TEMA TERANG — seluruh situs
   ==================================================================

   Latar hampir putih, satu permukaan putih, teks abu, satu warna aksen biru.
   Dipakai di semua halaman: yang dilihat pelanggan (/a/KODE), yang diisi
   pemilik usaha (/aktifkan.php), dan panel kerja penjual (/admin). Satu merek,
   satu wajah — admin tidak lagi punya tema sendiri.

   Semua aturan di bawah berawalan `.theme-light`. Yang di-override hanya token
   warna dan beberapa permukaan yang dulu ditulis dengan nilai gelap tetap
   (.topbar, .brand-mark, bayangan .bulkbar). Tata letak, ukuran huruf, dan —
   yang paling penting — geometri kartu cetak 85 mm tidak berubah sama sekali,
   karena `.card-sq`, `.cs-panel`, `.print-card`, dan `.tent` menetapkan
   warnanya sendiri dan tidak ikut token. */

.theme-light {
  color-scheme: light;

  --bg: #fafafa;
  --bg-2: #ffffff;
  --surface: #ffffff;
  --surface-2: #f5f5f7;
  --surface-3: #ebebed;

  --line: #e3e3e6;
  --line-2: #efeff1;

  --ink: #1d1d1f;
  --ink-2: #6e6e73;
  --ink-3: #8e8e93;

  --accent: #0071e3;
  --accent-ink: #ffffff;
  --accent-soft: rgba(0, 113, 227, .10);
  --accent-line: rgba(0, 113, 227, .30);

  --warn: #a35a00;
  --warn-soft: #fff6e8;
  --warn-line: #f2d8b4;

  --danger: #d70015;
  --danger-soft: #fff0ef;
  --danger-line: #f5c3c0;
}

/* Garis empat warna di puncak halaman dihilangkan: rujukan yang diminta
   pemilik benar-benar tanpa hiasan apa pun. */
body.theme-light::before { display: none; }

/* ------------------------------------------------------------------ shell admin */

/* Topbar ditulis dengan satu nilai gelap tetap supaya bisa tembus pandang di
   atas latar gelap. Di atas putih nilai itu jadi pita arang. Diganti putih
   susu yang sama tembusnya, dengan garis bawah yang tipis saja. */
.theme-light .topbar {
  background: rgba(255, 255, 255, .86);
  -webkit-backdrop-filter: saturate(180%) blur(14px);
  backdrop-filter: saturate(180%) blur(14px);
}

/* Tanda merek: gradasi aksen → hijau tua. Dengan aksen biru hasilnya biru
   berlumur hijau, jadi gradasinya dibatasi ke keluarga biru saja. */
.theme-light .brand-mark {
  background: linear-gradient(160deg, #2f8ef0, #0059b8);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .30);
}

/* Tombol "Keluar" sengaja paling redup di menu; di atas putih --ink-3 masih
   terbaca, tapi hover-nya perlu latar sendiri. */
.theme-light .topnav a:last-child:hover { background: var(--surface-2); }

/* Bilah pilih-massal melayang di atas tabel, jadi butuh bayangan. Nilai gelap
   35% di atas putih terbaca seperti noda, bukan seperti lapisan. */
.theme-light .bulkbar {
  background: rgba(255, 255, 255, .94);
  -webkit-backdrop-filter: saturate(160%) blur(10px);
  backdrop-filter: saturate(160%) blur(10px);
  box-shadow: 0 8px 24px -8px rgba(0, 0, 0, .16), 0 1px 2px rgba(0, 0, 0, .04);
}

/* ------------------------------------------------------------------ shell publik */

.wrap-pub {
  max-width: 560px;
  padding: 0 20px 56px;
}

.pub-brand {
  margin: 26px 0 0;
  text-align: center;
}

.pub-brand-a {
  font-size: 13px;
  font-weight: 600;
  letter-spacing: .01em;
  color: var(--ink-3);
}

.pub-brand-a:hover { color: var(--ink); text-decoration: none; }

.pub {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-height: calc(100svh - 140px);
  padding: 32px 0 0;
}

.pub-card {
  width: 100%;
  max-width: 480px;
  padding: 44px 40px 40px;
  background: var(--surface);
  border-radius: 22px;
  text-align: center;
  /* Satu bayangan lebar dan lembut, bukan bingkai: kartu terangkat dari latar
     tanpa garis tepi yang menambah satu lagi elemen untuk dilihat. */
  box-shadow:
    0 1px 2px rgba(0, 0, 0, .04),
    0 18px 48px -18px rgba(0, 0, 0, .14);
}

.pub-h1 {
  font-size: 28px;
  font-weight: 700;
  letter-spacing: -.028em;
  line-height: 1.15;
  color: var(--ink);
}

.pub-lead {
  margin: 14px auto 0;
  max-width: 38ch;
  font-size: 15.5px;
  line-height: 1.65;
  color: var(--ink-2);
}

.pub-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 46px;
  margin-top: 26px;
  padding: 12px 26px;
  border-radius: 999px;
  background: var(--accent);
  color: var(--accent-ink);
  font-size: 15px;
  font-weight: 600;
  letter-spacing: -.005em;
  transition: background .14s;
}

.pub-btn:hover { background: #0077ed; text-decoration: none; }
.pub-btn:active { background: #0062c4; }

.pub-foot {
  margin-top: 26px;
  font-size: 13.5px;
  line-height: 1.6;
  color: var(--ink-3);
  text-align: center;
}

.pub-foot a { color: var(--accent); font-weight: 500; }

/* ------------------------------------------------------------------ penyesuaian terang */

/* `.input:hover` di tema gelap memakai satu nilai hex tetap; di sini harus
   ikut token, kalau tidak kolom jadi berbingkai abu tua di atas putih. */
.theme-light .input:hover { border-color: #c9c9ce; }
.theme-light .input:focus { background: var(--surface); }

.theme-light .panel { box-shadow: 0 1px 2px rgba(0, 0, 0, .03); }

/* Tiga warna catatan di tema gelap dipilih supaya terbaca di atas hitam.
   Di atas putih semuanya terlalu pucat, jadi diganti versi gelap. */
.theme-light .note-ok   { background: #eefaf1; border-color: #c4e9d0; color: #0f6b33; }
.theme-light .note-warn { background: #fff7e8; border-color: #f0d9b0; color: #8a5200; }
.theme-light .note-err  { background: #fff0ef; border-color: #f3c4c1; color: #b00014; }

/* Kotak "usaha terpilih": latarnya sudah ikut aksen, tapi teksnya masih
   memakai hijau tetap dari tema gelap. */
.theme-light .pick-text b { color: #0b3d75; }
.theme-light .pick-text span { color: #5a7a9e; }
.theme-light .pick .btn { color: #0b3d75; }
.theme-light .pick .btn:hover { background: rgba(0, 113, 227, .12); }

/* Centang "berhasil" tetap hijau, bukan biru: warna aksen di sini berarti
   tautan, sedangkan hijau berarti selesai. */
.theme-light .done-badge {
  background: #eafaf1;
  border-color: #c3ecd4;
  color: #12855a;
}

/* Halaman pendaratan scan memakai kartu yang sama rupanya dengan halaman
   depan: putih, sudut besar, bayangan lembut, tanpa garis tepi. */
.theme-light .fallback {
  margin-top: 10vh;
  padding: 40px 32px 34px;
  border: 0;
  border-radius: 22px;
  box-shadow:
    0 1px 2px rgba(0, 0, 0, .04),
    0 18px 48px -18px rgba(0, 0, 0, .14);
}

.theme-light .fallback h1 { font-size: 23px; letter-spacing: -.025em; }
.theme-light .fallback p { font-size: 14.5px; }

@media (max-width: 720px) {
  .wrap-pub { padding: 0 16px 40px; }
  .pub { min-height: calc(100svh - 120px); padding-top: 22px; }
  .pub-card { padding: 34px 24px 30px; border-radius: 18px; }
  .pub-h1 { font-size: 24px; }
  .pub-lead { font-size: 15px; }
  .theme-light .fallback { margin-top: 6vh; padding: 34px 24px 28px; border-radius: 18px; }
}
