/* ADILABA theme — dimuat SETELAH bulma.min.css di base.html.
   1) Override variabel custom-property warna Bulma v1 ke palet dashboard
      (referensi user). Bulma v1 TIDAK punya variabel hex datar seperti
      `--bulma-primary: #38b2a3` yang benar-benar dipakai komponen — setiap
      komponen (.button.is-primary, .tag.is-warning, dst) membaca
      --bulma-*-h/-s/-l lalu menghitung sendiri semua turunan (hover, soft,
      light, invert, dst). Jadi tiap warna di bawah adalah hasil konversi
      HSL dari hex targetnya:
        primer/teal (tombol utama, sidebar)  #38b2a3 -> hsl(173 52% 46%)
        link/biru (tombol sekunder, tautan)  #257d98 -> hsl(194 61% 37%)
                     — keduanya warna ke-5 & ke-7 dari palet "TealGrn-7"
                     (misc/Teal-blue.scss, referensi user): ADILABA
                     sengaja dua warna primer — teal untuk "LABA" (laba/
                     pertumbuhan), biru untuk "ADIL" (kepercayaan/aman) —
                     menyatu di sidebar & kartu unggulan lewat gradasi
                     (lihat .sidebar, .upgrade-card, .auth-card-panel
                     .is-intro), sementara tombol/tautan biasa tetap pakai
                     satu warna flat masing-masing.
        sekunder (kuning)  #F3C049 -> hsl(42 88% 62%)
        teks (navy)        #253141 -> hsl(215 28% 20%)
   2) Shell dashboard: sidebar gradien teal->biru + item aktif jadi pil
      putih, konten utama putih di atas latar biru pucat, kartu upgrade
      paket di bawah sidebar. */

:root {
  /* Primer — teal, mewakili "LABA" (laba/pertumbuhan). Dipakai untuk
     tombol utama, badge, dan salah satu ujung gradien sidebar/kartu
     unggulan (lihat .sidebar, .upgrade-card). */
  --bulma-primary-h: 173deg;
  --bulma-primary-s: 52%;
  --bulma-primary-l: 46%;
  /* Link — biru, mewakili "ADIL" (kepercayaan/aman). Dipakai untuk
     tombol sekunder (.is-link) & tautan, dan ujung lain gradien yang
     sama dengan primer di atas. */
  --bulma-link-h: 194deg;
  --bulma-link-s: 61%;
  --bulma-link-l: 37%;
  /* Lightness gradien dipisah dari --bulma-primary-l/--bulma-link-l di
     atas — sengaja, supaya permukaan besar (sidebar, kartu unggulan)
     bisa punya nada gelap sendiri di mode gelap, terlepas dari lightness
     tombol/tautan yang justru harus DINAIKKAN di mode gelap biar tetap
     terbaca (lihat blok mode gelap di bawah). Default mode terang: sama
     dengan warna tombol. */
  --sidebar-gradient-primary-l: var(--bulma-primary-l);
  --sidebar-gradient-link-l: var(--bulma-link-l);
  /* Titik tengah gradien (--palette-6, lihat ramp di bawah) — h/s/l
     dipisah sendiri (bukan var(--palette-6) langsung) supaya lightness-nya
     ikut disesuaikan per mode gelap/terang sama seperti dua ujungnya,
     bukan warna hex tetap yang jadi pita terang aneh di tengah gradien
     gelap. */
  --sidebar-gradient-mid-h: 184deg;
  --sidebar-gradient-mid-s: 57%;
  --sidebar-gradient-mid-l: 40%;
  /* Gradien "dua warna menyatu" (teal "LABA" -> biru "ADIL") — dipakai di
     permukaan besar (sidebar, kartu unggulan), bukan di tombol/tag kecil
     supaya tidak berlebihan. Titik tengah memberi sedikit kedalaman
     ekstra tanpa mengubah dua ujung warnanya. */
  --brand-gradient: linear-gradient(
    160deg,
    hsl(var(--bulma-primary-h), var(--bulma-primary-s), var(--sidebar-gradient-primary-l)),
    hsl(var(--sidebar-gradient-mid-h), var(--sidebar-gradient-mid-s), var(--sidebar-gradient-mid-l)),
    hsl(var(--bulma-link-h), var(--bulma-link-s), var(--sidebar-gradient-link-l))
  );

  /* Ramp 7 langkah mint->teal->biru (misc/Teal-blue.scss, referensi user
     "TealGrn-7") — --palette-5/-7 adalah hex persis yang sama dengan
     --bulma-primary/--bulma-link di atas (dikonversi balik dari HSL),
     jadi satu keluarga warna yang sama, bukan tambahan lepas. Sebelum
     ini cuma langkah 5 & 7 yang kepakai (tombol/link) — sisanya (badge
     ikon stat-card) malah pakai ungu/pink/oranye yang tidak berhubungan
     sama sekali, itu sumber "kaku"/tidak menyatu yang paling kentara di
     dashboard. Dipakai buat aksen kecil (badge, border tipis), bukan
     latar besar/tombol — supaya variasinya terasa halus, bukan ramai. */
  --palette-1: #b0f2bc;
  --palette-2: #89e8ac;
  --palette-3: #67dba5;
  --palette-4: #4cc8a3;
  --palette-5: #38b2a3;
  --palette-6: #2c98a0;
  --palette-7: #257d98;

  /* Status hijau — indikator untung/status positif ("Selesai", laba,
     tombol "Bagikan via WhatsApp"). Sebelumnya h93 l25 — hijau-lumut
     gelap yang jauh lebih redup dari warna lain di tema ini (primer
     l46, link l37), kentara banget di tombol WhatsApp yang solid warna
     penuh. Dinaikkan ke hijau segar ala WhatsApp sendiri (~h142 l49),
     l42 di sini biar teks putih di atas tombol tetap kontras. */
  --bulma-success-h: 142deg;
  --bulma-success-s: 70%;
  --bulma-success-l: 42%;

  /* Sekunder — kuning cerah (tombol utama, sorotan "DP diterima"). */
  --bulma-warning-h: 42deg;
  --bulma-warning-s: 88%;
  --bulma-warning-l: 62%;

  /* Netral — teks navy. --bulma-danger sengaja tidak disentuh (tetap
     merah default Bulma untuk "Batal"/hapus). */
  --bulma-text-h: 215deg;
  --bulma-text-s: 28%;
  --bulma-text-l: 20%;

  /* Token desain (redesign struktur Swift-inspired, warna teal tetap —
     lihat plan "Redesign visual"). Dipakai di seluruh kartu/tombol biar
     radius/shadow/transition konsisten, bukan angka literal berulang. */
  --radius-sm: 8px;
  --radius-md: 12px;
  --radius-lg: 20px;
  --shadow-card: 0 4px 14px rgba(37, 49, 65, 0.08);
  --shadow-card-hover: 0 8px 24px rgba(37, 49, 65, 0.1);
  --transition: 180ms cubic-bezier(0.4, 0, 0.2, 1);
  --transition-slow: 260ms cubic-bezier(0.4, 0, 0.2, 1);
  --sidebar-width: 220px;
  --sidebar-width-collapsed: 68px;
  /* Lightness dasar untuk cuci warna tipis di puncak .card-soft (lihat
     di bawah) — dipisah dari nilai literalnya sendiri supaya mode gelap
     bisa menimpanya jadi jauh lebih gelap (bukan tambalan terang aneh di
     atas kartu gelap), sama pola dengan --sidebar-gradient-*-l. */
  --card-wash-l: 93%;

  /* animate.css (static/css/animate.min.css) default durasinya 1s —
     terasa lambat untuk app yang reload penuh tiap navigasi. Dipercepat
     di sini, satu tempat, berlaku ke semua `.animate__animated`. */
  --animate-duration: 0.35s;

  /* Token permukaan/teks — dipisah dari --bulma-* di atas supaya bisa
     ditimpa per mode gelap/terang (lihat toggle manual #theme-toggle,
     static/js/theme.js) tanpa menduplikasi tiap aturan CSS di bawah.
     Nilai di :root ini adalah default mode terang. */
  --color-page-bg: #eef2f2;
  --color-section-label: #8791a0;
  --color-card-bg: #fff;
  --color-card-border: #eaf2f6;
  --color-heading: #253141;
  --color-empty-state: #a6b0bb;
  --color-product-price: #6c7671;
  /* Krem — literal tetap (bukan token permukaan yang membalik warna per
     mode gelap/terang di atas), dipakai buat aksen kecil di atas latar
     gradien (mis. .button.is-outlined-cream di bawah), bukan sebagai
     latar kartu/halaman. */
  --color-cream: #e9e5d8;
  --pattern-checked-l: 96%;
  --pola-icon-bg-l: 94%;
  /* Lightness pill diturunkan sedikit dari sebelumnya (92/90/94 -> lebih
     jenuh) — pastel yang sama tetap terbaca, cuma tidak sepucat
     sebelumnya, biar status "Paid"/"Diterima"/dst. lebih menonjol
     sekilas mata di tengah tabel yang didominasi teks netral. */
  --tag-success-bg: hsl(var(--bulma-success-h), var(--bulma-success-s), 88%);
  --tag-success-fg: hsl(var(--bulma-success-h), var(--bulma-success-s), 26%);
  --tag-warning-bg: hsl(var(--bulma-warning-h), var(--bulma-warning-s), 85%);
  --tag-warning-fg: hsl(var(--bulma-warning-h), 70%, 30%);
  --tag-danger-bg: hsl(4deg, 85%, 90%);
  --tag-danger-fg: hsl(4deg, 60%, 40%);
  --tag-light-bg: #eef1f3;
  --tag-light-fg: #5c6773;
}

