/* ===================================================================
   Gaya aplikasi KSP - tampilan web modern.
   Nama kelas sengaja dipertahankan sama seperti versi sebelumnya
   (window, window-title, btn, form-grid, badge, dst) supaya seluruh
   halaman Blade yang sudah ada langsung ikut tampilan baru tanpa
   perlu diubah satu per satu.
   =================================================================== */

/* ===== 0. Huruf ===== */
/* Inter - huruf yang dipakai odoo.com; gaya mereka menyebutnya sendiri lewat
   --font-sans-serif: "Inter", "Odoo Unicode Support Noto", sans-serif.

   Berkasnya DIBUNDEL LOKAL di public/fonts/, bukan dimuat dari Google Fonts:
   aturan proyek melarang CDN, dan koperasi ini harus tetap tampil benar ketika
   sambungan keluarnya mati - yang di Lampung Tengah bukan kejadian langka.

   Satu berkas variabel 48KB meliputi seluruh bobot 100-900, jadi tidak ada
   permintaan tambahan per ketebalan huruf. Lisensi SIL Open Font License 1.1,
   yang memang mengizinkan pembundelan seperti ini. */
@font-face {
    font-family: 'Inter';
    font-style: normal;
    font-weight: 100 900;
    font-display: swap;
    src: url('../fonts/inter-latin-var.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ===== 1. Token desain ===== */
:root {
    /* Huruf odoo, dipakai seluruh aplikasi. */
    --font-odoo: 'Inter', "Segoe UI Variable Text", "Segoe UI", system-ui, -apple-system, Roboto, Arial, sans-serif;

    --brand-50:  #eff6ff;
    --brand-100: #dbeafe;
    --brand-200: #bfdbfe;
    --brand-500: #3b82f6;
    --brand-600: #2563eb;
    --brand-700: #1d4ed8;
    --brand-900: #1e3a8a;

    --ink:        #0f172a;
    --ink-soft:   #334155;
    --muted:      #64748b;
    --muted-soft: #94a3b8;

    --surface:     #ffffff;
    --surface-alt: #f8fafc;
    --canvas:      #eef1f6;
    --line:        #e5e9f0;
    --line-strong: #cbd5e1;

    --ok-bg:   #ecfdf5;  --ok-line:   #a7f3d0;  --ok-ink:   #047857;
    --bad-bg:  #fef2f2;  --bad-line:  #fecaca;  --bad-ink:  #b91c1c;

    --r-sm: 7px;
    --r-md: 10px;
    --r-lg: 14px;
    --r-pill: 999px;

    --shadow-xs: 0 1px 2px rgba(15, 23, 42, .05);
    --shadow-sm: 0 1px 3px rgba(15, 23, 42, .07), 0 1px 2px rgba(15, 23, 42, .04);
    --shadow-md: 0 6px 16px rgba(15, 23, 42, .07), 0 1px 3px rgba(15, 23, 42, .05);
    --shadow-lg: 0 16px 40px rgba(15, 23, 42, .16), 0 4px 10px rgba(15, 23, 42, .07);
    --ring: 0 0 0 3px rgba(37, 99, 235, .18);

    --page-w: 1180px;
    --form-label-w: 190px;
    --form-gap: 16px;

    /* Tema DataTables v2 (variabel bawaan paketnya) */
    --dt-row-hover: 37, 99, 235;
    --dt-row-hover-alpha: .05;
    --dt-row-stripe: 15, 23, 42;
    --dt-row-stripe-alpha: .014;
    --dt-column-ordering-alpha: .012;
    --dt-row-selected: 37, 99, 235;
}

* { box-sizing: border-box; }

html, body {
    height: 100%;
    margin: 0;
    /* Inter dipakai seluruh aplikasi sekarang, bukan header saja. Membiarkan
       isi halaman berhuruf sistem sementara headernya Inter membuat keduanya
       terbaca sebagai dua aplikasi yang ditempel. */
    font-family: var(--font-odoo);
    font-size: 14px;
    line-height: 1.5;
    color: var(--ink);
    background: var(--canvas);
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
}

h1, h2, h3, h4, h5 { line-height: 1.25; letter-spacing: -.01em; }

.app {
    display: flex;
    flex-direction: column;
    height: 100vh;
}

/* Scrollbar tipis agar tidak mengganggu tampilan */
* {
    scrollbar-width: thin;
    scrollbar-color: var(--line-strong) transparent;
}

*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-track { background: transparent; }

*::-webkit-scrollbar-thumb {
    background: var(--line-strong);
    border: 3px solid transparent;
    border-radius: var(--r-pill);
    background-clip: content-box;
}

*::-webkit-scrollbar-thumb:hover { background-color: var(--muted-soft); background-clip: content-box; }

/* ===== 2. Lambang koperasi di header ===== */
/* Header sudah putih sejak gaya odoo.com diikuti, jadi lambangnya tidak lagi
   memerlukan sel putih sendiri. Sel itu dulu ada semata-mata karena biru pada
   lambang koperasi (#0000EB) tenggelam di atas strip yang juga biru tua. */
.ribbon .brand {
    display: flex;
    align-items: center;
    align-self: center;
    flex: 0 0 auto;
    margin-right: 14px;
    padding: 5px 10px;
    border-radius: var(--r-md);
    text-decoration: none;
    transition: background-color .12s ease;
}

.ribbon .brand:hover { background: var(--surface-alt); }
.ribbon .brand:focus-visible { outline: none; box-shadow: var(--ring); }

.brand-mark {
    display: block;
    width: 32px;
    height: 32px;
    flex: 0 0 auto;
    object-fit: contain;
}

/* ===== Ikon (sprite SVG di partials/icons.blade.php) ===== */
.ico {
    width: 16px;
    height: 16px;
    flex: 0 0 auto;
    vertical-align: -3px;
    color: inherit;
}

/* ===== 3. Menu utama: strip tab + panel melayang ===== */
/* Bentuk dan warnanya mengikuti bilah menu odoo.com: strip putih dan lapang,
   dengan panel besar yang MELAYANG di atas isi halaman saat tabnya disentuh
   tetikus. Melayang, bukan menetap seperti pita Office - dengan dua baris
   kelompok, panel yang ikut mengalir akan mendorong isi halaman lebih dari
   250px ke bawah setiap saat, padahal isinya cuma dibaca beberapa detik
   sekali.

   Warna aksen odoo yang keunguan (#714B67) diganti biru khas aplikasi ini
   (--brand-700) di semua tempat: tab yang aktif, tab yang disentuh, judul
   lajur, dan avatar pemakai.

   Kelas .menubar dipertahankan pada elemen yang sama semata-mata karena 13
   lembar gaya cetak di resources/views menyembunyikan header lewat nama itu;
   .menubar sendiri tidak lagi memberi gaya apa pun. */
.ribbon {
    display: flex;
    flex-direction: column;
    flex: 0 0 auto;
    /* Inter untuk seluruh isi header. Ia berhuruf x lebih tinggi dari Segoe UI,
       jadi jarak antarhurufnya sedikit dirapatkan - tanpa itu label tab terbaca
       renggang pada ukuran 14.5px. */
    font-family: var(--font-odoo);
    letter-spacing: -.006em;
    background: var(--surface);
    border-bottom: 1px solid var(--line);
    user-select: none;
    position: relative;
    z-index: 50;
}

/* --- Strip tab ---------------------------------------------------------- */
/* Tinggi 56px dan huruf 14.5px berbobot normal: bilah odoo lapang dan ringan,
   dan itu sebagian besar datang dari ruang kosongnya, bukan dari hurufnya.
   Bobot 500 ke atas akan langsung mengubahnya kembali menjadi bilah menu
   aplikasi perkantoran. */
.ribbon-tabs {
    display: flex;
    align-items: stretch;
    min-height: 56px;
    padding: 0 16px;
    background: var(--surface);
    color: var(--ink);
}

/* Tab benar-benar di tengah header, bukan di tengah ruang sisa: kedua sisi
   (.ribbon-sisi) diberi lebar lentur yang sama, sehingga lebar lambang dan
   lebar nama pemakai - yang tidak pernah sama - tidak menggeser titik
   tengahnya. Daftar tab sendiri selebar isinya, dan baru menyusut lalu bisa
   digeser mendatar ketika layarnya memang tidak cukup. */
.ribbon-sisi {
    display: flex;
    align-items: stretch;
    flex: 1 1 0;
}

.ribbon-sisi-kanan {
    align-items: center;
    justify-content: flex-end;
    gap: 4px;
}

.ribbon-tablist {
    display: flex;
    align-items: stretch;
    flex: 0 1 auto;
    gap: 2px;
    min-width: 0;
    overflow-x: auto;
    scrollbar-width: none;
}

.ribbon-tablist::-webkit-scrollbar { display: none; }

.ribbon-tab {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 0;
    padding: 0 15px;
    border: 0;
    background: none;
    color: var(--ink-soft);
    font-family: inherit;
    font-size: 14.5px;
    font-weight: 400;
    white-space: nowrap;
    cursor: pointer;
    transition: color .12s ease, box-shadow .12s ease;
}

/* Warna saja saat disentuh, tanpa blok latar - itu yang membuat bilah odoo
   terasa ringan. Blok abu-abu yang menyala di bawah kursor mengubahnya
   kembali menjadi bilah tombol. */
.ribbon-tab:hover { color: var(--brand-700); }

/* Tab yang panelnya sedang terbuka: biru penuh dengan garis di kakinya,
   menyambung ke panel putih di bawahnya. */
.ribbon-tab.buka {
    color: var(--brand-700);
    font-weight: 500;
    box-shadow: inset 0 -2px 0 var(--brand-600);
}

/* Tab milik halaman yang sedang dibuka. Garisnya lebih tipis dan warnanya
   lebih tenang daripada tab yang terbuka - ia keterangan letak, bukan sesuatu
   yang sedang terjadi. */
.ribbon-tab.aktif {
    color: var(--brand-700);
    font-weight: 500;
    box-shadow: inset 0 -2px 0 var(--brand-200);
}

.ribbon-tab.aktif.buka { box-shadow: inset 0 -2px 0 var(--brand-600); }

.ribbon-tab:focus-visible { outline: none; box-shadow: var(--ring); }

/* Ikon tiap tab berwarna sendiri-sendiri, seperti deretan ikon aplikasi di
   odoo. Yang berwarna hanya ikonnya - labelnya tetap seragam abu-abu tua,
   supaya bilahnya berwarna-warni tanpa menjadi sulit dibaca. Warnanya bergilir
   delapan, jadi tab kesembilan mengulang warna pertama. */
.ribbon-tab .ico { opacity: .92; transition: opacity .12s ease, transform .12s ease; }
.ribbon-tab:hover .ico { opacity: 1; transform: scale(1.08); }

.ribbon-tab:nth-child(8n+1) .ico { color: #1d4ed8; }
.ribbon-tab:nth-child(8n+2) .ico { color: #00a09d; }
.ribbon-tab:nth-child(8n+3) .ico { color: #7c3aed; }
.ribbon-tab:nth-child(8n+4) .ico { color: #d97706; }
.ribbon-tab:nth-child(8n+5) .ico { color: #0891b2; }
.ribbon-tab:nth-child(8n+6) .ico { color: #db2777; }
.ribbon-tab:nth-child(8n+7) .ico { color: #16a34a; }
.ribbon-tab:nth-child(8n+8) .ico { color: #6366f1; }

/* --- Panel melayang ----------------------------------------------------- */
.ribbon-panel {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    z-index: 60;
    justify-content: center;
    padding: 24px 16px 28px;
    background: var(--surface);
    border-bottom: 1px solid var(--line);
    box-shadow: var(--shadow-md);
    overflow-x: auto;
}

.ribbon-panel.buka {
    display: flex;
    animation: panel-in .14s ease-out;
}

/* Sapuan pendek saat panel muncul. Tanpa itu ia menyembul seketika dan terbaca
   seperti kedipan layar, bukan seperti sesuatu yang dibuka. */
@keyframes panel-in {
    from { opacity: 0; transform: translateY(-4px); }
    to   { opacity: 1; transform: none; }
}

/* Lebar isinya dibatasi lalu ditengahkan, sehingga titik tengahnya berimpit
   dengan titik tengah deretan tab di atasnya. Batas itu pula yang membuat
   kelompok melipat ke baris kedua - persis susunan dua baris di odoo.com -
   alih-alih berbaris memanjang sampai ke tepi layar lebar.

   PETAK, bukan flex-wrap. Versi flex sebelumnya punya dua cacat yang saling
   menyembunyikan, dan gejalanya persis keluhan "menu Laporan RAT bergeser
   sendiri ke bawah":

   1. `flex: 0 0 212px` TIDAK PERNAH BERLAKU. Lebar terkecil bawaan sebuah item
      flex adalah lebar isinya (`min-width: auto`), sedangkan `.ribbon-btn`
      memakai `white-space: nowrap`. Satu perintah sepanjang "Pendapatan &
      Biaya Bunga Accrual" karena itu memaksa lajurnya menjadi ~285px, dan
      lajur yang isinya pendek tetap 212px - lajurnya tidak pernah sama lebar,
      sehingga baris kedua memang mustahil sejajar dengan baris pertama.
   2. `justify-content: center` MENENGAHKAN SISA BARIS TERAKHIR. Empat kelompok
      pada baris bermuatan tiga meninggalkan satu kelompok sendirian, dan ia
      ditaruh di tengah - tidak di bawah lajur mana pun. Itulah yang terbaca
      sebagai "bergeser sendiri".

   Petak dengan lajur `max-content` menyelesaikan keduanya sekaligus: tiap lajur
   selebar isi terlebar DI LAJUR ITU, sama untuk semua barisnya, dan kelompok
   sisa jatuh tepat di bawah lajur pertama.

   Tiga lajur, bukan empat. Bukan selera: label terpanjang aplikasi ini 32 huruf,
   yang membuat satu lajur ~285px, sehingga empat lajur menuntut ~1.250px -
   lebih lebar dari jendela peramban yang lazim dipakai di koperasi. Panel menu
   yang harus digeser ke samping lebih buruk daripada panel yang dua baris.
   Tiga juga membagi rata menu terbanyak: Keanggotaan yang 6 kelompok menjadi
   dua baris penuh, bukan 4 + 2 yang timpang. */
.ribbon-panel-isi {
    display: grid;
    grid-template-columns: repeat(3, max-content);
    justify-content: start;
    align-items: start;
    gap: 24px 38px;
    max-width: 980px;
}

/* --- Satu kelompok ------------------------------------------------------ */
/* Tanpa lebar tetap: petak di atas yang menyamakan lebar antarbaris, dan lebar
   tetap yang lebih sempit dari isinya hanya akan diabaikan seperti dulu. */
.ribbon-grup {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

/* Garis di bawah judul kelompok, bukan garis tegak antarkelompok. Itu yang
   membedakan dua baris kelompok supaya tetap terbaca sebagai daftar-daftar
   terpisah tanpa memagari apa pun. */
.ribbon-grup-label {
    margin: 0 0 8px;
    padding: 0 8px 8px;
    border-bottom: 1px solid var(--brand-200);
    color: var(--brand-700);
    font-size: 12px;
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
}

/* Judul tiap lajur berganti warna mengikuti letaknya, seperti di odoo.com.
   Bukan sekadar hiasan: dengan sampai enam lajur berjudul dalam satu panel,
   warnalah yang membuat mata menemukan kembali lajur yang tadi dilihat tanpa
   membaca ulang judulnya. TIGA warna, sejumlah lajur per baris - jadi lajur
   yang duduk di kolom yang sama selalu berwarna sama, baris atas maupun bawah.

   Angka ini WAJIB sama dengan jumlah lajur di `.ribbon-panel-isi`. Sebelum
   perbaikan 31 Agustus 2026 ia `4n` sementara yang muat sebaris hanya tiga,
   sehingga warna justru berpindah kolom tiap baris - persis kebalikan dari
   gunanya.

   Merah sengaja dihindari sekalipun odoo memakainya: di aplikasi yang penuh
   angka uang, merah berarti galat atau minus, bukan kategori. */
.ribbon-grup:nth-child(3n+1) .ribbon-grup-label { color: #1d4ed8; border-bottom-color: #bfdbfe; }
.ribbon-grup:nth-child(3n+2) .ribbon-grup-label { color: #00a09d; border-bottom-color: #99e6e4; }
.ribbon-grup:nth-child(3n+3) .ribbon-grup-label { color: #b45309; border-bottom-color: #fde68a; }

.ribbon-grup-isi {
    display: flex;
    flex-direction: column;
    gap: 1px;
}

/* --- Satu perintah ------------------------------------------------------ */
.ribbon-btn {
    display: flex;
    align-items: center;
    gap: 9px;
    height: 30px;
    padding: 0 8px;
    border-radius: var(--r-sm);
    color: var(--ink-soft);
    font-size: 13.5px;
    text-decoration: none;
    white-space: nowrap;
    transition: background-color .1s ease, color .1s ease;
}

.ribbon-btn .ico { color: var(--muted); transition: color .1s ease; }

/* Halaman yang sedang dibuka ditandai di daftarnya sendiri. Tanpa ini satu-satunya
   petunjuk letak pemakai adalah remah jejak di bawah header - sedangkan tab yang
   menyala hanya menyebut kelompoknya, bukan perintah mana yang sedang dijalankan.
   Ditulis SEBELUM aturan :hover: keduanya sama kuat, jadi yang belakangan menang,
   dan menyorot perintah yang sedang aktif harus tetap memberi tanggapan. */
.ribbon-btn.kini {
    background: var(--brand-50);
    color: var(--brand-700);
    font-weight: 600;
    box-shadow: inset 2px 0 0 var(--brand-600);
}

.ribbon-btn.kini .ico { color: var(--brand-600); }

/* Sorotan biru muda, bukan biru pekat: panel ini padat - 81 perintah dalam satu
   menu - dan blok biru penuh yang melompat mengikuti tetikus terbaca sebagai
   kedipan, bukan sebagai penunjuk. */
.ribbon-btn:hover { background: var(--brand-50); color: var(--brand-700); }
.ribbon-btn:hover .ico { color: var(--brand-600); }
.ribbon-btn:focus-visible { outline: none; box-shadow: var(--ring); }

/* Perintah yang halamannya belum dibangun tetap ditampilkan: pemakai perlu
   tahu apa yang akan ada, dan menyembunyikannya membuat bentuk menu berubah
   tiap kali satu fase selesai. */
.ribbon-btn.disabled { color: var(--muted-soft); cursor: not-allowed; }
.ribbon-btn.disabled .ico { opacity: .7; }
.ribbon-btn.disabled:hover { background: none; color: var(--muted-soft); }
.ribbon-btn.disabled:hover .ico { color: var(--muted); }

/* Kode pintasan - petunjuk apa yang harus diketik di kotak pintasan (Ctrl+K).
   Sengaja redup: ia keterangan, bukan nama perintahnya. */
.ribbon-btn .kode {
    margin-left: auto;
    padding-left: 14px;
    color: var(--muted-soft);
    font-size: 10.5px;
    font-weight: 600;
    letter-spacing: .05em;
    font-variant-numeric: tabular-nums;
}

.ribbon-btn:hover .kode,
.ribbon-btn.kini .kode { color: var(--brand-500); }

/* --- Menu akun (satu-satunya dropdown yang tersisa) ---------------------- */
.ribbon ul {
    display: flex;
    align-items: center;
    list-style: none;
    margin: 0;
    padding: 0;
    gap: 2px;
}

.menubar-item { position: relative; display: flex; align-items: center; }

.menubar-item > a {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 10px;
    border-radius: var(--r-md);
    color: var(--ink-soft);
    font-size: 13.5px;
    font-weight: 500;
    text-decoration: none;
    white-space: nowrap;
    transition: background-color .12s ease, color .12s ease;
}

.menubar-item > a:hover { background: var(--surface-alt); color: var(--ink); }

.menubar-item.open > a {
    background: var(--brand-50);
    color: var(--brand-700);
}

.menubar-item > a:focus-visible { outline: none; box-shadow: var(--ring); }

.ribbon .caret {
    width: 0;
    height: 0;
    border-left: 4px solid transparent;
    border-right: 4px solid transparent;
    border-top: 4.5px solid currentColor;
    opacity: .5;
}

.ribbon .dropdown {
    display: none;
    position: absolute;
    top: 100%;
    left: auto;
    right: 0;
    z-index: 1000;
    flex-direction: column;
    min-width: 218px;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--r-md);
    box-shadow: var(--shadow-lg);
    padding: 6px;
    margin-top: 6px;
    gap: 1px;
}

.menubar-item.open > .dropdown {
    display: flex;
    animation: dropdown-in .13s ease-out;
}

@keyframes dropdown-in {
    from { opacity: 0; transform: translateY(-4px); }
    to   { opacity: 1; transform: none; }
}

.ribbon .dropdown li { width: 100%; }

.ribbon .dropdown a {
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 7px 12px;
    border-radius: var(--r-sm);
    color: var(--ink-soft);
    font-size: 13.5px;
    text-decoration: none;
    white-space: nowrap;
    transition: background-color .1s ease, color .1s ease;
}

.ribbon .dropdown a:hover {
    background: var(--brand-50);
    color: var(--brand-700);
}

.ribbon .dropdown a .ico { color: var(--muted); transition: color .1s ease; }
.ribbon .dropdown a:hover .ico { color: var(--brand-600); }

.menubar-user > a { font-weight: 500; }

/* Avatar memakai biru khas aplikasi - inilah pengganti aksen keunguan odoo,
   dan satu-satunya blok warna pekat yang tersisa di header putih ini. */
.menubar-user .avatar {
    display: grid;
    place-items: center;
    width: 28px;
    height: 28px;
    border-radius: 50%;
    background: linear-gradient(135deg, var(--brand-500), var(--brand-900));
    color: #fff;
    font-size: 12px;
    font-weight: 700;
}

/* Kepala daftar akun: nama pemakai dan perannya. Keterangan peran dulu berupa
   chip di bilah judul; bilah itu hilang saat header disatukan, dan membedakan
   admin dari teller terlalu penting untuk sekadar dibuang. */
.menubar-user .dropdown-head {
    display: flex;
    flex-direction: column;
    gap: 1px;
    padding: 9px 14px 10px;
    margin-bottom: 4px;
    border-bottom: 1px solid var(--line);
    cursor: default;
}

.menubar-user .dropdown-head strong {
    font-size: 13px;
    color: var(--ink);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.menubar-user .dropdown-head small { font-size: 11.5px; color: var(--muted); }

/* ===== 4. Area konten ===== */
.content {
    flex: 1 1 auto;
    overflow: auto;
    padding: 22px 20px 32px;
    scroll-behavior: smooth;
}

/* ===== Breadcrumb ===== */
.breadcrumb {
    max-width: var(--page-w);
    margin: 0 auto 14px;
}

.breadcrumb ol {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    list-style: none;
    margin: 0;
    padding: 0;
    font-size: 12.5px;
}

.breadcrumb li {
    display: flex;
    align-items: center;
    min-width: 0;
}

.breadcrumb a,
.breadcrumb span {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 8px;
    border-radius: var(--r-sm);
    color: var(--muted);
    text-decoration: none;
}

.breadcrumb a { transition: background-color .12s ease, color .12s ease; }
.breadcrumb a:hover { background: var(--surface); color: var(--brand-700); }
.breadcrumb a:focus-visible { outline: none; box-shadow: var(--ring); }

.breadcrumb [aria-current="page"] {
    color: var(--ink);
    font-weight: 600;
}

.breadcrumb .ico { width: 14px; height: 14px; }
.breadcrumb .sep { color: var(--muted-soft); opacity: .7; }

/* Panel konten (dulu "window" gaya MDI, sekarang kartu).
   Dibuat rata mengikuti odoo: bayangan tebal dan sudut besar membuat tiap
   halaman terlihat seperti kartu yang melayang di atas sesuatu, padahal ia
   satu-satunya isi halaman - tidak ada yang perlu dibedakan ketinggiannya. */
.window {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--r-md);
    box-shadow: var(--shadow-xs);
    margin: 0 auto 18px;
    max-width: var(--page-w);
    overflow: hidden;
    animation: card-in .2s ease-out both;
}

@keyframes card-in {
    from { opacity: 0; transform: translateY(6px); }
    to   { opacity: 1; transform: none; }
}

.window.narrow { max-width: 680px; }

/* Judul panel: berlatar putih dan berukuran besar, seperti panel kendali
   odoo - strip abu-abu di kepala kartu adalah kebiasaan aplikasi perkantoran,
   dan ia menyita perhatian yang seharusnya jatuh ke isinya. */
.window-title {
    display: flex;
    align-items: center;
    gap: 10px;
    background: var(--surface);
    border-bottom: 1px solid var(--line);
    color: var(--ink);
    font-size: 17px;
    font-weight: 600;
    letter-spacing: -.02em;
    padding: 15px 20px;
}

/* overflow-x: tabel yang lebih lebar dari kartu tetap bisa digeser, tidak
   terpotong oleh sudut membulat .window (overflow: hidden). */
.window-body { padding: 18px; overflow-x: auto; }

/* Dua window-body berurutan: rapatkan jaraknya */
.window-body + .window-body { padding-top: 0; }

/* Pola "window-body toolbar" (baris filter/cetak di atas isi) jadi strip sendiri */
.window-body.toolbar {
    margin-bottom: 0;
    padding: 12px 18px;
    border-bottom: 1px solid var(--line);
}

.window-body.toolbar + .window-body { padding-top: 18px; }

/* ===== 5. Status bar ===== */
.statusbar {
    display: flex;
    align-items: center;
    gap: 8px;
    background: var(--surface);
    border-top: 1px solid var(--line);
    padding: 7px 18px;
    flex: 0 0 auto;
    font-size: 12px;
    color: var(--muted);
}

.statusbar span {
    padding: 3px 10px;
    border-radius: var(--r-pill);
    background: var(--surface-alt);
    white-space: nowrap;
}

.statusbar span strong { color: var(--ink-soft); font-weight: 600; }

.statusbar .grow { flex: 1 1 auto; background: none; padding: 0; }

/* ===== 6. Toolbar & tombol ===== */
.toolbar {
    display: flex;
    gap: 10px;
    align-items: center;
    flex-wrap: wrap;
    margin-bottom: 14px;
}

.toolbar label { color: var(--muted); font-size: 13px; }

/* Kelompok kanan toolbar: penyaring didorong menjauh dari tombol aksi. Dua
   jenis kendali yang berbeda tugasnya - satu mengubah data, satu cuma
   mengubah apa yang terlihat - tidak pantas berjajar rapat seolah setara. */
.toolbar-kanan {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px;
    margin-left: auto;
}

/* Penyaring berbentuk pil dengan labelnya di dalam, mengikuti facet pencarian
   odoo. Sebelumnya labelnya mengambang sebagai teks lepas di antara tombol -
   di sana ia terbaca seperti keterangan tombol di sebelahnya, bukan sebagai
   nama kolom yang sedang disaring. */
/* Pil, bukan sudut 6px. Daftar pilihan bawaan <select> memang tidak bisa
   ditata CSS - karena itu daftarnya digambar sendiri di bawah, sehingga
   pemicunya bebas berbentuk apa pun tanpa bertengkar dengan daftarnya. */
.filter {
    display: flex;
    align-items: center;
    gap: 2px;
    padding-left: 10px;
    border: 1px solid var(--line-strong);
    border-radius: var(--r-pill);
    background: var(--surface);
    transition: border-color .12s ease, box-shadow .12s ease;
}

.filter:hover { border-color: var(--muted-soft); }
.filter:focus-within { border-color: var(--brand-500); box-shadow: var(--ring); }

.toolbar .filter > label {
    color: var(--muted);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
    white-space: nowrap;
}

.filter > select {
    width: auto;
    border: 0;
    border-radius: 6px;
    background-color: transparent;
    padding: 7px 30px 7px 8px;
    font-size: 13px;
    font-weight: 500;
}

.filter > select:hover { border-color: transparent; }
.filter > select:focus { box-shadow: none; }

/* Penyaring bisa juga berupa tanggal atau kotak ketik, bukan hanya select -
   rentang "Dari / s.d." di halaman jurnal contohnya. */
.filter > input {
    width: auto;
    border: 0;
    border-radius: var(--r-pill);
    background-color: transparent;
    padding: 7px 10px 7px 8px;
    font-size: 13px;
    font-weight: 500;
}

.filter > input:hover { border-color: transparent; }
.filter > input:focus { box-shadow: none; }

/* --- Daftar pilihan buatan sendiri (penyaring toolbar) -------------------
   <select> bawaan menggambar daftarnya lewat sistem operasi: kotak bersudut
   tajam dengan sorot biru tua, kebal terhadap CSS. Selama pemicunya berbentuk
   pil, keduanya selalu terlihat sebagai dua benda yang tidak berhubungan.
   Daftarnya karena itu digambar sendiri sebagai elemen halaman biasa.

   Select aslinya tetap ada di DOM - lihat app.js - hanya disembunyikan; ia yang
   tetap menyimpan nilainya dan memancarkan event `change`. */
.pilih-asli {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    border: 0;
    opacity: 0;
    pointer-events: none;
}

.pilih { position: relative; display: flex; }

.pilih-trigger {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 7px 12px 7px 8px;
    border: 0;
    border-radius: var(--r-pill);
    background: none;
    color: var(--ink);
    font: inherit;
    font-size: 13px;
    font-weight: 500;
    white-space: nowrap;
    cursor: pointer;
}

.pilih-trigger:focus-visible { outline: none; }

/* Ikon chevron di sprite menghadap ke kanan; diputar supaya menunjuk ke bawah,
   lalu ke atas saat daftarnya terbuka. */
.pilih-trigger .ico {
    width: 14px;
    height: 14px;
    color: var(--muted);
    transform: rotate(90deg);
    transition: transform .14s ease;
}

.pilih.buka .pilih-trigger .ico { transform: rotate(-90deg); }

.pilih-daftar {
    display: none;
    position: absolute;
    top: calc(100% + 8px);
    left: -11px;
    z-index: 900;
    min-width: calc(100% + 22px);
    max-height: 288px;
    overflow-y: auto;
    margin: 0;
    padding: 6px;
    list-style: none;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--r-md);
    box-shadow: var(--shadow-lg);
}

.pilih.buka .pilih-daftar { display: block; animation: dropdown-in .13s ease-out; }

.pilih-daftar li {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 7px 12px;
    border-radius: var(--r-sm);
    color: var(--ink-soft);
    font-size: 13px;
    white-space: nowrap;
    cursor: pointer;
}

/* Satu sorotan untuk tetikus dan papan ketik: dua warna sorot yang berbeda di
   daftar yang sama membuat orang mengira ada dua hal yang sedang terjadi. */
.pilih-daftar li:hover,
.pilih-daftar li.sorot { background: var(--brand-50); color: var(--brand-700); }

/* Yang sedang terpilih ditandai centang, BUKAN blok biru penuh - blok itu
   bertabrakan dengan sorotan kursor, dan pemakai jadi tidak bisa membedakan
   "yang sedang dipilih" dari "yang sedang ditunjuk". */
.pilih-daftar li[aria-selected="true"] {
    color: var(--brand-700);
    font-weight: 600;
}

.pilih-daftar li[aria-selected="true"]::after {
    content: "\2713";
    margin-left: auto;
    font-size: 12px;
}

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
    font: inherit;
    font-size: 13.5px;
    font-weight: 550;
    line-height: 1.2;
    background: var(--surface);
    border: 1px solid var(--line-strong);
    border-radius: 6px;
    padding: 8px 15px;
    cursor: pointer;
    color: var(--ink-soft);
    text-decoration: none;
    white-space: nowrap;
    transition: background-color .12s ease, border-color .12s ease, box-shadow .12s ease, transform .06s ease;
}

/* Warna aksen muncul saat disentuh, bukan menetap. Tombol sekunder odoo
   memang bergaris warna aksen, tetapi satu toolbar di sini bisa memuat lima
   tombol - lima kotak biru berjajar berhenti menjadi penunjuk dan mulai
   menjadi latar. */
.btn:hover {
    background: var(--brand-50);
    border-color: var(--brand-200);
    color: var(--brand-700);
}

.btn:active { transform: translateY(1px); }

.btn:focus-visible { outline: none; box-shadow: var(--ring); }

.btn:disabled,
.btn[disabled] {
    opacity: .55;
    cursor: not-allowed;
    transform: none;
}

.btn-primary {
    background: var(--brand-600);
    border-color: var(--brand-600);
    color: #fff;
}

.btn-primary:hover {
    background: var(--brand-700);
    border-color: var(--brand-700);
    color: #fff;
}

/* Tombol yang hanya berpindah halaman, bukan mengubah data: tanpa garis tepi
   dan tanpa latar, supaya tombol aksi di sebelahnya tetap yang paling berat di
   baris itu. Sebelumnya ketiganya berbentuk kotak yang sama, sehingga "Tambah
   Rekening" dan "Buku Besar" terbaca sebagai dua hal yang sederajat - padahal
   yang satu membuat data dan yang satu cuma pindah halaman. */
.btn-ghost {
    border-color: transparent;
    background: transparent;
    color: var(--muted);
}

.btn-ghost:hover {
    background: var(--brand-50);
    border-color: transparent;
    color: var(--brand-700);
}

/* Tautan yang MENINGGALKAN halaman ini, dipisahkan dari tombol aksi oleh garis
   tegak. "Tambah Rekening" membuka formulir milik halaman ini; "Buku Besar" dan
   "Jurnal Umum" membawa pemakai pergi. Selama keduanya sama-sama berbentuk
   tombol, tidak ada yang memberi tahu perbedaan itu - jadi di sini mereka bukan
   tombol sama sekali, melainkan tautan berpanah. */
.toolbar-tautan {
    display: flex;
    align-items: center;
    gap: 16px;
    margin-left: 6px;
    padding-left: 16px;
    border-left: 1px solid var(--line);
}

.toolbar-tautan a {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 2px 2px;
    border-radius: 4px;
    color: var(--muted);
    font-size: 13.5px;
    text-decoration: none;
    transition: color .12s ease;
}

.toolbar-tautan a:hover {
    color: var(--brand-700);
    text-decoration: underline;
    text-underline-offset: 3px;
}

.toolbar-tautan a:focus-visible { outline: none; box-shadow: var(--ring); }

/* Panah kecil di ujung - penanda bahwa tautannya membawa pergi, bukan membuka
   sesuatu di halaman ini. */
.toolbar-tautan a::after {
    content: "\2192";
    color: var(--muted-soft);
    font-size: 13px;
    transition: transform .12s ease;
}

.toolbar-tautan a:hover::after { transform: translateX(2px); }

.btn-danger { color: var(--bad-ink); border-color: var(--bad-line); background: var(--surface); }

.btn-danger:hover { background: var(--bad-bg); border-color: #f87171; color: var(--bad-ink); }

.btn-sm { padding: 4px 10px; font-size: 12.5px; border-radius: 6px; gap: 5px; }

/* Ikon tombol sedikit lebih kecil & redup dari teksnya supaya teks tetap utama. */
.btn .ico { width: 15px; height: 15px; color: var(--brand-600); opacity: .85; }
.btn:hover .ico { opacity: 1; }
.btn-danger .ico { color: var(--bad-ink); }
.btn-primary .ico { color: #fff; opacity: .9; }
.btn-sm .ico { width: 14px; height: 14px; }

/* ===== 7. Form ===== */
.form-grid {
    display: grid;
    grid-template-columns: var(--form-label-w) minmax(220px, 440px);
    gap: 12px var(--form-gap);
    align-items: center;
}

.form-grid label {
    text-align: right;
    color: var(--ink-soft);
    font-size: 13.5px;
    font-weight: 500;
}

.form-grid .full { grid-column: 2; }

input[type="text"], input[type="password"], input[type="email"],
input[type="date"], input[type="number"], input[type="search"],
input[type="tel"], select, textarea {
    font: inherit;
    font-size: 13.5px;
    color: var(--ink);
    border: 1px solid var(--line-strong);
    border-radius: var(--r-sm);
    padding: 8px 11px;
    width: 100%;
    background: var(--surface);
    transition: border-color .12s ease, box-shadow .12s ease, background-color .12s ease;
}

input::placeholder, textarea::placeholder { color: var(--muted-soft); }

input:hover:not(:disabled), select:hover:not(:disabled), textarea:hover:not(:disabled) {
    border-color: var(--muted-soft);
}

input:focus, select:focus, textarea:focus {
    outline: none;
    border-color: var(--brand-500);
    box-shadow: var(--ring);
}

input:disabled, select:disabled, textarea:disabled,
input[readonly], textarea[readonly] {
    background: var(--surface-alt);
    color: var(--muted);
    cursor: not-allowed;
}

select {
    appearance: none;
    padding-right: 32px;
    background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath fill='none' stroke='%2364748b' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round' d='M1 1.5 6 6.5 11 1.5'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 11px center;
}

textarea { line-height: 1.55; resize: vertical; }

/* Angka rupiah lebih rapi dengan digit selebar sama */
input[type="number"] { font-variant-numeric: tabular-nums; }

input[type="checkbox"], input[type="radio"] {
    width: 15px;
    height: 15px;
    accent-color: var(--brand-600);
    cursor: pointer;
}

.checkbox-list {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.checkbox-list label {
    text-align: left;
    display: flex;
    gap: 8px;
    align-items: center;
    cursor: pointer;
    font-weight: 400;
}

fieldset {
    border: 1px solid var(--line);
    border-radius: var(--r-md);
    background: var(--surface-alt);
    margin: 0 0 16px;
    padding: 14px 16px 16px;
}

legend {
    font-weight: 600;
    font-size: 13px;
    color: var(--ink-soft);
    padding: 0 8px;
}

.form-actions {
    margin-top: 20px;
    display: flex;
    gap: 10px;
    flex-wrap: wrap;
}

.form-grid + .form-actions { margin-left: calc(var(--form-label-w) + var(--form-gap)); }

.error-text {
    color: var(--bad-ink);
    font-size: 12.5px;
    grid-column: 2;
}

.hint {
    color: var(--muted);
    font-size: 12.5px;
    line-height: 1.55;
}

/* Catatan penjelas setingkat halaman: batang warna di kiri dan latar redup,
   supaya terbaca sebagai keterangan dan bukan sebagai data yang ikut dibaca
   baris demi baris.

   Sasarannya `.window-body > p.hint` - anak LANGSUNG panel isi - bukan `.hint`
   begitu saja. Kelas itu dipakai 300-an kali, sebagian besar sebagai keterangan
   kecil di samping isian formulir, dan menjadikan semuanya kotak berbatang
   warna akan membuat setiap formulir penuh kotak. Dengan pembatas anak
   langsung, 164 catatan setingkat halaman berubah sekaligus tanpa satu pun
   berkas Blade disunting, sementara yang di dalam formulir tetap apa adanya. */
.window-body > p.hint {
    margin: 0 0 16px;
    padding: 12px 14px;
    border-left: 3px solid var(--brand-200);
    border-radius: 0 var(--r-sm) var(--r-sm) 0;
    background: var(--surface-alt);
    line-height: 1.65;
}

/* Contoh nomor atau kode di tengah kalimat. Dikecualikan dari isi <pre> supaya
   blok log tidak ikut berbingkai per barisnya. */
:not(pre) > code {
    padding: 1px 6px;
    border: 1px solid var(--line);
    border-radius: 4px;
    background: var(--surface);
    color: var(--ink-soft);
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: .92em;
}

/* ===== 8. Alert ===== */
.alert {
    max-width: var(--page-w);
    margin: 0 auto 14px;
    padding: 12px 16px;
    border: 1px solid;
    border-left-width: 3px;
    border-radius: var(--r-md);
    font-size: 13.5px;
    box-shadow: var(--shadow-xs);
    animation: card-in .2s ease-out both;
}

.alert-status { background: var(--ok-bg);  border-color: var(--ok-line);  border-left-color: #10b981; color: var(--ok-ink); }
.alert-error  { background: var(--bad-bg); border-color: var(--bad-line); border-left-color: #ef4444; color: var(--bad-ink); }

/* ===== 9. Tabel & DataTables =====
   Satu tampilan untuk semua tabel: kotak luar, garis antarbaris, dan garis
   antarkolom - grid penuh seperti tabel aplikasi lawas.

   `table.display` ikut disebut, bukan hanya `table.dataTable`: puluhan halaman
   memakai kelas itu untuk tabel STATIS yang tidak pernah di-init DataTables,
   sementara CSS DataTables hanya menata tabel yang sudah di-init (`.dataTable`
   dipasang oleh JS-nya). Tanpa baris ini tabel-tabel tersebut tampil tanpa
   garis sama sekali. */
table.dataTable,
table.display,
table.plain,
table.form-table,
table.dash-info {
    width: 100%;
    border-collapse: separate;
    border-spacing: 0;
    font-size: 13px;
}

/* Daftar panjang dibiarkan tanpa kotak luar, mengikuti tampilan daftar odoo:
   kotak itu sudah digambar oleh .window yang membungkusnya, dan menggambarnya
   dua kali membuat daftar terlihat terkurung. Tabel label-nilai (form-table,
   dash-info) TETAP berkotak - ia rincian sebuah data, bukan daftar, dan tanpa
   kotak ia berhamburan di tengah halaman. */
table.form-table,
table.dash-info {
    border: 1px solid var(--line);
    border-radius: var(--r-md);
    overflow: hidden;
}

table.dataTable > thead > tr > th,
table.dataTable > thead > tr > td,
table.display > thead > tr > th,
table.display > thead > tr > td,
table.plain > thead > tr > th,
table.plain > thead > tr > td {
    background: var(--surface);
    border-bottom: 1px solid var(--line-strong);
    padding: 11px 12px;
    color: var(--muted);
    font-size: 11.5px;
    font-weight: 600;
    letter-spacing: .04em;
    text-transform: uppercase;
    text-align: left;
}

table.dataTable > tbody > tr > *,
table.display > tbody > tr > *,
table.plain > tbody > tr > *,
table.form-table > tbody > tr > *,
table.dash-info > tbody > tr > * {
    padding: 11px 12px;
    text-align: left;
    vertical-align: top;
}

/* Garis antarbaris: dipasang di atas tiap baris kecuali yang pertama, supaya
   tidak menggandakan garis bawah kepala tabel maupun kotak luarnya. */
table.dataTable > tbody > tr:not(:first-child) > *,
table.display > tbody > tr:not(:first-child) > *,
table.plain > tbody > tr:not(:first-child) > *,
table.form-table > tbody > tr:not(:first-child) > *,
table.dash-info > tbody > tr:not(:first-child) > * {
    border-top: 1px solid var(--line);
}

/* Garis antarkolom HANYA untuk tabel label-nilai. Daftar panjang tidak lagi
   digaris tegak: mata sudah dituntun oleh perataan kolomnya sendiri, dan grid
   penuh membuat daftar 25 baris terbaca seperti kertas milimeter.
   Kolom terakhir dilewati karena kotak luarnya sudah menutupnya. */
table.form-table > tbody > tr > *:not(:last-child),
table.dash-info > tbody > tr > *:not(:last-child) {
    border-right: 1px solid var(--line);
}

table.dataTable > tfoot > tr > *,
table.display > tfoot > tr > *,
table.plain > tfoot > tr > * {
    background: var(--surface-alt);
    border-top: 1px solid var(--line-strong);
    padding: 9px 12px;
    font-weight: 600;
}

table.dataTable > tbody > tr:hover > *,
table.display > tbody > tr:hover > *,
table.plain > tbody > tr:hover > * { background: var(--brand-50); }

table.dataTable.row-border > tbody > tr > *,
table.dataTable.display > tbody > tr > * { border-top-color: var(--line); }

table.dataTable td.dt-right, table.dataTable th.dt-right,
td.dt-right, th.dt-right { font-variant-numeric: tabular-nums; }

table.dataTable > tbody > tr:hover > * { transition: box-shadow .1s ease; }

/* Tabel rincian berpasangan label-nilai: kolom kiri (<th> di dalam <tbody>)
   diberi latar redup supaya terbaca sebagai label, bukan sebagai data. */
table.form-table > tbody > tr > th,
table.dash-info > tbody > tr > td:first-child {
    width: 190px;
    background: var(--surface-alt);
    color: var(--muted);
    font-weight: 600;
}

/* Kontrol DataTables (cari, jumlah baris, info, halaman) */
/* Kendali DataTables berjajar MENDATAR dalam satu baris.

   Aturan global `select, input { width: 100% }` benar untuk formulir, tetapi di
   sini ia yang memecah "Tampilkan _MENU_ baris" dan "Cari:" menjadi beberapa
   baris: kendalinya memakan seluruh lebar, sehingga kata di kiri dan kanannya
   terdorong ke atas dan ke bawahnya. */
div.dt-container .dt-length,
div.dt-container .dt-search {
    display: flex;
    align-items: center;
    gap: 8px;
}

/* Selectnya bisa berada di dalam <label> ataupun bersebelahan dengannya,
   tergantung versi DataTables - keduanya dijadikan baris mendatar. */
div.dt-container .dt-length label,
div.dt-container .dt-search label {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 0;
    white-space: nowrap;
}

div.dt-container .dt-search input,
div.dt-container select.dt-input {
    width: auto;
    border: 1px solid var(--line-strong);
    border-radius: 6px;
    padding: 6px 10px;
    font-size: 13px;
}

div.dt-container .dt-search input { min-width: 210px; padding: 6px 12px; }

div.dt-container .dt-search input:focus,
div.dt-container select.dt-input:focus {
    outline: none;
    border-color: var(--brand-500);
    box-shadow: var(--ring);
}

div.dt-container .dt-search, div.dt-container .dt-length { color: var(--muted); font-size: 13px; }
div.dt-container .dt-info { color: var(--muted); font-size: 12.5px; padding-top: 12px; }

div.dt-container .dt-layout-row { margin-bottom: 4px; }

div.dt-container .dt-paging { padding-top: 10px; }

div.dt-container .dt-paging .dt-paging-button {
    border: 1px solid transparent;
    border-radius: var(--r-sm);
    background: transparent;
    color: var(--ink-soft) !important;
    font-size: 13px;
    min-width: 32px;
    padding: 5px 10px;
    margin: 0 2px;
    transition: background-color .12s ease, color .12s ease, border-color .12s ease;
}

div.dt-container .dt-paging .dt-paging-button:hover {
    background: var(--surface-alt) !important;
    border-color: var(--line);
    color: var(--ink) !important;
}

div.dt-container .dt-paging .dt-paging-button.current,
div.dt-container .dt-paging .dt-paging-button.current:hover {
    background: var(--brand-600) !important;
    border-color: var(--brand-600);
    color: #fff !important;
    font-weight: 600;
}

div.dt-container .dt-paging .dt-paging-button.disabled,
div.dt-container .dt-paging .dt-paging-button.disabled:hover {
    background: transparent !important;
    border-color: transparent;
    color: var(--muted-soft) !important;
}

div.dt-container .dt-processing {
    border: 1px solid var(--line);
    border-radius: var(--r-md);
    box-shadow: var(--shadow-md);
    background: var(--surface);
    color: var(--ink-soft);
    font-weight: 500;
}

/* Tabel sederhana non-DataTables: seluruh tampilannya kini satu tempat dengan
   tabel lain di bagian 9, supaya tidak ada dua gaya tabel yang berbeda. */

.badge {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 2px 10px;
    border-radius: var(--r-pill);
    border: 1px solid transparent;
    font-size: 11.5px;
    font-weight: 600;
    line-height: 1.6;
    white-space: nowrap;
}

.badge-on  { background: var(--ok-bg);  border-color: var(--ok-line);  color: var(--ok-ink); }
.badge-off { background: #f1f5f9;       border-color: #e2e8f0;         color: var(--muted); }
.badge-bad { background: var(--bad-bg); border-color: var(--bad-line); color: var(--bad-ink); }

.actions-cell { display: flex; gap: 6px; flex-wrap: wrap; }

/* Kode OTP di Setup > Monitor OTP. Dibuat besar & berjarak supaya petugas
   bisa membacakannya lewat telepon tanpa salah baca. */
.otp-kode {
    display: inline-block;
    font-family: ui-monospace, "Cascadia Mono", "Consolas", monospace;
    font-size: 20px;
    font-weight: 700;
    letter-spacing: 4px;
    color: var(--brand-700);
    background: var(--brand-50);
    border: 1px solid var(--brand-200);
    border-radius: var(--r-sm);
    padding: 2px 10px;
    cursor: pointer;
    user-select: all;
}

.otp-kode:hover { background: var(--brand-100); }
.otp-kode.tersalin { background: var(--ok-bg); border-color: var(--ok-line); color: var(--ok-ink); }
.otp-sisa { font-variant-numeric: tabular-nums; }

/* ===== 10. Halaman login (gaya odoo) ===== */
/* Odoo meletakkan kartu login di atas bidang polos berwarna netral, tanpa
   gradasi dan tanpa kepala kartu berwarna. Warnanya baru muncul di tempat yang
   memang perlu ditekan - tombol dan cincin fokus - dan di sinilah warna biru
   khas koperasi ini menggantikan warna plum milik odoo.

   Latarnya memakai --canvas, ground yang sama dengan seluruh halaman lain,
   sehingga masuk aplikasi tidak lagi terasa seperti berpindah ke aplikasi lain
   yang kebetulan berwarna biru tua. */
body.login-page {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px;
    background: var(--canvas);
}

/* Kartu dan keterangan kakinya diperlakukan sebagai satu tumpukan supaya
   keduanya ikut tertengahkan bersama, bukan hanya kartunya. */
.login-bingkai {
    width: 380px;
    max-width: 100%;
    animation: login-in .28s ease-out both;
}

@keyframes login-in {
    from { opacity: 0; transform: translateY(12px) scale(.985); }
    to   { opacity: 1; transform: none; }
}

.login-dialog {
    padding: 30px 30px 28px;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--r-md);
    box-shadow: var(--shadow-md);
}

/* --- Identitas koperasi di kepala kartu --------------------------------- */
.login-koperasi { text-align: center; margin-bottom: 26px; }

/* Lambang koperasi. Latarnya transparan dan kartu login berlatar putih, jadi
   tidak perlu sel putih - berbeda dengan .brand-mark di strip tab yang biru tua. */
.login-koperasi .logo {
    display: block;
    width: 60px;
    height: 60px;
    margin: 0 auto 14px;
    object-fit: contain;
}

.login-koperasi .nama {
    font-size: 17px;
    font-weight: 650;
    letter-spacing: -.02em;
    line-height: 1.3;
}

.login-koperasi .kota {
    margin-top: 3px;
    color: var(--muted);
    font-size: 12px;
    letter-spacing: .06em;
    text-transform: uppercase;
}

/* --- Isian ------------------------------------------------------------- */
/* Label di ATAS isiannya, bukan di sampingnya seperti .form-grid milik halaman
   dalam. Formulir ini hanya dua baris dan selebar 320px; label di samping akan
   memakan sepertiga lebarnya dan menyisakan kotak ketik yang sempit. */
.login-bidang { margin-bottom: 16px; }

.login-bidang label {
    display: block;
    margin-bottom: 6px;
    color: var(--ink-soft);
    font-size: 12.5px;
    font-weight: 600;
}

.login-bidang input { padding: 10px 12px; font-size: 14px; }

.login-bidang .error-text {
    display: block;
    grid-column: auto;
    margin-top: 5px;
}

/* Satu-satunya bidang berwarna penuh di halaman ini, dan memang satu-satunya
   yang harus ditekan. */
.login-kirim {
    width: 100%;
    justify-content: center;
    margin-top: 6px;
    padding: 11px 16px;
    font-size: 14px;
}

/* --- Keterangan kaki ---------------------------------------------------- */
/* Sejajar dengan baris "Powered by Odoo" di bawah kartu mereka. Isinya di sini
   dibuat berguna: nasabah yang tersesat ke alamat ini langsung tahu halaman
   ini bukan untuk mereka, tanpa harus mencoba masuk lebih dulu. */
.login-kaki {
    margin: 18px 0 0;
    text-align: center;
    color: var(--muted);
    font-size: 12px;
    line-height: 1.6;
}

/* ===== 11. Log ===== */
pre.log {
    background: #0f172a;
    color: #cbd5e1;
    border-radius: var(--r-md);
    padding: 14px 16px;
    overflow: auto;
    max-height: 65vh;
    font-family: "Cascadia Code", Consolas, "SF Mono", Menlo, monospace;
    font-size: 12px;
    line-height: 1.6;
    margin: 0;
}

/* ===== 12. Beranda (gaya odoo) ===== */
/* Tanpa bingkai jendela, berlatar putih dan lapang. Isinya sedikit dan memang
   seharusnya begitu - pekerjaan sebenarnya ada di balik menu. Karena itu
   halamannya dibatasi selebar 900px lalu ditengahkan: isi yang sedikit dan
   dibentangkan selebar layar 1920px terbaca sebagai halaman yang gagal dimuat,
   bukan sebagai halaman yang memang ringkas. */
.beranda {
    max-width: 900px;
    margin: 0 auto;
    padding: 10px 4px 0;
    font-family: var(--font-odoo);
}

/* --- Pita sambutan ------------------------------------------------------ */
/* Diberi latar bertint supaya bagian atas halaman punya bobot. Tanpa itu,
   halaman seringkas ini hanya berupa beberapa baris teks yang menggantung di
   sudut kiri atas bidang putih yang sangat luas. */
.beranda-sambut {
    display: flex;
    align-items: center;
    gap: 18px;
    flex-wrap: wrap;
    margin-bottom: 22px;
    padding: 24px 26px;
    border: 1px solid var(--line);
    border-radius: var(--r-lg);
    background: linear-gradient(115deg, #f2f6ff 0%, #f4fbfa 55%, #faf6ff 100%);
}

.beranda-sambut .avatar-lg {
    display: grid;
    place-items: center;
    width: 54px;
    height: 54px;
    flex: 0 0 auto;
    border-radius: 50%;
    background: linear-gradient(135deg, var(--brand-500), var(--brand-900));
    box-shadow: 0 5px 14px rgba(29, 78, 216, .22);
    color: #fff;
    font-size: 22px;
    font-weight: 700;
}

.beranda-sambut-teks { flex: 1 1 240px; min-width: 0; }

.beranda-sambut .kicker {
    margin: 0 0 3px;
    color: var(--brand-700);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .09em;
    text-transform: uppercase;
}

.beranda-sambut .who {
    margin: 0;
    font-size: 26px;
    font-weight: 600;
    letter-spacing: -.024em;
    line-height: 1.2;
}

.beranda-sambut .hari {
    margin: 5px 0 0;
    color: var(--muted);
    font-size: 13px;
}

/* Tombol pintasan: rupanya sengaja seperti kotak pencarian, bukan seperti
   tombol aksi - yang dibukanya memang kotak ketik, dan menyamarkannya sebagai
   tombol biasa membuat orang tidak menduga bisa langsung mengetik. */
.beranda-cari {
    display: flex;
    align-items: center;
    gap: 9px;
    flex: 0 0 auto;
    padding: 9px 12px;
    border: 1px solid var(--line-strong);
    border-radius: var(--r-pill);
    background: var(--surface);
    color: var(--muted);
    font-family: inherit;
    font-size: 13px;
    cursor: pointer;
    transition: border-color .12s ease, color .12s ease, box-shadow .12s ease;
}

.beranda-cari:hover {
    border-color: var(--brand-500);
    color: var(--brand-700);
    box-shadow: var(--shadow-sm);
}

.beranda-cari:focus-visible { outline: none; box-shadow: var(--ring); }
.beranda-cari .ico { color: var(--brand-600); }
.beranda-cari .tombol-kunci { display: flex; gap: 3px; }

.beranda-cari kbd {
    padding: 1px 5px;
    border: 1px solid var(--line-strong);
    border-bottom-width: 2px;
    border-radius: 4px;
    background: var(--surface-alt);
    color: var(--muted);
    font-family: inherit;
    font-size: 10.5px;
    font-weight: 600;
}

/* --- Keterangan kerja --------------------------------------------------- */
/* Empat kartu setara, bukan deretan yang dipisah garis: setelah petak modul
   dihilangkan, merekalah satu-satunya isi halaman ini, dan isi tunggal yang
   tanpa bentuk terbaca seperti sisa dari sesuatu yang belum selesai. */
.beranda-fakta {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(196px, 1fr));
    gap: 12px;
    margin: 0;
    padding: 0;
}

.beranda-fakta > div {
    padding: 15px 16px 16px;
    border: 1px solid var(--line);
    border-radius: var(--r-md);
    background: var(--surface);
}

.beranda-fakta dt {
    display: flex;
    align-items: center;
    gap: 7px;
    margin-bottom: 7px;
    color: var(--muted);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
}

.beranda-fakta dd {
    margin: 0;
    color: var(--ink);
    font-size: 16px;
    font-weight: 600;
    letter-spacing: -.014em;
    line-height: 1.35;
    word-break: break-word;
}

/* Ikonnya berwarna-warni mengikuti palet yang sama dengan ikon tab di header
   dan bergilir mengikuti urutan kartu - warnanya yang membedakan keempatnya
   sekilas, sebelum satu hurufnya pun terbaca. */
.beranda-fakta > div:nth-child(4n+1) dt .ico { color: #1d4ed8; }
.beranda-fakta > div:nth-child(4n+2) dt .ico { color: #00a09d; }
.beranda-fakta > div:nth-child(4n+3) dt .ico { color: #b45309; }
.beranda-fakta > div:nth-child(4n+4) dt .ico { color: #7c3aed; }

/* --- Keterangan bawah --------------------------------------------------- */
/* Tanpa bingkai dan tanpa latar biru: ia catatan kaki, dan kotak biru penuh
   membuatnya bersaing perhatian dengan keterangan kerja di atasnya - padahal
   yang satu perlu dibaca tiap hari, yang ini cukup sekali. */
.dash-note {
    display: flex;
    gap: 9px;
    align-items: flex-start;
    max-width: 640px;
    margin: 22px 0 0;
    padding: 0 2px;
    color: var(--muted);
    font-size: 12.5px;
    line-height: 1.6;
}

.dash-note .ico { color: var(--brand-500); margin-top: 2px; }

/* Tabel info lama (masih dipakai di halaman Help > Informasi Program) -
   tampilannya ikut tabel lain di bagian 9; lebarnya dibatasi karena isinya
   hanya label & nilai. */
.dash-info { max-width: 620px; }

/* ===== 12b. Kotak pintasan halaman (Ctrl+K / F2) ===== */
.petunjuk-pintasan { display: flex; align-items: center; gap: 4px; opacity: .85; }

.pintasan {
    position: fixed;
    inset: 0;
    z-index: 99000;
    display: flex;
    justify-content: center;
    align-items: flex-start;
    padding: 12vh 16px 16px;
    background: rgba(15, 23, 42, .38);
    backdrop-filter: blur(3px);
    -webkit-backdrop-filter: blur(3px);
}

.pintasan[hidden] { display: none; }

.pintasan-kotak {
    width: 100%;
    max-width: 560px;
    max-height: 70vh;
    display: flex;
    flex-direction: column;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--r-lg);
    box-shadow: var(--shadow-lg);
    overflow: hidden;
    animation: card-in .16s ease-out both;
}

.pintasan-cari {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 12px 14px;
    border-bottom: 1px solid var(--line);
}

.pintasan-cari .ico { color: var(--muted); flex: 0 0 auto; }

.pintasan-cari input {
    flex: 1 1 auto;
    min-width: 0;
    border: 0;
    background: none;
    color: var(--ink);
    font-family: inherit;
    font-size: 14.5px;
}

.pintasan-cari input:focus { outline: none; }

.pintasan-hasil {
    list-style: none;
    margin: 0;
    padding: 6px;
    overflow-y: auto;
}

.pintasan-hasil li {
    display: flex;
    align-items: baseline;
    gap: 12px;
    padding: 8px 12px;
    border-radius: var(--r-sm);
    cursor: pointer;
    font-size: 13.5px;
    color: var(--ink-soft);
}

.pintasan-hasil li.terpilih { background: var(--brand-600); color: #fff; }

.pintasan-hasil .kode {
    flex: 0 0 58px;
    color: var(--brand-700);
    font-size: 11.5px;
    font-weight: 700;
    letter-spacing: .06em;
    font-variant-numeric: tabular-nums;
}

.pintasan-hasil li.terpilih .kode { color: #fff; }

.pintasan-hasil .jalur { margin-left: auto; padding-left: 14px; color: var(--muted-soft); font-size: 11.5px; }
.pintasan-hasil li.terpilih .jalur { color: rgba(255, 255, 255, .8); }

.pintasan-kosong { padding: 18px 14px; color: var(--muted); font-size: 13px; text-align: center; }

.pintasan-kaki {
    display: flex;
    flex-wrap: wrap;
    gap: 6px 16px;
    padding: 9px 14px;
    border-top: 1px solid var(--line);
    background: var(--surface-alt);
    color: var(--muted);
    font-size: 11.5px;
}

.pintasan kbd,
.statusbar kbd {
    display: inline-block;
    min-width: 18px;
    padding: 1px 5px;
    border: 1px solid var(--line-strong);
    border-bottom-width: 2px;
    border-radius: 4px;
    background: var(--surface);
    color: var(--ink-soft);
    font-family: inherit;
    font-size: 10.5px;
    font-weight: 600;
    text-align: center;
}

.statusbar kbd { min-width: 0; padding: 0 4px; border-bottom-width: 1px; font-size: 10px; }

/* ===== 13. Overlay proses (mengunci layar selama aksi berjalan) ===== */
#app-loading {
    display: none;
    position: fixed;
    inset: 0;
    z-index: 100000;
    background: rgba(15, 23, 42, .38);
    backdrop-filter: blur(3px);
    -webkit-backdrop-filter: blur(3px);
    cursor: progress;
}

#app-loading.is-visible {
    display: flex;
    align-items: center;
    justify-content: center;
}

/* Sesaat setelah aksi dimulai layar sudah terkunci, tetapi kotaknya belum
   ditampilkan supaya aksi yang selesai cepat tidak terlihat berkedip. */
#app-loading.is-pending {
    background: transparent;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
}

#app-loading.is-pending .loading-box { visibility: hidden; }

#app-loading .loading-box {
    width: 330px;
    max-width: 90vw;
    background: var(--surface);
    border-radius: var(--r-lg);
    box-shadow: var(--shadow-lg);
    overflow: hidden;
    animation: card-in .16s ease-out both;
}

#app-loading .window-title {
    background: var(--surface-alt);
    font-size: 13px;
    padding: 11px 16px;
}

#app-loading .loading-body {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 18px 16px;
}

#app-loading .spinner {
    flex: 0 0 auto;
    width: 26px;
    height: 26px;
    border: 3px solid var(--brand-100);
    border-top-color: var(--brand-600);
    border-radius: 50%;
    animation: app-spin .8s linear infinite;
}

@keyframes app-spin {
    to { transform: rotate(360deg); }
}

#app-loading .loading-text { font-weight: 600; font-size: 13.5px; }

#app-loading .loading-note {
    margin-top: 3px;
    color: var(--muted);
    font-size: 12px;
}

/* ===== 14. Layar sempit ===== */
@media (max-width: 820px) {
    :root { --form-label-w: 100%; }

    .content { padding: 16px 12px 26px; }
    .window-body { padding: 14px; }

    .form-grid { grid-template-columns: 1fr; gap: 4px; }
    .form-grid label { text-align: left; margin-top: 8px; }
    .form-grid .full, .error-text { grid-column: 1; }
    .form-grid + .form-actions { margin-left: 0; }

    /* Layar sempit: strip tab digeser mendatar, dan lambangnya ikut tergeser
       bersama tab - ia hanya penanda, bukan tombol yang harus selalu ada. */
    .ribbon-tabs { min-height: 48px; padding: 0 8px; }
    .ribbon .brand { margin-right: 8px; padding: 4px 6px; }
    .ribbon-tab { padding: 0 12px; }
    /* Tidak ada ruang sisa untuk dibagi di sini - sisi kiri dan kanan cukup
       selebar isinya, dan tabnya digeser mendatar. */
    .ribbon-sisi { flex: 0 0 auto; }
    /* Panel melayang bisa lebih tinggi dari layarnya sendiri di sini; ia
       digulung ke dalam, bukan dibiarkan menjulur ke luar jendela. */
    .ribbon-panel { max-height: 72vh; overflow-y: auto; padding: 14px 12px 18px; }
    /* Lajurnya dikurangi, bukan dibiarkan tiga. Petak tiga lajur berlebar isi
       tetap ~930px sekalipun layarnya 820px - dan karena lajur `max-content`
       tidak menyusut, yang terjadi bukan melipat melainkan panel yang harus
       digeser MENDATAR untuk membaca lajur ketiga. */
    .ribbon-panel-isi { grid-template-columns: repeat(2, max-content); gap: 14px 20px; }
    /* Beranda: sambutan menumpuk, dan tombol pencarian pindah ke baris
       sendiri selebar penuh - di lebar ini ia tidak muat di samping nama. */
    .beranda-sambut { padding: 18px; gap: 14px; }
    .beranda-sambut .who { font-size: 21px; }
    .beranda-cari { flex: 1 0 100%; justify-content: center; }
    .beranda-fakta { grid-template-columns: repeat(auto-fit, minmax(148px, 1fr)); gap: 10px; }
    /* Kartu login menyempit mengikuti layar; jarak dalamnya ikut dikurangi
       supaya isian tidak terjepit di antara dua tepi. */
    .login-dialog { padding: 24px 20px 22px; }

    .statusbar { overflow-x: auto; padding: 7px 12px; }
    /* Tidak ada papan ketik untuk ditekan; kodenya tetap tampil di menu. */
    .petunjuk-pintasan { display: none; }
}

/* Layar HP: dua lajur pun tidak muat (2 x ~285px + jarak = ~590px), jadi
   panelnya menjadi satu lajur dan digulung tegak - arah gulung yang memang
   sudah dipakai orang, bukan mendatar. */
@media (max-width: 620px) {
    .ribbon-panel-isi { grid-template-columns: max-content; }
}

/* ===== 15. Preferensi gerakan ===== */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: .001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .001ms !important;
    }

    #app-loading .spinner { animation-duration: 2.4s !important; animation-iteration-count: infinite !important; }
}

/* ===== 16. Cetak ===== */
@media print {
    body { background: #fff; }

    .titlebar, .menubar, .statusbar, .breadcrumb, .no-print, .alert, #app-loading { display: none !important; }

    .app { height: auto; display: block; }
    .content { overflow: visible; padding: 0; }

    .window {
        border: none;
        border-radius: 0;
        box-shadow: none;
        max-width: none;
        margin: 0;
        animation: none;
    }

    .window-title { background: none; border-bottom: 1px solid #999; padding: 0 0 6px; }
    .window-body { padding: 0; overflow: visible; background: none; border: none; }
}
