/* ==========================================================================
   GELORA — LAPISAN 3 dari 4 (sumber kebenaran tunggal untuk tampilan aplikasi)
   ==========================================================================

   URUTAN MUAT (lihat layouts/app.blade.php) dan siapa memiliki apa:

     1. dashboards/.../core.css   vendor Sneat/Bootstrap — kerangka mentah
     2. css/theme-gelora.css      recolor Sneat ke palet brand
     3. css/app-sneat-theme.css   variabel --bs-* Bootstrap
     4. css/app.css               ← BERKAS INI. Token, kerangka, dan SELURUH
                                    komponen aplikasi. Satu-satunya tempat
                                    card, tombol, lencana, tabel, formulir,
                                    dashboard, kasir, dan denah didefinisikan.
     5. css/gelora-ui.css         HANYA penyesuaian pustaka pihak ketiga
                                    (DataTables, Select2, ApexCharts, Toastr,
                                    SweetAlert, scrollbar). TIDAK BOLEH
                                    mendefinisikan ulang komponen di atas.

   ATURAN ANTI-TABRAKAN
   --------------------
   Sebelumnya .btn, .badge, .card, .form-control, .grid-cols-*, .kasir-chip,
   .floor-plan-*, dan .stat-tile masing-masing didefinisikan di DUA berkas
   dengan nilai berbeda. Karena app.css memakai !important untuk warna tapi
   gelora-ui.css memakai spesifisitas biasa untuk bentuk, hasil akhirnya adalah
   campuran dari keduanya — radius dari satu berkas, warna dari berkas lain,
   transform hover dari berkas ketiga. Itulah "CSS tabrakan" yang membuat
   tampilan tidak pernah konsisten.

   Aturan sekarang:
   - satu selector = satu tempat. Kalau sebuah kelas muncul di berkas ini, ia
     TIDAK BOLEH muncul lagi di gelora-ui.css;
   - !important hanya dipakai untuk mengalahkan core.css/theme-gelora.css
     (vendor), tidak pernah untuk berkelahi dengan berkas Gelora sendiri;
   - varian tema gelap ditulis persis setelah aturan terangnya, bukan
     dikumpulkan di akhir berkas, supaya perubahan tidak pernah lupa pasangannya.

   Konsep visual: "Court & Cue" — teal (billiard/padel) + amber (energi/CTA).
   ========================================================================== */

/* ==========================================================================
   1. TOKEN
   ========================================================================== */

:root {
  /* Brand */
  --color-primary-50:  #F0FDFA;
  --color-primary-100: #CCFBF1;
  --color-primary-500: #14B8A6;
  --color-primary-600: #0D9488;
  --color-primary-700: #0F766E;
  --color-accent-500:  #F59E0B;
  --color-accent-600:  #D97706;
  --color-info-500:    #2563EB;

  /* Semantik */
  --color-success: #22C55E;
  --color-warning: #F59E0B;
  --color-danger:  #EF4444;

  /* Netral (Slate) */
  --color-ink-900: #0F172A;
  --color-ink-700: #334155;
  --color-ink-600: #475569;
  --color-ink-400: #94A3B8;
  --color-ink-300: #CBD5E1;
  --color-ink-200: #E2E8F0;
  --color-ink-100: #F1F5F9;
  --color-bg:      #F6F8FB;
  --color-surface: #FFFFFF;
  /* Permukaan kedua: kepala tabel, dasar panel di dalam kartu. */
  --color-surface-2: #F8FAFC;

  /* Bentuk & bayangan — SATU skala, dipakai semua komponen.
     Sebelumnya ada dua skala radius (--radius-* dan --gel-radius-*) dengan
     nilai berbeda untuk komponen yang bersebelahan; itu yang membuat sudut
     kartu, tombol, dan chip tidak pernah terlihat satu keluarga. */
  --radius-sm: 8px;
  --radius-md: 12px;
  --radius-lg: 16px;
  --radius-pill: 999px;
  --shadow-sm:  0 1px 2px rgb(15 23 42 / .05), 0 1px 3px rgb(15 23 42 / .06);
  --shadow-md:  0 2px 4px rgb(15 23 42 / .05), 0 8px 20px -8px rgb(15 23 42 / .14);
  --shadow-pop: 0 10px 24px -6px rgb(15 23 42 / .18), 0 4px 8px -4px rgb(15 23 42 / .08);
  --ring: 0 0 0 3px rgb(20 184 166 / .20);

  /* Tipografi */
  --font-sans: "Plus Jakarta Sans", "Inter", system-ui, sans-serif;
  --font-mono: "JetBrains Mono", ui-monospace, monospace;

  /* Layout */
  --bottomnav-height: 64px;
  --sidebar-width: 258px;
  --topbar-height: 60px;
  --content-pad: 24px;

  --ease: cubic-bezier(.4, 0, .2, 1);
}

[data-theme="dark"] {
  --color-bg:        #0B1220;
  --color-surface:   #131C2E;
  --color-surface-2: #18233A;
  --color-ink-900: #F1F5F9;
  --color-ink-700: #CBD5E1;
  --color-ink-600: #94A3B8;
  --color-ink-400: #7C8CA6;
  --color-ink-300: #3A4761;
  --color-ink-200: #24314A;
  --color-ink-100: #1B2537;
  --shadow-sm:  0 1px 2px rgb(0 0 0 / .3), 0 1px 3px rgb(0 0 0 / .28);
  --shadow-md:  0 2px 6px rgb(0 0 0 / .34), 0 12px 28px -10px rgb(0 0 0 / .5);
  --shadow-pop: 0 14px 32px -8px rgb(0 0 0 / .6), 0 4px 10px -4px rgb(0 0 0 / .4);
}

/* ==========================================================================
   2. DASAR
   ========================================================================== */

*, *::before, *::after { box-sizing: border-box; }
html, body { height: 100%; }
body {
  margin: 0;
  font-family: var(--font-sans);
  background: var(--color-bg);
  color: var(--color-ink-900);
  font-size: 14px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}
h1, h2, h3, h4, h5, h6 { margin: 0 0 .5em; font-weight: 700; color: var(--color-ink-900); letter-spacing: -.01em; }
p { margin: 0 0 .75em; }
a { color: var(--color-primary-700); text-decoration: none; }
a:hover { text-decoration: underline; }
img { max-width: 100%; display: block; }
button { font-family: inherit; }
hr { border: none; border-top: 1px solid var(--color-ink-200); margin: 16px 0; }
/* Warna tautan tema gelap DI-SCOPE ke area konten.
   Versi globalnya, [data-theme="dark"] a, memakai spesifisitas (0,1,1) dan
   mengalahkan kelas komponen ber-spesifisitas (0,1,0) — akibatnya seluruh
   item bottom-nav (yang berupa <a>) ikut berwarna teal muda, sementara item
   yang AKTIF tetap teal tua dari kelasnya sendiri. Hierarkinya jadi terbalik:
   yang tidak aktif justru lebih menyala daripada yang aktif. */