html,
body {
  min-height: 100vh;
}

body {
  background: var(--color-page-bg);
  font-family: "Mulish", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
    Helvetica, Arial, sans-serif;
}

/* Shell = bingkai teal (referensi user, misc/dashboard.jpg) — sidebar
   menyatu langsung dengan warna bingkai ini (transparent, bukan warna
   sendiri), konten (.app-main) jadi kartu putih yang mengambang dengan
   jarak di dalamnya, bukan panel yang menempel penuh ke tepi. */
.app-shell {
  display: flex;
  min-height: 100vh;
  background: var(--brand-gradient);
}

.sidebar {
  width: var(--sidebar-width);
  flex-shrink: 0;
  background: transparent;
  display: flex;
  flex-direction: column;
  padding: 1.75rem 1rem;
  overflow: hidden;
  transition: width var(--transition-slow), padding var(--transition-slow);
}

/* Toggle "push" (item #19-ish, referensi codepen.io/kyunwang/pen/zNOoxb) —
   di desktop, .app-main melebar otomatis lewat flexbox begitu .sidebar
   menyempit, tanpa perlu animasi terpisah di sisi konten. Diciutkan jadi
   rel ikon (68px), bukan disembunyikan total (0px), supaya navigasi
   tidak pernah hilang — lihat keputusan di percakapan. */
.sidebar-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin: 0 0.5rem 0.35rem;
}

.sidebar-logo {
  display: block;
  font-weight: 800;
  font-size: 1.15rem;
  letter-spacing: 0.02em;
  color: #fff;
  text-decoration: none;
  white-space: nowrap;
}

.sidebar-toggle-btn {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  padding: 0;
  border: none;
  border-radius: var(--radius-sm);
  background: none;
  color: rgba(255, 255, 255, 0.7);
  cursor: pointer;
  transition: background-color var(--transition), color var(--transition);
}

.sidebar-toggle-btn:hover {
  background: rgba(255, 255, 255, 0.12);
  color: #fff;
}

.sidebar-toggle-btn svg {
  width: 18px;
  height: 18px;
}

.sidebar-toggle-btn .icon-expand {
  display: none;
}

/* Nama bisnis aktif di bawah logo, link ke tenants:pilih_bisnis (halaman
   ganti/tambah bisnis) — baru relevan sejak satu akun bisa punya lebih
   dari satu bisnis (Doc/ROADMAP.md "multi-bisnis per akun"). */
.sidebar-business {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin: 0 0.5rem 1.5rem;
  padding: 0.3rem 0.5rem;
  border-radius: 8px;
  color: rgba(255, 255, 255, 0.65);
  text-decoration: none;
  font-size: 0.8rem;
  font-weight: 600;
  overflow: hidden;
}

.sidebar-business svg {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
}

.sidebar-business span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.sidebar-business:hover,
.sidebar-business.is-active {
  background: rgba(255, 255, 255, 0.12);
  color: #fff;
}

.sidebar-nav {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  flex-grow: 1;
  /* min-height:0 wajib di sini — tanpa ini flex item dengan flex-grow
     tidak pernah menyusut di bawah tinggi kontennya sendiri, jadi
     overflow-y:auto tidak pernah kepakai (klasik "gotcha" flexbox).
     Perlu kalau banyak pola usaha aktif sekaligus (Doc/POLA_USAHA.md) —
     menu jadi lebih panjang dari tinggi sidebar. */
  min-height: 0;
  /* Maks 11 item kelihatan tanpa scroll, sisanya baru discroll — bukan
     angka sembarang: dihitung dari tinggi .sidebar-item (padding
     vertikal 1.5rem + tinggi baris teks 0.9rem × line-height 1.5 Bulma
     = 1.35rem, jadi 2.85rem/item) ditambah gap 0.4rem × 10 celah untuk
     11 item. Hitung ulang kalau padding/font-size/gap .sidebar-item
     diubah. */
  max-height: calc(11 * 2.85rem + 10 * 0.4rem);
  overflow-y: auto;
  overflow-x: hidden;
  scrollbar-width: thin;
  scrollbar-color: rgba(255, 255, 255, 0.35) transparent;
}

