/* =====================================================================
   Gelora — LAPIS KONTEN.
   =====================================================================

   Menggantikan gelora.css + components.css + tables.css + home.css dan
   bagian 7-11 & 18-24 main.css. Keempatnya dihapus, tidak digabung.

   ATURAN BERKAS INI, DAN INI YANG BERBEDA DARI SEBELUMNYA:

     Tata letak BUKAN urusan berkas ini. Kisi, kolom, jarak antar-blok, dan
     runtun responsif diserahkan ke Bootstrap 5.3.8 (.row / .col-* / .g-* /
     .d-flex / .gap-*) yang memang sudah dimuat setiap halaman staf.

     Sebelumnya Bootstrap dimuat penuh lalu diabaikan: kisinya cuma dipakai
     3 dari 42 view, sisanya `display: grid` bikinan tangan yang tersebar di
     lima berkas dengan breakpoint yang tidak pernah sama (991 / 1023,98 /
     1199 / 1200). Itulah sebab kolom meluber dan tiap halaman terasa
     dirancang orang yang berbeda.

     Yang ditulis di sini HANYA RUPA: warna, garis, sudut, tebal huruf,
     tinggi kendali. Kalau sebuah aturan menyebut lebar kolom atau
     grid-template, ia salah tempat.

   Kosakatanya mengikuti Sneat (ThemeSelection) supaya orang berikutnya
   mengenalinya: .card > .card-header > .card-body, .avatar > .avatar-initial,
   .bg-label-* untuk lencana lembut, .nav-pills untuk tab.

   Palet dari tokens.css. Tidak ada kuning.

   Isi:
      1. Kepala halaman
      2. Kartu
      3. Avatar & kotak ikon
      4. Lencana (bg-label-*)
      5. Kartu angka
      6. Tabel
      7. DataTables & paginasi
      8. Formulir
      9. Tombol
     10. Tab (.nav-pills)
     11. Peringatan (.alert)
     12. Daftar baris
     13. Keadaan kosong
     14. Struk
     15. Notifikasi
     16. Zona unggah gambar
     17. Select2
     18. Pil status & sisa utilitas kecil
   ===================================================================== */


/* ---------------------------------------------------------------------
   1. Kepala halaman

   Dipakai 37 dari 42 halaman lewat satu partial, jadi titik ungkit
   terbesar di seluruh aplikasi.

   Judul halaman TIDAK lagi diulang di topbar. Sneat, Materio, dan Vuexy
   sama-sama tidak menaruhnya di sana; menampilkannya dua kali dalam satu
   layar membuat halaman terbaca seperti dua rancangan yang ditumpuk.
--------------------------------------------------------------------- */
.page-head {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
    margin-bottom: 24px;
}
/* Kolom kiri: HANYA eyebrow + judul + keterangan. Tombol kembali pindah ke
   .page-head__actions di kanan — kalau ia ikut di sini, eyebrow dan judul
   mulai dari sebelah kanan sebuah kotak tombol dan tepi kirinya bertingkat. */
.page-head__main { min-width: 0; flex: 1 1 260px; }
.page-head__back { flex-shrink: 0; }

/* Huruf kapital kecil ber-tracking lebar. Warnanya redam, BUKAN teal:
   eyebrow muncul di setiap halaman, dan aksen yang dipakai di mana-mana
   berhenti menjadi aksen. */
.page-head__eyebrow {
    font-size: .625rem;
    font-weight: 600;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--text-eyebrow);
    margin-bottom: 5px;
}
.page-head__title {
    font-size: clamp(1.375rem, 1.05rem + 1vw, 1.75rem);
    font-weight: 700;
    letter-spacing: -.025em;
    line-height: 1.15;
    color: var(--text-main);
    margin: 0;
}
.page-head__meta {
    font-size: .75rem;
    color: var(--text-muted-green);
    margin-top: 6px;
    font-variant-numeric: tabular-nums;
}
.page-head__actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }

/* Label kelompok di antara dua blok kartu. */
.section-label {
    font-size: .625rem;
    font-weight: 600;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--text-eyebrow);
    margin: 0 0 12px;
}


/* ---------------------------------------------------------------------
   2. Kartu

   SATU anatomi untuk 42 halaman: .card > .card-header > .card-body.
   Garis rambut, tanpa bayangan — --shadow-sm memang `none` di tokens.
--------------------------------------------------------------------- */
.card {
    background-color: var(--surface-card);
    border: 1px solid var(--border-hairline);
    border-radius: var(--radius-xl);
    box-shadow: none;
    /* Bootstrap memberi .card `word-wrap: break-word`; itu memutus kata di
       tengah pada kolom sempit. Yang kita mau: bungkus di spasi, dan hanya
       potong kalau benar-benar tidak muat. */
    word-wrap: normal;
    overflow-wrap: break-word;
}
.card > .card-body { padding: 20px; }
.card > .card-body + .card-body { padding-top: 0; }

.card-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    flex-wrap: wrap;
    padding: 16px 20px;
    background-color: transparent;
    border-bottom: 1px solid var(--border-hairline);
    border-radius: var(--radius-xl) var(--radius-xl) 0 0;
    min-height: 0;
}
.card-header + .card-body { padding-top: 18px; }

/* .card-title dipakai DUA arti di markup lama: judul kartu, dan label kecil
   di atas angka. Yang kedua selalu dibarengi .text-muted, jadi keduanya bisa
   hidup berdampingan tanpa saling menimpa. */
.card-title {
    font-size: .8125rem;
    font-weight: 700;
    letter-spacing: -.01em;
    color: var(--text-main);
    margin: 0;
}
.card-title.text-muted,
.card-body > .card-title:first-child {
    font-size: .6875rem;
    font-weight: 600;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--text-eyebrow);
}
.card-subtitle { font-size: .75rem; color: var(--text-muted-green); margin: 4px 0 0; }

/* Sub-judul di dalam kartu yang tidak memakai .card-title. Tanpa aturan ini
   ia memakai ukuran <h2>/<h3>/<h4> bawaan dan jadi lebih besar daripada judul
   kartunya sendiri — hierarkinya terbalik. */
.card-body > h2:not(.card-title):not([class*="h4"]),
.card-body > h3:not(.card-title),
.card-body > h4:not(.card-title) {
    font-size: .875rem;
    font-weight: 700;
    letter-spacing: -.01em;
    margin: 0 0 10px;
}

.card-footer {
    padding: 14px 20px;
    background-color: var(--surface-sunken);
    border-top: 1px solid var(--border-hairline);
    border-radius: 0 0 var(--radius-xl) var(--radius-xl);
}

