/* =====================================================================
   SIPASI — Elegant Deep Purple Theme
   Layer di atas volt.min.css. Semua warna diturunkan dari token di :root
   supaya gampang di-tuning satu tempat.

   Disusun mengikuti pola tema SIPeMa (sipema-blue.css) pada aplikasi
   abdimas, dengan palet ungu tua dan tambahan penyesuaian untuk markup
   SIPASI yang banyak memakai lebar `style="width: NNrem"` inline.
   ===================================================================== */

:root {
    /* Brand — ungu tua. Nama token sengaja netral warna supaya menukar palet
       cukup di blok ini saja, tanpa mengganti nama di mana-mana.

       Dibuat lebih tua DAN lebih kalem: kejenuhannya diturunkan dari 81%
       ke 42%. Ungu terang berkroma tinggi (#9333EA sebelumnya) yang bikin
       mata cepat lelah, bukan sekadar terangnya. Efek sampingnya kontras
       ikut naik — tombol 7,17:1 terhadap putih (dari 5,38), teks tautan
       8,76:1 (dari 6,98). Shade 400 ke atas hanya untuk aksen dan ikon,
       tidak pernah untuk teks. */
    --sp-brand-975: #281533;
    --sp-brand-950: #331B41;
    --sp-brand-900: #442357;
    --sp-brand-800: #552C6D;
    --sp-brand-700: #663582;
    --sp-brand-600: #773E98;
    --sp-brand-500: #9254B6;
    --sp-brand-400: #AD80C6;
    --sp-brand-300: #CCB5D9;
    --sp-brand-100: #EDE3F2;
    --sp-brand-50:  #F7F2FA;

    /* Netral keunguan, ikut diredam supaya tidak beradu dengan isi */
    --sp-bg:        #F7F5F9;
    --sp-surface:   #FFFFFF;
    --sp-border:    #E7E1EB;
    --sp-text:      #1E1A22;
    --sp-text-soft: #625A6A;
    --sp-muted:     #948CA0;

    /* Status sengaja tidak ikut berubah: hijau/kuning/merah/teal punya arti
       yang sudah dikenal pengguna, dan tetap mudah dibedakan dari warna
       utama karena warna utamanya bukan salah satu dari keempatnya. */
    --sp-success: #15803D;
    --sp-warning: #E9A23B;
    --sp-danger:  #DC3545;
    --sp-info:    #0E9AA7;

    /* Elevasi & bentuk */
    --sp-radius:    .75rem;
    --sp-radius-sm: .5rem;
    --sp-shadow-xs: 0 1px 2px rgba(51, 27, 65, .06);
    --sp-shadow-sm: 0 2px 8px rgba(51, 27, 65, .07);
    --sp-shadow-md: 0 6px 20px rgba(51, 27, 65, .09);
    --sp-shadow-lg: 0 14px 40px rgba(51, 27, 65, .16);
    --sp-ring:      0 0 0 .2rem rgba(119, 62, 152, .18);
}




/* ---------------------------------------------------------------------
   Global
   --------------------------------------------------------------------- */