.sidebar-nav::-webkit-scrollbar {
  width: 6px;
}

.sidebar-nav::-webkit-scrollbar-track {
  background: transparent;
}

.sidebar-nav::-webkit-scrollbar-thumb {
  background-color: rgba(255, 255, 255, 0.35);
  border-radius: 999px;
}

/* Indikator hover yang meluncur (static/js/sidebar-hover.js) — satu
   elemen bersama yang dipindah/diubah tinggi lewat `transform`+`height`
   mengikuti item yang di-hover, bukan tiap item menyalakan latarnya
   sendiri-sendiri. `.sidebar-item:hover` di bawah tetap jadi fallback
   kalau JS gagal/belum jalan (warnanya sama, jadi tidak kelihatan beda). */
.sidebar-hover-indicator {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  z-index: 0;
  border-radius: var(--radius-md);
  background: rgba(255, 255, 255, 0.12);
  opacity: 0;
  transform: translateY(0);
  transition: transform var(--transition), height var(--transition),
    opacity var(--transition);
  pointer-events: none;
}

.sidebar-item {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.75rem 0.9rem;
  border-radius: var(--radius-md);
  color: rgba(255, 255, 255, 0.78);
  text-decoration: none;
  font-weight: 600;
  font-size: 0.9rem;
  transition: background-color var(--transition), color var(--transition);
}

.sidebar-item svg {
  width: 20px;
  height: 20px;
  flex-shrink: 0;
}

/* Keluar (accounts:logout) is a POST-only view since Django 4.1 (GET
   logout was dropped — a state-changing action must not be a plain
   link), so it's a <form><button> instead of <a href>, styled to match
   the anchor-based sidebar items exactly. */
button.sidebar-item {
  width: 100%;
  border: none;
  background: none;
  font-family: inherit;
  cursor: pointer;
  text-align: left;
}

.sidebar-item:hover {
  background: rgba(255, 255, 255, 0.12);
  color: #fff;
}

.sidebar-item.is-active {
  /* Literal tetap (bukan var(--color-card-bg)) dengan sengaja — sidebar
     selalu berlatar gradien gelap (--brand-gradient) di kedua mode,
     jadi pil aktifnya harus tetap terang di mode gelap juga, bukan ikut
     membalik jadi gelap seperti --color-card-bg. Sama alasannya dengan
     .landing-footer yang juga sengaja pakai warna tetap. */
  background: #fff;
  color: hsl(var(--bulma-primary-h), var(--bulma-primary-s), var(--bulma-primary-l));
  font-weight: 700;
}

.sidebar-footer {
  margin-top: auto;
}

/* Toggle mode gelap/terang manual (static/js/theme.js) — ikon berganti
   sesuai mode aktif saat ini, bukan mode tujuan. */
.theme-toggle .theme-icon-light {
  display: none;
}

.theme-toggle.is-dark-active .theme-icon-dark {
  display: none;
}

.theme-toggle.is-dark-active .theme-icon-light {
  display: inline-flex;
}

/* Kartu promosi upgrade paket, di bawah sidebar (lihat base.html — cuma
   tampil kalau tenant belum di paket tertinggi). Sengaja tanpa href
   fungsional: app `billing` belum dibangun (Doc/APPS.md "Belum
   dibangun"), jadi tombolnya jujur berlabel "Segera Hadir", bukan link
   yang pura-pura ke mana-mana. */
.upgrade-card {
  background: linear-gradient(
    160deg,
    hsl(var(--bulma-primary-h), var(--bulma-primary-s), calc(var(--sidebar-gradient-primary-l) - 12%)),
    hsl(var(--bulma-link-h), var(--bulma-link-s), calc(var(--sidebar-gradient-link-l) - 8%))
  );
  border-radius: 18px;
  padding: 1.1rem;
  margin: 0.75rem 0.5rem 0;
  color: #fff;
}

.upgrade-card svg {
  width: 28px;
  height: 28px;
  margin-bottom: 0.5rem;
  color: hsl(var(--bulma-warning-h), var(--bulma-warning-s), var(--bulma-warning-l));
}

.upgrade-card .upgrade-title {
  display: block;
  font-weight: 700;
  font-size: 0.95rem;
  margin-bottom: 0.25rem;
}

.upgrade-card p {
  font-size: 0.78rem;
  line-height: 1.4;
  color: rgba(255, 255, 255, 0.8);
  margin-bottom: 0.9rem;
}

.upgrade-card .upgrade-cta {
  display: inline-block;
  background: hsl(var(--bulma-warning-h), var(--bulma-warning-s), var(--bulma-warning-l));
  color: #2c2c2a;
  font-weight: 700;
  font-size: 0.78rem;
  padding: 0.4rem 0.9rem;
  border-radius: 999px;
}

.app-main {
  background: var(--color-card-bg);
  flex-grow: 1;
  min-width: 0;
  margin: 12px;
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
  padding: 2rem 2.5rem;
}

/* Layar tanpa sidebar (login, daftar, `hide_sidebar` seperti onboarding
   pola) — konten ditengahkan vertikal, bukan nempel atas, biar terasa
   seperti layar tersendiri (bukan dashboard yang kebetulan kosong). */
.app-shell:not(:has(.sidebar)) .app-main {
  /* align-items sengaja dibiarkan default (stretch) — kalau di-set
     "center", anak langsung `.app-main` (mis. `.columns` Bulma) ikut
     menciut jadi lebar seukuran isinya sendiri, merusak perhitungan
     lebar persen `.column` di dalamnya (bug: kotak kecil bisa-discroll
     di halaman beranda publik). Ditengahkan lewat `.app-main > *`
     (max-width + margin:auto) yang sudah ada, bukan lewat align-items. */
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 1rem;
}

/* Tanpa batas ini, kartu/form ikut melebar sampai tepi layar di monitor
   lebar — kelihatan kosong/aneh untuk form sesimpel input harga. Konten
   dibatasi & ditengahkan seperti dashboard app pada umumnya. */
.app-main > * {
  max-width: 1000px;
  margin-left: auto;
  margin-right: auto;
}