[data-theme="dark"] .app-content a,
[data-theme="dark"] .bottom-sheet a,
[data-theme="dark"] .notif-dropdown a { color: #5EEAD4; }

/* Hormati preferensi "kurangi gerak" satu kali di sini, bukan per komponen. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
}

/* ==========================================================================
   3. KERANGKA APLIKASI
   --------------------------------------------------------------------------
   Desktop (>1024px): sidebar tetap di kiri + topbar sticky.
   Tablet/HP (<=1024px): sidebar menjadi laci geser, bottom-nav muncul.
   Satu markup, tampilan diatur murni lewat media query.
   ========================================================================== */

.app-shell { min-height: 100%; display: flex; }

/* ---- Sidebar ---------------------------------------------------------- */
.app-sidebar {
  width: var(--sidebar-width);
  flex-shrink: 0;
  background: var(--color-surface) !important;   /* !important: core.css mematok putih */
  border-right: 1px solid var(--color-ink-200);
  display: flex;
  flex-direction: column;
  position: fixed;
  top: 0; bottom: 0; left: 0;
  z-index: 40;
  box-shadow: none;
}

.app-brand {
  height: var(--topbar-height);
  flex-shrink: 0;
  padding: 0 20px;
  border-bottom: 1px solid var(--color-ink-200);
  background: var(--color-surface);
  font-size: 18px;
  display: flex;
  align-items: center;
}
.brand-mark { display: block; flex-shrink: 0; }
.app-brand-link {
  color: var(--color-primary-700) !important;
  text-decoration: none;
  display: flex; align-items: center; gap: 10px;
  font-weight: 800; letter-spacing: -.02em;
}
.app-brand-link:hover { text-decoration: none; }
[data-theme="dark"] .app-brand-link { color: #5EEAD4 !important; }

/* Daftar menu — markup Sneat (.menu-inner > .menu-item > .menu-link), tampilan
   sepenuhnya diambil alih di sini supaya tidak bergantung pada recolor vendor
   yang tidak punya varian gelap.

   Selector di bawah SENGAJA panjang (.app-sidebar.bg-menu-theme .menu-inner >
   .menu-item.active > .menu-link). theme-gelora.css memuat aturan Sneat
   ".bg-menu-theme .menu-inner > .menu-item.active > .menu-link" dengan
   background-color !important pada spesifisitas (0,4,0). Aturan yang lebih
   pendek di sini kalah meskipun ikut memakai !important, dan hasilnya menu
   aktif memakai latar dari Sneat tapi warna teks dari sini — kombinasi yang
   kontrasnya jatuh ke 2,15:1. Rantai yang lebih panjang menutup celah itu. */
.app-sidebar .menu-inner {
  flex: 1;
  overflow-y: auto;
  padding: 10px 0 !important;
  margin: 0;
  list-style: none;
}
.app-sidebar .menu-item { margin: 0; }
.app-sidebar.bg-menu-theme .menu-inner .menu-item .menu-link,
.app-sidebar .menu-link {
  display: flex; align-items: center; gap: 12px;
  margin: 2px 12px;
  padding: 10px 14px;
  border-radius: var(--radius-md) !important;
  color: var(--color-ink-700) !important;
  font-weight: 600;
  font-size: 13.5px;
  text-decoration: none;
  transition: background-color .16s var(--ease), color .16s var(--ease);
}
.app-sidebar.bg-menu-theme .menu-inner .menu-item .menu-link .menu-icon,
.app-sidebar .menu-link i {
  width: 20px; flex-shrink: 0;
  text-align: center; font-size: 15px;
  color: var(--color-ink-400);
  margin: 0;
  transition: color .16s var(--ease);
}
.app-sidebar.bg-menu-theme .menu-inner .menu-item .menu-link:hover,
.app-sidebar .menu-link:hover {
  background: var(--color-primary-50);
  color: var(--color-primary-700) !important;
  text-decoration: none;
}
.app-sidebar.bg-menu-theme .menu-inner .menu-item .menu-link:hover .menu-icon,
.app-sidebar .menu-link:hover i { color: var(--color-primary-600); }
.app-sidebar.bg-menu-theme .menu-inner > .menu-item.active > .menu-link,
.app-sidebar .menu-item.active > .menu-link {
  background: var(--color-primary-500) !important;
  color: #04302B !important;
  font-weight: 700;
  box-shadow: 0 6px 14px -6px rgb(13 148 136 / .55);
}
.app-sidebar.bg-menu-theme .menu-inner > .menu-item.active > .menu-link .menu-icon,
.app-sidebar .menu-item.active > .menu-link i { color: #04302B !important; }
/* Sneat menggambar pita aktif lewat ::before di tepi kanan — tidak dipakai. */
.app-sidebar .menu-item.active::before { display: none; }
.app-sidebar .menu-link > div { color: inherit; font-weight: inherit; }
.menu-inner-shadow { display: none; }

[data-theme="dark"] .app-sidebar.bg-menu-theme .menu-inner .menu-item .menu-link,
[data-theme="dark"] .app-sidebar .menu-link { color: #CBD5E1 !important; }
[data-theme="dark"] .app-sidebar.bg-menu-theme .menu-inner .menu-item .menu-link .menu-icon,
[data-theme="dark"] .app-sidebar .menu-link i { color: #94A3B8; }
[data-theme="dark"] .app-sidebar.bg-menu-theme .menu-inner .menu-item .menu-link:hover,
[data-theme="dark"] .app-sidebar .menu-link:hover {
  background: rgb(20 184 166 / .12);
  color: #5EEAD4 !important;
}
[data-theme="dark"] .app-sidebar.bg-menu-theme .menu-inner .menu-item .menu-link:hover .menu-icon,
[data-theme="dark"] .app-sidebar .menu-link:hover i { color: #5EEAD4; }
/* Menu aktif tetap teal terang di tema gelap, jadi tintanya tetap gelap.
   Tanpa aturan ini, aturan warna teks menu gelap di atas (spesifisitas sama,
   ditulis belakangan) menang dan menu aktif jadi abu terang di atas teal —
   2,0:1, justru baris yang paling penting yang paling sulit dibaca. */
[data-theme="dark"] .app-sidebar.bg-menu-theme .menu-inner > .menu-item.active > .menu-link,
[data-theme="dark"] .app-sidebar .menu-item.active > .menu-link { color: #04302B !important; }
[data-theme="dark"] .app-sidebar.bg-menu-theme .menu-inner > .menu-item.active > .menu-link .menu-icon,
[data-theme="dark"] .app-sidebar .menu-item.active > .menu-link i { color: #04302B !important; }

/* Menu duplikat di bottom-sheet "Lainnya" (partials/_nav-items). */
.app-nav-link {
  display: flex; align-items: center; gap: 12px;
  padding: 11px 14px;
  border-radius: var(--radius-md);
  color: var(--color-ink-700);
  font-weight: 600;
  margin-bottom: 2px;
}
.app-nav-link:hover { background: var(--color-primary-50); text-decoration: none; color: var(--color-primary-700); }
.app-nav-link.is-active { background: var(--color-primary-500); color: #04302B; }
.app-nav-link .icon { width: 20px; text-align: center; font-size: 15px; flex-shrink: 0; }

/* ---- Kolom utama ------------------------------------------------------ */
.app-main {
  flex: 1;
  min-width: 0;                  /* wajib: tanpa ini tabel lebar melebarkan halaman */
  margin-left: var(--sidebar-width);
  display: flex;
  flex-direction: column;
  min-height: 100%;
}

/* ---- Topbar -----------------------------------------------------------
   Sebelumnya barisan kanan (tema, notifikasi, pemilih cabang, tombol keluar)
   tidak boleh menyusut, sehingga di HP tombol "Keluar" terdorong ke luar layar
   dan pemilih cabang terpotong. Sekarang: judul yang mengalah lebih dulu, lalu
   pemilih cabang menyusut sampai batas terbaca, dan di layar sempit label
   tombol keluar berganti ikon. */
.app-topbar {
  height: var(--topbar-height);
  min-height: var(--topbar-height);
  flex-shrink: 0;
  background: var(--color-surface);
  border-bottom: 1px solid var(--color-ink-200);
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 20px;
  position: sticky;
  top: 0;
  z-index: 30;
  gap: 12px;
}
.app-topbar__lead {
  display: flex; align-items: center; gap: 10px;
  min-width: 0; flex: 1 1 auto;
}
.app-topbar__title {
  font-weight: 700; font-size: 15px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  min-width: 0;
}
.app-topbar__tools {
  display: flex; align-items: center; gap: 6px;
  flex: 0 1 auto; min-width: 0;
}
.app-topbar .btn { min-height: 36px; }
.app-topbar__menu-btn { display: none; }
/* Dipindah dari apendiks theme-gelora.css: Sneat mewarnai judul topbar
   #697a8d (4,4:1) padahal ini penanda "kamu sedang di halaman apa". */
.app-topbar .breadcrumb-item,
.app-topbar .breadcrumb-item a { color: var(--color-ink-700); }
.app-topbar .text-muted { color: var(--color-ink-600); }

/* Ikon bulat pada topbar (tema & notifikasi) — target sentuh persegi rapi. */
.app-topbar .btn-icon {
  width: 38px; height: 38px; padding: 0;
  border-radius: var(--radius-md);
  flex-shrink: 0;
}

/* Pemilih cabang: menyusut, tapi tidak pernah sampai teksnya menabrak panah. */
.app-topbar .outlet-switch {
  min-width: 0;
  max-width: 220px;
  flex: 0 1 220px;
}
.app-topbar .outlet-switch select {
  width: 100%;
  min-width: 0;
  height: 38px;
  font-size: 13px;
  font-weight: 600;
  text-overflow: ellipsis;
}

.app-content {
  padding: var(--content-pad);
  flex: 1;
  display: block;
  min-width: 0;
}
/* Guard: .content-wrapper Sneat adalah flex+space-between dan mendorong kartu
   terakhir ke dasar viewport. App ini tidak memakai pola itu. */
.app-content.content-wrapper { display: block; justify-content: flex-start; }

/* ---- Bottom nav & laci (HP) ------------------------------------------- */
.app-bottomnav { display: none; }
.sidebar-backdrop { display: none; }

@media (max-width: 1200px) {
  :root { --sidebar-width: 236px; }
}

@media (max-width: 1024px) {
  :root { --content-pad: 18px; }
  .app-sidebar {
    transform: translateX(-100%);
    transition: transform .22s var(--ease);
    box-shadow: var(--shadow-pop);
  }
  .app-sidebar.is-open { transform: translateX(0); }
  .app-main { margin-left: 0; }
  .app-topbar__menu-btn { display: inline-flex; }

  .sidebar-backdrop {
    position: fixed; inset: 0;
    background: rgb(15 23 42 / .45);
    z-index: 39;
    display: none;
  }
  .sidebar-backdrop.is-open { display: block; }
}

@media (max-width: 768px) {
  :root { --content-pad: 14px; }
  .app-topbar { padding: 0 12px; gap: 8px; }
  .app-topbar__title { font-size: 14px; }
  .app-topbar .outlet-switch { flex: 0 1 132px; max-width: 132px; }
  .app-content { padding: var(--content-pad) var(--content-pad) calc(var(--bottomnav-height) + 24px); }

  .app-bottomnav {
    display: flex;
    position: fixed;
    left: 0; right: 0; bottom: 0;
    height: calc(var(--bottomnav-height) + env(safe-area-inset-bottom));
    background: var(--color-surface);
    border-top: 1px solid var(--color-ink-200);
    box-shadow: 0 -4px 16px -8px rgb(15 23 42 / .2);
    z-index: 50;
    padding-bottom: env(safe-area-inset-bottom);
  }
  .app-bottomnav__item {
    flex: 1;
    display: flex; flex-direction: column;
    align-items: center; justify-content: center;
    gap: 3px;
    background: none; border: none;
    color: var(--color-ink-600);
    font-size: 11px; font-weight: 600;
    text-decoration: none;
    padding: 0;
  }
  .app-bottomnav__item:hover { text-decoration: none; color: var(--color-primary-600); }
  .app-bottomnav__item .icon { font-size: 19px; line-height: 1; }
  /* Aktif = teal terang. --color-primary-600 (#0D9488) terlalu gelap di atas
     permukaan gelap; di sana ia justru lebih redup daripada item tidak aktif. */
  .app-bottomnav__item.is-active { color: var(--color-primary-700); }
  [data-theme="dark"] .app-bottomnav__item { color: var(--color-ink-600); }
  [data-theme="dark"] .app-bottomnav__item.is-active { color: #2DD4BF; }
  [data-theme="dark"] .app-bottomnav__item:hover { color: #5EEAD4; }
}

/* Layar sangat sempit: judul topbar dan label tombol keluar dilepas.
   Keduanya berlebihan di HP — nama halaman sudah muncul sebagai .page-head di
   badan konten dan menu aktif ditandai di bottom-nav. Mempertahankannya justru
   menyisakan "Ber…" yang terpotong dan mendorong pemilih cabang keluar layar. */
@media (max-width: 600px) {
  .app-topbar__title { display: none; }
  .app-topbar__lead { flex: 0 0 auto; }
  .app-topbar__logout-text { display: none; }
  .app-topbar .outlet-switch { flex: 1 1 auto; max-width: none; }
}

/* ---- Bottom sheet (panel detail HP) ----------------------------------- */
.bottom-sheet-backdrop {
  position: fixed; inset: 0;
  background: rgb(15 23 42 / .45);
  z-index: 60;
  display: none;
}
.bottom-sheet-backdrop.is-open { display: block; }
.bottom-sheet {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  background: var(--color-surface);
  border-radius: 20px 20px 0 0;
  box-shadow: var(--shadow-pop);
  z-index: 61;
  max-height: 85vh;
  overflow-y: auto;
  padding: 16px 20px calc(24px + env(safe-area-inset-bottom));
  transform: translateY(100%);
  transition: transform .24s var(--ease);
}
.bottom-sheet.is-open { transform: translateY(0); }
.bottom-sheet__handle {
  width: 40px; height: 4px; border-radius: 2px;
  background: var(--color-ink-300);
  margin: 0 auto 14px;
}

@media (min-width: 769px) {
  /* Di desktop panel detail berdiri sebagai kartu biasa, bukan sheet. */
  .bottom-sheet-backdrop { display: none !important; }
  .bottom-sheet {
    position: static;
    transform: none;
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
    max-height: none;
    padding: 20px;
  }
  .bottom-sheet__handle { display: none; }
  /* "Lainnya" hanya relevan di HP — sidebar penuh sudah ada di desktop. */
  #moreMenuSheet, #moreMenuBackdrop { display: none !important; }
}

/* ==========================================================================
   4. KOMPONEN
   ========================================================================== */

/* ---- Kartu -------------------------------------------------------------
   Semua view memakai <div class="card">isi langsung</div> TANPA .card-body,
   jadi padding ada di .card. Sneat menjadikan .card sebuah flex column (untuk
   pola .card-body/.card-footer bawaan Bootstrap yang app ini tidak pakai) —
   sebagai flex item, <table> membuat tinggi kartu melar tak terduga. Kembalikan
   ke block.
   Kartu TIDAK mengangkat saat hover: ini permukaan, bukan tombol. */
.card {
  display: block;
  background: var(--color-surface);
  border: 1px solid var(--color-ink-200);
  border-radius: var(--radius-lg);
  padding: 20px;
  box-shadow: var(--shadow-sm);
  min-width: 0;
}
/* Sengaja TIDAK ada aturan ".card + .card { margin-top }": dua kartu yang
   bersebelahan di dalam .grid adalah saudara langsung juga, dan margin itu
   menurunkan kartu kedua 16px sehingga dua kartu satu baris tidak lagi sejajar.
   Jarak antar kartu yang bertumpuk diatur di view lewat .mb-16 / .mt-16. */

/* Tabel lebar digulung DI DALAM kartunya, tidak pernah melebarkan halaman.
   --------------------------------------------------------------------------
   Menggulung saja tidak cukup. Chromium memakai scrollbar overlay yang tidak
   memakan tempat dan tidak terlihat sampai disentuh, jadi tabel yang lebih
   lebar dari kartunya tampak seperti terpotong begitu saja — di /membership-tiers
   tombol "Edit" terpenggal di tengah kata dan tombol "Hapus" hilang sama
   sekali, tanpa satu pun petunjuk bahwa masih ada isi di sebelah kanan.

   Bayangan tepi di bawah ini adalah teknik "scrolling shadows": dua lapisan
   berwarna permukaan dipasang background-attachment:local sehingga IKUT
   bergulir, dan dua lapisan bayangan dipasang scroll sehingga DIAM. Saat
   gulungan berada di ujung, lapisan permukaan menutupi bayangannya; begitu
   masih ada isi di satu sisi, bayangan sisi itu muncul. Tanpa JavaScript, dan
   otomatis hilang kalau tabelnya memang muat. */
.card > .table,
.card > .table-responsive,
.card > .table-wrap,
.card > .dataTables_wrapper { max-width: 100%; overflow-x: auto; }
.card > .table { display: block; }

.card > .table,
.table-wrap,
.app-content .dt-scroll-body,
.app-content .dataTables_scrollBody {
  background-image:
    linear-gradient(to right, var(--color-surface) 40%, rgb(255 255 255 / 0)),
    linear-gradient(to left,  var(--color-surface) 40%, rgb(255 255 255 / 0)),
    radial-gradient(farthest-side at 0 50%,   rgb(15 23 42 / .14), rgb(15 23 42 / 0)),
    radial-gradient(farthest-side at 100% 50%, rgb(15 23 42 / .14), rgb(15 23 42 / 0));
  background-position: left center, right center, left center, right center;
  background-size: 28px 100%, 28px 100%, 13px 100%, 13px 100%;
  background-repeat: no-repeat;
  background-attachment: local, local, scroll, scroll;
}
[data-theme="dark"] .card > .table,
[data-theme="dark"] .table-wrap,
[data-theme="dark"] .app-content .dt-scroll-body,
[data-theme="dark"] .app-content .dataTables_scrollBody {
  background-image:
    linear-gradient(to right, var(--color-surface) 40%, rgb(19 28 46 / 0)),
    linear-gradient(to left,  var(--color-surface) 40%, rgb(19 28 46 / 0)),
    radial-gradient(farthest-side at 0 50%,   rgb(0 0 0 / .5), rgb(0 0 0 / 0)),
    radial-gradient(farthest-side at 100% 50%, rgb(0 0 0 / .5), rgb(0 0 0 / 0));
}

.card-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  padding: 0 0 14px !important;
  margin: 0 0 16px !important;
  background: transparent !important;
  border-bottom: 1px solid var(--color-ink-200) !important;
}
.card-title {
  font-size: 15px; font-weight: 800; margin: 0 !important;
  display: flex; align-items: center; gap: 8px;
  letter-spacing: -.01em;
}
.card-title i { color: var(--color-primary-600); }

/* ---- Kepala halaman --------------------------------------------------- */
.page-head {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 16px; flex-wrap: wrap;
  margin-bottom: 20px;
}
.page-head__main { display: flex; align-items: center; gap: 12px; min-width: 0; }
.page-head__back { flex-shrink: 0; border-radius: var(--radius-pill); }
.page-head__eyebrow {
  font-size: 11.5px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .08em;
  color: var(--color-primary-700);
}
.page-head__title {
  margin: 2px 0 0;
  font-size: 24px; font-weight: 800; line-height: 1.2;
  letter-spacing: -.02em;
}
.page-head__actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
[data-theme="dark"] .page-head__eyebrow { color: #2DD4BF; }

/* ---- Tombol ------------------------------------------------------------
   SATU sistem. Bentuk tombol tidak pernah berubah antar state — hanya isian
   dan tepinya. Tidak ada transform: tombol tidak bergoyang saat disentuh
   kursor. State lanjutan dibuat lebih TERANG, bukan lebih gelap, karena semua
   tombol berisi warna memakai tinta gelap.
   Tiga tingkat: isi penuh (utama) / bergaris (sekunder) / polos (tersier). */
.btn,
.btn-primary, .btn-accent, .btn-gelora, .btn-gelora-accent,
.btn-outline-primary, .btn-outline-secondary, .btn-gelora-outline,
.btn-ghost, .btn-danger, .btn-label-secondary {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  border-radius: var(--radius-sm);
  border: 1px solid transparent;
  padding: 9px 16px;
  min-height: 38px;
  font-weight: 600;
  font-size: 13.5px;
  line-height: 1.4;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  box-shadow: none;
  transform: none;
  transition: background-color .16s var(--ease), border-color .16s var(--ease), color .16s var(--ease);
}
.btn:hover, .btn:focus, .btn:active { transform: none; text-decoration: none; }
.btn-sm { padding: 6px 12px; min-height: 34px; font-size: 12.5px; border-radius: 7px; }
.btn-lg { padding: 12px 22px; min-height: 46px; font-size: 15px; border-radius: 10px; }
.btn-block { width: 100%; }
.btn:disabled, .btn.disabled { opacity: .5; cursor: not-allowed; }

/* ---- Hapus di dalam baris daftar: tenang, bukan merah pekat ---------------
   Kolom aksi pada halaman daftar (fasilitas, produk, kategori, tarif, slot,
   promo, biaya…) memakai .btn-danger yang sama dengan tombol aksi utama.
   Selector-nya sengaja "tbody", bukan ".td-actions": sebagian view menaruh
   tombol hapusnya di <td> polos tanpa kelas, dan aturan yang bergantung pada
   kelas itu melewatkan mereka.
   Hasilnya satu kolom penuh berisi tombol merah pekat sejajar dari atas ke
   bawah — bagian paling mencolok di layar adalah aksi yang paling jarang
   dipakai dan paling berbahaya kalau tersenggol.

   Pola yang dipakai di sini (sama seperti GitHub/Linear/Stripe): baris daftar
   memberi isyarat merah yang tenang, dan MERAH PEKAT disimpan untuk kotak
   konfirmasi — yang di app ini sudah ada lewat .js-confirm-delete. Merah pekat
   baru muncul saat kursor benar-benar berada di atas tombolnya. */
.app-content .table tbody .btn-danger,
.app-content .list-row .btn-danger {
  background-color: transparent !important;
  border-color: #FCA5A5 !important;
  color: #B91C1C !important;
}
.app-content .table tbody .btn-danger:hover,
.app-content .table tbody .btn-danger:focus,
.app-content .list-row .btn-danger:hover {
  background-color: #DC2626 !important;
  border-color: #DC2626 !important;
  color: #fff !important;
}
.app-content .table tbody .btn-danger:disabled,
.app-content .table tbody .btn-danger.disabled {
  border-color: var(--color-ink-200) !important;
  color: var(--color-ink-400) !important;
  background-color: transparent !important;
}
[data-theme="dark"] .app-content .table tbody .btn-danger,
[data-theme="dark"] .app-content .list-row .btn-danger {
  border-color: #7F1D1D !important;
  color: #FCA5A5 !important;
}
.btn:focus-visible { outline: 2px solid var(--color-primary-700); outline-offset: 2px; }
[data-theme="dark"] .btn:focus-visible { outline-color: #2DD4BF; }

.btn-primary, .btn-gelora {
  background-color: #14B8A6 !important;
  border-color: #14B8A6 !important;
  color: #04302B !important;
}
.btn-primary:hover, .btn-gelora:hover,
.btn-primary:focus, .btn-primary.focus, .btn-check:focus + .btn-primary {
  background-color: #2DD4BF !important; border-color: #2DD4BF !important; color: #04302B !important;
}
.btn-primary:active, .btn-primary.active,
.btn-check:checked + .btn-primary, .show > .btn-primary.dropdown-toggle {
  background-color: #5EEAD4 !important; border-color: #5EEAD4 !important; color: #04302B !important;
}

.btn-accent, .btn-gelora-accent {
  background-color: #F59E0B !important; border-color: #F59E0B !important; color: #2B1A02 !important;
}
.btn-accent:hover, .btn-accent:focus,
.btn-gelora-accent:hover, .btn-gelora-accent:focus {
  background-color: #FBBF24 !important; border-color: #FBBF24 !important; color: #2B1A02 !important;
}

.btn-outline-secondary, .btn-gelora-outline, .btn-label-secondary {
  background-color: var(--color-surface) !important;
  border-color: var(--color-ink-300) !important;
  color: var(--color-ink-700) !important;
}
.btn-outline-secondary:hover, .btn-gelora-outline:hover, .btn-label-secondary:hover,
.btn-outline-secondary:focus, .btn-gelora-outline:focus {
  background-color: var(--color-ink-100) !important;
  border-color: var(--color-primary-500) !important;
  color: var(--color-primary-700) !important;
}

.btn-outline-primary {
  background-color: transparent !important;
  border-color: #14B8A6 !important;
  color: #0F766E !important;
}
.btn-outline-primary:hover, .btn-outline-primary:focus {
  background-color: #14B8A6 !important; border-color: #14B8A6 !important; color: #04302B !important;
}

.btn-ghost {
  background-color: transparent !important;
  border-color: transparent !important;
  color: var(--color-ink-700) !important;
}
.btn-ghost:hover { background-color: var(--color-ink-100) !important; color: var(--color-ink-900) !important; }

.btn-danger {
  background-color: #DC2626 !important; border-color: #DC2626 !important; color: #fff !important;
}
.btn-danger:hover, .btn-danger:focus {
  background-color: #B91C1C !important; border-color: #B91C1C !important; color: #fff !important;
}

[data-theme="dark"] .btn-outline-secondary,
[data-theme="dark"] .btn-gelora-outline,
[data-theme="dark"] .btn-label-secondary {
  background-color: transparent !important;
  border-color: var(--color-ink-300) !important;
  color: var(--color-ink-700) !important;
}
[data-theme="dark"] .btn-outline-secondary:hover,
[data-theme="dark"] .btn-gelora-outline:hover {
  background-color: var(--color-ink-200) !important; color: #fff !important;
}
[data-theme="dark"] .btn-ghost { color: var(--color-ink-700) !important; }
[data-theme="dark"] .btn-ghost:hover { background-color: var(--color-ink-200) !important; color: #fff !important; }
[data-theme="dark"] .btn-outline-primary { color: #2DD4BF !important; border-color: #2DD4BF !important; }

/* ---- Lencana -----------------------------------------------------------
   Sneat memberi .badge color:#fff + uppercase + line-height:.75. Kalau hanya
   sebagian yang di-override, sisanya "bocor" ke lencana tanpa varian warna
   (teks putih di atas transparan = tidak terlihat). Reset lengkap di sini.
   Pasangan bg-label-* Sneat juga diganti: yang terburuk (bg-label-success)
   hanya 1,58:1. */
.badge {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 10px;
  border-radius: var(--radius-pill);
  font-size: 11.5px;
  font-weight: 700;
  line-height: 1.45;
  letter-spacing: .01em;
  text-transform: none;
  white-space: nowrap;
  color: var(--color-ink-700);
  background: var(--color-ink-200);
}
.badge.bg-label-primary   { background-color: #CCFBF1 !important; color: #115E59 !important; }
.badge.bg-label-success   { background-color: #DCFCE7 !important; color: #166534 !important; }
.badge.bg-label-warning   { background-color: #FEF3C7 !important; color: #92400E !important; }
.badge.bg-label-danger    { background-color: #FEE2E2 !important; color: #991B1B !important; }
.badge.bg-label-info      { background-color: #DBEAFE !important; color: #1E40AF !important; }
.badge.bg-label-secondary { background-color: #E2E8F0 !important; color: #334155 !important; }
.badge-accent { background: #FEF3C7; color: #92400E; }

[data-theme="dark"] .badge                    { background: var(--color-ink-200); color: var(--color-ink-700); }
[data-theme="dark"] .badge.bg-label-primary   { background-color: #10302D !important; color: #5EEAD4 !important; }
[data-theme="dark"] .badge.bg-label-success   { background-color: #0C3A2A !important; color: #6EE7B7 !important; }
[data-theme="dark"] .badge.bg-label-warning   { background-color: #3A2A0B !important; color: #FCD34D !important; }
[data-theme="dark"] .badge.bg-label-danger    { background-color: #3B1414 !important; color: #FCA5A5 !important; }
[data-theme="dark"] .badge.bg-label-info      { background-color: #16233F !important; color: #93C5FD !important; }
[data-theme="dark"] .badge.bg-label-secondary { background-color: #23303F !important; color: #CBD5E1 !important; }
[data-theme="dark"] .badge-accent             { background: #3A2A0B; color: #FCD34D; }

/* ---- Tabel -------------------------------------------------------------
   Hampir semua halaman daftar adalah tabel, jadi keterbacaan di sini
   menjatuhkan atau menyelamatkan ratusan baris sekaligus. Sneat mewarnai sel
   #697a8d (4,4:1) — meleset dari 4,5:1. */
.table {
  --bs-table-color: var(--color-ink-700);
  --bs-table-border-color: var(--color-ink-200);
  --bs-table-hover-bg: rgb(20 184 166 / .06);
  --bs-table-striped-bg: rgb(15 23 42 / .018);
  width: 100%;
  margin: 0;
  font-size: 13.5px;
  color: var(--color-ink-700);
  border-collapse: collapse;
}
.table thead th {
  background: var(--color-surface-2);
  color: var(--color-ink-600);
  font-size: 11px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: .06em;
  padding: 11px 12px;
  border-bottom: 1px solid var(--color-ink-200);
  white-space: nowrap;      /* judul kolom tidak boleh terpenggal */
  vertical-align: middle;
  text-align: left;
}
.table tbody td {
  padding: 12px 12px;
  vertical-align: middle;
  border-color: var(--color-ink-200);
  color: var(--color-ink-700);
}
.table tbody tr { transition: background-color .12s var(--ease); }
.table .num { font-variant-numeric: tabular-nums; white-space: nowrap; }
.table .cell-strong { font-weight: 700; color: var(--color-ink-900); }
.table .td-actions { white-space: nowrap; text-align: right; }
.table .td-actions .btn { margin: 2px 0; }
.table .td-photo { width: 64px; padding-right: 4px; }
[data-theme="dark"] .table { --bs-table-striped-bg: rgb(255 255 255 / .025); }
[data-theme="dark"] .table thead th { color: var(--color-ink-600); }

/* Pembungkus tabel lebar: gulung di dalam kartu, jangan lebarkan halaman. */
/* Bootstrap 5 memberi ".table > :not(:first-child)" garis atas 2px berwarna
   currentColor. Efeknya <tbody> mendapat garis dua kali lebih tebal dan lebih
   gelap daripada garis antar-baris, sehingga tiap tabel punya satu coretan
   berat tepat di bawah kepala kolom yang tidak berhubungan dengan apa pun.
   Disamakan dengan garis tabel biasa. */
.app-content .table > :not(:first-child) { border-top: 1px solid var(--color-ink-200); }
.app-content .table > tbody { border-top-color: var(--color-ink-200); }

.table-wrap {
  width: 100%; max-width: 100%;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}
.table-wrap > .table { display: table; min-width: 100%; }

/* ---- Formulir ----------------------------------------------------------
   Dua cacat yang diperbaiki: (1) nilai isian dirender dengan abu redam yang
   sama dengan teks pembantu, sehingga data tersimpan tampak seperti
   placeholder; (2) <select> memakai appearance:none tanpa panah pengganti,
   jadi tidak ada penanda bahwa ia bisa dibuka.
   Selector di-scope ke .app-content DAN .auth-page-wrap supaya halaman login
   ikut mendapat sistem yang sama. */
.app-content .form-control,
.app-content .form-select,
.app-content input[type="text"],
.app-content input[type="email"],
.app-content input[type="password"],
.app-content input[type="number"],
.app-content input[type="tel"],
.app-content input[type="url"],
.app-content input[type="date"],
.app-content input[type="time"],
.app-content input[type="datetime-local"],
.app-content input[type="search"],
.app-content textarea,
.app-content select,
.auth-page-wrap .form-control {
  width: 100%;
  color: var(--color-ink-900);
  background-color: var(--color-surface);
  border: 1px solid var(--color-ink-300);
  border-radius: var(--radius-sm);
  padding: 9px 13px;
  font-family: inherit;
  font-size: 13.5px;
  font-weight: 500;
  line-height: 1.45;
  min-height: 40px;
  transition: border-color .16s var(--ease), box-shadow .16s var(--ease);
}
.app-content textarea { min-height: 84px; }
.app-content .form-control::placeholder,
.app-content textarea::placeholder,
.app-content input::placeholder { color: var(--color-ink-400); font-weight: 400; }

.app-content .form-control:focus,
.app-content .form-select:focus,
.app-content input:focus,
.app-content textarea:focus,
.app-content select:focus,
.auth-page-wrap .form-control:focus {
  border-color: var(--color-primary-500);
  box-shadow: var(--ring);
  outline: none;
}
.app-content .form-control:disabled,
.app-content input:disabled,
.app-content select:disabled {
  background-color: var(--color-ink-100); color: var(--color-ink-600); cursor: not-allowed;
}
.app-content .is-invalid,
.app-content .form-control.is-invalid { border-color: #DC2626; }
.app-content .invalid-feedback { color: #991B1B; font-size: 12.5px; }

/* Panah dropdown kustom. Padding kanan 34px menjamin teks terpanjang tidak
   pernah menabrak panah — inilah "Semua✓" yang tertindih sebelumnya. */
.app-content select,
.app-content .form-select {
  appearance: none; -webkit-appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23475569' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 6l4 4 4-4'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 11px center;
  background-size: 15px;
  padding-right: 34px;
  cursor: pointer;
}
[data-theme="dark"] .app-content select,
[data-theme="dark"] .app-content .form-select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23CBD5E1' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 6l4 4 4-4'/%3E%3C/svg%3E");
}
/* Pemilih cabang di topbar berada di LUAR .app-content — beri aturan sendiri. */
.app-topbar .outlet-switch select {
  appearance: none; -webkit-appearance: none;
  color: var(--color-ink-900);
  background-color: var(--color-surface);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23475569' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 6l4 4 4-4'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 10px center;
  background-size: 14px;
  border: 1px solid var(--color-ink-300);
  border-radius: var(--radius-sm);
  padding: 0 32px 0 12px;
  cursor: pointer;
}
.app-topbar .outlet-switch select:focus { border-color: var(--color-primary-500); box-shadow: var(--ring); outline: none; }
[data-theme="dark"] .app-topbar .outlet-switch select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23CBD5E1' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 6l4 4 4-4'/%3E%3C/svg%3E");
}

.form-group { margin-bottom: 16px; }
.form-label,
.app-content .form-label {
  display: block;
  font-size: 11.5px; font-weight: 800;
  letter-spacing: .05em; text-transform: uppercase;
  color: var(--color-ink-600);
  margin-bottom: 6px;
}
.form-hint, .app-content .form-hint { font-size: 12.5px; color: var(--color-ink-600); margin-top: 5px; }
.form-error { font-size: 12.5px; color: var(--color-danger); margin-top: 5px; }
.form-row { display: flex; gap: 12px; flex-wrap: wrap; align-items: flex-end; }
.form-row > .form-group { flex: 1 1 180px; min-width: 0; }

/* Baris filter (kepala halaman daftar & kartu "Filter"): setiap kolom punya
   lebar minimum. <select> menyusut mengikuti teks terpanjangnya sementara
   panah dropdown kustom menempati 34px terakhir — tanpa lebar minimum, pilihan
   pendek seperti "Semua" tercetak persis di bawah panahnya. */
.app-content .flex > .form-group { min-width: 148px; }
.app-content .flex > .form-group[style*="max-width"] { min-width: 0; }

.app-content .form-check-input:checked {
  background-color: var(--color-primary-500);
  border-color: var(--color-primary-500);
}
.app-content .form-check-input:focus {
  border-color: var(--color-primary-500);
  box-shadow: var(--ring);
}
.app-content .form-check-label { color: var(--color-ink-900); }

[data-theme="dark"] .app-content .form-control,
[data-theme="dark"] .app-content .form-select,
[data-theme="dark"] .app-content input,
[data-theme="dark"] .app-content textarea,
[data-theme="dark"] .app-content select {
  background-color: var(--color-ink-100); border-color: var(--color-ink-300); color: #fff;
}
[data-theme="dark"] .app-content input::placeholder,
[data-theme="dark"] .app-content textarea::placeholder { color: var(--color-ink-400); }
[data-theme="dark"] .app-content .form-control:disabled { background-color: var(--color-ink-200); color: var(--color-ink-600); }

@media (pointer: coarse) {
  .app-content .form-control,
  .app-content select,
  .app-content input { min-height: 44px; }
}

/* ---- Alert -------------------------------------------------------------
   .alert bawaan Sneat memakai tinta berwarna terang di atas tint terang
   (terburuk 1,71:1). */
.alert {
  border-radius: var(--radius-md);
  border: 1px solid transparent;
  padding: 12px 16px;
}
.alert-primary { background-color: #CCFBF1 !important; border-color: #99F6E4 !important; color: #115E59 !important; }
.alert-success { background-color: #DCFCE7 !important; border-color: #BBF7D0 !important; color: #166534 !important; }
.alert-warning { background-color: #FEF3C7 !important; border-color: #FDE68A !important; color: #92400E !important; }
.alert-danger  { background-color: #FEE2E2 !important; border-color: #FECACA !important; color: #991B1B !important; }
.alert-info    { background-color: #DBEAFE !important; border-color: #BFDBFE !important; color: #1E40AF !important; }
.alert-light   { background-color: var(--color-surface-2) !important; border-color: var(--color-ink-200) !important; color: var(--color-ink-900) !important; }
.alert code { background: rgb(15 23 42 / .08); padding: 1px 5px; border-radius: 4px; color: inherit; }

[data-theme="dark"] .alert-primary { background-color: #10302D !important; border-color: #14403B !important; color: #5EEAD4 !important; }
[data-theme="dark"] .alert-success { background-color: #0C3A2A !important; border-color: #14532D !important; color: #6EE7B7 !important; }
[data-theme="dark"] .alert-warning { background-color: #3A2A0B !important; border-color: #5C4410 !important; color: #FCD34D !important; }
[data-theme="dark"] .alert-danger  { background-color: #3B1414 !important; border-color: #5C1D1D !important; color: #FCA5A5 !important; }
[data-theme="dark"] .alert-info    { background-color: #16233F !important; border-color: #1E3A5F !important; color: #93C5FD !important; }
[data-theme="dark"] .alert-light   { background-color: var(--color-ink-100) !important; border-color: var(--color-ink-200) !important; color: var(--color-ink-700) !important; }
[data-theme="dark"] .alert code    { background: rgb(255 255 255 / .10); }

/* Strip aksi (mis. booking online belum diverifikasi). */
.alert-strip {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 16px; border-radius: var(--radius-md);
  background: #FFFBEB; border: 1px solid #FDE68A;
  color: var(--color-ink-900); text-decoration: none;
}
.alert-strip:hover { background: #FEF3C7; text-decoration: none; }
.alert-strip__icon { color: var(--color-accent-600); flex-shrink: 0; }
.alert-strip__cta { margin-left: auto; font-weight: 700; color: #92400E; white-space: nowrap; }
[data-theme="dark"] .alert-strip { background: #3A2A0B; border-color: #5C4410; color: #FCD34D; }
[data-theme="dark"] .alert-strip:hover { background: #4A360E; }
[data-theme="dark"] .alert-strip__cta { color: #FCD34D; }

/* ---- Teks redam & utilitas -------------------------------------------- */
.app-content .text-muted,
.app-content small.text-muted { color: var(--color-ink-600) !important; }

/* .text-danger/.text-success datang dari Bootstrap lewat --bs-danger/--bs-success.
   Nilai terangnya (#EF4444 / #22C55E) dirancang untuk latar putih; di atas
   permukaan gelap keduanya turun ke sekitar 4:1. Dipertegas di sini, satu tempat,
   karena keduanya dipakai untuk angka penting (selisih kas, laba bersih). */
.app-content .text-danger  { color: #B91C1C !important; }
.app-content .text-success { color: #15803D !important; }
[data-theme="dark"] .app-content .text-danger  { color: #FCA5A5 !important; }
[data-theme="dark"] .app-content .text-success { color: #6EE7B7 !important; }
.flex { display: flex; }
.items-center { align-items: center; }
.justify-between { justify-content: space-between; }
.gap-8 { gap: 8px; }
.gap-12 { gap: 12px; }
.mt-16 { margin-top: 16px; }
.mb-16 { margin-bottom: 16px; }

/* ---- Grid utilitas -----------------------------------------------------
   SATU set titik henti untuk semua kolom (sebelumnya .grid-cols-2 pecah di
   768px menurut satu berkas dan 900px menurut berkas lain, sehingga di antara
   keduanya kolom kadang 1 kadang 2 tergantung urutan muat). */
.grid { display: grid; gap: 16px; }
.grid-cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid-cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.grid-cols-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
@media (max-width: 1200px) { .grid-cols-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 1024px) { .grid-cols-3 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 860px)  { .grid-cols-2, .grid-cols-3, .grid-cols-4 { grid-template-columns: minmax(0, 1fr); } }

/* ---- Ubin angka generik (.stat-tile) ---------------------------------- */
.stat-tile {
  background: var(--color-surface);
  border: 1px solid var(--color-ink-200);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  padding: 18px 20px;
  min-width: 0;
}
.stat-tile__label {
  font-size: 11.5px; font-weight: 800;
  color: var(--color-ink-600);
  text-transform: uppercase; letter-spacing: .06em;
}
.stat-tile__value {
  font-size: 26px; font-weight: 800; margin-top: 6px;
  letter-spacing: -.02em; font-variant-numeric: tabular-nums;
  line-height: 1.15;
}
.stat-tile__meta { font-size: 12px; color: var(--color-ink-600); margin-top: 4px; }
.stat-tile.is-warning { border-color: #FDE68A; background: #FFFBEB; }
[data-theme="dark"] .stat-tile.is-warning { border-color: #5C4410; background: #2A200B; }

/* ---- Baris daftar ringkas --------------------------------------------- */
.list-row {
  display: flex; align-items: center; gap: 12px;
  padding: 11px 12px; margin: 0 -12px;
  border-radius: var(--radius-md);
  border-bottom: 1px solid var(--color-ink-200);
  transition: background-color .15s var(--ease);
}
.list-row:last-child { border-bottom: none; }
.list-row:hover { background: var(--color-surface-2); }
.list-row__icon { width: 28px; text-align: center; flex-shrink: 0; }
.list-row__body { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.list-row__body .text-muted { font-size: 12px; }
.list-row__meta { display: flex; align-items: center; gap: 8px; flex-shrink: 0; font-size: 12px; }

/* ---- Keadaan kosong ---------------------------------------------------- */
.empty-state { text-align: center; padding: 34px 20px; color: var(--color-ink-600); }
.empty-state i { font-size: 32px; color: var(--color-ink-300); display: block; margin-bottom: 10px; }

/* ---- Thumbnail entitas -------------------------------------------------- */
.thumb {
  width: 46px; height: 46px;
  border-radius: var(--radius-sm);
  object-fit: cover;
  display: block;
  border: 1px solid var(--color-ink-200);
  background: var(--color-surface);
}
.thumb--empty {
  display: flex; align-items: center; justify-content: center;
  background: var(--color-ink-200); color: var(--color-ink-600);
  font-size: 15px;
}

/* ---- Avatar kecil ------------------------------------------------------ */
.avatar-sm {
  width: 30px; height: 30px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--color-primary-50); color: var(--color-primary-700);
  font-size: 12px; font-weight: 800; flex-shrink: 0;
}
[data-theme="dark"] .avatar-sm { background: #10302D; color: #5EEAD4; }

/* ==========================================================================
   5. NOTIFIKASI (lonceng topbar)
   ========================================================================== */

.notif-widget { position: relative; flex-shrink: 0; }
.notif-badge {
  position: absolute; top: 2px; right: 2px;
  background: var(--color-danger); color: #fff;
  font-size: 10px; font-weight: 800; line-height: 1;
  min-width: 16px; height: 16px; border-radius: var(--radius-pill);
  display: flex; align-items: center; justify-content: center;
  padding: 0 3px;
  box-shadow: 0 0 0 2px var(--color-surface);
}
.notif-dropdown {
  position: absolute; top: calc(100% + 10px); right: 0;
  width: 360px; max-width: calc(100vw - 24px);
  max-height: 440px; overflow-y: auto;
  background: var(--color-surface);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-pop);
  border: 1px solid var(--color-ink-200);
  z-index: 70;
  display: none;
}
.notif-dropdown.is-open { display: block; }
.notif-dropdown__header {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding: 12px 16px; border-bottom: 1px solid var(--color-ink-200);
  position: sticky; top: 0; background: var(--color-surface); z-index: 1;
}
.notif-dropdown__footer {
  padding: 10px 16px; text-align: center;
  border-top: 1px solid var(--color-ink-200);
  font-weight: 700; font-size: 13px;
  position: sticky; bottom: 0; background: var(--color-surface);
}
.notif-item {
  display: flex; gap: 10px; padding: 12px 16px;
  border-bottom: 1px solid var(--color-ink-200);
  cursor: pointer;
}
.notif-item:last-child { border-bottom: none; }
.notif-item:hover { background: var(--color-primary-50); }
[data-theme="dark"] .notif-item:hover { background: rgb(20 184 166 / .1); }
.notif-item.is-unread { background: color-mix(in srgb, var(--color-primary-500) 7%, transparent); }
.notif-item__icon {
  width: 34px; height: 34px; border-radius: 50%; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  color: #fff; font-size: 13px;
}
.notif-item__icon.level-info { background: var(--color-info-500); }
.notif-item__icon.level-warning { background: var(--color-accent-600); }
.notif-item__icon.level-danger { background: var(--color-danger); }
.notif-item__icon.level-success { background: #16A34A; }
.notif-item__body { flex: 1; min-width: 0; }
.notif-item__title { font-weight: 700; font-size: 13px; }
.notif-item__text { font-size: 12px; color: var(--color-ink-600); margin-top: 2px; }
.notif-item__meta { font-size: 11px; color: var(--color-ink-400); margin-top: 4px; }
.notif-item__dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--color-primary-500); flex-shrink: 0; margin-top: 6px;
}

/* ==========================================================================
   6. DASHBOARD
   --------------------------------------------------------------------------
   Prinsip: satu skala jarak untuk semua panel; tiap angka punya jangkar visual
   berupa ubin ikon; hierarki dari lebar kolom, bukan dari warna; garis tipis
   sebagai pemisah, bayangan seminimal mungkin.

   Kartu angka memakai kolom TETAP, bukan auto-fit. Dengan auto-fit, enam kartu
   pada layar 1440px jatuh menjadi 5 + 1 yatim di baris kedua, dan lebar per
   kartu menjadi terlalu sempit sehingga label dua kata ("Pengeluaran Hari Ini")
   terpotong ke dua baris pada sebagian kartu saja — angkanya lalu tidak sejajar
   antar kartu. Tiga kolom membuat enam kartu selalu jatuh 3 + 3 dan cukup lebar
   untuk label satu baris.
   ========================================================================== */

.dash-welcome {
  display: flex; align-items: center; justify-content: space-between;
  gap: 20px; flex-wrap: wrap;
  background: var(--color-surface);
  border: 1px solid var(--color-ink-200);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  padding: 22px 24px;
  margin-bottom: 16px;
}
.dash-welcome__title { font-size: 22px; font-weight: 800; margin: 0; line-height: 1.2; letter-spacing: -.02em; }
.dash-welcome__meta { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 10px; }

.dash-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 11px; border-radius: var(--radius-pill);
  background: var(--color-primary-50); color: var(--color-primary-700);
  font-size: 12px; font-weight: 700;
}
.dash-chip--muted { background: var(--color-ink-100); color: var(--color-ink-700); }
.dash-chip--danger { background: #FEE2E2; color: #991B1B; }
[data-theme="dark"] .dash-chip { background: #10302D; color: #5EEAD4; }
[data-theme="dark"] .dash-chip--muted { background: var(--color-ink-200); color: var(--color-ink-700); }
[data-theme="dark"] .dash-chip--danger { background: #3B1414; color: #FCA5A5; }

/* ---- Kartu angka ------------------------------------------------------- */
.dash-stats {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16px;
  margin-bottom: 16px;
}
/* Jumlah kolom mengikuti JUMLAH KARTU, bukan lebar minimum.
   Blok kartu angka dipakai ulang di beberapa halaman dengan jumlah berbeda:
   Beranda 6, Invoice 3, Riwayat Shift 4. Dengan auto-fit maupun tiga kolom
   tetap, salah satu dari ketiganya selalu menyisakan kartu yatim di baris
   terakhir. Kueri jumlah di bawah membuat tiap set jatuh rata: 6 -> 3+3,
   4 -> 4, 3 -> 3, 2 -> 2. */
@media (min-width: 1281px) {
  .dash-stats { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .dash-stats:has(> :nth-child(1):last-child) { grid-template-columns: minmax(0, 1fr); }
  .dash-stats:has(> :nth-child(2):last-child) { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .dash-stats:has(> :nth-child(4):last-child) { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
.dash-stat {
  position: relative;
  overflow: hidden;
  background: var(--color-surface);
  border: 1px solid var(--color-ink-200);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  padding: 18px 20px 18px 22px;
  display: flex; gap: 14px; align-items: center;
  min-width: 0;
}
/* Pita warna tipis di tepi kiri — penanda jenis kartu. */
.dash-stat::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
  background: var(--color-primary-500);
}
.dash-stat--accent::before  { background: var(--color-accent-500); }
.dash-stat--info::before    { background: var(--color-info-500); }
.dash-stat--warning::before { background: var(--color-accent-600); }
.dash-stat--danger::before  { background: var(--color-danger); }

.dash-stat__icon {
  width: 44px; height: 44px; flex-shrink: 0;
  border-radius: var(--radius-md);
  display: flex; align-items: center; justify-content: center;
  font-size: 16px;
  background: var(--color-primary-50); color: var(--color-primary-700);
}
.dash-stat--accent  .dash-stat__icon { background: #FFF7ED; color: var(--color-accent-600); }
.dash-stat--info    .dash-stat__icon { background: #EFF6FF; color: var(--color-info-500); }
.dash-stat--warning .dash-stat__icon { background: #FFFBEB; color: #B45309; }
.dash-stat--danger  .dash-stat__icon { background: #FEF2F2; color: #DC2626; }

/* min-width:0 pada kolom teks: tanpa ini angka panjang ("Rp 12.500.000")
   melebarkan kartu dan merusak grid. */
.dash-stat > div { min-width: 0; }
.dash-stat__label {
  font-size: 12px; font-weight: 700; color: var(--color-ink-600);
  letter-spacing: .01em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.dash-stat__value {
  font-size: 25px; font-weight: 800; line-height: 1.15; margin-top: 3px;
  letter-spacing: -.02em; font-variant-numeric: tabular-nums;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.dash-stat__meta {
  font-size: 12px; color: var(--color-ink-600); margin-top: 3px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.dash-stat.is-warning { border-color: #FDE68A; }
.dash-stat--danger { border-color: #FECACA; }
[data-theme="dark"] .dash-stat__icon           { background: #10302D; color: #2DD4BF; }
[data-theme="dark"] .dash-stat--accent  .dash-stat__icon { background: #3A2A0B; color: #FBBF24; }
[data-theme="dark"] .dash-stat--info    .dash-stat__icon { background: #16233F; color: #93C5FD; }
[data-theme="dark"] .dash-stat--warning .dash-stat__icon { background: #3A2A0B; color: #FCD34D; }
[data-theme="dark"] .dash-stat--danger  .dash-stat__icon { background: #3B1414; color: #FCA5A5; }
[data-theme="dark"] .dash-stat.is-warning { border-color: #5C4410; }
[data-theme="dark"] .dash-stat--danger    { border-color: #5C1D1D; }

/* ---- Susunan dua kolom ------------------------------------------------- */
.dash-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr);
  gap: 16px;
  align-items: start;              /* panel pendek tidak diregangkan */
}

.dash-panel {
  background: var(--color-surface);
  border: 1px solid var(--color-ink-200);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  padding: 20px 22px;
  min-width: 0;
}
.dash-panel + .dash-panel { margin-top: 16px; }
.dash-panel__head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; flex-wrap: wrap;
  padding-bottom: 14px; margin-bottom: 4px;
  border-bottom: 1px solid var(--color-ink-200);
}
.dash-panel__title { font-size: 15px; font-weight: 800; margin: 0; letter-spacing: -.01em; }
.dash-panel__count { font-size: 12px; font-weight: 700; color: var(--color-ink-600); }

.dash-item {
  display: flex; align-items: center; gap: 14px;
  padding: 14px 0; border-bottom: 1px solid var(--color-ink-200);
}
.dash-item:last-child { border-bottom: none; padding-bottom: 0; }
.dash-item__icon {
  width: 38px; height: 38px; flex-shrink: 0; border-radius: var(--radius-md);
  display: flex; align-items: center; justify-content: center; font-size: 14px;
  background: var(--color-ink-100); color: var(--color-ink-700);
}
.dash-item__body { min-width: 0; flex: 1; }
.dash-item__title { font-weight: 700; font-size: 14px; }
.dash-item__sub { font-size: 12.5px; color: var(--color-ink-600); margin-top: 2px; }
.dash-item__meta { flex-shrink: 0; text-align: right; display: flex; flex-direction: column; align-items: flex-end; gap: 4px; }
.dash-item__time { font-size: 12px; color: var(--color-ink-600); font-variant-numeric: tabular-nums; }

.dash-actions { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
.dash-action {
  display: flex; flex-direction: column; gap: 8px;
  padding: 14px; border-radius: var(--radius-md);
  border: 1px solid var(--color-ink-200); background: var(--color-surface);
  color: var(--color-ink-900); text-decoration: none;
  transition: border-color .18s var(--ease), background-color .18s var(--ease);
}
.dash-action:hover {
  border-color: var(--color-primary-500); background: var(--color-primary-50);
  text-decoration: none;
}
[data-theme="dark"] .dash-action:hover { background: rgb(20 184 166 / .1); }
.dash-action i { font-size: 15px; color: var(--color-primary-600); }
.dash-action span { font-size: 13px; font-weight: 700; line-height: 1.3; }

.dash-empty { text-align: center; padding: 26px 12px; color: var(--color-ink-600); }
.dash-empty i { font-size: 24px; color: var(--color-ink-300); display: block; margin-bottom: 8px; }
.dash-empty p { margin: 0; font-size: 13px; }

.dash-chart { position: relative; height: 240px; }
.dash-chart__note { margin: 14px 0 0; font-size: 12.5px; color: var(--color-ink-600); }
.dash-chart__note strong { color: var(--color-ink-900); font-variant-numeric: tabular-nums; }

.dash-live {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 11px; font-weight: 800; letter-spacing: .04em; text-transform: uppercase;
  color: #16A34A;
}
.dash-live i { font-size: 8px; animation: dash-pulse 2s ease-in-out infinite; }
@keyframes dash-pulse { 0%, 100% { opacity: 1; } 50% { opacity: .25; } }
[data-theme="dark"] .dash-live { color: #4ADE80; }

@media (max-width: 1000px) { .dash-grid { grid-template-columns: minmax(0, 1fr); } }
@media (max-width: 640px) {
  /* Di HP kartu angka tetap DUA kolom, bukan satu: satu kolom membuat tiap
     kartu setinggi seperempat layar sehingga hanya dua angka terlihat tanpa
     menggulir. Versi ringkasnya cukup terbaca. */
  .dash-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
  .dash-stat { padding: 14px 12px 14px 15px; gap: 10px; flex-direction: column; align-items: flex-start; }
  .dash-stat__icon { width: 34px; height: 34px; font-size: 13px; border-radius: 10px; }
  .dash-stat__value { font-size: 19px; }
  .dash-stat__label { font-size: 11px; white-space: normal; }
  .dash-stat__meta { font-size: 11px; }
  .dash-welcome { padding: 18px; gap: 14px; }
  .dash-welcome__title { font-size: 19px; }
  .dash-panel { padding: 16px; }
  .dash-actions { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .dash-chart { height: 200px; }
}

/* ==========================================================================
   7. WORKSPACE KASIR
   --------------------------------------------------------------------------
   Dua zona: .kasir-main (denah + katalog F&B) mengisi ruang, .kasir-cart
   (panel keranjang) menetap di kanan. Di bawah 1024px keranjang menjadi
   bottom-sheet, pola yang sama dengan .bottom-sheet.
   ========================================================================== */

.kasir-workspace { display: flex; gap: 18px; align-items: flex-start; }
.kasir-main { flex: 1; min-width: 0; }

.kasir-cart {
  width: 380px; flex-shrink: 0;
  position: sticky; top: calc(var(--topbar-height) + 16px);
  max-height: calc(100vh - var(--topbar-height) - 32px);
  display: flex; flex-direction: column;
  overflow: hidden;
  background: var(--color-surface);
  border: 1px solid var(--color-ink-200);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
  padding: 0;
}
.kasir-cart__head {
  background: linear-gradient(120deg, var(--color-primary-700), var(--color-primary-500));
  color: #fff;
  padding: 13px 18px;
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  flex-shrink: 0;
}
.kasir-cart__head strong { font-size: 15px; font-weight: 800; display: flex; align-items: center; gap: 9px; }
.kasir-cart__head .badge { background: rgb(255 255 255 / .2) !important; color: #fff !important; border: 1px solid rgb(255 255 255 / .28); }
.kasir-cart__head .btn-ghost { color: rgb(255 255 255 / .88) !important; }
.kasir-cart__head .btn-ghost:hover { background: rgb(255 255 255 / .16) !important; color: #fff !important; }
#unitDetailBody { padding: 16px 18px; overflow-y: auto; flex: 1; min-height: 0; }
.kasir-cart__fnb {
  border-top: 1px solid var(--color-ink-200);
  padding: 13px 18px 15px;
  background: var(--color-surface-2);
  flex-shrink: 0;
  max-height: 34vh;
  overflow-y: auto;
}
.kasir-cart__fnb > strong {
  font-size: 11px; text-transform: uppercase; letter-spacing: .07em;
  color: var(--color-ink-600); display: flex; align-items: center; gap: 8px;
}
.kasir-cart__footer {
  border-top: 1px solid var(--color-ink-200);
  padding: 12px 18px 14px;
  background: var(--color-surface);
  flex-shrink: 0;
}
.kasir-cart__footer .grand { display: flex; justify-content: space-between; align-items: center; font-weight: 800; font-size: 15px; }
.kasir-cart__footer .grand span:last-child { color: var(--color-primary-700); font-variant-numeric: tabular-nums; }
[data-theme="dark"] .kasir-cart__footer .grand span:last-child { color: #2DD4BF; }
.kasir-cart__backdrop { display: none; }

/* Bagian di dalam panel unit. */
.kasir-panel-section { margin-bottom: 16px; }
.kasir-panel-section > .section-label {
  font-size: 11px; font-weight: 800; text-transform: uppercase; letter-spacing: .07em;
  color: var(--color-ink-600); margin-bottom: 8px;
  display: flex; align-items: center; gap: 8px;
}
.kasir-panel-section > .section-label::after {
  content: ""; flex: 1; height: 1px; background: var(--color-ink-200);
}

/* Item keranjang F&B. */
.cart-fnb-item {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 10px;
  border-radius: var(--radius-md);
  background: var(--color-surface);
  border: 1px solid var(--color-ink-200);
  margin-bottom: 8px;
}
.cart-fnb-item:last-child { margin-bottom: 0; }
.cart-fnb-item__icon {
  width: 34px; height: 34px; border-radius: 10px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  background: var(--color-primary-50); color: var(--color-primary-700); font-size: 14px;
}
[data-theme="dark"] .cart-fnb-item__icon { background: #10302D; color: #5EEAD4; }
.cart-fnb-item__name { font-weight: 700; font-size: 13px; color: var(--color-ink-900); }
.cart-fnb-item__price { font-size: 12px; color: var(--color-ink-600); font-variant-numeric: tabular-nums; }
.cart-fnb-item__stepper { display: flex; align-items: center; gap: 4px; }
.cart-fnb-item__stepper .btn {
  width: 28px; height: 28px; min-height: 28px; padding: 0; border-radius: 8px;
  display: flex; align-items: center; justify-content: center; font-size: 13px;
}
.cart-fnb-item__qty { min-width: 22px; text-align: center; font-weight: 800; font-size: 13px; }
.cart-fnb-item__remove {
  color: var(--color-ink-400); background: none; border: none; cursor: pointer;
  padding: 5px; border-radius: 8px; line-height: 1;
}
.cart-fnb-item__remove:hover { color: var(--color-danger); background: var(--color-ink-100); }

/* Kartu hasil pencarian member. */
.member-lookup__result { margin-top: 8px; }
.member-lookup-card {
  border: 1px solid var(--color-primary-500);
  background: var(--color-primary-50);
  border-radius: var(--radius-md);
  padding: 12px 14px;
  display: flex; gap: 12px; align-items: flex-start;
}
.member-lookup-card.is-plain { border-color: var(--color-ink-200); background: var(--color-surface); }
.member-lookup-card__avatar {
  width: 42px; height: 42px; border-radius: var(--radius-md); flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  background: var(--color-primary-500); color: #04302B; font-size: 16px;
}
.member-lookup-card__avatar.is-plain { background: var(--color-ink-300); color: var(--color-ink-700); }
.member-lookup-card__name { font-weight: 800; color: var(--color-ink-900); font-size: 14px; }
.member-lookup-card__meta { font-size: 12px; color: var(--color-ink-600); margin-top: 2px; }
.member-lookup-card__badges { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 6px; }
.member-lookup-card__actions { margin-top: 8px; }
[data-theme="dark"] .member-lookup-card { border-color: #1F6F66; background: #0E2B27; }

/* ---- Chip pilihan ------------------------------------------------------ */
.kasir-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 7px 15px;
  border-radius: var(--radius-pill);
  font-family: inherit; font-weight: 700; font-size: 13px;
  background: var(--color-surface);
  border: 1.5px solid var(--color-ink-300);
  color: var(--color-ink-700);
  cursor: pointer;
  transition: background-color .15s var(--ease), border-color .15s var(--ease), color .15s var(--ease);
}
.kasir-chip:hover:not(:disabled) { border-color: var(--color-primary-500); color: var(--color-primary-700); }
.kasir-chip.is-active {
  background: var(--color-primary-500);
  border-color: var(--color-primary-500);
  color: #04302B;
}
.kasir-chip:disabled { opacity: .42; cursor: not-allowed; }
.kasir-chip-row { display: flex; flex-wrap: wrap; gap: 8px; }
/* Strip jam ketersediaan — versi ringkas supaya 14 jam tidak memakan panel. */
.kasir-chip.is-hour { cursor: default; padding: 5px 10px; font-size: 12px; }
.kasir-chip.is-hour em { font-style: normal; font-weight: 600; font-size: 11px; opacity: .75; }
.kasir-chip.is-hour.is-past { opacity: .45; }
.kasir-chip.is-hour.is-full { border-color: #FECACA; background: #FEF2F2; color: #B91C1C; }
.kasir-chip.is-hour.is-now { border-color: var(--color-primary-500); box-shadow: 0 0 0 1px var(--color-primary-500); }
[data-theme="dark"] .kasir-chip.is-hour.is-full { background: #3B1414; color: #FCA5A5; border-color: #7F1D1D; }
#sessionHourStrip .kasir-chip-row { gap: 6px; }

/* ---- Katalog F&B ------------------------------------------------------- */
.fnb-toolbar { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 14px; }
.fnb-tabs { display: flex; gap: 6px; flex-wrap: wrap; flex: 1; min-width: 0; }
.fnb-tab {
  border: 1px solid var(--color-ink-200); background: var(--color-surface);
  color: var(--color-ink-700); border-radius: var(--radius-pill);
  padding: 6px 14px; font-size: 13px; font-weight: 700; cursor: pointer;
  transition: background-color .15s var(--ease), border-color .15s var(--ease), color .15s var(--ease);
}
.fnb-tab span { color: var(--color-ink-600); font-weight: 600; margin-left: 2px; }
.fnb-tab:hover { border-color: var(--color-primary-500); color: var(--color-primary-700); }
.fnb-tab.is-active { background: var(--color-ink-900); border-color: var(--color-ink-900); color: #fff; }
.fnb-tab.is-active span { color: rgb(255 255 255 / .65); }
[data-theme="dark"] .fnb-tab.is-active { background: var(--color-primary-500); border-color: var(--color-primary-500); color: #04302B; }
[data-theme="dark"] .fnb-tab.is-active span { color: rgb(4 48 43 / .7); }

.fnb-search { position: relative; flex-shrink: 0; }
.fnb-search i { position: absolute; left: 12px; top: 50%; transform: translateY(-50%); color: var(--color-ink-400); font-size: 13px; }
.app-content .fnb-search input {
  border-radius: var(--radius-pill);
  padding: 7px 14px 7px 32px;
  width: 200px;
}

.fnb-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(168px, 1fr)); gap: 12px; }
.fnb-item {
  position: relative;
  display: flex; flex-direction: column; padding: 0; overflow: hidden;
  text-align: left; border-radius: var(--radius-md);
  border: 1px solid var(--color-ink-200); background: var(--color-surface);
  cursor: pointer; font: inherit; color: var(--color-ink-900);
  box-shadow: var(--shadow-sm);
  transition: border-color .15s var(--ease), box-shadow .15s var(--ease);
}
.fnb-item:hover:not(:disabled) { border-color: var(--color-primary-500); box-shadow: var(--shadow-md); }
.fnb-item:disabled { opacity: .6; cursor: not-allowed; }
.fnb-item__media {
  position: relative; width: 100%; aspect-ratio: 4 / 3;
  display: flex; align-items: center; justify-content: center;
  background: var(--color-primary-50);
  color: var(--color-primary-600); font-size: 26px;
  border-bottom: 1px solid var(--color-ink-200); overflow: hidden;
}
[data-theme="dark"] .fnb-item__media { background: #10302D; color: #5EEAD4; }
.fnb-item__media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.fnb-item__body { display: flex; flex-direction: column; gap: 2px; padding: 10px 12px 12px; align-items: flex-start; }
.fnb-item__name { font-weight: 700; font-size: 13px; line-height: 1.3; }
.fnb-item__price { font-size: 14px; color: var(--color-primary-700); font-weight: 800; font-variant-numeric: tabular-nums; }
[data-theme="dark"] .fnb-item__price { color: #2DD4BF; }
.fnb-item__add {
  position: absolute; right: 8px; bottom: 8px;
  width: 27px; height: 27px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: var(--color-primary-500); color: #04302B; font-size: 12px;
  box-shadow: var(--shadow-sm);
  transition: background-color .15s var(--ease);
}
.fnb-item:hover:not(:disabled) .fnb-item__add { background: #2DD4BF; }
.fnb-item:disabled .fnb-item__add { background: var(--color-ink-300); color: var(--color-ink-600); }
.fnb-item__qty {
  position: absolute; top: -6px; right: -6px;
  min-width: 22px; height: 22px; padding: 0 5px; border-radius: var(--radius-pill);
  display: flex; align-items: center; justify-content: center;
  background: var(--color-accent-500); color: #2B1A02;
  font-size: 11px; font-weight: 800;
  border: 2px solid var(--color-surface);
}
.fnb-item__stock {
  position: absolute; top: 8px; right: 8px; z-index: 1;
  font-size: 10px; font-weight: 800; line-height: 1;
  padding: 3px 7px; border-radius: var(--radius-pill);
  background: rgb(255 255 255 / .92); color: var(--color-ink-700);
  border: 1px solid var(--color-ink-200);
}
.fnb-item__stock.is-out { background: #FEE2E2; color: #B91C1C; border-color: #FECACA; }

@media (max-width: 1024px) {
  .kasir-workspace { display: block; }
  .kasir-cart {
    position: fixed; left: 0; right: 0; bottom: 0; top: auto;
    width: auto; max-height: 88vh;
    border-radius: 20px 20px 0 0;
    z-index: 61; transform: translateY(100%);
    transition: transform .24s var(--ease);
    box-shadow: var(--shadow-pop);
  }
  .kasir-cart.is-open { transform: translateY(0); }
  .kasir-cart__backdrop {
    position: fixed; inset: 0; background: rgb(15 23 42 / .45); z-index: 60; display: none;
  }
  .kasir-cart__backdrop.is-open { display: block; }
}

/* ==========================================================================
   8. DENAH (floor plan)
   --------------------------------------------------------------------------
   Warna ubin dan warna titik legenda WAJIB berasal dari satu tempat. Sebelumnya
   ubin diwarnai di CSS sementara titik legenda diwarnai lewat style inline di
   Blade, dan keduanya menyimpang: "Dipakai" dan "Maintenance" sama-sama amber
   sehingga legendanya menyesatkan. Sekarang legenda memakai kelas
   .floor-plan-legend__dot.status-* yang mengambil warna dari daftar yang sama.
   ========================================================================== */

.floor-plan-canvas {
  position: relative;
  overflow: auto;
  border-radius: var(--radius-lg);
  border: 1px solid var(--color-ink-200);
  background:
    linear-gradient(var(--color-ink-200) 1px, transparent 1px),
    linear-gradient(90deg, var(--color-ink-200) 1px, transparent 1px);
  background-size: 26px 26px;
  background-color: var(--color-bg);
  /* Tinggi dihitung ulang oleh kasir-pos.js agar seluruh unit muat tanpa
     terpotong; nilai di sini hanya bekal awal sebelum skrip berjalan. */
  min-height: 360px;
  transition: height .24s var(--ease), min-height .24s var(--ease);
}
.floor-plan-canvas.is-expanded { min-height: 620px; }

.floor-plan-unit {
  position: absolute;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  gap: 3px;
  border-radius: var(--radius-md);
  border: 2px solid rgb(255 255 255 / .85);
  box-shadow: var(--shadow-sm);
  padding: 4px;
  text-align: center;
  font-size: 12px; font-weight: 800; line-height: 1.15;
  overflow: hidden;
  user-select: none;
  cursor: pointer;
  transition: box-shadow .16s var(--ease), filter .16s var(--ease);
}
.floor-plan-unit.shape-circle { border-radius: 50%; }
.floor-plan-unit:hover { box-shadow: var(--shadow-pop); filter: brightness(1.04); z-index: 5; }

/* Unit KOSONG adalah keadaan paling sering: ia dibuat tenang (bidang terang
   bertinta gelap) supaya yang menarik perhatian justru unit yang sedang
   dipakai. Label putih di atas abu #94A3B8 sebelumnya cuma 2,56:1. */
.floor-plan-unit.status-available   { background: #E2E8F0; color: #1E293B; border-color: #CBD5E1; }
.floor-plan-unit.status-occupied    { background: #F59E0B; color: #2B1A02; }
.floor-plan-unit.status-booked      { background: #14B8A6; color: #04302B; }
.floor-plan-unit.status-maintenance { background: #64748B; color: #fff; }
[data-theme="dark"] .floor-plan-unit.status-available { background: #24314A; color: #CBD5E1; border-color: #3A4761; }

.floor-plan-unit__chip {
  font-size: 10px; font-weight: 800; letter-spacing: .02em;
  padding: 1px 7px; border-radius: var(--radius-pill);
  background: rgb(255 255 255 / .85); color: #1E293B;
  white-space: nowrap;
}

.floor-plan-tabs { display: flex; gap: 8px; margin-bottom: 14px; flex-wrap: wrap; }
.floor-plan-tab {
  border: 1px solid var(--color-ink-200);
  background: var(--color-surface);
  color: var(--color-ink-700);
  border-radius: var(--radius-pill);
  padding: 8px 18px;
  font-size: 13px; font-weight: 700;
  text-decoration: none !important;
  transition: background-color .16s var(--ease), border-color .16s var(--ease), color .16s var(--ease);
}
.floor-plan-tab:hover { border-color: var(--color-primary-500); color: var(--color-primary-700); }
.floor-plan-tab.is-active {
  background: var(--color-primary-500);
  border-color: var(--color-primary-500);
  color: #04302B;
}

.floor-plan-legend {
  display: flex; gap: 8px; flex-wrap: wrap;
  padding: 12px 0 0;
  margin-top: 12px;
  border-top: 1px solid var(--color-ink-200);
}
.floor-plan-legend__item {
  display: inline-flex; align-items: center; gap: 7px;
  font-size: 12px; font-weight: 700; color: var(--color-ink-700);
  background: var(--color-surface-2);
  border: 1px solid var(--color-ink-200);
  padding: 4px 11px; border-radius: var(--radius-pill);
}
.floor-plan-legend__dot {
  width: 10px; height: 10px; border-radius: 3px;
  display: inline-block; flex-shrink: 0;
  border: 1px solid rgb(15 23 42 / .12);
}
/* Sumber warna legenda = sumber warna ubin. Jangan tulis warna inline di Blade. */
.floor-plan-legend__dot.status-available   { background: #E2E8F0; }
.floor-plan-legend__dot.status-occupied    { background: #F59E0B; }
.floor-plan-legend__dot.status-booked      { background: #14B8A6; }
.floor-plan-legend__dot.status-maintenance { background: #64748B; }
[data-theme="dark"] .floor-plan-legend__dot.status-available { background: #24314A; }

/* ==========================================================================
   9. HALAMAN KHUSUS
   ========================================================================== */

/* ---- Login staf -------------------------------------------------------- */
.auth-page-wrap {
  min-height: 100vh;
  display: flex; align-items: center; justify-content: center;
  background: linear-gradient(160deg, var(--color-primary-700), var(--color-primary-500));
  padding: 24px;
}

/* ---- Struk / invoice --------------------------------------------------- */
.receipt-card {
  max-width: 640px; margin: 0 auto;
  background: var(--color-surface);
  border: 1px solid var(--color-ink-200);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
  overflow: hidden;
}
.receipt-card__head {
  background: linear-gradient(120deg, var(--color-primary-700), var(--color-primary-500));
  color: #fff;
  padding: 22px 26px;
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
}
.receipt-card__head h3 { color: #fff; margin: 0; font-weight: 800; }
.receipt-card__head p { margin: 2px 0 0; color: rgb(255 255 255 / .85); font-size: 12.5px; }
.receipt-card__body { padding: 22px 26px; }
.receipt-divider { border: none; border-top: 1px dashed var(--color-ink-300); margin: 16px 0; }
.receipt-row { display: flex; justify-content: space-between; gap: 12px; padding: 5px 0; font-size: 13.5px; }
.receipt-row.grand { font-weight: 800; font-size: 16px; padding-top: 10px; }

/* ---- Dropzone unggah gambar -------------------------------------------- */
.img-dropzone__target {
  border: 1.5px dashed var(--color-ink-300);
  border-radius: var(--radius-md);
  background: var(--color-surface-2);
  min-height: 118px;
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
  padding: 12px;
  transition: border-color .16s var(--ease), background-color .16s var(--ease);
}
.img-dropzone__target:hover,
.img-dropzone__target.dz-drag-hover {
  border-color: var(--color-primary-500);
  background: var(--color-primary-50);
}
.img-dropzone__target .dz-message {
  margin: 0; text-align: center;
  color: var(--color-ink-600); font-weight: 600; font-size: 13px;
}
.img-dropzone__target .dz-message i {
  font-size: 26px; color: var(--color-primary-500);
  display: block; margin-bottom: 6px;
}
.img-dropzone__target .dz-preview { margin: 4px; }
.img-dropzone__target .dz-preview .dz-image { border-radius: var(--radius-sm); }
.img-dropzone__target .dz-preview .dz-error-message { font-size: 12px; }
.img-dropzone__current {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  margin-bottom: 10px; padding: 10px;
  border: 1px solid var(--color-ink-200);
  border-radius: var(--radius-md);
  background: var(--color-surface);
}
.img-dropzone__current img {
  width: 84px; height: 84px; object-fit: cover;
  border-radius: var(--radius-sm);
  border: 1px solid var(--color-ink-200);
}

/* ==========================================================================
   10. RESPONSIF — jaring pengaman
   --------------------------------------------------------------------------
   Terukur sebelum perbaikan: pada 390px lebar dokumen /reports 984, /outlets
   746, /invoices 651 — hampir semua halaman internal harus digeser ke samping
   untuk dibaca. Penyebabnya berulang: baris flex yang tidak boleh menyusut,
   dan tabel lebar tanpa wadah penggulung.

   Aturan penggulung tabel berlaku di SEMUA lebar, bukan hanya di HP: pada
   1280px halaman /invoices pun masih meluber 57px karena tabel 13 kolom.
   ========================================================================== */

/* Tabel & DataTables tidak pernah melebarkan halaman, di lebar berapa pun.
   --------------------------------------------------------------------------
   DUA NAMA KELAS. DataTables yang dipakai di sini adalah versi 2.x, yang
   membungkus tabel dengan .dt-container dan memberi nama .dt-scroll-* pada
   wadah gulungnya; nama versi 1.x (.dataTables_wrapper, .dataTables_scroll*)
   masih muncul karena app.js memakai opsi `dom` warisan. Selama hanya nama
   1.x yang ditulis di sini, tabel yang TIDAK memakai scrollX (kurang dari 8
   kolom) lolos tanpa pembungkus — /facility-types dengan 7 kolom meluber 89px
   pada layar 820px dan menggeser seluruh halaman. Kedua nama harus disebut.

   overflow-x: auto, bukan hidden: "hidden" memang menghentikan halaman melebar
   tapi membuat kolom terakhir tidak bisa dijangkau sama sekali. */
.app-content .dataTables_wrapper,
.app-content .dt-container { max-width: 100%; overflow-x: auto; }
.app-content .dataTables_wrapper .dataTables_scroll,
.app-content .dataTables_wrapper .dataTables_scrollHead,
.app-content .dataTables_wrapper .dataTables_scrollBody,
.app-content .dt-container .dt-scroll,
.app-content .dt-container .dt-scroll-head,
.app-content .dt-container .dt-scroll-body { max-width: 100%; }
.app-content .dataTables_wrapper .dataTables_scrollBody,
.app-content .dt-container .dt-scroll-body { overflow-x: auto; }
.app-content .table-responsive { max-width: 100%; overflow-x: auto; }

@media (max-width: 768px) {
  .page-head { flex-direction: column; align-items: stretch; gap: 12px; }
  .page-head__main { flex-wrap: wrap; }
  .page-head__title { font-size: 20px; word-break: break-word; }
  .page-head__actions { width: 100%; }
  .page-head__actions .btn { flex: 1 1 auto; justify-content: center; }

  /* Baris flex apa pun di dalam konten boleh membungkus. */
  .app-content .flex { flex-wrap: wrap; }
  .app-content .form-row { flex-direction: column; align-items: stretch; }
  .app-content .form-row > .form-group { width: 100%; min-width: 0; }

  .card { padding: 16px; }
  .card > form, .card > .grid { min-width: 0; }

  /* Semua tabel digulung di dalam kartunya. */
  .app-content table { display: block; overflow-x: auto; max-width: 100%; -webkit-overflow-scrolling: touch; }
  .floor-plan-canvas { max-width: 100%; }

  /* Jaring pengaman terakhir. */
  .app-shell, .app-main { max-width: 100vw; overflow-x: hidden; }
}

/* Target sentuh pada perangkat jari. */
@media (pointer: coarse), (max-width: 768px) {
  .app-content .btn,
  .app-content .kasir-chip,
  .app-content .floor-plan-tab,
  .app-content .fnb-tab { min-height: 42px; }
  .app-content .btn-sm { min-height: 38px; }
}

@media (max-width: 480px) {
  .page-head__actions { flex-direction: column; }
  .page-head__actions .btn { width: 100%; }
}

/* ==========================================================================
   11. CETAK
   ========================================================================== */
@media print {
  .app-sidebar, .app-topbar, .app-bottomnav, .bottom-sheet, .bottom-sheet-backdrop,
  .sidebar-backdrop, .page-head__actions, .no-print { display: none !important; }
  .app-main { margin-left: 0; }
  .app-content { padding: 0; }
  .card { box-shadow: none; break-inside: avoid; }
  body { background: #fff; }
}