/* Kartu yang membungkus tabel: badan tanpa padding supaya tabel menempel
   ke tepi kartu, bukan mengambang di dalam kotak putih kedua. */
.card--flush > .card-body { padding: 0; }

/* Kartu yang ikut tergulir bersama halaman panjang (ringkasan, struk). */
.card--sticky { position: sticky; top: 96px; }
@media (max-width: 991.98px) { .card--sticky { position: static; } }

/* Kartu bernada gelap untuk satu blok penekanan per halaman. Dipakai
   hemat: kalau semua kartu menonjol, tidak ada yang menonjol. */
.card--ink {
    background-color: var(--g-shell-900);
    border-color: var(--g-shell-800);
    color: rgba(255, 255, 255, .82);
}
.card--ink .card-title,
.card--ink h1, .card--ink h2, .card--ink h3, .card--ink h4, .card--ink .h4 { color: #FFFFFF; }
.card--ink .text-muted,
.card--ink .card-title.text-muted { color: rgba(255, 255, 255, .62) !important; }
.card--ink .card-header { border-bottom-color: rgba(255, 255, 255, .12); }


/* ---------------------------------------------------------------------
   3. Avatar & kotak ikon

   Tanda khas Sneat: kotak ikon bertint di atas angka. Inilah satu detail
   yang paling terasa membedakan dasbor berbayar dari kartu polos.
--------------------------------------------------------------------- */
.avatar {
    flex-shrink: 0;
    width: 40px;
    height: 40px;
    position: relative;
    display: inline-flex;
}
.avatar-sm { width: 32px; height: 32px; }
.avatar-lg { width: 48px; height: 48px; }

.avatar > .avatar-initial,
.avatar > img {
    width: 100%;
    height: 100%;
    border-radius: var(--radius-md);
    object-fit: cover;
}
.avatar-initial {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    /* Berdiri sendiri (mis. di tombol profil topbar) ia bulat 34px; sebagai
       anak .avatar ia mengikuti ukuran induknya lewat aturan di atas. */
    width: 34px;
    height: 34px;
    border-radius: 50%;
    background-color: var(--g-accent-soft);
    color: var(--g-shell-800);
    font-size: .75rem;
    font-weight: 700;
    letter-spacing: .02em;
    text-transform: uppercase;
    line-height: 1;
}
.avatar > .avatar-initial { font-size: .875rem; }
.avatar-sm > .avatar-initial { font-size: .6875rem; }


/* ---------------------------------------------------------------------
   4. Lencana lembut (bg-label-*)

   Satu keluarga warna dipakai lencana DAN kotak ikon — persis Sneat.
   Tanpa kuning: peringatan memakai jingga (--sys-orange), bukan kuning.
--------------------------------------------------------------------- */
.badge {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 4px 9px;
    font-size: .6875rem;
    font-weight: 700;
    letter-spacing: .01em;
    line-height: 1.35;
    border-radius: var(--radius-sm);
    white-space: nowrap;
}
.badge i { font-size: .6875rem; }

.bg-label-primary   { background-color: var(--g-accent-soft) !important;      color: var(--g-shell-800) !important; }
.bg-label-success   { background-color: var(--sys-green-bg) !important;       color: #15803D !important; }
.bg-label-danger    { background-color: var(--sys-red-bg) !important;         color: #B91C1C !important; }
.bg-label-warning   { background-color: var(--sys-orange-bg) !important;      color: #9A3412 !important; }
.bg-label-info      { background-color: #E0F2FE !important;                   color: #075985 !important; }
.bg-label-secondary { background-color: var(--surface-sunken) !important;     color: var(--text-muted-green) !important;
                      box-shadow: inset 0 0 0 1px var(--border-hairline); }

/* Lencana pekat sekali-sekali — hanya untuk keadaan yang harus menang
   melawan latar berwarna. */
.badge-accent { background-color: var(--g-accent); color: var(--g-ink-on-accent); }
.badge-type   { background-color: var(--surface-sunken); color: var(--text-muted-green);
                box-shadow: inset 0 0 0 1px var(--border-hairline); }


/* ---------------------------------------------------------------------
   5. Kartu angka

   Markupnya kartu biasa, jadi tidak ada keluarga kelas baru untuk dihafal:

     <div class="card"><div class="card-body">
       <div class="avatar"><span class="avatar-initial bg-label-primary">
         <i class="fa-solid fa-..."></i></span></div>
       <div class="card-title text-muted">Label</div>
       <div class="stat-value">12</div>
       <div class="stat-delta is-up">+8% vs kemarin</div>
     </div></div>
--------------------------------------------------------------------- */
/* Kotak angka mandiri: kartu dengan padding sudah menyatu, supaya halaman
   yang menampilkan deretan angka tidak perlu menumpuk .card > .card-body
   di setiap petaknya. Warnanya datang dari tint kotak ikon, bukan dari
   kartunya — versi lama punya empat varian warna kartu (--accent, --info,
   is-warning, --danger) yang membuat satu baris angka terlihat seperti
   palet cat, bukan data. */
.stat-card {
    height: 100%;
    padding: 18px;
    background-color: var(--surface-card);
    border: 1px solid var(--border-hairline);
    border-radius: var(--radius-xl);
}
.stat-card--row { display: flex; align-items: center; gap: 14px; }
.stat-card--row > div { min-width: 0; }
/* Kotak ikon di kartu angka memakai tint aksen, bukan abu-abu netral —
   inilah detail Sneat yang membuat deretan angka terbaca sebagai kartu
   rancangan, bukan tabel yang dikotak-kotakkan. */
.stat-card--row > .row-icon {
    width: 40px;
    height: 40px;
    font-size: .9375rem;
    background-color: var(--g-accent-soft);
    border-color: transparent;
    color: var(--g-shell-800);
}

/* Batang okupansi di kartu hero. */
.hero-bar {
    height: 5px;
    border-radius: 999px;
    background-color: rgba(255, 255, 255, .16);
    overflow: hidden;
}
.hero-bar > span {
    display: block;
    height: 100%;
    min-width: 3px;
    border-radius: 999px;
    background-color: var(--g-accent);
}

/* Kartu KPI di kolom yang tingginya mengikuti kartu tetangga: isinya
   ditengahkan, kalau tidak angkanya menggantung di atas dengan ruang
   kosong menganga di bawahnya. */
.card--flag > .card-body {
    display: flex;
    flex-direction: column;
    justify-content: center;
}

.stat-value {
    font-size: 1.75rem;
    font-weight: 700;
    letter-spacing: -.03em;
    line-height: 1.05;
    color: var(--text-main);
    font-variant-numeric: tabular-nums;
    font-feature-settings: 'tnum' 1;
}
.stat-value--sm { font-size: 1.25rem; }
.stat-value__of { font-size: .875rem; font-weight: 600; color: var(--text-eyebrow); letter-spacing: 0; }

.stat-delta {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    margin-top: 6px;
    font-size: .6875rem;
    font-weight: 600;
    color: var(--text-muted-green);
}
.stat-delta.is-up   { color: #15803D; }
.stat-delta.is-down { color: #B91C1C; }

/* Pita keadaan di tepi kiri kartu. Netral saat semuanya beres — warna
   pekat disimpan untuk pengecualian, supaya yang berwarna benar-benar
   berarti "lihat saya". */
.card--flag { position: relative; overflow: hidden; }
.card--flag::before {
    content: '';
    position: absolute;
    inset: 0 auto 0 0;
    width: 3px;
    background-color: var(--border-strong);
}
.card--flag.is-live::before  { background-color: var(--g-accent); }
.card--flag.is-warn::before  { background-color: var(--sys-orange); }
.card--flag.is-alert::before { background-color: var(--sys-red); }

/* Titik "sedang berjalan". */
.live-dot { display: inline-flex; align-items: center; gap: 6px; }
.live-dot::before {
    content: '';
    width: 6px; height: 6px;
    border-radius: 50%;
    background-color: var(--sys-green);
    animation: gelora-pulse 2s ease-in-out infinite;
}
@keyframes gelora-pulse { 0%, 100% { opacity: 1; } 50% { opacity: .25; } }


/* ---------------------------------------------------------------------
   6. Tabel

   Baris 48px, kepala tenggelam, TANPA zebra. Zebra menambah satu warna
   yang harus dibaca di setiap baris tanpa membawa informasi; garis rambut
   sudah cukup memisahkan.
--------------------------------------------------------------------- */
.table-wrap,
.table-responsive {
    width: 100%;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}

.table {
    width: 100%;
    margin: 0;
    border-color: var(--border-hairline);
    color: var(--text-main);
    font-size: .8125rem;
    vertical-align: middle;
    --bs-table-bg: transparent;
    --bs-table-striped-bg: transparent;
    --bs-table-hover-bg: var(--surface-sunken);
}

.table > thead th {
    position: sticky;
    top: 0;
    z-index: var(--z-sticky);
    padding: 11px 14px;
    background-color: var(--surface-sunken);
    border-bottom: 1px solid var(--border-hairline);
    font-size: .625rem;
    font-weight: 700;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--text-eyebrow);
    white-space: nowrap;
    vertical-align: middle;
}
.table > tbody td {
    height: 48px;
    padding: 10px 14px;
    border-bottom: 1px solid var(--border-hairline);
    vertical-align: middle;
}
.table > tbody tr:last-child td { border-bottom: none; }
.table > tbody tr:hover td { background-color: var(--surface-sunken); }

/* Baris rapat untuk tabel yang isinya banyak sekali (mis. rincian invoice). */
.table--tight > tbody td { height: 38px; padding: 7px 12px; }

.cell-strong { font-weight: 700; color: var(--text-main); }
.cell-sub { display: block; font-size: .6875rem; color: var(--text-muted-green); margin-top: 2px; }

/* Kolom aksi: selalu di kanan, tidak pernah membungkus. */
.td-actions {
    white-space: nowrap;
    text-align: right;
}
.td-actions > * + * { margin-left: 6px; }

.td-photo { width: 64px; }
.thumb {
    width: 44px;
    height: 44px;
    border-radius: var(--radius-md);
    object-fit: cover;
    border: 1px solid var(--border-hairline);
    background-color: var(--surface-sunken);
}
.thumb--empty {
    display: grid;
    place-items: center;
    color: var(--text-eyebrow);
    font-size: .875rem;
}

/* Baris penyaring di atas tabel. */
.filter-row {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}
.filter-row__sep {
    width: 1px;
    height: 22px;
    background-color: var(--border-hairline);
    text-indent: -9999px;
    overflow: hidden;
    flex-shrink: 0;
}
/* Isian tanggal WAJIB punya lebar. Sebagai anak flex tanpa lebar, .form-control
   memakai lebar bawaan input lalu memuai — di kepala halaman ketiganya jadi
   bertumpuk vertikal dan menabrak judul. */
.filter-row .form-control,
.filter-row .form-select { width: 140px; flex: 0 0 auto; }
@media (max-width: 575.98px) {
    .filter-row { width: 100%; }
    .filter-row .form-control, .filter-row .form-select { flex: 1 1 120px; width: auto; min-width: 0; }
    .filter-row__sep { display: none; }
}


/* ---------------------------------------------------------------------
   7. DataTables & paginasi
--------------------------------------------------------------------- */
.dt-container { width: 100%; }

/* Nama kelas ini datang dari opsi `dom` di app.js:
   '<"dataTables_toolbar"lf>rt<"dataTables_bottom"ip>'.
   Aturan lama menyasar .dt-layout-row bawaan DataTables 2 — kelas yang
   TIDAK pernah muncul karena `dom` menggantikannya. Akibatnya bilah alat
   tabel tidak punya padding sama sekali: kotak cari menempel persis di
   garis kartu. */
.dataTables_toolbar,
.dataTables_bottom {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    flex-wrap: wrap;
    padding: 14px 20px;
}
.dataTables_toolbar { border-bottom: 1px solid var(--border-hairline); }
.dataTables_bottom  { border-top: 1px solid var(--border-hairline); }

.dt-length, .dataTables_length {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: .75rem;
    color: var(--text-muted-green);
    white-space: nowrap;
}
.dt-length label, .dataTables_length label { margin: 0; font-weight: 600; }
.dt-length select, .dataTables_length select { width: auto; min-width: 68px; }

.dt-search, .dataTables_filter { margin-left: auto; }
.dt-search input, .dataTables_filter input { width: 200px; max-width: 100%; }
@media (max-width: 575.98px) {
    /* DataTables membungkus input pencarian di dalam <label>. Tanpa label
       ikut dijadikan blok, input 100% hanya mengisi lebar label yang masih
       inline — kotak cari tampil separuh lebar dan menggantung di tengah. */
    .dt-search, .dataTables_filter { margin-left: 0; width: 100%; }
    .dt-search label, .dataTables_filter label { display: block; width: 100%; margin: 0; }
    .dt-search input, .dataTables_filter input { width: 100%; }
}

.dt-info, .dataTables_info {
    font-size: .6875rem;
    color: var(--text-muted-green);
    font-variant-numeric: tabular-nums;
}
.dataTables_paginate { margin-left: auto; }

/* CATATAN: TIDAK boleh `position: relative` di sini. Kepala tabel memakai
   position: sticky, dan relative pada elemen yang sama membatalkannya —
   dulu kepala tabel berhenti menempel di 8 halaman gara-gara ini. */
.table-dt thead th { cursor: pointer; }
.table-dt thead th.dt-orderable-none,
.table-dt thead th.sorting_disabled { cursor: default; }

.pagination { margin: 0; gap: 4px; }
.page-link {
    min-width: 34px;
    height: 34px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0 10px;
    font-size: .75rem;
    font-weight: 600;
    color: var(--text-main);
    background-color: var(--surface-card);
    border: 1px solid var(--border-hairline);
    border-radius: var(--radius-md);
}
.page-link:hover { background-color: var(--surface-sunken); color: var(--text-main); }
.page-item.active .page-link {
    background-color: var(--g-accent);
    border-color: var(--g-accent);
    color: var(--g-ink-on-accent);
}
.page-item.disabled .page-link { opacity: .45; }
.page-link:focus { box-shadow: 0 0 0 3px var(--g-accent-soft); }


/* ---------------------------------------------------------------------
   8. Formulir

   Nama .form-group / .form-row / .form-hint / .form-error dipertahankan:
   dipakai 164 / 34 / 97 / 8 kali. Menggantinya satu per satu tidak
   mengubah apa pun yang dilihat pengguna.
--------------------------------------------------------------------- */
.form-group { margin-bottom: 16px; }
.form-group:last-child { margin-bottom: 0; }

/* Dua kolom yang runtuh jadi satu. Ini SATU-SATUNYA kisi di berkas ini,
   dan hanya karena ia melekat pada komponen formulirnya sendiri. */
.form-row {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 16px;
}
@media (max-width: 575.98px) { .form-row { grid-template-columns: minmax(0, 1fr); } }

.form-label {
    display: block;
    margin-bottom: 6px;
    font-size: .75rem;
    font-weight: 600;
    letter-spacing: -.005em;
    color: var(--text-main);
}
.form-label .req, .form-label .text-danger { color: var(--sys-red); }

.form-control,
.form-select {
    height: 42px;
    padding: 9px 12px;
    font-size: .8125rem;
    color: var(--text-main);
    background-color: var(--surface-card);
    border: 1px solid var(--border-hairline);
    border-radius: var(--radius-md);
    box-shadow: none;
    transition: border-color var(--dur-fast) linear, box-shadow var(--dur-fast) linear;
}
textarea.form-control { height: auto; min-height: 88px; padding: 10px 12px; }
.form-control:focus,
.form-select:focus {
    border-color: var(--g-accent);
    box-shadow: 0 0 0 3px var(--g-accent-soft);
    background-color: var(--surface-card);
    color: var(--text-main);
}
.form-control::placeholder { color: #8A94A6; }
.form-control:disabled, .form-control[readonly],
.form-select:disabled {
    background-color: var(--surface-sunken);
    color: var(--text-muted-green);
    cursor: not-allowed;
}
.form-control-sm, .form-select-sm { height: 36px; padding: 6px 10px; font-size: .75rem; }
.form-control-lg, .form-select-lg { height: 48px; font-size: .875rem; }

.form-control.is-invalid, .form-select.is-invalid { border-color: var(--sys-red); }
.form-control.is-invalid:focus { box-shadow: 0 0 0 3px rgba(239, 68, 68, .16); }

.form-hint, .form-text {
    display: block;
    margin-top: 5px;
    font-size: .6875rem;
    line-height: 1.5;
    color: var(--text-muted-green);
}
/* .form-hint juga dipakai di sel tabel untuk teks sekunder. display:block
   mencabut sel dari layout tabel dan menggeser seluruh kolom sesudahnya. */
td.form-hint, th.form-hint { display: table-cell; margin-top: 0; }
.form-error, .invalid-feedback {
    display: block;
    margin-top: 5px;
    font-size: .6875rem;
    font-weight: 600;
    color: #B91C1C;
}

.input-group-text {
    padding: 0 12px;
    font-size: .75rem;
    font-weight: 600;
    color: var(--text-muted-green);
    background-color: var(--surface-sunken);
    border: 1px solid var(--border-hairline);
    border-radius: var(--radius-md);
}

/* Kotak centang & sakelar. */
.form-check { min-height: 0; margin-bottom: 0; padding-left: 1.7em; }
.form-check-input, .form-check-input-custom {
    width: 1.05em;
    height: 1.05em;
    margin-top: .18em;
    border: 1px solid var(--border-strong);
    background-color: var(--surface-card);
    cursor: pointer;
}
.form-check-input:checked, .form-check-input-custom:checked {
    background-color: var(--g-accent);
    border-color: var(--g-accent);
}
.form-check-input:focus, .form-check-input-custom:focus {
    border-color: var(--g-accent);
    box-shadow: 0 0 0 3px var(--g-accent-soft);
}
.form-check-label { font-size: .8125rem; cursor: pointer; }
.form-switch .form-check-input { width: 2.1em; border-radius: 999px; }

/* Layar sentuh: 44px minimum. */
@media (pointer: coarse) {
    .form-control, .form-select { height: 44px; }
    .form-control-sm, .form-select-sm { height: 40px; }
}


/* ---------------------------------------------------------------------
   9. Tombol
--------------------------------------------------------------------- */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
    min-height: 40px;
    padding: 8px 16px;
    font-size: .8125rem;
    font-weight: 600;
    letter-spacing: -.005em;
    line-height: 1.3;
    border-radius: var(--radius-md);
    border: 1px solid transparent;
    box-shadow: none;
    white-space: nowrap;
    transition: background-color var(--dur-fast) linear,
                border-color var(--dur-fast) linear,
                color var(--dur-fast) linear;
}
.btn:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--g-accent-soft); }
.btn-sm { min-height: 34px; padding: 6px 12px; font-size: .75rem; gap: 5px; }
.btn-lg { min-height: 46px; padding: 11px 22px; font-size: .875rem; }
.btn-block { width: 100%; }
.btn:disabled, .btn.disabled { opacity: .5; }

.btn-accent, .btn-primary {
    background-color: var(--g-accent);
    border-color: var(--g-accent);
    color: var(--g-ink-on-accent);
}
.btn-accent:hover, .btn-primary:hover,
.btn-accent:focus, .btn-primary:focus {
    /* Hover MENERANG. Teal gelap di atas kanvas gading justru terbaca
       "mati" saat digelapkan. */
    background-color: var(--g-accent-hover);
    border-color: var(--g-accent-hover);
    color: var(--g-ink-on-accent);
}

.btn-ink {
    background-color: var(--g-shell-900);
    border-color: var(--g-shell-900);
    color: #FFFFFF;
}
.btn-ink:hover { background-color: var(--g-shell-800); border-color: var(--g-shell-800); color: #FFFFFF; }

.btn-ghost, .btn-outline-secondary {
    background-color: var(--surface-card);
    border-color: var(--border-hairline);
    color: var(--text-main);
}
.btn-ghost:hover, .btn-outline-secondary:hover,
.btn-ghost:focus, .btn-outline-secondary:focus {
    background-color: var(--surface-sunken);
    border-color: var(--border-strong);
    color: var(--text-main);
}

/* BUKAN --sys-red (#EF4444): teks putih di atasnya hanya 3,76:1, di bawah
   ambang AA 4,5:1. #DC2626 memberi 4,83:1 dengan warna yang praktis sama.
   Tombol ini muncul di enam halaman, jadi selisihnya bukan hal sepele. */
.btn-danger {
    background-color: #DC2626;
    border-color: #DC2626;
    color: #FFFFFF;
}
.btn-danger:hover { background-color: #B91C1C; border-color: #B91C1C; color: #FFFFFF; }

.btn-label-secondary {
    background-color: var(--surface-sunken);
    border-color: var(--border-hairline);
    color: var(--text-muted-green);
}
.btn-label-secondary:hover { background-color: var(--border-hairline); color: var(--text-main); }

/* Tombol ikon untuk kolom aksi tabel.

   Sebelumnya tiap baris membawa "Edit" abu-abu dan "Hapus" MERAH PENUH.
   Sepuluh baris berarti sepuluh tombol merah berjajar - halaman daftar
   terbaca seperti daftar peringatan, dan tindakan paling merusak justru
   yang paling menarik mata. Sekarang keduanya ikon tenang; merahnya baru
   muncul saat kursor benar-benar di atas tombol hapus. */
.btn-icon {
    width: 34px;
    min-width: 34px;
    height: 34px;
    min-height: 34px;
    padding: 0;
    font-size: .8125rem;
    color: var(--text-muted-green);
    background-color: transparent;
    border-color: transparent;
}
.btn-icon:hover {
    background-color: var(--surface-sunken);
    border-color: var(--border-hairline);
    color: var(--text-main);
}
.btn-icon--danger:hover { background-color: var(--sys-red-bg); border-color: #FCA5A5; color: #B91C1C; }

@media (pointer: coarse) {
    .btn-icon { width: 44px; min-width: 44px; height: 44px; min-height: 44px; }
}

.btn-link {
    min-height: 0;
    padding: 0;
    border: none;
    background: none;
    color: var(--g-shell-700);
    font-weight: 600;
    text-decoration: none;
}
.btn-link:hover { color: var(--g-accent-hover); text-decoration: underline; }

/* Layar sentuh. */
@media (pointer: coarse) {
    .btn { min-height: 44px; }
    .btn-sm { min-height: 38px; }
}


/* ---------------------------------------------------------------------
   10. Tab (.nav-pills)

   Pakai .nav-pills bawaan Bootstrap, bukan .pill-tabs bikinan sendiri.
--------------------------------------------------------------------- */
.nav-pills {
    gap: 6px;
    padding: 4px;
    background-color: var(--surface-sunken);
    border: 1px solid var(--border-hairline);
    border-radius: var(--radius-lg);
    display: inline-flex;
    flex-wrap: wrap;
    max-width: 100%;
}
.nav-pills .nav-link {
    padding: 7px 14px;
    font-size: .75rem;
    font-weight: 600;
    color: var(--text-muted-green);
    background-color: transparent;
    border: none;
    border-radius: var(--radius-md);
    white-space: nowrap;
}
.nav-pills .nav-link:hover { color: var(--text-main); }
.nav-pills .nav-link.active,
.nav-pills .show > .nav-link {
    background-color: var(--surface-card);
    color: var(--text-main);
    box-shadow: inset 0 0 0 1px var(--border-hairline);
}
.nav-pills .nav-link .badge { margin-left: 6px; }

.nav-tabs {
    border-bottom: 1px solid var(--border-hairline);
    gap: 2px;
}
.nav-tabs .nav-link {
    padding: 9px 14px;
    font-size: .8125rem;
    font-weight: 600;
    color: var(--text-muted-green);
    border: none;
    border-bottom: 2px solid transparent;
    border-radius: 0;
}
.nav-tabs .nav-link.active {
    color: var(--text-main);
    background: none;
    border-bottom-color: var(--g-accent);
}

@media (pointer: coarse) {
    .nav-pills .nav-link { min-height: 40px; display: inline-flex; align-items: center; }
}


/* ---------------------------------------------------------------------
   11. Peringatan
--------------------------------------------------------------------- */
.alert {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 12px 16px;
    font-size: .8125rem;
    line-height: 1.55;
    border: 1px solid transparent;
    border-radius: var(--radius-lg);
    margin-bottom: 16px;
}
.alert > i:first-child { margin-top: 2px; flex-shrink: 0; }
.alert-info    { background-color: #F0F9FF; border-color: #BAE6FD; color: #075985; }
.alert-success { background-color: var(--sys-green-bg);  border-color: #86EFAC; color: #15803D; }
.alert-warning { background-color: var(--sys-orange-bg); border-color: #FDBA74; color: #9A3412; }
.alert-danger  { background-color: var(--sys-red-bg);    border-color: #FCA5A5; color: #B91C1C; }
.alert-secondary { background-color: var(--surface-sunken); border-color: var(--border-hairline); color: var(--text-muted-green); }


/* ---------------------------------------------------------------------
   12. Daftar baris

   Pengganti tabel untuk daftar pendek di dalam kartu sempit.
--------------------------------------------------------------------- */
.list-row {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 11px 0;
    border-bottom: 1px solid var(--border-hairline);
}
.list-row:last-child { border-bottom: none; }
.list-row:first-child { padding-top: 0; }
.list-row__body { flex: 1; min-width: 0; }
.list-row__title {
    font-size: .8125rem;
    font-weight: 600;
    color: var(--text-main);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.list-row__sub { font-size: .6875rem; color: var(--text-muted-green); margin-top: 2px; }
.list-row__side {
    flex-shrink: 0;
    text-align: right;
    font-size: .75rem;
    font-variant-numeric: tabular-nums;
    color: var(--text-muted-green);
    white-space: nowrap;
}

/* Kotak ikon kecil di kepala baris. */
.row-icon {
    flex-shrink: 0;
    width: 34px; height: 34px;
    display: grid; place-items: center;
    border-radius: var(--radius-md);
    background-color: var(--surface-sunken);
    border: 1px solid var(--border-hairline);
    color: var(--text-eyebrow);
    font-size: .8125rem;
}

/* Baris tingkat keanggotaan (halaman Tingkat Member). */
.tier-row {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 13px 0;
    border-bottom: 1px solid var(--border-hairline);
    flex-wrap: wrap;
}
.tier-row:last-child { border-bottom: none; }
.tier-edit-row { background-color: var(--surface-sunken); border-radius: var(--radius-lg); padding: 14px; }


/* ---------------------------------------------------------------------
   13. Keadaan kosong

   Setiap keadaan kosong membawa satu tindakan. "Belum ada data" tanpa
   jalan keluar adalah jalan buntu.
--------------------------------------------------------------------- */
.empty-state {
    padding: 44px 20px;
    text-align: center;
    color: var(--text-muted-green);
}
.empty-state__icon {
    width: 52px; height: 52px;
    margin: 0 auto 14px;
    display: grid; place-items: center;
    border-radius: 50%;
    background-color: var(--surface-sunken);
    border: 1px solid var(--border-hairline);
    color: var(--text-eyebrow);
    font-size: 1.125rem;
}
.empty-state__title {
    font-size: .875rem;
    font-weight: 700;
    color: var(--text-main);
    margin-bottom: 5px;
}
.empty-state p { font-size: .8125rem; margin: 0 0 16px; }
.empty-state p:last-child { margin-bottom: 0; }


/* ---------------------------------------------------------------------
   14. Struk
--------------------------------------------------------------------- */
.receipt-card { border: 1px solid var(--border-hairline); border-radius: var(--radius-xl); overflow: hidden; }
.receipt-card__head {
    padding: 16px 18px;
    background-color: var(--surface-sunken);
    border-bottom: 1px solid var(--border-hairline);
}
.receipt-card__body { padding: 18px; }

.receipt-row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    padding: 6px 0;
    font-size: .8125rem;
    color: var(--text-muted-green);
}
.receipt-row > :last-child {
    font-weight: 600;
    color: var(--text-main);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}
.receipt-divider { height: 1px; background-color: var(--border-hairline); margin: 10px 0; }

.grand {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    padding-top: 12px;
    margin-top: 6px;
    border-top: 1px solid var(--border-strong);
    font-size: 1.0625rem;
    font-weight: 700;
    color: var(--text-main);
    font-variant-numeric: tabular-nums;
}


/* ---------------------------------------------------------------------
   15. Notifikasi
--------------------------------------------------------------------- */
.notification-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 14px 16px;
    border-bottom: 1px solid var(--border-hairline);
}
.notification-title {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: .8125rem;
    font-weight: 700;
    margin: 0;
}
/* Jumlah belum dibaca tinggal di SINI, bukan di lonceng: pil tiga karakter
   di sudut tombol 42px selalu menjulur keluar tombolnya. */
.notification-count {
    padding: 2px 7px;
    font-size: .625rem;
    font-weight: 700;
    line-height: 1.4;
    color: #FFFFFF;
    background-color: var(--sys-red);
    border-radius: 999px;
    font-variant-numeric: tabular-nums;
}
.btn-clear-all {
    background: none;
    border: none;
    padding: 0;
    font-size: .6875rem;
    font-weight: 600;
    color: var(--g-shell-700);
}
.btn-clear-all:hover { color: var(--g-accent-hover); }

.notification-list { max-height: 380px; overflow-y: auto; }
.notification-footer {
    display: block;
    padding: 12px;
    text-align: center;
    font-size: .75rem;
    font-weight: 600;
    color: var(--g-shell-700);
    border-top: 1px solid var(--border-hairline);
}
.notification-footer:hover { background-color: var(--surface-sunken); }

.notif-item {
    display: flex;
    align-items: flex-start;
    gap: 11px;
    padding: 12px 16px;
    border-bottom: 1px solid var(--border-hairline);
    cursor: pointer;
}
.notif-item:last-child { border-bottom: none; }
.notif-item:hover { background-color: var(--surface-sunken); }
.notif-item.is-unread { background-color: var(--g-accent-soft); }
.notif-item__icon {
    flex-shrink: 0;
    width: 32px; height: 32px;
    display: grid; place-items: center;
    border-radius: var(--radius-md);
    background-color: var(--surface-sunken);
    color: var(--text-eyebrow);
    font-size: .75rem;
}
.notif-item__icon.level-success { background-color: var(--sys-green-bg);  color: #15803D; }
.notif-item__icon.level-warning { background-color: var(--sys-orange-bg); color: #9A3412; }
.notif-item__icon.level-danger  { background-color: var(--sys-red-bg);    color: #B91C1C; }
.notif-item__icon.level-info    { background-color: #E0F2FE;              color: #075985; }
.notif-item__body { flex: 1; min-width: 0; display: block; }
.notif-item__title { display: block; font-size: .8125rem; font-weight: 700; color: var(--text-main); }
.notif-item__text  { display: block; font-size: .75rem; color: var(--text-muted-green); margin-top: 2px; }
.notif-item__meta  { display: block; font-size: .625rem; color: var(--text-eyebrow); margin-top: 4px; }
.notif-item__dot {
    flex-shrink: 0;
    width: 7px; height: 7px;
    margin-top: 6px;
    border-radius: 50%;
    background-color: var(--g-accent);
}


/* ---------------------------------------------------------------------
   16. Zona unggah gambar
--------------------------------------------------------------------- */
.img-dropzone { display: flex; align-items: flex-start; gap: 14px; flex-wrap: wrap; }
.img-dropzone__target {
    flex: 1 1 220px;
    min-height: 88px;
    display: grid;
    place-items: center;
    padding: 14px;
    text-align: center;
    border: 1px dashed var(--border-strong);
    border-radius: var(--radius-lg);
    background-color: var(--surface-sunken);
    color: var(--text-muted-green);
    font-size: .75rem;
    cursor: pointer;
    transition: border-color var(--dur-fast) linear, background-color var(--dur-fast) linear;
}
.img-dropzone__target:hover,
.img-dropzone__target.is-drag {
    border-color: var(--g-accent);
    background-color: var(--g-accent-soft);
}
.dz-message { pointer-events: none; }

/* Pratinjau Dropzone. CSS bawaan Dropzone hanya berlaku di dalam kelas
   .dropzone, jadi tanpa aturan ini ikon centang/silang SVG-nya tampil
   ukuran asli (besar) dan menumpuk di bawah pratinjau. */
.img-dropzone__target { position: relative; }
.img-dropzone__target.dz-started { place-items: center start; }
.img-dropzone__target.dz-started .dz-message { display: none; }
.img-dropzone__target .dz-preview {
    position: relative;
    display: flex; align-items: center; gap: 12px;
    width: 100%; margin: 0; text-align: left;
}
.img-dropzone__target .dz-image {
    position: relative; flex-shrink: 0;
    width: 88px; height: 88px; overflow: hidden;
    border-radius: var(--radius-md);
    border: 1px solid var(--border-hairline);
    background-color: var(--surface-card);
}
.img-dropzone__target .dz-image img { width: 100%; height: 100%; object-fit: cover; display: block; }
.img-dropzone__target .dz-details { min-width: 0; flex: 1; display: grid; gap: 2px; font-size: .75rem; color: var(--text-muted-green); }
.img-dropzone__target .dz-filename { order: -1; color: var(--text-main); font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.img-dropzone__target .dz-filename span, .img-dropzone__target .dz-size span { background: none; padding: 0; border: 0; }
.img-dropzone__target .dz-progress {
    position: absolute; left: 8px; bottom: 8px; width: 72px; height: 4px;
    border-radius: 999px; overflow: hidden; background-color: rgba(0, 0, 0, .12);
}
.img-dropzone__target .dz-upload { display: block; height: 100%; width: 0; background-color: var(--g-accent); transition: width var(--dur-fast) linear; }
.img-dropzone__target .dz-complete .dz-progress { display: none; }
.img-dropzone__target .dz-success-mark,
.img-dropzone__target .dz-error-mark {
    position: absolute; top: 6px; left: 62px;
    width: 20px; height: 20px; border-radius: 50%;
    display: none; pointer-events: none;
}
.img-dropzone__target .dz-success-mark svg,
.img-dropzone__target .dz-error-mark svg { width: 20px; height: 20px; display: block; }
.img-dropzone__target .dz-success .dz-success-mark { display: block; background-color: var(--g-accent); }
.img-dropzone__target .dz-error .dz-error-mark { display: block; background-color: var(--sys-red); }
.img-dropzone__target .dz-success-mark path,
.img-dropzone__target .dz-error-mark g { fill: #fff; stroke: #fff; fill-opacity: 1; }
.img-dropzone__target .dz-error-message { display: none; }
.img-dropzone__target .dz-remove {
    position: absolute; right: 0; top: 50%; transform: translateY(-50%);
    padding: 5px 10px; border-radius: var(--radius-md);
    border: 1px solid var(--border-strong); background-color: var(--surface-card);
    color: var(--text-main); font-size: .75rem; font-weight: 600; text-decoration: none;
}
.img-dropzone__target .dz-remove:hover { border-color: var(--sys-red); color: var(--sys-red); }

/* Gambar tersimpan (mode edit): thumbnail + tombol hapus berdampingan. */
.img-dropzone__current { display: flex; flex-direction: column; align-items: flex-start; gap: 8px; }
.img-dropzone__current img {
    width: 88px; height: 88px; object-fit: cover;
    border-radius: var(--radius-lg);
    border: 1px solid var(--border-hairline);
    background-color: var(--surface-sunken);
}


/* ---------------------------------------------------------------------
   17. Select2

   Panel hasilnya ditempelkan select2 ke <body>, DI LUAR .card dan
   .table-responsive. Itulah yang menyelamatkannya dari overflow:hidden —
   jadi jangan pernah menyetel dropdownParent ke dalam cangkang mana pun.

   Tema select2-bootstrap-5 mengirim `z-index: 1`, yang kalah dari setiap
   cangkang sticky/fixed. Ditimpa di sini.

   Topbar SENGAJA tidak memakai select2: lihat catatan di layouts/app.
--------------------------------------------------------------------- */
.select2-container { z-index: var(--z-dropdown); }
.select2-container--open { z-index: calc(var(--z-overlay) + 10); }
.select2-dropdown {
    border: 1px solid var(--border-hairline);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-overlay);
    overflow: hidden;
}
.select2-container--bootstrap-5 .select2-selection {
    min-height: 42px;
    padding: 0 12px;
    display: flex;
    align-items: center;
    background-color: var(--surface-card);
    border: 1px solid var(--border-hairline);
    border-radius: var(--radius-md);
    font-size: .8125rem;
}
.select2-container--bootstrap-5 .select2-selection--single .select2-selection__rendered {
    flex: 1;
    min-width: 0;
    padding: 0;
    color: var(--text-main);
    line-height: 1.4;
}
.select2-container--bootstrap-5 .select2-selection--single .select2-selection__placeholder { color: #8A94A6; }
.select2-container--bootstrap-5.select2-container--focus .select2-selection,
.select2-container--bootstrap-5.select2-container--open .select2-selection {
    border-color: var(--g-accent);
    box-shadow: 0 0 0 3px var(--g-accent-soft);
}
.select2-container--bootstrap-5 .select2-search--dropdown .select2-search__field {
    height: 36px;
    padding: 0 10px;
    font-size: .8125rem;
    border: 1px solid var(--border-hairline);
    border-radius: var(--radius-sm);
}
.select2-container--bootstrap-5 .select2-search--dropdown .select2-search__field:focus {
    border-color: var(--g-accent);
    outline: none;
}
.select2-container--bootstrap-5 .select2-results__option { padding: 8px 12px; font-size: .8125rem; }
.select2-container--bootstrap-5 .select2-results__option--highlighted,
.select2-container--bootstrap-5 .select2-results__option--selected {
    background-color: var(--g-accent-soft) !important;
    color: var(--text-main) !important;
}
.select2-container--bootstrap-5 .select2-results__option[aria-disabled="true"] { color: var(--text-eyebrow); }
.select2-container--bootstrap-5.select2-sm .select2-selection { min-height: 36px; padding: 0 10px; font-size: .75rem; }
.select2-container--bootstrap-5 .select2-selection--multiple { padding: 5px 8px; flex-wrap: wrap; gap: 4px; }
.select2-container--bootstrap-5 .select2-selection__choice {
    background-color: var(--g-accent-soft);
    border: none;
    border-radius: var(--radius-sm);
    color: var(--g-shell-800);
    font-size: .6875rem;
    font-weight: 600;
    padding: 3px 7px;
}
@media (pointer: coarse) {
    .select2-container--bootstrap-5 .select2-selection { min-height: 44px; }
    .select2-container--bootstrap-5 .select2-results__option { padding: 12px; }
}


/* ---------------------------------------------------------------------
   18. Pil status & sisa utilitas kecil
--------------------------------------------------------------------- */
.status-pill {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 10px;
    font-size: .6875rem;
    font-weight: 700;
    border-radius: 999px;
    white-space: nowrap;
}
.status-pill::before { content: ''; width: 6px; height: 6px; border-radius: 50%; background-color: currentColor; }
.status-available   { background-color: var(--status-available-bg); color: var(--status-available-ink); box-shadow: inset 0 0 0 1px var(--status-available-line); }
.status-occupied    { background-color: var(--status-occupied-bg);  color: var(--status-occupied-ink);  box-shadow: inset 0 0 0 1px var(--status-occupied-line); }
.status-booked      { background-color: var(--status-booked-bg);    color: var(--status-booked-ink);    box-shadow: inset 0 0 0 1px var(--status-booked-line); }
.status-maintenance { background-color: var(--status-maint-bg);     color: var(--status-maint-ink);     box-shadow: inset 0 0 0 1px var(--status-maint-line); }

/* Wadah bertinggi PASTI untuk kanvas Chart.js. Wajib: chart dipakai dengan
   maintainAspectRatio:false, dan dalam mode itu ia mengambil tinggi dari
   induknya. Tanpa tinggi pasti tiap pengukuran ulang menambah tinggi kanvas
   — halaman ini pernah memanjang 2.661px. */
.chart-box { position: relative; width: 100%; height: 260px; }
.chart-box canvas { max-width: 100%; }
@media (max-width: 575.98px) { .chart-box { height: 210px; } }

.chart-box--tall { height: 320px; }
@media (max-width: 575.98px) { .chart-box--tall { height: 240px; } }

/* ApexCharts (halaman Laporan) diselaraskan ke token. */
.apexcharts-canvas text { font-family: var(--bs-body-font-family) !important; }
.apexcharts-gridline { stroke: var(--border-hairline) !important; }
.apexcharts-tooltip {
    border: 1px solid var(--border-hairline) !important;
    box-shadow: var(--shadow-overlay) !important;
    border-radius: var(--radius-md) !important;
}
.apexcharts-tooltip-title {
    background-color: var(--surface-sunken) !important;
    border-bottom: 1px solid var(--border-hairline) !important;
    font-weight: 700 !important;
}

/* Bootstrap tidak punya padanannya. Tanpa ini, anak flex menolak menyusut
   di bawah lebar isinya dan mendorong saudaranya keluar wadah. */
.min-w-0 { min-width: 0 !important; }

/* ---------------------------------------------------------------------
   Halaman masuk staf (resources/views/auth/login.blade.php)

   Satu-satunya halaman berlatar gelap penuh: tepat sebelum masuk, layar
   penuh warna merek membuat peralihan ke dalam aplikasi terasa disengaja,
   bukan seperti halaman nyasar.

   Dulu ditulis sebagai <style> inline di dalam view itu. Gaya inline di
   halaman yang berdiri sendiri gampang terlewat saat berkas gaya dirapikan,
   dan tidak terjangkau uji cakupan kelas.
--------------------------------------------------------------------- */
body.auth-body {
    min-height: 100vh;
    display: grid;
    place-items: center;
    padding: 24px;
    background:
        radial-gradient(1100px 620px at 15% -10%, rgba(36, 107, 253, .20), transparent 60%),
        var(--g-shell-900);
}
.auth-card { width: 100%; max-width: 392px; }
.auth-brand {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    font-size: 1.35rem;
    font-weight: 800;
    letter-spacing: -.02em;
    color: var(--text-main);
}


/* Stempel "diperbarui pukul ...". */
.stamp {
    font-size: .6875rem;
    color: var(--text-eyebrow);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

@media (prefers-reduced-motion: reduce) {
    .live-dot::before { animation: none; }
    .btn, .form-control, .form-select, .img-dropzone__target { transition: none; }
}


/* Warna pop-up detail laga (assets/css/bracket.css, bagian 9) di dasbor.
   Situs publik menimpanya di public.css supaya ikut tema terang/gelap. */
.md-modal {
    --md-surface: var(--surface-card);
    --md-soft: var(--surface-sunken);
    --md-text: var(--text-main);
    --md-muted: var(--text-muted-green);
    --md-line: var(--border-hairline);
    --md-accent: var(--g-accent);
    --md-win: #1D4ED8;
}

/* ---------------------------------------------------------------------
   Editor "Tampilan Website" (settings/website) — Plan V1.3 §12.3e
--------------------------------------------------------------------- */
.theme-editor .card-body > .form-hint:first-child { margin-top: 0; }
.theme-color-row { display: flex; align-items: flex-start; gap: 12px; }
.theme-color-row__swatch {
    width: 44px; height: 44px; flex-shrink: 0; margin-top: 26px; padding: 2px;
    border: 1px solid var(--border-strong); border-radius: var(--radius-md); background: var(--surface-card); cursor: pointer;
}
.theme-section-list { list-style: none; margin: 0; padding: 0; border: 1px solid var(--border-hairline); border-radius: var(--radius-lg); }
.theme-section-list__item {
    display: flex; align-items: center; justify-content: space-between; gap: 12px;
    padding: 8px 12px; border-bottom: 1px solid var(--border-hairline);
}
.theme-section-list__item:last-child { border-bottom: 0; }
.theme-section-list__actions { display: inline-flex; gap: 4px; }
.theme-preview { position: sticky; top: calc(var(--navbar-height) + 12px); }
.theme-preview__stage { padding: 12px; background: var(--surface-sunken); border-top: 1px solid var(--border-hairline); }
.theme-preview__frame {
    display: block; width: 100%; height: 72vh; margin: 0 auto; border: 1px solid var(--border-hairline);
    border-radius: var(--radius-md); background: #FFFFFF; transition: width var(--dur-base) var(--ease-out);
}
.theme-preview__frame.is-mobile { width: 390px; max-width: 100%; }
.btn-label-danger { color: var(--sys-red); background: var(--sys-red-bg); border-color: transparent; }
.btn-label-danger:hover { color: #FFFFFF; background: var(--sys-red); }

/* Pelunasan sisa DP sebelum check-in (bookings/_check-in-action) */
.booking-settle { display: inline-flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.booking-settle .form-select { width: auto; min-width: 96px; }

/* Log Audit Kasir (audit/index) */
.audit-reason { max-width: 320px; white-space: normal; }
.audit-diff { font-size: .75rem; font-variant-numeric: tabular-nums; }