/* Titik kecil berwarna di depan tiap judul section (::before) — dipakai
   di puluhan template lewat satu class ini, jadi satu sentuhan warna
   yang konsisten menyebar ke seluruh app tanpa perlu menyentuh HTML
   satu-satu. Sengaja satu warna tetap (bukan bervariasi per section)
   — ini penanda bermerek yang berulang, bukan pembeda antar-kartu yang
   berdampingan (beda kasus dari badge stat-card yang memang perlu
   berbeda-beda supaya tidak monoton). */
.section-label {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-section-label);
  margin-bottom: 0.5rem;
}

.section-label::before {
  content: "";
  width: 6px;
  height: 6px;
  flex-shrink: 0;
  border-radius: 999px;
  background: hsl(var(--bulma-primary-h), var(--bulma-primary-s), var(--bulma-primary-l));
}

/* Umpan balik tekan + transisi halus untuk semua tombol Bulma
   (.button.is-primary/.is-outlined/.is-text/.is-danger dst — dipakai di
   seluruh 49 template, jadi override di satu tempat ini mengalir ke
   semuanya tanpa menyentuh HTML mana pun). */
.button {
  border-radius: var(--radius-md);
  transition: transform var(--transition), box-shadow var(--transition),
    background-color var(--transition), border-color var(--transition);
}

/* Bayangan hover berwarna (bukan abu-abu netral) khusus tombol warna
   utama — sengaja lewat box-shadow (bukan menimpa background-color/
   background), supaya tidak bentrok dengan mesin hover Bulma v1 sendiri
   yang berbasis variabel CSS (--bulma-button-background-l dst.) — hasil
   akhirnya tombol yang sama seperti biasa, cuma dapat "glow" warnanya
   sendiri pas disentuh, bukan bayangan gelap generik seperti tombol
   lain. */
.button.is-primary:hover {
  box-shadow: 0 6px 16px
    hsla(var(--bulma-primary-h), var(--bulma-primary-s), var(--bulma-primary-l), 0.35);
}

.button.is-link:hover {
  box-shadow: 0 6px 16px
    hsla(var(--bulma-link-h), var(--bulma-link-s), var(--bulma-link-l), 0.35);
}

.button:active {
  transform: scale(0.97);
}

/* Varian outline warna krem (var(--color-cream)) — Bulma sendiri cuma
   tahu is-outlined dikombinasikan dengan warna tema (.is-primary,
   .is-link, dst), bukan warna custom di luar itu, jadi tombolnya
   ditulis manual di sini. Dipakai di tombol "Login" navbar landing page
   (di atas latar gradien .landing-navbar/.landing-hero) — border+teks
   krem, isi solid krem+teks navy pas hover, sama pola dengan tombol
   is-outlined bawaan Bulma pada umumnya. */
.button.is-outlined-cream {
  background: transparent;
  border-color: var(--color-cream);
  color: var(--color-cream);
}

.button.is-outlined-cream:hover {
  background: var(--color-cream);
  border-color: var(--color-cream);
  color: var(--color-heading);
}

/* .button.is-warning.is-outlined bawaan Bulma v1 TIDAK mengisi latar
   pas hover (cuma mempertebal border) — beda dari .is-outlined-cream
   custom di atas. Ditimpa di sini biar tombol "Register" (navbar
   landing page) hover-nya sama persis polanya: isi solid warning +
   teks putih (bukan warna invert bawaan Bulma, yang belum tentu putih
   untuk warna terang seperti kuning). */
.button.is-warning.is-outlined:hover {
  background: hsl(var(--bulma-warning-h), var(--bulma-warning-s), var(--bulma-warning-l));
  border-color: hsl(var(--bulma-warning-h), var(--bulma-warning-s), var(--bulma-warning-l));
  color: var(--color-cream);
}

/* Badge status jadi pill lembut (background pastel + teks pekat)
   menggantikan solid-saturated+teks-putih bawaan Bulma — dipakai apa
   adanya di titipan/layanan/langganan/riwayat-penjualan/pelanggan tanpa
   perubahan HTML. */
.tag {
  border-radius: 999px;
  font-weight: 700;
}

.tag.is-success {
  background: var(--tag-success-bg);
  color: var(--tag-success-fg);
}

.tag.is-warning {
  background: var(--tag-warning-bg);
  color: var(--tag-warning-fg);
}

.tag.is-danger {
  background: var(--tag-danger-bg);
  color: var(--tag-danger-fg);
}

.tag.is-light {
  background: var(--tag-light-bg);
  color: var(--tag-light-fg);
}

/* Kartu putih (--color-card-bg) di dalam .app-main yang sekarang juga
   putih (sejak .app-main sendiri jadi kartu mengambang di atas bingkai
   teal — lihat .app-shell/.app-main) — dibedakan lewat garis tipis +
   bayangan halus, bukan lewat warna latar. */