body {
    background-color: var(--sp-bg);
    color: var(--sp-text);
    font-family: Inter, "Segoe UI", system-ui, -apple-system, "Helvetica Neue", Arial, sans-serif;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6 {
    color: var(--sp-brand-900);
    font-weight: 600;
    letter-spacing: -.01em;
}

a { color: var(--sp-brand-700); }
a:hover { color: var(--sp-brand-700); }

.text-primary { color: var(--sp-brand-700) !important; }
.text-gray-900, .text-dark { color: var(--sp-text) !important; }
.text-gray-500, .text-gray-600, .text-muted { color: var(--sp-text-soft) !important; }

.bg-primary { background-color: var(--sp-brand-600) !important; }
.bg-gray-800 { background-color: var(--sp-brand-900) !important; }
.bg-soft, .bg-soft-brand { background-color: var(--sp-brand-50) !important; }

.shadow, .shadow-sm { box-shadow: var(--sp-shadow-sm) !important; }
.shadow-lg { box-shadow: var(--sp-shadow-md) !important; }

::selection { background: var(--sp-brand-100); color: var(--sp-brand-900); }

/* Scrollbar halus */
* { scrollbar-width: thin; scrollbar-color: #D0BEDA transparent; }
::-webkit-scrollbar { width: 8px; height: 8px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: #D0BEDA; border-radius: 8px; }
::-webkit-scrollbar-thumb:hover { background: var(--sp-brand-400); }

/* ---------------------------------------------------------------------
   Sidebar
   --------------------------------------------------------------------- */

.sidebar {
    background: linear-gradient(180deg, var(--sp-brand-975) 0%, var(--sp-brand-950) 55%, var(--sp-brand-900) 100%) !important;
    box-shadow: 2px 0 24px rgba(51, 27, 65, .18);
    border-right: 1px solid rgba(255, 255, 255, .05);
}

.sidebar .sidebar-inner { padding-bottom: 2rem; }

.sidebar .nav-item { margin-bottom: .15rem; }

.sidebar .nav-link,
.sidebar .nav-item .nav-link {
    color: #DED1E6;
    font-size: .9rem;
    font-weight: 500;
    border-radius: var(--sp-radius-sm);
    padding: .55rem .8rem;
    transition: background-color .18s ease, color .18s ease, box-shadow .18s ease;
}

.sidebar .nav-link .sidebar-icon,
.sidebar .nav-link .sidebar-icon svg { color: #C1ADCD; transition: color .18s ease; }

.sidebar .nav-item .nav-link:hover,
.sidebar .nav-link:hover {
    background-color: rgba(173, 128, 198, .14);
    color: #FFFFFF;
}

.sidebar .nav-link:hover .sidebar-icon,
.sidebar .nav-link:hover .sidebar-icon svg { color: var(--sp-brand-400); }

.sidebar .nav-item.active > .nav-link,
.sidebar .nav-link.active {
    /* 700->600, bukan 600->500: pada shade 500 teks putih tidak pernah
       cukup kontras untuk teks berukuran normal. Pada 600 (#773E98) 7,17:1. */
    background: linear-gradient(90deg, var(--sp-brand-700) 0%, var(--sp-brand-600) 100%);
    color: #FFFFFF;
    font-weight: 600;
    box-shadow: 0 6px 16px rgba(119, 62, 152, .35);
}

.sidebar .nav-item.active > .nav-link .sidebar-icon,
.sidebar .nav-item.active > .nav-link .sidebar-icon svg { color: #FFFFFF; }

/* Submenu bertingkat (pemilih Role) */
.sidebar .multi-level {
    margin: .15rem 0 .35rem .55rem;
    padding-left: .55rem;
    border-left: 1px solid rgba(255, 255, 255, .12);
}

.sidebar .multi-level .nav-link {
    font-size: .84rem;
    color: #CBB9D5;
    padding: .4rem .7rem;
}

.sidebar .multi-level .nav-item.active > .nav-link {
    background: rgba(119, 62, 152, .9);
    box-shadow: none;
}

.sidebar .link-arrow svg { opacity: .7; }

.sidebar .user-card { border-bottom-color: rgba(255, 255, 255, .1); }

.sidebar-heading {
    color: #CABBD3;
    letter-spacing: .08em;
    font-weight: 600;
}

/* ---------------------------------------------------------------------
   Navbar atas
   --------------------------------------------------------------------- */

.navbar-dashboard {
    background: rgba(255, 255, 255, .94);
    -webkit-backdrop-filter: saturate(180%) blur(12px);
    backdrop-filter: saturate(180%) blur(12px);
    border: 1px solid var(--sp-border);
    border-radius: var(--sp-radius);
    box-shadow: var(--sp-shadow-sm);
    margin-top: .85rem;
    /* !important supaya menang atas kelas ps-0 / pe-2 / pb-0 di markup
       navbar, kalau tidak tombol toggle menempel persis di tepi bar. */
    padding: .5rem .9rem !important;
    position: sticky;
    top: .5rem;
    z-index: 60;
}

.navbar-dashboard .sidebar-text {
    color: var(--sp-brand-900);
    font-weight: 600;
    font-size: .98rem;
    letter-spacing: -.01em;
}

.navbar-dashboard .sidebar-toggle {
    color: var(--sp-brand-700);
    background: var(--sp-brand-50);
    border-radius: var(--sp-radius-sm);
    width: 2.25rem; height: 2.25rem;
    padding: 0;
    flex: 0 0 auto;
    transition: background-color .18s ease, color .18s ease;
}

/* .d-lg-inline-block memakai !important, jadi perlu !important juga supaya
   ikonnya bisa ditengahkan pakai flex. Wajib dikurung media query lg: tanpa
   itu selector ini (0,2,0) mengalahkan .d-none (0,1,0) dan tombolnya ikut
   muncul di mobile, padahal di sana yang dipakai .navbar-toggler. */
@media (min-width: 992px) {
    .navbar-dashboard .sidebar-toggle {
        display: inline-flex !important;
        align-items: center;
        justify-content: center;
    }
}

.navbar-dashboard .sidebar-toggle .toggle-icon {
    display: block;
    width: 1.15rem;
    height: 1.15rem;
}

.navbar-dashboard .sidebar-toggle:hover,
.navbar-dashboard .sidebar-toggle:focus {
    background: var(--sp-brand-100);
    color: var(--sp-brand-700);
    box-shadow: none;
}

.navbar-dashboard .nav-link { color: var(--sp-text) !important; }

.navbar-dashboard .avatar {
    border: 2px solid var(--sp-brand-100);
    box-shadow: var(--sp-shadow-xs);
    /* Tanpa ini avatar tergencet jadi lonjong di layar sempit: lebarnya
       diatur inline (50px) tapi flex boleh menyusutkannya. */
    flex-shrink: 0;
}

/* Navbar mobile (di luar .content) */
.navbar-theme-primary:not(.headroom) {
    background: linear-gradient(90deg, var(--sp-brand-975) 0%, var(--sp-brand-900) 100%) !important;
}

/* ---------------------------------------------------------------------
   Card
   --------------------------------------------------------------------- */

.card {
    background-color: var(--sp-surface);
    border: 1px solid var(--sp-border);
    border-radius: var(--sp-radius);
    box-shadow: var(--sp-shadow-sm);
    transition: box-shadow .2s ease;
    /* Banyak kartu SIPASI dipatok `style="width: NNrem"`; ini membuatnya
       tetap menyusut di layar sempit tanpa menyentuh markup-nya. */
    max-width: 100%;
}

.card.shadow:hover, .card.shadow-lg:hover { box-shadow: var(--sp-shadow-md); }

/* Volt menulis `.card .card-header { background: 0 0 }` (0,2,0) yang
   mengalahkan `.card-header` (0,1,0); selektornya disamakan agar menang. */
.card-header,
.card .card-header {
    background-color: var(--sp-surface);
    border-bottom: 1px solid var(--sp-border);
    color: var(--sp-brand-900);
    font-weight: 600;
    border-top-left-radius: var(--sp-radius);
    border-top-right-radius: var(--sp-radius);
    padding: 1rem 1.5rem;
}

.card-footer,
.card .card-footer {
    background-color: var(--sp-surface);
    border-top: 1px solid var(--sp-border);
    border-bottom-left-radius: var(--sp-radius);
    border-bottom-right-radius: var(--sp-radius);
}

.card .card-title { color: var(--sp-brand-900); }

/* ---------------------------------------------------------------------
   Tombol
   --------------------------------------------------------------------- */

.btn {
    border-radius: var(--sp-radius-sm);
    font-weight: 500;
    transition: background-color .18s ease, border-color .18s ease, box-shadow .18s ease, transform .12s ease;
}

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

.btn-primary,
.btn-secondary {
    background: linear-gradient(180deg, var(--sp-brand-600) 0%, var(--sp-brand-700) 100%);
    border-color: var(--sp-brand-700);
    color: #fff;
    box-shadow: 0 2px 6px rgba(102, 53, 130, .25);
}

.btn-primary:hover, .btn-primary:focus,
.btn-secondary:hover, .btn-secondary:focus {
    background: linear-gradient(180deg, var(--sp-brand-700) 0%, var(--sp-brand-800) 100%);
    border-color: var(--sp-brand-700);
    color: #fff;
    box-shadow: 0 4px 12px rgba(102, 53, 130, .32);
}

.btn-check:focus + .btn-primary, .btn-primary:focus,
.btn-check:focus + .btn-secondary, .btn-secondary:focus { box-shadow: var(--sp-ring); }

/* Tombol gelap bawaan Volt (dipakai tombol Sign in) ikut jadi ungu */
.btn-gray-800 {
    background: linear-gradient(180deg, var(--sp-brand-600) 0%, var(--sp-brand-700) 100%);
    border-color: var(--sp-brand-700);
    color: #fff;
}
.btn-gray-800:hover, .btn-gray-800:focus {
    background: linear-gradient(180deg, var(--sp-brand-700) 0%, var(--sp-brand-800) 100%);
    border-color: var(--sp-brand-700);
    color: #fff;
}

.btn-outline-primary {
    color: var(--sp-brand-700);
    border-color: var(--sp-brand-500);
    background: transparent;
}
.btn-outline-primary:hover {
    background: var(--sp-brand-600);
    border-color: var(--sp-brand-600);
    color: #fff;
}

.btn-info { background-color: var(--sp-info); border-color: var(--sp-info); color: #fff; }
.btn-info:hover { background-color: #0B7F8A; border-color: #0B7F8A; color: #fff; }

.btn-success { background-color: var(--sp-success); border-color: var(--sp-success); color: #fff; }
.btn-success:hover { background-color: #126B34; border-color: #126B34; color: #fff; }

.btn-warning { background-color: var(--sp-warning); border-color: var(--sp-warning); color: #fff; }
.btn-warning:hover { background-color: #D08D28; border-color: #D08D28; color: #fff; }

.btn-danger { background-color: var(--sp-danger); border-color: var(--sp-danger); }

/* Volt menulis keadaan nonaktif sebagai `.btn-info:disabled` (0,2,0), yang
   mengalahkan `.btn-info` (0,1,0) milik tema ini — tanpa blok berikut,
   tombol yang di-disable kembali ke biru bawaan Volt. */
.btn-primary.disabled, .btn-primary:disabled,
.btn-secondary.disabled, .btn-secondary:disabled,
.btn-gray-800.disabled, .btn-gray-800:disabled {
    background: var(--sp-brand-600);
    border-color: var(--sp-brand-600);
    color: #fff;
}

.btn-info.disabled, .btn-info:disabled {
    background-color: var(--sp-info);
    border-color: var(--sp-info);
    color: #fff;
}

.btn-success.disabled, .btn-success:disabled {
    background-color: var(--sp-success);
    border-color: var(--sp-success);
    color: #fff;
}

.btn-warning.disabled, .btn-warning:disabled {
    background-color: var(--sp-warning);
    border-color: var(--sp-warning);
    color: #fff;
}

.btn-outline-primary.disabled, .btn-outline-primary:disabled {
    color: var(--sp-brand-700);
    border-color: var(--sp-brand-500);
}

.btn-light, .btn-outline-light {
    background-color: #fff;
    border-color: var(--sp-border);
    color: var(--sp-text);
}
.btn-light:hover, .btn-outline-light:hover {
    background-color: var(--sp-brand-50);
    border-color: var(--sp-brand-100);
    color: var(--sp-brand-700);
}

/* ---------------------------------------------------------------------
   Tabel
   --------------------------------------------------------------------- */

.table {
    color: var(--sp-text);
    border-color: var(--sp-border);
}

.table thead th,
.table > thead > tr > th {
    background-color: var(--sp-brand-50);
    color: var(--sp-brand-800);
    font-size: .74rem;
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
    border-bottom: 1px solid var(--sp-border);
    vertical-align: middle;
}

/* 45 halaman memakai <thead class="thead-light">. Aturan Volt untuk kelas
   itu (`.table .thead-light th`, 0,2,1) mengalahkan `.table thead th`
   (0,1,1) di atas, jadi warnanya harus dinyatakan ulang di sini. */
.table .thead-light th,
.table .thead-dark th {
    background-color: var(--sp-brand-50);
    color: var(--sp-brand-800);
}

.table > :not(caption) > * > * { border-bottom-color: #F3EFF5; }

.table > :not(caption) > * > th,
.table > :not(caption) > * > td { padding: .85rem .9rem; }

.table tbody tr { transition: background-color .15s ease; }
.table-hover > tbody > tr:hover,
.table-hover tbody tr:hover > * { background-color: var(--sp-brand-50); color: var(--sp-text); }

.table-striped > tbody > tr:nth-of-type(odd) > * { background-color: #FBFAFC; color: var(--sp-text); }

/* Card yang membungkus tabel: sudut tabel ikut membulat */
.card > .table-responsive:last-child,
.card > .table:last-child {
    border-bottom-left-radius: var(--sp-radius);
    border-bottom-right-radius: var(--sp-radius);
    overflow: hidden;
}

/* Kolom/heading sticky yang sudah dipakai di beberapa halaman (my_css.css) */
.sticky-column { background-color: #fff; box-shadow: 2px 0 6px rgba(51, 27, 65, .08); }
.sticky-header { background-color: var(--sp-brand-50); box-shadow: 0 2px 6px rgba(51, 27, 65, .08); }

/* Warna baris berstatus: versi lebih lembut dan selaras dengan tema.
   Warna `success` diberi garis kiri sebagai penanda kedua — garis kiri dipasang sebagai penanda kedua supaya tetap terbaca,
   termasuk bagi yang kesulitan membedakan warna. */
.table > :not(caption) > tr.table-success > *,
.table > :not(caption) > * > tr.table-success > * { --bs-table-bg: #E4F5EA; }
.table > :not(caption) > tr.table-warning > *,
.table > :not(caption) > * > tr.table-warning > * { --bs-table-bg: #FDF3E2; }
.table > :not(caption) > tr.table-danger > *,
.table > :not(caption) > * > tr.table-danger > * { --bs-table-bg: #FCEDEF; }
.table > :not(caption) > tr.table-info > *,
.table > :not(caption) > * > tr.table-info > * { --bs-table-bg: #E4F5F7; }

.table tr.table-success > td:first-child { box-shadow: inset .25rem 0 0 var(--sp-success); }
.table tr.table-warning > td:first-child { box-shadow: inset .25rem 0 0 var(--sp-warning); }
.table tr.table-danger  > td:first-child { box-shadow: inset .25rem 0 0 var(--sp-danger); }
.table tr.table-info    > td:first-child { box-shadow: inset .25rem 0 0 var(--sp-info); }

/* Baris berstatus tetap terbaca saat di-hover */
.table-hover > tbody > tr.table-success:hover > * { --bs-table-accent-bg: #D7EEE0; }
.table-hover > tbody > tr.table-warning:hover > * { --bs-table-accent-bg: #F8EAD2; }
.table-hover > tbody > tr.table-danger:hover  > * { --bs-table-accent-bg: #F8E0E4; }
.table-hover > tbody > tr.table-info:hover    > * { --bs-table-accent-bg: #D6EDF0; }

/* ---------------------------------------------------------------------
   Form
   --------------------------------------------------------------------- */

.form-control, .form-select {
    border: 1px solid #E2D9E8;
    border-radius: var(--sp-radius-sm);
    color: var(--sp-text);
    background-color: #fff;
    transition: border-color .18s ease, box-shadow .18s ease;
}

.form-control::placeholder { color: var(--sp-muted); }

.form-control:focus, .form-select:focus {
    border-color: var(--sp-brand-500);
    box-shadow: var(--sp-ring);
}

.form-control:disabled, .form-control[readonly], .form-select:disabled {
    background-color: #F8F5F9;
    color: var(--sp-text-soft);
}

.form-label, label { color: var(--sp-text); font-weight: 500; }

.input-group-text {
    background-color: var(--sp-brand-50);
    border-color: #E2D9E8;
    color: var(--sp-brand-700);
    border-radius: var(--sp-radius-sm);
}

.form-check-input:checked { background-color: var(--sp-brand-600); border-color: var(--sp-brand-600); }
.form-check-input:focus { border-color: var(--sp-brand-500); box-shadow: var(--sp-ring); }

/* Choices.js */
.choices__inner { border-radius: var(--sp-radius-sm); border-color: #E2D9E8; background-color: #fff; }
.choices__list--dropdown { border-color: #E2D9E8; border-radius: var(--sp-radius-sm); box-shadow: var(--sp-shadow-md); }
.choices__list--dropdown .choices__item--selectable.is-highlighted { background-color: var(--sp-brand-50); }
.choices__list--multiple .choices__item { background-color: var(--sp-brand-600); border-color: var(--sp-brand-700); border-radius: 999px; }

/* ---------------------------------------------------------------------
   Badge, alert, dropdown, modal, tab, pagination
   --------------------------------------------------------------------- */

.badge {
    border-radius: 999px;
    padding: .38em .75em;
    font-weight: 600;
    letter-spacing: .01em;
}

.badge.bg-primary { background-color: var(--sp-brand-600) !important; }
.badge.bg-info { background-color: var(--sp-info) !important; }
.badge.bg-success { background-color: var(--sp-success) !important; }
.badge.bg-secondary { background-color: var(--sp-brand-700) !important; }

.alert {
    border: 1px solid transparent;
    border-radius: var(--sp-radius-sm);
    box-shadow: var(--sp-shadow-xs);
}
.alert-primary { background-color: var(--sp-brand-50); border-color: var(--sp-brand-100); color: var(--sp-brand-800); }
.alert-success { background-color: #E7F6EC; border-color: #C4E8D1; color: #14612F; }
.alert-danger  { background-color: #FDECEE; border-color: #F8CFD5; color: #9B1C2A; }
.alert-warning { background-color: #FDF5E7; border-color: #F7E3BE; color: #8A5A12; }
.alert-info    { background-color: #E6F5F7; border-color: #C3E6EB; color: #0A6570; }

.dropdown-menu {
    border: 1px solid var(--sp-border);
    border-radius: var(--sp-radius);
    box-shadow: var(--sp-shadow-md);
    padding: .4rem;
}
.dropdown-item { border-radius: var(--sp-radius-sm); font-size: .9rem; color: var(--sp-text); }
.dropdown-item:hover, .dropdown-item:focus { background-color: var(--sp-brand-50); color: var(--sp-brand-700); }

.modal-content {
    border: 0;
    border-radius: var(--sp-radius);
    box-shadow: var(--sp-shadow-lg);
    overflow: hidden;
}
.modal-header {
    background: linear-gradient(90deg, var(--sp-brand-800) 0%, var(--sp-brand-700) 100%);
    color: #fff;
    border-bottom: 0;
    padding: 1rem 1.5rem;
}
.modal-header .modal-title, .modal-header h1, .modal-header h2,
.modal-header h3, .modal-header h4, .modal-header h5, .modal-header h6 { color: #fff; }
.modal-header .btn-close { filter: invert(1) grayscale(1); opacity: .85; }
.modal-footer { border-top: 1px solid var(--sp-border); background-color: #FDFCFD; }

.nav-tabs { border-bottom: 1px solid var(--sp-border); }
.nav-tabs .nav-link {
    color: var(--sp-text-soft);
    border: 0;
    border-bottom: 2px solid transparent;
    border-radius: 0;
    font-weight: 500;
}
.nav-tabs .nav-link:hover { color: var(--sp-brand-700); border-bottom-color: var(--sp-brand-100); }
.nav-tabs .nav-link.active {
    color: var(--sp-brand-700);
    background: transparent;
    border-bottom-color: var(--sp-brand-600);
    font-weight: 600;
}

.nav-pills .nav-link.active { background-color: var(--sp-brand-600); border-radius: var(--sp-radius-sm); }

.page-link { color: var(--sp-brand-700); border-color: var(--sp-border); }
.page-link:hover { background-color: var(--sp-brand-50); color: var(--sp-brand-700); border-color: var(--sp-brand-100); }
.page-item.active .page-link { background-color: var(--sp-brand-600); border-color: var(--sp-brand-600); color: #fff; }

.progress { background-color: #ECE4F1; border-radius: 999px; }
.progress-bar { background-color: var(--sp-brand-600); }

.list-group-item { border-color: var(--sp-border); color: var(--sp-text); }
.list-group-item.active { background-color: var(--sp-brand-600); border-color: var(--sp-brand-600); }

/* Volt/Bootstrap menggambar <hr> dengan `background-color: currentColor` dan
   `opacity: .25`. Menaikkan opacity saja membuat garisnya sekuat warna teks
   (nyaris hitam), jadi warnanya ikut diganti ke warna garis tema. */
hr {
    border: 0;
    background-color: var(--sp-border);
    color: var(--sp-border);
    opacity: 1;
}

.breadcrumb-item + .breadcrumb-item::before { color: var(--sp-muted); }
.breadcrumb-item a { color: var(--sp-brand-700); }
.breadcrumb-item.active { color: var(--sp-text-soft); }

/* ---------------------------------------------------------------------
   Footer
   --------------------------------------------------------------------- */

footer.bg-white, .footer {
    background-color: var(--sp-surface) !important;
    border: 1px solid var(--sp-border);
    border-radius: var(--sp-radius);
    box-shadow: var(--sp-shadow-xs);
    color: var(--sp-text-soft);
    padding: 1.5rem !important;
}

/* ---------------------------------------------------------------------
   Konten
   --------------------------------------------------------------------- */

.content {
    padding: 0 1.25rem 1.25rem 1.25rem;
    /* Volt memberi .content `overflow:hidden`, dan itu menjadikannya scroll
       container sehingga `position:sticky` pada navbar tidak pernah menempel.
       `overflow:clip` mengunci tampilan yang sama tanpa membuat scroll
       container, jadi sticky-nya bekerja. Deklarasi `hidden` sengaja
       ditinggal di depan sebagai fallback untuk browser lama yang belum
       mengenal `clip` (di sana navbar sekadar tidak sticky, tidak rusak). */
    overflow: hidden;
    overflow: clip;
}

/* .sticky-header (my_css.css) memakai top:0; beri offset supaya header
   tabelnya berhenti di bawah navbar, bukan tersembunyi di baliknya. */
.sticky-header { top: 5.75rem; }

/* Utility tambahan yang dipakai tema */
.text-brand { color: var(--sp-brand-900) !important; }
.bg-brand { background-color: var(--sp-brand-900) !important; }

/* =====================================================================
   Branding — sidebar & navbar mobile
   ===================================================================== */

.sidebar-brand-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .5rem;
    padding: .35rem 0 1.1rem;
    margin-bottom: .9rem;
    border-bottom: 1px solid rgba(255, 255, 255, .1);
}

.sidebar-brand {
    display: flex;
    align-items: center;
    gap: .75rem;
    text-decoration: none;
    overflow: hidden;
    min-width: 0;
}

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

.sidebar-close {
    flex: 0 0 auto;
    width: 2rem; height: 2rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--sp-radius-sm);
    color: #CBB9D5;
    background: rgba(255, 255, 255, .08);
    transition: background-color .18s ease, color .18s ease;
}

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

.sidebar-brand-logo {
    flex: 0 0 auto;
    width: 2.4rem; height: 2.4rem;
    border-radius: .7rem;
    object-fit: cover;
    background: #fff;
    padding: 2px;
    box-shadow: 0 6px 16px rgba(29, 14, 37, .35);
}

.sidebar-brand-copy { display: flex; flex-direction: column; line-height: 1.2; min-width: 0; }

.sidebar-brand-copy .brand-name {
    color: #fff;
    font-weight: 700;
    font-size: 1.05rem;
    letter-spacing: -.01em;
}

.sidebar-brand-copy .brand-desc {
    color: #C1ADCD;
    font-size: .72rem;
    letter-spacing: .02em;
    white-space: nowrap;
}

/* Saat sidebar diciutkan, .sidebar-text sudah di-opacity:0 oleh Volt —
   rapatkan juga jaraknya supaya logo tetap di tengah kolom 95px. */
.sidebar.contracted .sidebar-brand-row { justify-content: center; }
.sidebar.contracted .sidebar-brand { gap: 0; }

/* Navbar mobile (menggantikan logo bawaan template) */
.navbar-brand-sipasi {
    display: flex;
    align-items: center;
    gap: .6rem;
    padding-top: .35rem;
    padding-bottom: .35rem;
}

.navbar-brand-logo {
    width: 2.1rem; height: 2.1rem;
    border-radius: .6rem;
    object-fit: cover;
    background: #fff;
    padding: 2px;
}

.navbar-brand-text {
    color: #fff;
    font-weight: 700;
    font-size: 1.1rem;
    letter-spacing: -.01em;
    /* Volt meng-uppercase .navbar-brand; penulisan resminya "SIPASI". */
    text-transform: none;
}

.navbar-theme-primary .navbar-toggler {
    border: 1px solid rgba(255, 255, 255, .25);
    border-radius: var(--sp-radius-sm);
    padding: .35rem .55rem;
}

.navbar-theme-primary .navbar-toggler:focus { box-shadow: 0 0 0 .2rem rgba(255, 255, 255, .18); }

/* =====================================================================
   Identitas pengguna di navbar
   ===================================================================== */

.navbar-user-name {
    display: block;
    max-width: 14rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    line-height: 1.25;
    color: var(--sp-text);
}

.navbar-user-role {
    display: block;
    font-size: .72rem;
    font-weight: 600;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--sp-brand-700);
    line-height: 1.2;
}

.navbar-dashboard .dropdown-toggle::after { color: var(--sp-muted); }

/* Di bawah lg, judul panjang di navbar putih mengulang brand bar mobile di
   atasnya dan memakan dua baris — sembunyikan, sisakan avatar + dropdown. */
@media (max-width: 991.98px) {
    .navbar-dashboard .sidebar-text { display: none; }
    .navbar-dashboard { justify-content: flex-end; }
    .navbar-dashboard .navbar-user-name { max-width: 11rem; }
}

@media (max-width: 575.98px) {
    .navbar-dashboard { padding-top: .35rem !important; padding-bottom: .35rem !important; }
    .navbar-dashboard .avatar { width: 2.5rem !important; height: 2.5rem !important; }
    .navbar-dashboard .navbar-user-name { max-width: 9.5rem; font-size: .82rem; }
}

/* =====================================================================
   Halaman Auth (login) — .sipasi-auth
   ===================================================================== */

.sipasi-auth {
    position: relative;
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 2rem 1rem;
    background:
        radial-gradient(1100px 620px at 12% -10%, rgba(173, 128, 198, .34) 0%, transparent 60%),
        radial-gradient(900px 560px at 92% 108%, rgba(102, 53, 130, .42) 0%, transparent 62%),
        linear-gradient(140deg, #1D0E25 0%, var(--sp-brand-900) 45%, var(--sp-brand-700) 100%);
    overflow: hidden;
}

/* Grid halus sebagai tekstur latar */
.sipasi-auth::before {
    content: "";
    position: absolute;
    inset: 0;
    background-image:
        linear-gradient(rgba(255, 255, 255, .045) 1px, transparent 1px),
        linear-gradient(90deg, rgba(255, 255, 255, .045) 1px, transparent 1px);
    background-size: 56px 56px;
    -webkit-mask-image: radial-gradient(circle at 50% 45%, #000 0%, transparent 78%);
    mask-image: radial-gradient(circle at 50% 45%, #000 0%, transparent 78%);
    pointer-events: none;
}

.sipasi-auth-card {
    position: relative;
    z-index: 1;
    width: 100%;
    max-width: 62rem;
    background: var(--sp-surface);
    border-radius: 1.25rem;
    box-shadow: 0 30px 70px rgba(29, 14, 37, .45);
    overflow: hidden;
}

/* --- Panel kiri (branding) --- */

.sipasi-auth-brand {
    position: relative;
    background: linear-gradient(160deg, var(--sp-brand-900) 0%, var(--sp-brand-800) 55%, var(--sp-brand-700) 100%);
    color: #EFE7F3;
    padding: 3rem 2.75rem;
    display: flex;
    flex-direction: column;
    justify-content: center;
    overflow: hidden;
}

.sipasi-auth-brand::after {
    content: "";
    position: absolute;
    right: -5rem; bottom: -7rem;
    width: 20rem; height: 20rem;
    border-radius: 50%;
    background: radial-gradient(circle, rgba(173, 128, 198, .32) 0%, transparent 68%);
    pointer-events: none;
}

.sipasi-auth-brand > * { position: relative; z-index: 1; }

.sipasi-auth-logo {
    width: 3.25rem; height: 3.25rem;
    border-radius: .875rem;
    object-fit: cover;
    background: #fff;
    padding: .25rem;
    box-shadow: 0 8px 20px rgba(29, 14, 37, .35);
}

.sipasi-auth-brand .sipasi-wordmark {
    font-size: 1.9rem;
    font-weight: 700;
    letter-spacing: -.02em;
    color: #fff;
    margin: 1.5rem 0 .4rem;
    line-height: 1.15;
}

.sipasi-auth-brand .sipasi-tagline {
    font-size: .95rem;
    line-height: 1.65;
    color: #D0BEDA;
    margin-bottom: 2rem;
}

.sipasi-auth-points { list-style: none; padding: 0; margin: 0; }

.sipasi-auth-points li {
    display: flex;
    align-items: flex-start;
    gap: .7rem;
    font-size: .9rem;
    color: #DED1E6;
    margin-bottom: .85rem;
}

.sipasi-auth-points li:last-child { margin-bottom: 0; }

.sipasi-auth-points .tick {
    flex: 0 0 auto;
    width: 1.4rem; height: 1.4rem;
    border-radius: 50%;
    background: rgba(173, 128, 198, .22);
    color: #D6BFE3;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    margin-top: .05rem;
}

.sipasi-auth-points .tick svg { width: .8rem; height: .8rem; }

/* --- Panel kanan (form) --- */

.sipasi-auth-form { padding: 3rem 2.75rem; }

.sipasi-auth-form .auth-title {
    font-size: 1.45rem;
    font-weight: 700;
    color: var(--sp-brand-900);
    margin-bottom: .35rem;
    letter-spacing: -.02em;
}

.sipasi-auth-form .auth-subtitle {
    color: var(--sp-text-soft);
    font-size: .92rem;
    margin-bottom: 1.9rem;
}

.sipasi-auth-form .form-label {
    font-size: .82rem;
    font-weight: 600;
    color: var(--sp-text-soft);
    text-transform: uppercase;
    letter-spacing: .05em;
    margin-bottom: .45rem;
}

.sipasi-auth-form .input-group-text {
    background: #fff;
    border-right: 0;
    color: var(--sp-brand-500);
    padding-left: .9rem;
    padding-right: .6rem;
}

.sipasi-auth-form .input-group .form-control {
    border-left: 0;
    padding-left: 0;
    height: 3rem;
}

.sipasi-auth-form .input-group:focus-within .input-group-text,
.sipasi-auth-form .input-group:focus-within .form-control {
    border-color: var(--sp-brand-500);
    box-shadow: none;
}

.sipasi-auth-form .input-group:focus-within {
    border-radius: var(--sp-radius-sm);
    box-shadow: var(--sp-ring);
}

.sipasi-auth-form .btn-signin {
    height: 3rem;
    font-weight: 600;
    letter-spacing: .01em;
    border-radius: var(--sp-radius-sm);
}

.sipasi-auth-form .auth-foot {
    margin-top: 2rem;
    padding-top: 1.25rem;
    border-top: 1px solid var(--sp-border);
    text-align: center;
    font-size: .82rem;
    color: var(--sp-muted);
}

/* Header ringkas untuk layar kecil (panel kiri disembunyikan) */
.sipasi-auth-mobile-head {
    display: flex;
    align-items: center;
    gap: .85rem;
    margin-bottom: 2rem;
}

.sipasi-auth-mobile-head img { width: 2.75rem; height: 2.75rem; border-radius: .75rem; object-fit: cover; }
.sipasi-auth-mobile-head .name { font-weight: 700; color: var(--sp-brand-900); line-height: 1.2; }
.sipasi-auth-mobile-head .desc { font-size: .78rem; color: var(--sp-text-soft); }

@media (min-width: 992px) { .sipasi-auth-mobile-head { display: none; } }

@media (max-width: 575.98px) {
    .sipasi-auth { padding: 1rem .75rem; }
    .sipasi-auth-form { padding: 2rem 1.5rem; }
    .sipasi-auth-card { border-radius: 1rem; }
}

/* =====================================================================
   Hero sambutan (dashboard)
   ===================================================================== */

.sipasi-hero {
    position: relative;
    border-radius: var(--sp-radius);
    padding: 1.75rem 1.9rem;
    color: #EFE7F3;
    background:
        radial-gradient(700px 380px at 88% -30%, rgba(173, 128, 198, .32) 0%, transparent 62%),
        linear-gradient(120deg, var(--sp-brand-950) 0%, var(--sp-brand-800) 62%, var(--sp-brand-700) 100%);
    box-shadow: var(--sp-shadow-md);
    overflow: hidden;
}

.sipasi-hero::after {
    content: "";
    position: absolute;
    right: -3.5rem; top: -6rem;
    width: 15rem; height: 15rem;
    border-radius: 50%;
    border: 1.5rem solid rgba(255, 255, 255, .05);
    pointer-events: none;
}

.sipasi-hero > * { position: relative; z-index: 1; }

.sipasi-hero .hero-greeting {
    font-size: .82rem;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: #D6BFE3;
    font-weight: 600;
    margin-bottom: .35rem;
}

.sipasi-hero .hero-name {
    font-size: 1.5rem;
    font-weight: 700;
    color: #fff;
    letter-spacing: -.02em;
    margin-bottom: .6rem;
    line-height: 1.25;
}

.sipasi-hero .hero-sub {
    font-size: .9rem;
    color: #D0BEDA;
    margin-bottom: 0;
}

.sipasi-hero .hero-chip {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    background: rgba(255, 255, 255, .12);
    border: 1px solid rgba(255, 255, 255, .18);
    color: #EFE7F3;
    border-radius: 999px;
    padding: .3rem .8rem;
    font-size: .8rem;
    font-weight: 600;
}

.sipasi-hero .hero-chip svg { width: .9rem; height: .9rem; }

.sipasi-hero .hero-avatar {
    width: 4.5rem; height: 4.5rem;
    border-radius: 50%;
    object-fit: cover;
    border: 3px solid rgba(255, 255, 255, .28);
    box-shadow: 0 10px 26px rgba(29, 14, 37, .35);
}

/* =====================================================================
   Carousel dashboard
   ===================================================================== */

.sipasi-carousel { border-radius: var(--sp-radius); overflow: hidden; }

/* Rasio dikunci mengikuti gambar banner supaya tinggi kartu tidak
   berubah-ubah saat slide berganti. */
.sipasi-carousel .carousel-item img {
    width: 100%;
    aspect-ratio: 2.48;
    object-fit: cover;
    display: block;
}

.sipasi-carousel .carousel-indicators { margin-bottom: .85rem; }

.sipasi-carousel .carousel-indicators [data-bs-target] {
    width: .55rem;
    height: .55rem;
    border-radius: 999px;
    border: 0;
    background-color: rgba(255, 255, 255, .55);
    box-shadow: 0 1px 4px rgba(29, 14, 37, .35);
    opacity: 1;
    transition: width .25s ease, background-color .25s ease;
}

.sipasi-carousel .carousel-indicators .active {
    width: 1.6rem;
    background-color: var(--sp-brand-400);
}

.sipasi-carousel .carousel-control-prev,
.sipasi-carousel .carousel-control-next {
    width: 3.5rem;
    opacity: 0;
    transition: opacity .2s ease;
}

.sipasi-carousel:hover .carousel-control-prev,
.sipasi-carousel:hover .carousel-control-next,
.sipasi-carousel .carousel-control-prev:focus-visible,
.sipasi-carousel .carousel-control-next:focus-visible { opacity: 1; }

/* Panahnya dipasang sebagai SVG sebaris di markup (lihat dashboard.html):
   Volt menggambar .carousel-control-*-icon lewat `content: '\f060'` dengan
   font "Font Awesome 5 Free", padahal font itu tidak dimuat di mana pun di
   aplikasi ini — yang tampil hanya kotak glyph kosong. */
.sipasi-carousel .sipasi-carousel-ikon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.2rem; height: 2.2rem;
    border-radius: 50%;
    color: #fff;
    background-color: rgba(51, 27, 65, .55);
    -webkit-backdrop-filter: blur(6px);
    backdrop-filter: blur(6px);
    transition: background-color .18s ease;
}

.sipasi-carousel .carousel-control-prev:hover .sipasi-carousel-ikon,
.sipasi-carousel .carousel-control-next:hover .sipasi-carousel-ikon {
    background-color: rgba(51, 27, 65, .78);
}

.sipasi-carousel .sipasi-carousel-ikon svg { width: 1.05rem; height: 1.05rem; }

/* Di layar sentuh tidak ada hover, jadi kontrolnya dibuat tetap terlihat. */
@media (hover: none) {
    .sipasi-carousel .carousel-control-prev,
    .sipasi-carousel .carousel-control-next { opacity: 1; }
}

/* Kartu kosong ketika belum ada gambar */
.sipasi-empty {
    text-align: center;
    padding: 3.5rem 1.5rem;
    color: var(--sp-text-soft);
}

.sipasi-empty svg {
    width: 3rem; height: 3rem;
    color: var(--sp-brand-400);
    margin-bottom: 1rem;
}

@media (max-width: 575.98px) {
    .sipasi-hero { padding: 1.35rem 1.25rem; }
    .sipasi-hero .hero-name { font-size: 1.2rem; }
}

/* =====================================================================
   Tabel data + simple-datatables
   ===================================================================== */

/* Scroll horizontal dipindah ke .dataTable-container supaya kotak pencarian,
   pemilih jumlah baris, dan pagination tetap di tempat saat tabel digeser. */
.dataTable-wrapper .dataTable-container {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}

/* Bayangan penanda "masih ada kolom di samping". Lapisan putih memakai
   background-attachment:local sehingga ikut tergeser dan menutup bayangan
   begitu sampai di ujung — jadi petunjuknya hilang sendiri saat tidak
   relevan. Cara ini dipakai untuk tabel biasa yang latar barisnya
   transparan. */
.table-responsive {
    background-image:
        linear-gradient(to right, var(--sp-surface) 30%, rgba(255, 255, 255, 0)),
        linear-gradient(to left,  var(--sp-surface) 30%, rgba(255, 255, 255, 0)),
        linear-gradient(to right, rgba(51, 27, 65, .14), rgba(51, 27, 65, 0)),
        linear-gradient(to left,  rgba(51, 27, 65, .14), rgba(51, 27, 65, 0));
    background-position: 0 0, 100% 0, 0 0, 100% 0;
    background-repeat: no-repeat;
    background-size: 44px 100%, 44px 100%, 15px 100%, 15px 100%;
    background-attachment: local, local, scroll, scroll;
    -webkit-overflow-scrolling: touch;
}

/* Tabel data punya baris berwarna yang menutup bayangan latar, jadi
   petunjuknya dipasang sebagai overlay di pembungkus yang tidak ikut
   tergeser. Kelas ada-geser-* di-toggle oleh sipasi.js sesuai posisi
   scroll, supaya bayangan tidak muncul saat tabelnya memang sudah muat. */
.dataTable-wrapper { position: relative; }

.dataTable-wrapper::before,
.dataTable-wrapper::after {
    content: "";
    position: absolute;
    top: var(--tabel-atas, 0);
    height: var(--tabel-tinggi, 100%);
    width: 2rem;
    pointer-events: none;
    opacity: 0;
    transition: opacity .2s ease;
    z-index: 3;
}

.dataTable-wrapper::before {
    left: 0;
    background: linear-gradient(to right, rgba(51, 27, 65, .16), rgba(51, 27, 65, 0));
}

.dataTable-wrapper::after {
    right: 0;
    background: linear-gradient(to left, rgba(51, 27, 65, .16), rgba(51, 27, 65, 0));
}

.dataTable-wrapper.ada-geser-kiri::before,
.dataTable-wrapper.ada-geser-kanan::after { opacity: 1; }

/* --- Kontrol datatables --- */

.dataTable-top,
.dataTable-bottom {
    align-items: center;
    gap: .75rem;
    color: var(--sp-text-soft);
    font-size: .875rem;
}

.dataTable-top { padding: 0 1.5rem 1rem; }
.dataTable-bottom { padding: 1.25rem 1.5rem 0; }

.dataTable-selector {
    border: 1px solid #E2D9E8;
    border-radius: var(--sp-radius-sm);
    color: var(--sp-text);
    padding: .45rem 2rem .45rem .85rem;
}

.dataTable-selector:focus {
    border-color: var(--sp-brand-500);
    box-shadow: var(--sp-ring);
    outline: 0;
}

.dataTable-input {
    border: 1px solid #E2D9E8;
    border-radius: var(--sp-radius-sm);
    color: var(--sp-text);
    padding: .45rem .85rem;
    min-width: 15rem;
}

.dataTable-input:focus {
    border-color: var(--sp-brand-500);
    box-shadow: var(--sp-ring);
    outline: 0;
}

.dataTable-input::placeholder { color: var(--sp-muted); }

.dataTable-info { color: var(--sp-text-soft); }

.dataTable-pagination a {
    color: var(--sp-brand-700);
    border-color: var(--sp-border);
    background-color: #fff;
}

.dataTable-pagination a:hover {
    background-color: var(--sp-brand-50);
    color: var(--sp-brand-700);
}

.dataTable-pagination > li.active a {
    background-color: var(--sp-brand-600);
    border-color: var(--sp-brand-600);
    color: #fff;
}

.dataTable-pagination > li.disabled a { color: var(--sp-muted); background-color: #F9F7FA; }

.dataTable-sorter { color: inherit; }

/* --- Penyesuaian layar kecil --- */

@media (max-width: 767.98px) {
    .dataTable-top,
    .dataTable-bottom { align-items: stretch; padding-left: 1rem; padding-right: 1rem; }

    /* Volt sudah menumpuk kedua baris ini; lebarkan isinya supaya tidak
       tampak menggantung di kiri. */
    .dataTable-top .dataTable-dropdown,
    .dataTable-top .dataTable-search { width: 100%; }
    .dataTable-top .dataTable-search { margin-top: .75rem; }
    .dataTable-input { width: 100%; min-width: 0; }

    .dataTable-bottom .dataTable-info { margin-bottom: .75rem; text-align: center; }
    .dataTable-pagination { justify-content: center; flex-wrap: wrap; row-gap: .35rem; }

    .table td, .table th { padding: .7rem .75rem; }
}

/* Volt memasang `.table td, .table th { white-space: nowrap }`. Di layar
   lebar itu wajar, tapi di layar sempit judul kolom panjang memaksa
   kolomnya melebar dan menyisakan beberapa piksel saja untuk kolom teks.
   Selektornya harus selengkap ini (0,2,1) supaya menang atas aturan Volt. */
@media (max-width: 991.98px) {
    .table thead th,
    .table > thead > tr > th,
    .table .thead-light th { white-space: normal; }
}

/* =====================================================================
   Daftar info ringkas — pengganti tabel dua kolom yang tidak muat di ponsel
   ===================================================================== */

.sipasi-info-list {
    margin: 0;
    border: 1px solid var(--sp-border);
    border-radius: var(--sp-radius);
    overflow: hidden;
    background: #FDFCFD;
}

.sipasi-info-list .info-row {
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: .85rem 1.1rem;
}

.sipasi-info-list .info-row + .info-row { border-top: 1px solid var(--sp-border); }

.sipasi-info-list dt {
    flex: 0 0 16rem;
    font-weight: 600;
    color: var(--sp-text-soft);
    font-size: .875rem;
    margin: 0;
}

.sipasi-info-list dd {
    margin: 0;
    color: var(--sp-text);
    font-weight: 500;
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: .5rem;
}

@media (max-width: 767.98px) {
    .sipasi-info-list .info-row { flex-direction: column; align-items: flex-start; gap: .35rem; }
    .sipasi-info-list dt { flex: 1 1 auto; font-size: .78rem; text-transform: uppercase; letter-spacing: .04em; }
}

/* =====================================================================
   Kepala halaman (judul + status + aksi utama)
   ===================================================================== */

.sipasi-page-head {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1.5rem;
    padding: 1.6rem 1.9rem;
    border-radius: var(--sp-radius);
    color: #EFE7F3;
    background:
        radial-gradient(640px 340px at 92% -20%, rgba(173, 128, 198, .3) 0%, transparent 62%),
        linear-gradient(120deg, var(--sp-brand-950) 0%, var(--sp-brand-800) 62%, var(--sp-brand-700) 100%);
    box-shadow: var(--sp-shadow-md);
    overflow: hidden;
}

.sipasi-page-head::after {
    content: "";
    position: absolute;
    right: -4rem; top: -6rem;
    width: 15rem; height: 15rem;
    border-radius: 50%;
    border: 1.25rem solid rgba(255, 255, 255, .05);
    pointer-events: none;
}

.sipasi-page-head > * { position: relative; z-index: 1; }

.sipasi-page-head .page-head-label {
    font-size: .78rem;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: #D6BFE3;
    font-weight: 600;
    margin-bottom: .3rem;
}

.sipasi-page-head .page-head-judul {
    font-size: 1.45rem;
    font-weight: 700;
    color: #fff;
    letter-spacing: -.02em;
    line-height: 1.25;
    margin-bottom: .85rem;
}

.sipasi-page-head .page-head-chips { display: flex; flex-wrap: wrap; gap: .5rem; }

.sipasi-page-head .page-head-chip {
    background: rgba(255, 255, 255, .12);
    border: 1px solid rgba(255, 255, 255, .18);
    color: #EFE7F3;
    border-radius: 999px;
    padding: .28rem .8rem;
    font-size: .78rem;
    font-weight: 600;
}

.sipasi-page-head .page-head-aksi {
    display: flex;
    flex-wrap: wrap;
    gap: .5rem;
    flex: 0 0 auto;
}

/* Tombol garis-luar di atas latar gelap kepala halaman */
.btn-outline-terang {
    background: transparent;
    border: 1px solid rgba(255, 255, 255, .38);
    color: #EFE7F3;
}

.btn-outline-terang:hover,
.btn-outline-terang:focus {
    background: rgba(255, 255, 255, .12);
    border-color: rgba(255, 255, 255, .55);
    color: #fff;
}

@media (max-width: 767.98px) {
    .sipasi-page-head {
        flex-direction: column;
        align-items: stretch;
        gap: 1.1rem;
        padding: 1.35rem 1.25rem;
    }
    .sipasi-page-head .page-head-judul { font-size: 1.2rem; }
    .sipasi-page-head .page-head-aksi .btn { flex: 1 1 100%; }
}

/* Tombol aksi di kepala halaman: penuh di ponsel supaya mudah disentuh */
@media (max-width: 575.98px) {
    .sipasi-page-actions,
    .sipasi-page-actions > div,
    .sipasi-page-actions .btn { width: 100%; }
}

/* =====================================================================
   Jaring pengaman lebar — kunci "mobile adaptive" di aplikasi ini

   Markup SIPASI mematok lebar lewat atribut inline di ~370 tempat
   (`style="width: 15rem"` dan seterusnya). `max-width` tidak bisa
   dikalahkan oleh `width` inline, jadi beberapa aturan di bawah ini
   membuat semuanya ikut menyusut di layar sempit tanpa perlu menyentuh
   satu pun atribut tersebut.
   ===================================================================== */

.form-control,
.form-select,
textarea.form-control { max-width: 100%; }

/* Input/select polos tanpa kelas Bootstrap ikut dijaga. */
.content input,
.content select,
.content textarea { max-width: 100%; }

/* Pembungkus teks di dalam sel tabel dan badan kartu. Dibatasi pada
   elemen yang memang memasang lebar inline supaya tata letak lain
   (kolom grid, sidebar) tidak ikut terpengaruh. */
.content div[style*="width"],
.content span[style*="width"],
.content p[style*="width"] { max-width: 100%; }

/* Gambar tidak pernah melebihi wadahnya. */
.content img { max-width: 100%; height: auto; }

/* =====================================================================
   Penyesuaian ponsel umum
   ===================================================================== */

@media (max-width: 767.98px) {
    .content { padding: 0 .75rem 1rem .75rem; }

    .card-header { padding: .9rem 1rem; }
    .card-body { padding: 1rem; }

    /* Baris tombol/field yang ditulis d-flex tanpa flex-wrap keluar dari
       kartu di layar sempit; biarkan turun ke baris berikutnya. */
    .card-body .d-flex:not(.flex-nowrap):not(.align-items-center) { flex-wrap: wrap; }

    /* Tombol berdampingan di dalam kartu diberi jarak vertikal saat
       terpaksa turun baris. */
    .card-body .btn { margin-bottom: .25rem; }

    /* Judul kartu tidak lagi memaksa satu baris. */
    .card-header h2, .card-header .h2,
    .card-header h5, .card-header .h5 { font-size: 1rem; line-height: 1.35; }

    footer.bg-white, .footer { padding: 1rem !important; }

    .modal-header { padding: .85rem 1rem; }
    .modal-body { padding: 1rem; }
}

@media (max-width: 575.98px) {
    /* Tabel rincian (label | nilai) di halaman data: rapatkan supaya
       kolom nilainya tidak tinggal beberapa piksel. */
    .table > :not(caption) > * > th,
    .table > :not(caption) > * > td { padding: .6rem .5rem; font-size: .85rem; }

    .breadcrumb { font-size: .8rem; }
}

/* =====================================================================
   Badge "halus" — latar tipis + teks pekat.

   Di dalam sel yang memuat empat status sekaligus, pil warna penuh saling
   berebut perhatian. Versi ini tetap jelas terbaca tanpa meramaikan baris.
   ===================================================================== */

.badge-halus {
    display: inline-block;
    border: 1px solid transparent;
    border-radius: 999px;
    padding: .18rem .6rem;
    font-size: .72rem;
    font-weight: 600;
    line-height: 1.5;
}

.badge-halus-success { background: #E4F5EC; border-color: #B7E3CC; color: #0A6C3D; }
.badge-halus-warning { background: #FCF2DF; border-color: #F1DCB5; color: #855312; }
.badge-halus-danger  { background: #FBE9EC; border-color: #F3C9D0; color: #96182A; }
.badge-halus-info    { background: #E6F5F7; border-color: #C3E6EB; color: #0A6570; }
.badge-halus-netral  { background: #F5F3F7; border-color: #E7E1EA; color: var(--sp-text-soft); }

/* --- Daftar status di dalam sel --- */

.daftar-status {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: .35rem;
}

/* Label dan pil berdampingan selama muat, lalu pil turun ke barisnya
   sendiri dan memakai lebar kolom penuh. Dua bentuk lain sempat dicoba dan
   gagal di kolom selebar ~190px: `justify-content: space-between` menyisakan
   ruang terlalu sempit untuk pil, dan grid `5.25rem 1fr` memaksa teks
   sepanjang "Penyiapan Dokumen Pencairan (5 of 8)" pecah jadi tumpukan
   potongan kata. */
.daftar-status li {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .2rem .5rem;
}

.daftar-status .status-nama { flex: 0 0 auto; }

.daftar-status .status-nama {
    font-size: .72rem;
    color: var(--sp-text-soft);
    white-space: nowrap;
}

/* Volt memasang `.p, ol li, p, ul li { font-size: 1rem }`, jadi ukuran teks
   harus dinyatakan pada <li>-nya sendiri, bukan cukup di induknya. */
.daftar-status li { font-size: .72rem; }

/* Teks seperti "Penyiapan Dokumen Pencairan (3 of 12)" perlu boleh turun
   baris; kolomnya sudah dibatasi max-width. */
.daftar-status .badge-halus { white-space: normal; flex: 0 1 auto; }

/* --- Kolom teks panjang --- */

/* Dulu dipatok `style="width: 20rem"` sehingga kolomnya kaku dan ikut
   melebarkan tabel. min/max-width membuatnya masih bisa menyusut di layar
   sempit tapi tetap membungkus rapi di layar lebar. */
.kolom-judul, .kolom-orang, .kolom-jurnal {
    white-space: normal;
    overflow-wrap: anywhere;
}

/* Kolom status hanya berisi pil pendek; `overflow-wrap: anywhere` di sini
   justru memecahnya di tengah kata. */
.kolom-status { white-space: normal; }

/* Aturan Volt `.table td, .table th { white-space: nowrap }` (0,1,1)
   mengalahkan kelas polos di atas (0,1,0) saat dipasang langsung pada <td>.
   Varian ber-`.table td` ini (0,2,1) yang membuatnya berlaku. */
.table td.kolom-judul,
.table td.kolom-orang,
.table td.kolom-jurnal {
    white-space: normal;
    overflow-wrap: anywhere;
}

.table td.kolom-status { white-space: normal; }

.kolom-judul  { min-width: 12rem; max-width: 20rem; }
.kolom-jurnal { min-width: 10rem; max-width: 15rem; }
.kolom-orang  { min-width: 8rem;  max-width: 11rem; }
.kolom-status { min-width: 12rem; max-width: 14rem; }

.sel-nomor, .sel-id { white-space: nowrap; }

/* `width: 1%` pada sel tabel = "sesempit isinya". Tanpa ini ketiga kolom
   ini ikut kebagian sisa ruang dan memakan lebar yang dibutuhkan kolom
   teks — No sempat selebar 67px untuk menampung satu digit. */
.table .sel-nomor,
.table .sel-id,
.table .sel-aksi { width: 1%; }

.table th.sel-nomor, .table td.sel-nomor { padding-left: .75rem; padding-right: .5rem; }

/* Nama penulis bertumpuk: beri jarak antarbaris supaya terbaca sebagai
   daftar, bukan satu paragraf. */
.daftar-orang { display: grid; gap: .15rem; font-size: .82rem; }

/* Keterangan kecil di bawah nilai utama sel (mis. tanggal konferensi). */
.sel-catatan {
    display: block;
    margin-top: .25rem;
    font-size: .74rem;
    color: var(--sp-text-soft);
    font-weight: 500;
}

/* --- Tombol aksi di baris tabel --- */

/* Sebelumnya hanya SVG telanjang tanpa nama maupun umpan balik — mudah
   terlewat dan sasaran sentuhnya kecil. */
.btn-detail {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    padding: .32rem .7rem;
    font-size: .78rem;
    font-weight: 600;
    white-space: nowrap;
}

.btn-detail svg { width: .95rem; height: .95rem; flex: 0 0 auto; }

/* --- Keadaan kosong --- */

.sipasi-tanpa-data {
    text-align: center;
    padding: 3rem 1.5rem;
    color: var(--sp-text-soft);
}

.sipasi-tanpa-data svg {
    width: 2.75rem; height: 2.75rem;
    color: var(--sp-brand-400);
    margin-bottom: .85rem;
}

.sipasi-tanpa-data .judul { font-weight: 600; color: var(--sp-text); margin-bottom: .25rem; }

/* --- Baris penyaring di atas tabel --- */

.sipasi-bar-saring {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 1rem;
}

.sipasi-bar-saring .kolom-saring { display: flex; flex-direction: column; gap: .3rem; }

.sipasi-bar-saring label {
    font-size: .74rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--sp-text-soft);
    margin: 0;
}

.sipasi-bar-saring .form-select { min-width: 9rem; }

/* Beberapa penyaring dikirim bersama-sama dalam satu <form> — misalnya
   rentang tanggal beserta tombol terapkannya. Form-nya sendiri ikut jadi
   baris flex supaya kolomnya berjajar seperti penyaring lain, bukan
   menumpuk ke bawah. */
.sipasi-bar-saring > form {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 1rem;
}

/* Kotak tanggal punya ikon kalender di depannya; tanpa lebar tetap ia
   menyusut sampai tanggalnya terpotong. */
.sipasi-bar-saring .kolom-saring-tanggal .input-group {
    width: 100%;
    max-width: 12rem;
    flex-wrap: nowrap;
}

@media (max-width: 575.98px) {
    .sipasi-bar-saring,
    .sipasi-bar-saring .kolom-saring,
    .sipasi-bar-saring form { width: 100%; }
    .sipasi-bar-saring .kolom-saring-tanggal .input-group { max-width: none; }
}

/* =====================================================================
   Tabel yang berubah jadi kartu di ponsel — .tabel-kartu

   Tabel tujuh kolom ini tidak akan pernah muat di layar 375px; menggesernya
   ke samping berarti judul publikasi dan statusnya tidak pernah terlihat
   bersamaan. Di bawah md tiap baris ditata ulang jadi kartu bertumpuk,
   dengan nama kolom diambil dari atribut data-label.

   Ditulis sebagai CSS murni supaya tetap bekerja setelah simple-datatables
   menyusun ulang tbody saat mencari, mengurutkan, atau berpindah halaman —
   baris hasil kloningnya membawa serta atribut data-label.
   ===================================================================== */

@media (max-width: 767.98px) {
    .tabel-kartu thead { display: none; }

    .tabel-kartu,
    .tabel-kartu tbody,
    .tabel-kartu tr,
    .tabel-kartu td {
        display: block;
        width: 100%;
    }

    .tabel-kartu tr {
        border: 1px solid var(--sp-border);
        border-radius: var(--sp-radius);
        background: var(--sp-surface);
        box-shadow: var(--sp-shadow-xs);
        margin-bottom: .85rem;
        padding: .35rem 0;
    }

    .table.tabel-kartu > :not(caption) > * > td {
        border: 0;
        padding: .45rem 1rem;
        white-space: normal;
    }

    .tabel-kartu td[data-label]::before {
        content: attr(data-label);
        display: block;
        font-size: .68rem;
        font-weight: 600;
        text-transform: uppercase;
        letter-spacing: .05em;
        color: var(--sp-muted);
        margin-bottom: .15rem;
    }

    /* Nomor urut kehilangan maknanya di daftar kartu; ID yang dipakai orang
       untuk merujuk satu publikasi, jadi itu yang jadi kepala kartu. */
    .tabel-kartu td.sel-nomor { display: none; }

    .tabel-kartu td.sel-id {
        font-weight: 700;
        color: var(--sp-brand-800);
        border-bottom: 1px solid var(--sp-border) !important;
        padding-bottom: .5rem;
        margin-bottom: .25rem;
    }

    /* Lebar kolom versi meja tidak relevan lagi saat ditumpuk. */
    .tabel-kartu .kolom-judul,
    .tabel-kartu .kolom-jurnal,
    .tabel-kartu .kolom-orang,
    .tabel-kartu .kolom-status { min-width: 0; max-width: none; }

    /* `width: 1%` yang membuat kolom No/ID/Detail sesempit isinya di layar
       lebar (0,2,0) mengalahkan `width: 100%` pada `.tabel-kartu td`
       (0,1,1) — tanpa baris ini selnya tinggal selebar satu huruf dan
       labelnya turun ke bawah satu per satu. */
    .table.tabel-kartu .sel-nomor,
    .table.tabel-kartu .sel-id,
    .table.tabel-kartu .sel-aksi { width: auto; }

    .tabel-kartu .kolom-judul { font-weight: 600; }

    .tabel-kartu .daftar-status .status-nama { flex: 0 0 6rem; }

    .tabel-kartu td.sel-aksi { padding-top: .25rem; }
    .tabel-kartu .btn-detail { width: 100%; justify-content: center; padding: .5rem; }

    /* Tanpa ini pembungkusnya masih menyediakan geseran mendatar untuk
       tabel yang sudah tidak lebar lagi. */
    .tabel-kartu-bungkus,
    .dataTable-wrapper:has(.tabel-kartu) .dataTable-container { overflow-x: visible; }
    .tabel-kartu-bungkus { background-image: none; }
}

/* =====================================================================
   Halaman rincian publikasi (data-artikel-diterima)
   ===================================================================== */

/* Kartu rincian dan kepala halamannya berbagi lebar maksimum yang sama
   supaya tepinya sejajar. Dulu dipatok `style="width: 53rem"` di markup. */
.sipasi-lebar-rincian {
    width: 100%;
    max-width: 53rem;
    margin-left: auto;
    margin-right: auto;
}

/* Judul artikel jadi judul halaman; panjangnya bisa dua sampai tiga baris,
   jadi ukurannya sedikit diturunkan dari kepala halaman biasa. */
.sipasi-page-head .page-head-judul { overflow-wrap: anywhere; }
.sipasi-lebar-rincian.sipasi-page-head .page-head-judul { font-size: 1.2rem; }

.sipasi-page-head .chip-baik {
    background: rgba(16, 185, 129, .28);
    border-color: rgba(16, 185, 129, .5);
    color: #C4F1DE;
}

.sipasi-page-head .chip-buruk {
    background: rgba(220, 53, 69, .28);
    border-color: rgba(220, 53, 69, .5);
    color: #FBD3D8;
}

/* ---------------------------------------------------------------------
   Tabel rincian (label | nilai | aksi)

   Tabel ini bukan daftar data melainkan rincian satu publikasi, jadi
   ditampilkan seperti daftar rincian: label redup, nilai menonjol, kolom
   aksi merapat ke kanan.
   --------------------------------------------------------------------- */

.tabel-detail { margin-bottom: 0; }

.tabel-detail > tbody > tr > td {
    border-bottom: 1px solid #F3EFF5;
    vertical-align: top;
    padding: .8rem .9rem;
    /* Volt memasang `white-space: nowrap` pada semua sel tabel. Pada tabel
       rincian akibatnya tiap kolom selebar teks terpanjangnya dan tabelnya
       meluber keluar kartu. Rincian justru harus boleh turun baris. */
    white-space: normal;
}

.tabel-detail > tbody > tr:last-child > td { border-bottom: 0; }

/* Kolom pertama = label. Lebarnya dulu dipatok `style="width: 10rem"` di 17
   baris; label seperti "Tautan Halaman Jurnal/Seminar" tidak muat dan
   memaksa kolomnya melebar sendiri. */
.tabel-detail > tbody > tr > td:first-child {
    color: var(--sp-text-soft);
    font-weight: 500;
    width: 13rem;
    min-width: 8rem;
    overflow-wrap: anywhere;
}

/* Kolom aksi = sel ke-3 yang sekaligus sel terakhir. Memakai :last-child
   saja akan salah sasaran: baris yang nilainya memakai colspan="2" juga
   berakhir sebagai sel terakhir dan teksnya ikut terdorong ke kanan. */
.tabel-detail > tbody > tr > td:nth-child(3):last-child,
.tabel-detail > tbody > tr > td.sel-aksi {
    width: 1%;
    text-align: right;
}

.sel-nilai {
    white-space: normal;
    /* break-word, bukan anywhere: `anywhere` memenggal kata di tengah
       begitu kolomnya menyempit. */
    overflow-wrap: break-word;
    color: var(--sp-text);
}

.sel-nilai + .sel-nilai { margin-top: .5rem; }

/* Tombol ikon di kolom aksi (.coffeeButton dari my_css.css). Sebelumnya
   SVG telanjang tanpa batas maupun umpan balik — sasaran sentuhnya kecil
   dan sulit dikenali sebagai tombol. */
.tabel-detail .coffeeButton {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2rem;
    height: 2rem;
    border-radius: var(--sp-radius-sm);
    color: var(--sp-brand-700);
    background: var(--sp-brand-50);
    transition: background-color .18s ease, color .18s ease;
}

.tabel-detail .coffeeButton:hover {
    background: var(--sp-brand-100);
    color: var(--sp-brand-700);
}

/* `.icon-xs me-2` bawaan markup menyisakan margin kanan di dalam tombol
   bundar, jadi ikonnya tidak di tengah. */
.tabel-detail .coffeeButton svg { margin: 0 !important; width: 1rem; height: 1rem; }
.tabel-detail .coffeeButton svg:hover { transform: none; }

/* Tautan unduh berkas di dalam sel: `.nav-link` bawaan Volt membuatnya
   setinggi baris menu dan tanpa penanda apa pun. */
.tabel-detail .nav-link {
    display: inline-flex !important;
    align-items: center;
    gap: .35rem;
    padding: .3rem .6rem;
    border: 1px solid var(--sp-brand-100);
    border-radius: 999px;
    background: var(--sp-brand-50);
    color: var(--sp-brand-700);
    font-size: .78rem;
    font-weight: 600;
}

.tabel-detail .nav-link:hover {
    background: var(--sp-brand-600);
    border-color: var(--sp-brand-600);
    color: #fff;
}

.tabel-detail .nav-link svg { margin: 0 !important; width: .95rem; height: .95rem; }

/* Catatan verifikasi ditulis <p style="white-space: pre-wrap; font-size:100%">;
   beri warna dan ukuran yang selaras dengan sel lain. */
.tabel-detail p { font-size: .875rem; margin-bottom: 0; color: var(--sp-text); }

/* ---------------------------------------------------------------------
   Deretan tombol di kaki kartu rincian
   --------------------------------------------------------------------- */

.sipasi-aksi-rincian {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: .5rem;
    padding: 1rem 1.5rem;
}

@media (max-width: 575.98px) {
    .sipasi-aksi-rincian { padding: 1rem; }
    .sipasi-aksi-rincian .btn { width: 100%; }
}

/* ---------------------------------------------------------------------
   Rincian di ponsel: label di atas, nilai di bawah
   --------------------------------------------------------------------- */

@media (max-width: 767.98px) {
    .tabel-detail,
    .tabel-detail tbody,
    .tabel-detail tr,
    .tabel-detail > tbody > tr > td { display: block; width: 100%; }

    .tabel-detail > tbody > tr {
        border-bottom: 1px solid var(--sp-border);
        padding: .55rem 0;
        position: relative;
    }

    .tabel-detail > tbody > tr:last-child { border-bottom: 0; }

    .tabel-detail > tbody > tr > td {
        border-bottom: 0;
        padding: .1rem .25rem;
    }

    /* Label jadi kepala baris. `width` di sini harus !important: sebagian
       sel masih membawa lebar dari markup, dan aturan lebar kolom di atas
       (0,3,1) tetap berlaku di dalam media query ini. */
    .tabel-detail > tbody > tr > td:first-child {
        width: auto !important;
        min-width: 0;
        font-size: .7rem;
        font-weight: 600;
        text-transform: uppercase;
        letter-spacing: .04em;
        color: var(--sp-muted);
    }

    /* Kolom aksi naik ke kanan atas baris supaya tidak menghabiskan satu
       baris sendiri di bawah nilainya. */
    .tabel-detail > tbody > tr > td:nth-child(3):last-child,
    .tabel-detail > tbody > tr > td.sel-aksi {
        width: auto !important;
        position: absolute;
        top: .45rem;
        right: .25rem;
        padding: 0;
    }

    /* Beri ruang di kanan supaya nilai tidak menabrak tombol aksi. */
    .tabel-detail > tbody > tr > td:nth-child(2) { padding-right: 2.5rem; }

    .tabel-detail-bungkus { overflow-x: visible; background-image: none; }
}

/* =====================================================================
   Formulir pelaporan (submission-artikel-diterima)
   ===================================================================== */

.sipasi-lebar-formulir {
    width: 100%;
    max-width: 60rem;
    margin-left: auto;
    margin-right: auto;
}

/* --- Kepala bagian formulir ---------------------------------------------

   Formulirnya panjang dan sebelumnya mengalir tanpa jeda dari Tipe
   Publikasi sampai Abstrak. Lima kepala bagian memberi titik istirahat dan
   memberi tahu apa yang sedang diisi.
   ---------------------------------------------------------------------- */

.sipasi-bagian {
    display: flex;
    align-items: flex-start;
    gap: .85rem;
    margin: 2rem 0 1.1rem;
    padding-top: 1.25rem;
    border-top: 1px solid var(--sp-border);
}

/* Bagian pertama menempel di bawah pesan flash / atas kartu, jadi tidak
   perlu garis pemisah maupun jarak atas. */
.card-body > .sipasi-bagian:first-child,
.form-control + .sipasi-bagian,
form > .sipasi-bagian:first-child {
    margin-top: .25rem;
    padding-top: 0;
    border-top: 0;
}

.sipasi-bagian .bagian-nomor {
    flex: 0 0 auto;
    width: 1.75rem;
    height: 1.75rem;
    border-radius: 50%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--sp-brand-50);
    border: 1px solid var(--sp-brand-100);
    color: var(--sp-brand-700);
    font-size: .8rem;
    font-weight: 700;
}

.sipasi-bagian .bagian-judul {
    font-weight: 600;
    color: var(--sp-brand-900);
    line-height: 1.3;
}

.sipasi-bagian .bagian-ket {
    font-size: .8rem;
    color: var(--sp-text-soft);
    margin-top: .1rem;
}

/* --- Tabel isian berulang (tim penulis, kolaborator) -------------------- */

/* Tombol tambah baris: dulu SVG telanjang tanpa batas, sulit dikenali
   sebagai tombol dan sasaran sentuhnya kecil. */
.tabel-input .coffeeButton {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.25rem;
    height: 2.25rem;
    border-radius: var(--sp-radius-sm);
    color: var(--sp-brand-700);
    background: var(--sp-brand-50);
    border: 1px solid var(--sp-brand-100);
    transition: background-color .18s ease, color .18s ease;
}

.tabel-input .coffeeButton:hover {
    background: var(--sp-brand-600);
    border-color: var(--sp-brand-600);
    color: #fff;
}

.tabel-input .coffeeButton svg { margin: 0 !important; width: 1.05rem; height: 1.05rem; }
.tabel-input .coffeeButton svg:hover { transform: none; }

/* Sel isian tidak perlu `white-space: nowrap` milik Volt. */
.table.tabel-input > :not(caption) > * > td { white-space: normal; vertical-align: middle; }

/* Kolom aksi sesempit tombolnya. */
.table.tabel-input > :not(caption) > * > td:last-child,
.table.tabel-input > thead > tr > th:last-child { width: 1%; }

@media (max-width: 767.98px) {
    /* Isian melebar penuh saat baris jadi kartu; nomor urut penulis tetap
       sempit karena isinya hanya satu atau dua digit. */
    .tabel-input td .form-control,
    .tabel-input td .form-select,
    .tabel-input td .input-group { width: 100%; }

    .tabel-input td[data-label="Urutan Penulis"] .form-control { width: 6rem; }

    /* Sel tanpa label = kolom tombol tambah; rapatkan ke kanan. */
    .tabel-input td:not([data-label]) { text-align: right; }
}

/* =====================================================================
   Kolom pencairan (reimburse-dosen)
   ===================================================================== */

.kolom-pencairan { min-width: 8rem; max-width: 11rem; white-space: normal; }

/* Nominal dibaca dengan membandingkan digit antarbaris, jadi angkanya
   dirata-kanan dan diberi angka lebar-tetap supaya kolomnya sejajar. */
.table td.kolom-pencairan { text-align: right; }

.nilai-uang {
    display: block;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    color: var(--sp-text);
}

.teks-kosong { color: var(--sp-muted); font-size: .8rem; font-style: italic; }

/* Keterangan tanggal di bawah nominal ikut rata kanan di tampilan tabel. */
.table td.kolom-pencairan .sel-catatan { text-align: right; }

@media (max-width: 767.98px) {
    /* Di mode kartu semuanya rata kiri seperti field lain. */
    .tabel-kartu td.kolom-pencairan,
    .tabel-kartu td.kolom-pencairan .sel-catatan { text-align: left; }
    .tabel-kartu .kolom-pencairan { min-width: 0; max-width: none; }
}

/* =====================================================================
   Riwayat proses (data-reimburse)
   ===================================================================== */

/* Kepala bagian di dalam kartu rincian tidak perlu jarak sebesar di
   formulir, dan lingkaran nomornya di sini berisi ikon, bukan angka. */
.card-body > .sipasi-bagian { margin-top: 1.5rem; }

.sipasi-bagian .bagian-nomor svg { width: .95rem; height: .95rem; }

.tabel-riwayat { margin-bottom: 0; }

/* Nama tahapan adalah isi utama tiap baris. */
.table.tabel-riwayat > tbody > tr > td.sel-aktivitas {
    font-weight: 600;
    color: var(--sp-text);
    white-space: normal;
}

.table.tabel-riwayat > tbody > tr > td { vertical-align: middle; }

/* Kolom status dan tanggal sesempit isinya supaya nama tahapan yang
   panjang ("Pengajuan Pencairan ke Keuangan") mendapat sisa ruangnya. */
.table.tabel-riwayat > :not(caption) > * > *:nth-child(2),
.table.tabel-riwayat > :not(caption) > * > *:nth-child(3) { width: 1%; white-space: nowrap; }

@media (max-width: 767.98px) {
    /* Nama tahapan jadi kepala kartu, seperti ID pada tabel daftar. */
    .tabel-kartu td.sel-aktivitas {
        font-weight: 700;
        color: var(--sp-brand-800);
        border-bottom: 1px solid var(--sp-border) !important;
        padding-bottom: .5rem;
        margin-bottom: .25rem;
    }

    .table.tabel-riwayat > :not(caption) > * > *:nth-child(2),
    .table.tabel-riwayat > :not(caption) > * > *:nth-child(3) { width: auto; white-space: normal; }
}

/* =====================================================================
   Kartu angka ringkasan (insentif-sitasi)

   Menggantikan tabel satu baris berisi lima kolom. Angka tunggal seperti
   jumlah sitasi dan nominal insentif lebih terbaca sebagai kartu; sebagai
   tabel, judul kolomnya sampai harus dipenggal dengan <br> agar muat.
   ===================================================================== */

.sipasi-statistik {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
    gap: 1rem;
}

.kartu-angka {
    background: var(--sp-surface);
    border: 1px solid var(--sp-border);
    border-radius: var(--sp-radius);
    box-shadow: var(--sp-shadow-sm);
    padding: 1.1rem 1.25rem;
}

.kartu-angka .angka-label {
    font-size: .72rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .05em;
    color: var(--sp-text-soft);
    margin-bottom: .4rem;
}

.kartu-angka .angka-nilai {
    font-size: 1.6rem;
    font-weight: 700;
    line-height: 1.15;
    color: var(--sp-brand-900);
    font-variant-numeric: tabular-nums;
}

/* Kartu angka yang punya tombol ubah di sebelah nilainya. */
.kartu-angka .angka-nilai-aksi {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .5rem;
}

/* Nominal rupiah lebih panjang dari jumlah sitasi; ukurannya diturunkan
   supaya tidak memaksa kartunya melebar. */
.kartu-angka .angka-uang { font-size: 1.25rem; }

.kartu-angka .angka-kosong {
    font-size: .95rem;
    font-weight: 500;
    font-style: italic;
    color: var(--sp-muted);
}

.kartu-angka .angka-catatan {
    margin-top: .3rem;
    font-size: .75rem;
    color: var(--sp-text-soft);
}

/* --- Kolom angka di dalam tabel ---------------------------------------- */

.kolom-angka { white-space: nowrap; }

/* Sesempit isinya, dan rata kanan supaya digitnya sejajar antarbaris. */
.table .kolom-angka { width: 1%; }
.table td.kolom-angka {
    text-align: right;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

@media (max-width: 767.98px) {
    /* Di mode kartu semuanya rata kiri seperti field lain. */
    .tabel-kartu td.kolom-angka { text-align: left; width: auto !important; }
}

/* =====================================================================
   Kolom tanggal di dalam tabel daftar
   ===================================================================== */

/* Tanggal punya panjang tetap, jadi kolomnya cukup selebar isinya —
   sisanya diberikan ke kolom judul dan nama media. */
.sel-tanggal { white-space: nowrap; }
.table .sel-tanggal { width: 1%; }

@media (max-width: 767.98px) {
    .tabel-kartu td.sel-tanggal { width: auto !important; }
}

/* =====================================================================
   Tombol hapus di baris tabel (data-jurnal-*)
   ===================================================================== */

/* .coffeeButton dari my_css.css hanya SVG telanjang. Varian hapus diberi
   warna bahaya supaya jelas aksinya tidak bisa dibatalkan. */
.btn-hapus {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.25rem;
    height: 2.25rem;
    border-radius: var(--sp-radius-sm);
    color: var(--sp-danger);
    background: #FBE9EC;
    border: 1px solid #F3C9D0;
    transition: background-color .18s ease, color .18s ease;
}

.btn-hapus:hover { background: var(--sp-danger); border-color: var(--sp-danger); color: #fff; }
.btn-hapus svg { margin: 0 !important; width: 1.05rem; height: 1.05rem; }
.btn-hapus svg:hover { transform: none; }

/* Baris "tidak ada hasil" dari partial AJAX. */
.baris-kosong {
    text-align: center;
    color: var(--sp-muted);
    font-style: italic;
}

/* Kotak pencarian butuh ruang lebih dari pemilih tahun. */
.sipasi-bar-saring .kolom-saring-lebar { flex: 1 1 22rem; }
.sipasi-bar-saring .kolom-saring-lebar .form-control { width: 100%; }

/* =====================================================================
   Tombol ubah di baris tabel (pasangan .btn-hapus)
   ===================================================================== */

.btn-ubah {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.25rem;
    height: 2.25rem;
    border-radius: var(--sp-radius-sm);
    color: var(--sp-brand-700);
    background: var(--sp-brand-50);
    border: 1px solid var(--sp-brand-100);
    transition: background-color .18s ease, color .18s ease;
}

.btn-ubah:hover { background: var(--sp-brand-600); border-color: var(--sp-brand-600); color: #fff; }
.btn-ubah svg { margin: 0 !important; width: 1.05rem; height: 1.05rem; }
.btn-ubah svg:hover { transform: none; }

/* =====================================================================
   Daftar tautan luar di dalam sel tabel

   Menggantikan URL mentah yang ditampilkan utuh. Alamat seperti
   scopus.com/sourceid/21100... memaksa kolomnya melebar padahal tidak
   ada yang benar-benar membacanya - yang dibutuhkan hanya "ini tautan
   apa" dan bisa diklik.
   ===================================================================== */

.kolom-tautan { white-space: normal; }
.table .kolom-tautan { width: 1%; }

.daftar-tautan {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: .3rem;
}

/* Volt memasang `.p, ol li, p, ul li { font-size: 1rem }`, jadi ukurannya
   harus dinyatakan pada <li>-nya sendiri, bukan cukup di induknya. */
.daftar-tautan li { font-size: .8rem; line-height: 1.3; }

.pil-tautan {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    padding: .25rem .6rem;
    border: 1px solid var(--sp-brand-100);
    border-radius: 999px;
    background: var(--sp-brand-50);
    color: var(--sp-brand-700);
    font-size: .78rem;
    font-weight: 600;
    text-decoration: none;
    white-space: nowrap;
    transition: background-color .18s ease, border-color .18s ease, color .18s ease;
}

.pil-tautan:hover,
.pil-tautan:focus {
    background: var(--sp-brand-600);
    border-color: var(--sp-brand-600);
    color: #fff;
    text-decoration: none;
}

.pil-tautan .ikon-jenis { width: .95rem; height: .95rem; flex: 0 0 auto; }

@media (max-width: 767.98px) {
    .tabel-kartu .kolom-tautan { width: auto !important; }
    .daftar-tautan { flex-direction: row; flex-wrap: wrap; }
}

/* URL panjang di dalam daftar rincian perlu boleh dipenggal di mana saja;
   tanpa ini alamat tanpa spasi melebar keluar modal. */
.pecah-kata { overflow-wrap: anywhere; word-break: break-word; }

/* =====================================================================
   Bar penyaring bertingkat (artikel-diterima-admin)

   Halaman admin punya tiga penyaring plus satu grup unduh dalam satu bar.
   Masing-masing dibungkus <form> sendiri karena tiap pilihan mengirimkan
   parameternya masing-masing ke server.
   ===================================================================== */

.sipasi-bar-saring form { margin: 0; }

/* Grup unduh menempel ke kanan pada layar lebar, dan turun penuh di bawahnya
   saat ruangnya tidak cukup. */
@media (max-width: 1199.98px) {
    .sipasi-bar-saring .ms-xl-auto { width: 100%; }
}

/* Nilai timeline di kolom status: label kiri, tanggal kanan, dan tanggalnya
   tidak dipenggal di tengah. */
.daftar-status li > span:last-child { white-space: nowrap; font-weight: 500; color: var(--sp-text); }

/* Keterangan "Diperbarui ... oleh ..." di bawah tombol aksi. */
.sel-aksi .sel-catatan { margin-top: .4rem; line-height: 1.35; }

/* Kartu ringkasan antrean di halaman admin: selebar isinya, tidak perlu
   memenuhi lebar halaman. */
.sipasi-kartu-antrean { max-width: 30rem; }

/* Kolom kotak centang di tabel keuangan: sesempit kotaknya. */
.sel-pilih { white-space: nowrap; }
.table .sel-pilih { width: 1%; }

@media (max-width: 767.98px) {
    .tabel-kartu td.sel-pilih { width: auto !important; }
}

/* =====================================================================
   Kartu ringkas — formulir satu-dua field (login-as)
   ===================================================================== */

/* Kartu selebar 60rem untuk satu field terasa kosong; 34rem cukup dan
   isinya tetap sejajar dengan kepala halamannya. */
.sipasi-lebar-ringkas {
    width: 100%;
    max-width: 34rem;
    margin-left: auto;
    margin-right: auto;
}

/* Keterangan kecil di bawah field: menjelaskan aturan isian tanpa
   menambah baris label. */
.petunjuk-field {
    display: block;
    margin-top: .4rem;
    font-size: .78rem;
    line-height: 1.4;
    color: var(--sp-text-soft);
}

/* =====================================================================
   Deretan pilihan centang / radio berdampingan
   ===================================================================== */

/* Menggantikan pola `d-flex` + `margin-right` sebaris: boleh turun baris,
   jaraknya seragam, dan sasaran sentuhnya tidak berdempetan di ponsel. */
.daftar-pilihan {
    display: flex;
    flex-wrap: wrap;
    gap: .6rem 1.5rem;
}

.daftar-pilihan .form-check { margin-bottom: 0; }

.daftar-pilihan .form-check-label {
    font-size: .875rem;
    cursor: pointer;
}

@media (max-width: 575.98px) {
    /* Satu pilihan per baris supaya mudah disentuh. */
    .daftar-pilihan { flex-direction: column; gap: .65rem; }
}

/* =====================================================================
   Verifikasi per dokumen — .kotak-verifikasi
   ===================================================================== */

/* Sebelumnya berupa tabel empat kolom (No | Dokumen | Tidak Valid | Valid)
   yang radionya tidak berlabel sama sekali: judul kolomnya yang jadi
   satu-satunya penanda arti, dan di ponsel kolom itu tergeser keluar
   layar sehingga tidak jelas radio mana yang mana. */
.kotak-verifikasi {
    border: 1px solid var(--sp-border);
    border-radius: var(--sp-radius-sm);
    background: var(--sp-brand-50);
    padding: .7rem .9rem;
}

.kotak-verifikasi + .kotak-verifikasi { margin-top: .6rem; }

.kotak-verifikasi .nama-dokumen {
    font-weight: 600;
    font-size: .875rem;
    color: var(--sp-text);
    margin-bottom: .45rem;
}

/* Deretan select program studi pada formulir eligibilitas. Jaraknya dulu
   ditulis `margin-bottom: 10px` pada tiap select. */
.daftar-prodi { display: grid; gap: .5rem; }

/* =====================================================================
   Daftar hasil pencarian yang panjang — .tabel-gulir-tinggi
   ===================================================================== */

/* Pencarian dosen mengembalikan sampai 100 baris; tingginya dibatasi supaya
   kotak pencarian tetap terlihat saat daftarnya digulir, dan kepala tabel
   ikut menempel di atas. Dulu max-height dan overflow ditulis sebaris pada
   pembungkusnya. */
.tabel-gulir-tinggi { max-height: 31rem; overflow-y: auto; }

.tabel-gulir-tinggi thead th {
    position: sticky;
    top: 0;
    z-index: 3;
}

@media (max-width: 767.98px) {
    /* Di mode kartu kepala tabel disembunyikan dan tiap baris jadi kartu;
       membatasi tingginya di sini justru menyembunyikan hasil pencarian. */
    .tabel-gulir-tinggi { max-height: none; }
}

/* =====================================================================
   Judul bagian di dalam kartu — .sipasi-judul-bagian
   ===================================================================== */

/* Judul beserta tombol ubahnya. Sebelumnya tombolnya diletakkan di baris
   grid tersendiri di atas tabelnya (col-md-8 / col-md-4 dengan
   justify-content-end), jadi di layar sempit ia melayang jauh dari
   bagian yang diubahnya. */
.sipasi-judul-bagian {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: .5rem 1rem;
    margin-bottom: .9rem;
}

.sipasi-judul-bagian + .sipasi-judul-bagian { margin-top: 1.5rem; }

/* Bagian kedua dan seterusnya dalam satu panel diberi jarak dari bagian
   sebelumnya. */
.tab-pane > .sipasi-judul-bagian ~ .sipasi-judul-bagian { margin-top: 2rem; }

/* =====================================================================
   Galeri gambar dashboard — .galeri-gambar
   ===================================================================== */

/* Sebelumnya berupa tabel satu kolom berjudul "Gambar", dan seluruh
   daftarnya dirender dua kali: sekali untuk melihat, sekali lagi (dengan
   kolom centang) untuk menghapus. Kini satu galeri saja; kotak centangnya
   yang muncul saat mode hapus dinyalakan. */
.galeri-gambar {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(17rem, 1fr));
    gap: 1rem;
}

.kartu-gambar {
    position: relative;
    display: block;
    margin: 0;
    border: 1px solid var(--sp-border);
    border-radius: var(--sp-radius);
    background: var(--sp-surface);
    box-shadow: var(--sp-shadow-xs);
    overflow: hidden;
}

.kartu-gambar img {
    display: block;
    width: 100%;
    height: auto;
    background: var(--sp-brand-50);
}

.kartu-gambar .nama-gambar {
    display: block;
    padding: .55rem .8rem;
    font-size: .76rem;
    line-height: 1.35;
    color: var(--sp-text-soft);
    overflow-wrap: anywhere;
}

.kartu-gambar .pilih-gambar {
    position: absolute;
    top: .6rem;
    right: .6rem;
    width: 1.35rem;
    height: 1.35rem;
    margin: 0;
    box-shadow: 0 1px 4px rgba(51, 27, 65, .35);
}

/* Di luar mode hapus, kotak centangnya tidak ada gunanya. */
.galeri-gambar:not(.mode-hapus) .pilih-gambar { display: none; }

.galeri-gambar.mode-hapus .kartu-gambar { cursor: pointer; }

/* Penanda terpilih; peramban tanpa :has() tetap menunjukkannya lewat
   kotak centangnya sendiri. */
.galeri-gambar.mode-hapus .kartu-gambar:has(.pilih-gambar:checked) {
    border-color: var(--sp-danger);
    box-shadow: 0 0 0 .18rem rgba(220, 53, 69, .22);
}

/* =====================================================================
   Penulis anggota unit sendiri — .orang-unit
   ===================================================================== */

/* Pada daftar publikasi KK/CoE/RI, penulis yang termasuk anggota unit
   ditandai supaya terbedakan dari rekan penulis lain. Sebelumnya ditulis
   `style="color: blue"` sebaris - warna di luar palet, dan warna saja
   bukan penanda yang cukup: pembaca layar maupun pengguna buta warna
   tidak menerima informasinya. Ketebalan huruf ikut jadi penanda. */
.orang-unit {
    color: var(--sp-brand-700);
    font-weight: 700;
}

/* =====================================================================
   Kolom nama yang lebih lapang — .kolom-orang-lebar
   ===================================================================== */

/* .kolom-orang dibatasi 11rem karena di kebanyakan tabel ia berdampingan
   dengan kolom judul dan jurnal yang sama-sama butuh ruang. Pada tabel yang
   kolom teksnya hanya nama - sisanya angka sempit - batas itu membuat nama
   panjang pecah jadi banyak baris padahal ruangnya berlebih.

   Ditulis dengan dua kelas (0,2,0) supaya menang atas `.kolom-orang`
   (0,1,0) tanpa bergantung pada urutan berkas. */
.kolom-orang.kolom-orang-lebar {
    min-width: 16rem;
    max-width: 26rem;
}

@media (max-width: 767.98px) {
    /* Di mode kartu lebar kolom versi meja tidak berlaku lagi. Aturan
       pelonggar bawaannya (.tabel-kartu .kolom-orang, 0,2,0) tidak cukup
       untuk mengalahkan kelas di atas, jadi dinyatakan ulang di sini. */
    .tabel-kartu .kolom-orang.kolom-orang-lebar { min-width: 0; max-width: none; }
}

/* Daftar butir pakta integritas. Volt memasang `ol li, ul li { font-size:
   1rem }`, jadi ukurannya harus dinyatakan pada <li>-nya sendiri - dulu
   ditulis `style="font-size: 14px"` pada tiap butir dan tiap paragraf. */
.sipasi-daftar-pakta li {
    font-size: .875rem;
    line-height: 1.5;
    margin-bottom: .35rem;
}

.modal-body > p { font-size: .875rem; }