.card-soft {
  /* Cuci warna tipis di puncak kartu, meluruh ke --color-card-bg polos
     dalam 160px — pengganti latar putih/krem datar di SEMUA kartu di
     seluruh app (49 template pakai class ini), supaya dashboard terasa
     lebih hidup tanpa jadi ramai/berat di mata untuk dipakai kerja
     seharian. --card-wash-l dipisah dari nilainya sendiri (bukan literal
     langsung) supaya mode gelap bisa menimpanya dengan aman. */
  background: linear-gradient(
    180deg,
    hsl(var(--bulma-primary-h), var(--bulma-primary-s), var(--card-wash-l)) 0%,
    var(--color-card-bg) 160px
  );
  border: 1px solid var(--color-card-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
  padding: 1.5rem;
  /* Jaring pengaman — tabel lebar (banyak kolom) di kolom sempit
     (`.column.is-one-third` dst) bisa meluber lewat tepi kartu tanpa
     ini; scroll horizontal di dalam kartu lebih rapi daripada isinya
     bocor keluar bentuk kartu. */
  overflow-x: auto;
}

/* Modifier opsional untuk `.table-container` di dalam `.card-soft` —
   tabel panjang (mis. pos:riwayat_penjualan) discroll VERTIKAL (atas-
   bawah) di dalam kartu begitu tingginya sendiri sudah mendekati tinggi
   layar, bukan bikin kartu (dan halamannya) memanjang terus. Dulu
   sempat pakai batas "8 baris" tetap (`calc(9 * 2.5rem)`), tapi itu
   meleset kalau satu sel membungkus jadi beberapa baris (mis. nomor
   nota panjang) — jadi baris riil lebih pendek dari perkiraan.
   `max-height: 65vh` otomatis menyesuaikan diri ke tinggi layar
   berapa pun dan berapa pun baris yang muat, tanpa perlu tahu tinggi
   satu baris sama sekali. `overflow-x: hidden` sengaja menimpa
   `overflow-x: auto` bawaan Bulma di `.table-container` — tanpa ini
   scrollbar horizontal ikut muncul berdampingan dengan yang vertikal,
   padahal yang diminta cuma navigasi atas-bawah. Cuma diterapkan ke
   `.table-container` yang diberi class ini secara eksplisit — tabel
   pendek di halaman lain tidak ikut kena batas ini (kartunya lebih
   pendek dari 65vh, jadi tidak pernah discroll sama sekali). */
.table-container.table-scroll-auto {
  max-height: 65vh;
  overflow-y: auto;
  overflow-x: hidden;
  scrollbar-width: thin;
  scrollbar-color: var(--color-card-border) transparent;
}

.table-container.table-scroll-auto::-webkit-scrollbar {
  width: 6px;
}

.table-container.table-scroll-auto::-webkit-scrollbar-track {
  background: transparent;
}

.table-container.table-scroll-auto::-webkit-scrollbar-thumb {
  background-color: var(--color-card-border);
  border-radius: 999px;
}

/* thead tetap kelihatan saat isi tabel discroll, bukan ikut tergulung
   ke atas dan hilang. */
.table-container.table-scroll-auto thead th {
  position: sticky;
  top: 0;
  background: var(--color-card-bg);
  z-index: 1;
}

.stat-card {
  background: var(--color-card-bg);
  border: 1px solid var(--color-card-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
  padding: 1.5rem;
}

.stat-card .stat-value {
  font-size: 2rem;
  font-weight: 800;
  color: var(--color-heading);
}

/* Kartu pilih pola usaha (tenants:onboarding_pola) — seluruh kartu bisa
   diketuk (radio disembunyikan, klik di mana pun di dalam <label> tetap
   memilihnya), highlight via :has(input:checked). Presedennya sudah ada
   fitur khusus Chrome/Android WebView di proyek ini (BarcodeDetector di
   kasir) — degradasi tanpa :has() masih fungsional, cuma tanpa highlight. */
.pattern-card {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  background: var(--color-card-bg);
  border: 2px solid var(--color-card-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
  padding: 1.25rem 1.5rem;
  cursor: pointer;
  height: 100%;
  transition: transform var(--transition), box-shadow var(--transition);
}

.pattern-card:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-card-hover);
}

.pattern-card input[type="radio"] {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}

.pattern-card:has(input:checked) {
  border-color: hsl(var(--bulma-primary-h), var(--bulma-primary-s), var(--bulma-primary-l));
  background: hsl(var(--bulma-primary-h), var(--bulma-primary-s), var(--pattern-checked-l));
}

.pattern-card-headline {
  font-weight: 700;
  color: var(--color-heading);
}

.pattern-card-examples {
  font-size: 0.85rem;
  color: var(--color-product-price);
}

/* Kartu auth (Masuk/Daftar/Pilih Pola Usaha) — panel kiri solid teal
   (ajakan pindah aksi / instruksi), panel kanan putih (form atau daftar
   opsi). */
.auth-card {
  display: flex;
  background: var(--color-card-bg);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
  overflow: hidden;
}

.auth-card-panel {
  flex: 1;
  min-width: 0;
  padding: 2.5rem;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

/* Panel "ajakan" (kiri) — dipakai untuk ajakan pindah ke aksi lain
   (Masuk <-> Daftar) maupun panel instruksi Pilih Pola Usaha (tanpa
   tombol, karena tidak ada aksi lain untuk dituju). */
.auth-card-panel.is-intro {
  flex: 0 0 280px;
  background: var(--brand-gradient);
  color: #fff;
}

.auth-card-heading {
  display: block;
  font-size: 1.5rem;
  font-weight: 800;
  margin-bottom: 0.75rem;
  line-height: 1.3;
}

.auth-card-panel.is-intro .auth-card-heading {
  color: #fff;
}

.auth-card-panel p {
  font-size: 0.9rem;
  line-height: 1.5;
  margin-bottom: 1.5rem;
}

.auth-card-panel.is-intro p {
  color: rgba(255, 255, 255, 0.85);
}

.auth-card-panel.is-form .auth-card-heading,
.auth-card-panel.is-list .auth-card-heading {
  color: var(--color-heading);
}

.auth-card-panel.is-form p,
.auth-card-panel.is-list p {
  color: var(--color-product-price);
}

.auth-card-panel.is-form form,
.auth-card-panel.is-list form {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.pola-option {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 1rem 1.25rem;
  border-radius: var(--radius-lg);
  border: 1px solid var(--color-card-border);
  cursor: pointer;
  transition: transform var(--transition), box-shadow var(--transition),
    background-color var(--transition), border-color var(--transition);
}

.pola-option input[type="radio"] {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}

.pola-option:hover {
  transform: translateY(-1px);
  box-shadow: var(--shadow-card);
}

.pola-option-icon {
  flex-shrink: 0;
  width: 44px;
  height: 44px;
  border-radius: 999px;
  background: hsl(var(--bulma-primary-h), var(--bulma-primary-s), var(--pola-icon-bg-l));
  color: hsl(var(--bulma-primary-h), var(--bulma-primary-s), var(--bulma-primary-l));
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: background-color var(--transition), color var(--transition);
}

.pola-option-icon svg {
  width: 22px;
  height: 22px;
}

.pola-option-text {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  min-width: 0;
  flex-grow: 1;
}

.pola-option-headline {
  font-weight: 700;
  color: var(--color-heading);
  transition: color var(--transition);
}

.pola-option-examples {
  font-size: 0.82rem;
  color: var(--color-product-price);
  transition: color var(--transition);
}

.pola-option-arrow {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: 0.25rem;
  font-size: 0.82rem;
  font-weight: 700;
  color: hsl(var(--bulma-primary-h), var(--bulma-primary-s), var(--bulma-primary-l));
  white-space: nowrap;
  transition: color var(--transition);
}

.pola-option-arrow svg {
  width: 16px;
  height: 16px;
}

.pola-option:has(input:checked) {
  background: hsl(var(--bulma-primary-h), var(--bulma-primary-s), var(--bulma-primary-l));
  border-color: transparent;
  box-shadow: var(--shadow-card-hover);
}

.pola-option:has(input:checked) .pola-option-headline,
.pola-option:has(input:checked) .pola-option-arrow {
  color: #fff;
}

.pola-option:has(input:checked) .pola-option-examples {
  color: rgba(255, 255, 255, 0.8);
}

.pola-option:has(input:checked) .pola-option-icon {
  background: rgba(255, 255, 255, 0.2);
  color: #fff;
}

/* Titik progres kuis onboarding (tenants:onboarding_pola) — dot putih
   solid untuk langkah yang sudah terjawab, dot redup untuk sisanya.
   Duduk di atas .auth-card-panel.is-intro's brand gradient, makanya
   basisnya putih transparan, bukan token warna lain. */
.quiz-progress {
  display: flex;
  gap: 6px;
  margin-bottom: 1rem;
}

.quiz-dot {
  width: 8px;
  height: 8px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.3);
  transition: background-color var(--transition);
}

.quiz-dot.is-done {
  background: #fff;
}

/* Daftar aktivitas ringkas (mis. "Riwayat Kas Terbaru" di finance/
   keuangan.html) — pengganti tabel di kolom sempit, supaya tidak pernah
   butuh scroll horizontal seperti tabel biasa. */
.mini-list {
  display: flex;
  flex-direction: column;
}

.mini-list-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0.75rem 0;
  border-bottom: 1px solid var(--color-card-border);
}

.mini-list-row:last-child {
  border-bottom: none;
  padding-bottom: 0;
}

.mini-list-row:first-child {
  padding-top: 0;
}

.mini-list-main {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  min-width: 0;
}

.mini-list-title {
  font-weight: 600;
  font-size: 0.9rem;
  color: var(--color-heading);
}

.mini-list-subtitle {
  font-size: 0.78rem;
  color: var(--color-product-price);
}

.mini-list-side {
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 0.3rem;
}

.mini-list-amount {
  font-weight: 700;
  font-size: 0.85rem;
  color: var(--color-heading);
  white-space: nowrap;
}

.mini-list-empty {
  justify-content: center;
  color: var(--color-empty-state);
}

/* Modifier opsional, sama seperti `.table-container.table-scroll-auto`
   — "Riwayat Kas Terbaru" (finance/keuangan.html) discroll VERTIKAL di
   dalam kartu begitu tingginya sendiri sudah mendekati tinggi layar,
   bukan bikin kartunya memanjang terus. `max-height: 65vh` menyesuaikan
   diri ke tinggi layar berapa pun, tanpa perlu menghitung tinggi satu
   baris (lihat komentar di .table-scroll-auto untuk alasannya). */
.mini-list.mini-list-scroll-auto {
  max-height: 65vh;
  overflow-y: auto;
  overflow-x: hidden;
  scrollbar-width: thin;
  scrollbar-color: var(--color-card-border) transparent;
}

.mini-list.mini-list-scroll-auto::-webkit-scrollbar {
  width: 6px;
}

.mini-list.mini-list-scroll-auto::-webkit-scrollbar-track {
  background: transparent;
}

.mini-list.mini-list-scroll-auto::-webkit-scrollbar-thumb {
  background-color: var(--color-card-border);
  border-radius: 999px;
}

.empty-state {
  text-align: center;
  padding: 3rem 1rem;
  color: var(--color-empty-state);
}

.empty-state svg {
  width: 64px;
  height: 64px;
  margin: 0 auto 1rem;
}

.avatar-circle {
  width: 36px;
  height: 36px;
  border-radius: 999px;
  background: hsla(
    var(--bulma-primary-h),
    var(--bulma-primary-s),
    var(--bulma-primary-l),
    0.12
  );
  color: hsl(var(--bulma-primary-h), var(--bulma-primary-s), var(--bulma-primary-l));
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.avatar-circle svg {
  width: 18px;
  height: 18px;
}

/* Badge ikon pastel — pengganti .stat-card teal tunggal saat beberapa
   angka ditampilkan berdampingan (lihat reports/today.html), biar tiap
   angka gampang dibedakan sekilas mata seperti referensi dashboard. */
.badge-circle {
  width: 40px;
  height: 40px;
  border-radius: 999px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 0.75rem;
}

.badge-circle svg {
  width: 20px;
  height: 20px;
}

/* Lima nada dari SATU keluarga ramp (--palette-1..7 di :root), bukan
   ungu/pink/oranye lepas seperti sebelumnya — itu penyebab dashboard
   terasa "kaku"/tidak menyatu paling kentara (5 kartu stat di
   reports/today.html berdampingan, masing-masing warna acak berbeda
   keluarga). Diurutkan mint -> teal-hijau -> teal -> teal-tua -> biru,
   jadi ombré halus satu arah, bukan tabrakan warna. */
.badge-mint {
  background: #e5fae9;
  color: #16832a;
}

.badge-tealgreen {
  background: #e6f9f0;
  color: #1d7c50;
}

.badge-teal {
  background: hsla(
    var(--bulma-primary-h),
    var(--bulma-primary-s),
    var(--bulma-primary-l),
    0.12
  );
  color: hsl(var(--bulma-primary-h), var(--bulma-primary-s), var(--bulma-primary-l));
}

.badge-deepteal {
  background: #e7f7f8;
  color: #217278;
}

.badge-blue {
  background: #e6f5f9;
  color: #1e657b;
}

/* Sentuhan warna tipis di tepi atas kartu, mengikuti badge ikonnya —
   :has() dipilih supaya tidak perlu menambah class terpisah ke
   .stat-card di tiap template, cukup badge yang sudah ada di dalamnya.
   .stat-card tanpa badge (mis. "Total" di pos/kasir.html) tidak
   kesentuh sama sekali oleh aturan ini. */
.stat-card:has(.badge-mint) {
  border-top: 3px solid #16832a;
}
.stat-card:has(.badge-tealgreen) {
  border-top: 3px solid #1d7c50;
}
.stat-card:has(.badge-teal) {
  border-top: 3px solid hsl(var(--bulma-primary-h), var(--bulma-primary-s), var(--bulma-primary-l));
}
.stat-card:has(.badge-deepteal) {
  border-top: 3px solid #217278;
}
.stat-card:has(.badge-blue) {
  border-top: 3px solid #1e657b;
}

/* Grid produk kasir (redesign search+scan+kategori) — kartu lebih ringkas
   dari .card-soft biasa karena banyak ditampilkan sekaligus. */
.product-card {
  padding: 0.4rem;
}

/* Grid kasir pakai class Bulma `.columns` (`.columns:not(.is-desktop) {
   display: flex }`) — sama seperti kasus .scan-overlay, aturan penulis itu
   menang atas default UA `[hidden] { display: none }` walau atribut
   `hidden` sudah dipasang JS (lihat static/js/kasir.js). Tanpa baris ini,
   grid tetap kelihatan (flex) meski disembunyikan. */
#kasir-product-grid[hidden] {
  display: none;
}

/* Kartu individual (.product-card) juga pakai class Bulma `.column`
   (`.column { display: block }`) — akar masalah sama persis seperti di
   atas, cuma di level kartu, bukan grid. Tanpa ini, filter per-kartu saat
   ngetik/pilih kategori (card.hidden di kasir.js) tidak kelihatan
   efeknya — kartu yang tidak cocok tetap muncul. */
.product-card[hidden] {
  display: none;
}

.product-card-inner {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  background: var(--color-card-bg);
  border: 1px solid var(--color-card-border);
  border-radius: var(--radius-md);
  padding: 0.75rem 1rem;
  box-shadow: var(--shadow-card);
  transition: transform var(--transition), box-shadow var(--transition);
}

.product-card-inner:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-card-hover);
}

.product-card-name {
  flex-grow: 1;
  font-weight: 600;
  font-size: 0.9rem;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.product-card-price {
  font-size: 0.85rem;
  color: var(--color-product-price);
  white-space: nowrap;
}

.product-card-qty {
  width: 3.25rem;
  height: 2.25rem;
  padding: 0 0.25rem;
  text-align: center;
  flex-shrink: 0;
}

.product-card-add {
  width: 2.25rem;
  height: 2.25rem;
  padding: 0;
  flex-shrink: 0;
}

/* Overlay scan kamera (kasir) — disembunyikan lewat atribut `hidden`
   sampai tombol ikon kamera diklik (lihat static/js/kasir.js). */
.scan-overlay {
  position: fixed;
  inset: 0;
  z-index: 100;
  background: rgba(20, 24, 22, 0.92);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1rem;
  padding: 1.5rem;
}

/* `hidden` dari static/js/kasir.js harus tetap menang atas `display: flex`
   di atas — tanpa ini overlay akan kelihatan terus meski atribut
   `hidden` terpasang, karena stylesheet penulis menang atas default
   UA `[hidden] { display: none }` walau specificity-nya setara. */
.scan-overlay[hidden] {
  display: none;
}

.scan-overlay video {
  max-width: 100%;
  max-height: 60vh;
  border-radius: 16px;
}

.scan-overlay p {
  color: #fff;
  text-align: center;
  max-width: 24rem;
}

/* Mode ciut (rel ikon) — desktop saja, dijaga min-width supaya tidak
   pernah tabrakan dengan layout bilah-bawah mobile di bawah (spesifitas
   attribute selector di sini lebih tinggi dari `.sidebar` polos, jadi
   tanpa penjagaan ini dia akan menang di layar kecil juga). */
@media (min-width: 769px) {
  html[data-sidebar="collapsed"] .sidebar {
    width: var(--sidebar-width-collapsed);
    padding-left: 0.6rem;
    padding-right: 0.6rem;
  }

  html[data-sidebar="collapsed"] .sidebar-top {
    justify-content: center;
  }

  html[data-sidebar="collapsed"] .sidebar-logo,
  html[data-sidebar="collapsed"] .sidebar-business span,
  html[data-sidebar="collapsed"] .sidebar-item span,
  html[data-sidebar="collapsed"] .upgrade-card {
    display: none;
  }

  html[data-sidebar="collapsed"] .sidebar-business,
  html[data-sidebar="collapsed"] .sidebar-item {
    justify-content: center;
  }

  html[data-sidebar="collapsed"] .sidebar-toggle-btn .icon-collapse {
    display: none;
  }

  html[data-sidebar="collapsed"] .sidebar-toggle-btn .icon-expand {
    display: inline-flex;
  }
}

@media (max-width: 768px) {
  .app-shell {
    flex-direction: column;
  }

  .sidebar {
    width: 100%;
    flex-direction: row;
    justify-content: space-around;
    padding: 0.5rem 0.5rem;
    order: 2;
    position: sticky;
    bottom: 0;
    /* Bilah bawah harus solid. Transparan membuat isi kartu di bawahnya
       tampak tembus ke belakang menu. */
    background: var(--brand-gradient);
    border-radius: 16px 16px 0 0;
    box-shadow: 0 -6px 18px rgba(15, 30, 40, 0.18);
    z-index: 20;
  }

  .sidebar-top,
  .upgrade-card {
    display: none;
  }

  .sidebar-nav,
  .sidebar-footer {
    flex-direction: row;
  }

  /* Menu bisa lebih banyak dari lebar layar HP. Bilah bawah digeser
     mendatar (bukan dipotong), dan setiap menu diberi label kecil di
     bawah ikonnya supaya tidak ambigu. */
  .sidebar-nav {
    flex: 1 1 auto;
    min-width: 0;
    overflow-x: auto;
    overflow-y: hidden;
    scrollbar-width: none;
  }

  .sidebar-nav::-webkit-scrollbar {
    display: none;
  }

  .sidebar-footer {
    display: flex;
    margin-top: 0;
    flex-shrink: 0;
  }

  /* Nama usaha di bilah bawah cukup ikonnya saja (ketuk untuk ganti bisnis). */
  .sidebar-business {
    flex-shrink: 0;
    align-self: center;
    margin: 0;
    padding: 0.4rem;
    color: #fff;
  }

  .sidebar-business span {
    display: none;
  }

  .sidebar-item {
    flex: 0 0 auto;
    flex-direction: column;
    gap: 0.15rem;
    min-width: 4.25rem;
    padding: 0.25rem 0.3rem;
    color: #fff;
  }

  /* Menu yang sedang dibuka ditandai dengan latar tipis, supaya jelas di
     mode terang maupun gelap. */
  .sidebar-item.is-active {
    background: rgba(255, 255, 255, 0.22);
    color: #fff;
  }

  .sidebar-item span {
    display: block;
    max-width: 4.25rem;
    overflow: hidden;
    text-overflow: ellipsis;
    font-size: 0.62rem;
    line-height: 1.1;
    white-space: nowrap;
  }

  /* Indikator hover meluncur diasumsikan vertikal (translateY+height) —
     tidak relevan di bilah-bawah mobile yang horizontal (dan perangkat
     sentuh tidak benar-benar punya "hover"), jadi disembunyikan saja. */
  .sidebar-hover-indicator {
    display: none;
  }

  .app-main {
    padding: 1rem;
    order: 1;
  }

  .auth-card {
    flex-direction: column;
  }

  .auth-card-panel {
    padding: 1.75rem;
  }

  .auth-card-panel.is-intro {
    flex: none;
  }

  /* Tabel jadi tumpukan kartu per-baris di HP (teknik CSS-murni ala
     justboil.github.io/bulma-responsive-tables, diadaptasi ke token
     kita) — tiap sel dapat label kolomnya sendiri lewat `data-label`
     (pseudo-elemen `content: attr(data-label)`), jadi tidak perlu
     scroll horizontal sama sekali di layar sempit. `.table-container`
     sendiri (dari Bulma) tetap dipakai di desktop untuk kasus tabel
     yang kebetulan masih lebih lebar dari kartunya. */
  .table-container.has-mobile-cards thead {
    display: none;
  }

  .table-container.has-mobile-cards tr {
    display: block;
    box-shadow: var(--shadow-card);
    border-radius: var(--radius-md);
  }

  .table-container.has-mobile-cards tr:not(:last-child) {
    margin-bottom: 0.75rem;
  }

  .table-container.has-mobile-cards td {
    display: flex;
    width: auto;
    justify-content: space-between;
    align-items: center;
    gap: 0.75rem;
    text-align: right;
    border-bottom: 1px solid var(--color-card-border);
  }

  .table-container.has-mobile-cards td:last-child {
    border-bottom: 0;
  }

  .table-container.has-mobile-cards td[data-label]::before {
    content: attr(data-label);
    font-weight: 700;
    text-align: left;
    color: var(--color-section-label);
  }
}

/* Mode gelap — dua pemicu: (1) preferensi sistem/browser lewat
   `prefers-color-scheme`, dipakai selama user belum memilih manual
   (dijaga `:not([data-theme="light"])` supaya pilihan manual "Terang"
   bisa menimpa sistem yang gelap); (2) toggle manual `#theme-toggle`
   (static/js/theme.js) yang menyetel `data-theme="dark"|"light"` di
   `<html>` dan disimpan di localStorage — berlaku apa pun preferensi
   sistem. Semua warna permukaan/teks sudah dipecah jadi custom
   property (`--color-*`, `--tag-*`) di :root, jadi di sini cukup timpa
   nilainya sekali — otomatis mengalir ke semua selector yang memakainya
   tanpa duplikasi aturan.

   Nilai-nilai di bawah sudah dicek rasio kontras WCAG terhadap
   --color-card-bg (#1d2422): teks body (--bulma-text-l 84%) ~10.8:1,
   heading (--color-heading) ~13.75:1, teks sekunder (--color-product-
   price/--color-section-label) ~5.6:1, empty-state ~5.8:1 — semua di
   atas ambang AA (4.5:1), tapi teks body sengaja tidak dibuat mendekati
   putih murni (dulu 90%, sekarang 84%) supaya tidak silau untuk bacaan
   panjang. Badge status (--tag-*-bg/-fg) juga dicek, semua 5.9–8:1. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bulma-primary-l: 56%;
    --bulma-link-l: 58%;
    /* Sidebar/kartu unggulan sengaja TIDAK ikut lightness tombol di atas
       (yang dinaikkan biar terbaca) — dibuat gelap & kaya sendiri supaya
       permukaan besarnya tidak menyilaukan di tengah UI serba gelap. */
    --sidebar-gradient-primary-l: 24%;
    --sidebar-gradient-link-l: 18%;
    --sidebar-gradient-mid-l: 21%;
    --bulma-success-l: 52%;
    --bulma-warning-l: 58%;
    --bulma-text-h: 210deg;
    --bulma-text-s: 12%;
    --bulma-text-l: 84%;

    --color-page-bg: #14181a;
    --color-section-label: #8f9ba3;
    --color-card-bg: #1d2422;
    --color-card-border: #2b332f;
    --color-heading: #f1efe8;
    --color-empty-state: #939f99;
    --color-product-price: #8f9ba3;
    --pattern-checked-l: 16%;
    --pola-icon-bg-l: 20%;
    --shadow-card: none;
    /* Jauh lebih gelap dari default 93% mode terang — cuma sedikit
       lebih terang dari --color-card-bg sendiri (bukan tambalan
       terang), jadi tetap terasa "menyala tipis", bukan aneh. */
    --card-wash-l: 20%;

    --tag-success-bg: hsl(var(--bulma-success-h), var(--bulma-success-s), 18%);
    --tag-success-fg: hsl(var(--bulma-success-h), var(--bulma-success-s), 75%);
    --tag-warning-bg: hsl(var(--bulma-warning-h), var(--bulma-warning-s), 22%);
    --tag-warning-fg: hsl(var(--bulma-warning-h), var(--bulma-warning-s), 78%);
    --tag-danger-bg: hsl(4deg, 45%, 20%);
    --tag-danger-fg: hsl(4deg, 70%, 80%);
    --tag-light-bg: #2b332f;
    --tag-light-fg: #c4cdd3;
  }
}

:root[data-theme="dark"] {
  --bulma-primary-l: 56%;
  --bulma-link-l: 58%;
  --sidebar-gradient-primary-l: 24%;
  --sidebar-gradient-link-l: 18%;
  --sidebar-gradient-mid-l: 21%;
  --bulma-success-l: 52%;
  --bulma-warning-l: 58%;
  --bulma-text-h: 210deg;
  --bulma-text-s: 12%;
  --bulma-text-l: 84%;

  --color-page-bg: #14181a;
  --color-section-label: #8f9ba3;
  --color-card-bg: #1d2422;
  --color-card-border: #2b332f;
  --color-heading: #f1efe8;
  --color-empty-state: #939f99;
  --color-product-price: #8f9ba3;
  --pattern-checked-l: 16%;
  --pola-icon-bg-l: 20%;
  --shadow-card: none;
  --card-wash-l: 20%;

  --tag-success-bg: hsl(var(--bulma-success-h), var(--bulma-success-s), 18%);
  --tag-success-fg: hsl(var(--bulma-success-h), var(--bulma-success-s), 75%);
  --tag-warning-bg: hsl(var(--bulma-warning-h), var(--bulma-warning-s), 22%);
  --tag-warning-fg: hsl(var(--bulma-warning-h), var(--bulma-warning-s), 78%);
  --tag-danger-bg: hsl(4deg, 45%, 20%);
  --tag-danger-fg: hsl(4deg, 70%, 80%);
  --tag-light-bg: #2b332f;
  --tag-light-fg: #c4cdd3;
}

/* Tur Fitur (static/js/feature-tour.js) — spotlight di atas elemen UI
   asli. .tour-spotlight adalah kotak transparan diposisikan tepat di
   atas elemen target; "cutout"-nya murni trik box-shadow (bayangan
   raksasa 9999px menutupi semua yang di luar kotak), tanpa SVG mask
   atau library. */
.tour-overlay {
  position: fixed;
  inset: 0;
  z-index: 9000;
}

.tour-spotlight {
  position: fixed;
  border-radius: var(--radius-md);
  box-shadow: 0 0 0 9999px rgba(20, 24, 31, 0.6);
  transition: top var(--transition), left var(--transition),
    width var(--transition), height var(--transition);
  pointer-events: none;
}

.tour-bubble {
  position: fixed;
  width: 300px;
  max-width: calc(100vw - 32px);
  background: var(--color-card-bg);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-card-hover);
  padding: 1rem;
  z-index: 9001;
}

.tour-bubble-title {
  font-weight: 700;
  color: var(--color-heading);
  margin-bottom: 0.4rem;
}

.tour-bubble-text {
  font-size: 0.85rem;
  color: var(--color-product-price);
  margin-bottom: 0.75rem;
}

.tour-bubble-actions {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
