/*
 * THI Admin visual system
 * A presentation-only layer: application markup and JavaScript hooks stay intact.
 */

/* ---------------------------------------------------------------------------
   Theme-agnostic tokens: brand colours, the green rail, type, geometry.
   Surface/text colours live in the light & dark blocks below instead - putting
   them here would outrank the theme's own [data-bs-theme="dark"] rules (equal
   specificity, and this file loads last) and the dark-mode toggle would do
   nothing.
   --------------------------------------------------------------------------- */
:root {
    --thi-green: #195929;
    --thi-green-deep: #103d1c;
    --thi-radius: 14px;
    --thi-accent: #2f7a41;
    --thi-font: "Plus Jakarta Sans", Inter, "Segoe UI", sans-serif;
    /* Bootstrap/Velzon's own font token - retargeting it converts every
       `font-family: var(--vz-font-sans-serif)` site in one move. */
    --vz-font-sans-serif: "Plus Jakarta Sans", Inter, "Segoe UI", sans-serif;
    --vz-primary: #195929;
    --vz-primary-rgb: 25, 89, 41;
    --vz-link-color: #195929;
    --vz-link-hover-color: #103d1c;
    --vz-vertical-menu-width: 264px;
    /* Rel yang diciutkan: sisto memakai 80px, bukan 70px bawaan tema. */
    --vz-vertical-menu-width-sm: 80px;
    /* Theme fills the whole topbar user block with this; sisto leaves it
       flush with the bar and only tints on hover, so keep it transparent. */
    --vz-topbar-user-bg: transparent;
    /* The rail stays green in both themes, so these are theme-agnostic. */
    --vz-vertical-menu-bg: #195929;
    --vz-vertical-menu-border: #195929;
    --vz-vertical-menu-item-color: rgba(255, 255, 255, .78);
    --vz-vertical-menu-item-bg: rgba(255, 255, 255, .12);
    --vz-vertical-menu-item-hover-color: #ffffff;
    --vz-vertical-menu-item-active-color: #ffffff;
    --vz-vertical-menu-item-active-bg: rgba(255, 255, 255, .16);
    --vz-vertical-menu-sub-item-color: rgba(255, 255, 255, .70);
    --vz-vertical-menu-sub-item-hover-color: #ffffff;
    --vz-vertical-menu-sub-item-active-color: #ffffff;
    --vz-vertical-menu-title-color: rgba(255, 255, 255, .56);
}

/* Light surfaces (default). */
:root,
:root[data-bs-theme="light"] {
    --thi-surface: #ffffff;
    --thi-surface-2: #f6f9f6;
    /* Belang baris tabel. Sengaja sedikit lebih terang dari --thi-surface-2
       yang dipakai kepala tabel, supaya kepalanya tidak lebur dengan baris
       ganjil pertama. */
    --thi-stripe: #fbfdfb;
    /* Batang abu-abu skeleton saat tabel memuat, dan kilau yang menyapu di
       atasnya. Kilaunya putih pekat karena batangnya terang. */
    --thi-skeleton: #e6ede8;
    --thi-skeleton-sheen: rgba(255, 255, 255, .85);
    --thi-green-soft: #e9f4eb;
    --thi-green-pale: #f4faf5;
    --thi-canvas: #f4f7f5;
    --thi-line: #e1eae3;
    --thi-ink: #18251c;
    --thi-muted: #708076;
    --vz-primary-text-emphasis: #103d1c;
    --vz-primary-bg-subtle: #e9f4eb;
    --vz-primary-border-subtle: #bcd9c2;
    --vz-body-bg: #f4f7f5;
    --vz-body-color: #26352a;
    --vz-border-color: #e1eae3;
    --vz-secondary-bg: #ffffff;
    --vz-tertiary-bg: #f8fbf8;
    --vz-header-bg: #ffffff;
    --vz-header-border: #e1eae3;
    --vz-header-item-color: #56705d;
    --vz-header-item-bg: #e9f4eb;
    --vz-header-item-sub-color: #708076;
    --vz-footer-bg: #ffffff;
    --vz-footer-color: #708076;
}

/* Dark surfaces - same green brand, inverted neutrals. */
:root[data-bs-theme="dark"] {
    --thi-surface: #1d2823;
    --thi-surface-2: #222e28;
    /* Di mode gelap arahnya dibalik: belang sedikit lebih terang dari alas,
       tapi tetap lebih gelap dari kepala tabel. */
    --thi-stripe: #202b26;
    /* Di mode gelap kilau putih pekat akan menyilaukan, jadi tipis sekali -
       cukup untuk terlihat bergerak. */
    --thi-skeleton: #2a3831;
    --thi-skeleton-sheen: rgba(255, 255, 255, .055);
    --thi-green-soft: #24402c;
    --thi-green-pale: #1f3326;
    --thi-canvas: #141c17;
    --thi-line: #2e3d34;
    --thi-ink: #e7f0e9;
    --thi-muted: #93a699;
    --vz-primary-text-emphasis: #9fe3ac;
    --vz-primary-bg-subtle: #24402c;
    --vz-primary-border-subtle: #37563f;
    --vz-body-bg: #141c17;
    --vz-body-color: #dce7df;
    --vz-border-color: #2e3d34;
    --vz-secondary-bg: #1d2823;
    --vz-tertiary-bg: #222e28;
    --vz-header-bg: #1d2823;
    --vz-header-border: #2e3d34;
    --vz-header-item-color: #b7c9bd;
    --vz-header-item-bg: #24402c;
    --vz-header-item-sub-color: #93a699;
    --vz-footer-bg: #1d2823;
    --vz-footer-color: #93a699;
    --vz-link-color: #9fe3ac;
    --vz-link-hover-color: #c3eecb;
}

/* The existing shell declares data-sidebar="dark". Keep that state for its
   responsive behaviour while replacing only its old blue/white palette. */
:root[data-sidebar="dark"] {
    --vz-vertical-menu-bg: #195929;
    --vz-vertical-menu-border: #195929;
    --vz-vertical-menu-item-color: rgba(255, 255, 255, .78);
    --vz-vertical-menu-item-bg: rgba(255, 255, 255, .12);
    --vz-vertical-menu-item-hover-color: #ffffff;
    --vz-vertical-menu-item-active-color: #ffffff;
    --vz-vertical-menu-item-active-bg: rgba(255, 255, 255, .16);
    --vz-vertical-menu-sub-item-color: rgba(255, 255, 255, .70);
    --vz-vertical-menu-sub-item-hover-color: #ffffff;
    --vz-vertical-menu-sub-item-active-color: #ffffff;
    --vz-vertical-menu-title-color: rgba(255, 255, 255, .56);
}

body,
.page-content {
    background: var(--thi-canvas);
    color: var(--thi-ink);
}

/* The theme hardcodes "hkgrotesk" (a bundled @font-face, so it really does
   render) and "Poppins" in a handful of places that ignore the font token
   above - the sidebar menu among them. Pull them all onto one typeface. */
body,
button,
input,
select,
textarea,
.h1, .h2, .h3, .h4, .h5, .h6,
h1, h2, h3, h4, h5, h6,
.ff-secondary,
.navbar-menu .navbar-nav .nav-link,
.navbar-menu .navbar-nav .nav-sm .nav-link,
.navbar-menu .navbar-nav .menu-title,
.chat-list > li a,
.contact-list li,
.fc .fc-multimonth-multicol .fc-daygrid-more-link,
.leaflet-map.leaflet-container {
    font-family: var(--thi-font);
}

/* Application shell */
#page-topbar {
    background: var(--thi-surface);
    border-bottom: 1px solid var(--thi-line);
    box-shadow: none;
}

.navbar-header { height: 72px; }
.navbar-brand-box { background: var(--thi-green); }
.app-menu.navbar-menu {
    width: var(--vz-vertical-menu-width);
    background: var(--thi-green);
    border-right: 0;
    box-shadow: none;
}

/* Education doodle texture, two layers at different scales/speeds for a
   subtle parallax. Decorative only: pointer-events off, rail content sits
   above it at z-index 1. */
.app-menu.navbar-menu::before,
.app-menu.navbar-menu::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 0;
    pointer-events: none;
    background-image: url(../images/page/doodle-edu.svg);
    background-repeat: repeat;
}

.app-menu.navbar-menu::before {
    background-size: 170px 219px;
    background-position: 0 0;
    opacity: .04;
    animation: thi-doodle-down 120s linear infinite;
}

.app-menu.navbar-menu::after {
    background-size: 264px 340px;
    background-position: 40px 90px;
    opacity: .02;
    animation: thi-doodle-up 180s linear infinite;
}

/* One full tile height per cycle so the loop is seamless. */
@keyframes thi-doodle-down {
    from { background-position: 0 0; }
    to   { background-position: 0 219px; }
}

@keyframes thi-doodle-up {
    from { background-position: 40px 90px; }
    to   { background-position: 40px -250px; }
}

@media (prefers-reduced-motion: reduce) {
    .app-menu.navbar-menu::before,
    .app-menu.navbar-menu::after { animation: none; }
}

.app-menu .navbar-brand-box,
.app-menu #scrollbar,
.app-menu .sidebar-background { position: relative; z-index: 1; }
.app-menu .navbar-brand-box { border-bottom: 1px solid rgba(255, 255, 255, .07); }
.app-menu .logo-lg img { max-height: 50px; object-fit: contain; }
.app-menu .logo-sm img { max-height: 36px; object-fit: contain; }

/* Brand block. The theme gives .logo a 70px line-height and centres the
   brand box, which would stretch the wordmark into three stacked lines —
   so the rail header is re-laid out here as a compact flex row. */
.app-menu .navbar-brand-box {
    display: flex;
    align-items: center;
    justify-content: flex-start;
    height: 72px;
    padding: 0 18px;
    text-align: left;
}
.app-menu .navbar-brand-box > .logo {
    flex: 0 0 auto;
    margin: 0;
    padding: 0;
    line-height: 1;
    text-align: left;
}
.app-menu .navbar-brand-box > .logo.thi-brand { justify-content: flex-start; }
.app-menu .navbar-brand-box > #vertical-hover { margin-left: auto; }

.thi-brand { display: flex !important; align-items: center; gap: 12px; line-height: 1; }
/* Kotak lambang 34px, sama dengan .sisto-brand__mark. Bedanya hanya alasnya:
   sisto memakai rgba(255,255,255,.08) karena lambangnya putih polos, sedangkan
   lambang THI berwarna dan hilang di atas alas setransparan itu - jadi di sini
   alasnya tetap putih. */
.app-menu .logo-lg img.thi-brand__mark {
    max-height: 34px;
    width: 34px;
    height: 34px;
    flex: 0 0 34px;
    object-fit: contain;
    border-radius: 9px;
    background: #fff;
    padding: 3px;
}
.thi-brand__text { display: flex; flex-direction: column; gap: 2px; white-space: nowrap; }
.thi-brand__name { font-size: 14px; font-weight: 800; letter-spacing: .2em; line-height: 1.1; color: #fff; }
.thi-brand__ver { font-size: 10px; font-weight: 600; letter-spacing: .16em; line-height: 1.1; color: rgba(255,255,255,.75); }

/* The rail's inner .container-fluid carries Bootstrap's 12px gutter, which
   stacked on top of the list padding and pushed the section labels ~34px in.
   Drop the gutter so the rail owns its own insets (12px + 10px = 22px). */
#scrollbar > .container-fluid { padding-left: 0; padding-right: 0; }

#scrollbar .navbar-nav { padding: 16px 12px 24px; }
.navbar-menu .navbar-nav .menu-title {
    margin: 22px 0 0;
    padding: 0 10px 10px;
    text-align: left;
    color: rgba(255,255,255,.68) !important;
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: .16em;
}
.navbar-menu .navbar-nav .menu-title > span { padding: 0; }
.navbar-menu .navbar-nav > .menu-title:first-child { margin-top: 0; }

#navbar-nav .nav-link {
    display: flex;
    align-items: center;
    gap: 13px;
    margin: 0 0 2px;
    padding: 11px 12px;
    color: rgba(255,255,255,.82) !important;
    border-radius: 10px;
    font-size: 13.5px;
    font-weight: 600;
    line-height: 1.35;
    transition: background .14s ease, color .14s ease;
}

/* Velzon ships a bold chevron that only rotates once expanded. Sisto shows a
   small muted caret pointing down at rest, so settle it there and keep the
   rotation purely as the open/closed cue. */
#navbar-nav .nav-link[data-bs-toggle="collapse"]:after {
    right: 14px;
    font-size: .8rem;
    color: rgba(255,255,255,.52);
    transform: rotate(90deg);
}
/* Keyed off .collapsed (Bootstrap keeps it accurate) rather than
   aria-expanded, which the menu markup hardcodes to "true" even when shut. */
#navbar-nav .nav-link[data-bs-toggle="collapse"]:not(.collapsed):after {
    color: rgba(255,255,255,.78);
    transform: rotate(-90deg);
}
#navbar-nav .nav-link[data-bs-toggle="collapse"]:hover:after,
#navbar-nav .nav-link[data-bs-toggle="collapse"].active:after { color: #fff; }

#navbar-nav .nav-link:hover {
    color: #fff !important;
    background: rgba(255,255,255,.09) !important;
}

#navbar-nav .nav-link.active {
    color: #fff !important;
    font-weight: 700;
    background: var(--thi-accent) !important;
    box-shadow: 0 8px 18px -10px rgba(9, 47, 20, .9);
}

/* Theme sizes menu icons at 18px with inherited line-height, which pushed
   each row to 46px tall. Pin them to an 18px box so the rhythm lands on
   sisto's 42px pitch. */
#navbar-nav .nav-link i,
#navbar-nav .nav-link .icon-dual {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 18px;
    width: 18px;
    height: 18px;
    min-width: 0;
    margin: 0;
    font-size: 16px;
    line-height: 1;
    color: currentColor;
}
/* Submenu: a hairline guide rail instead of the theme's per-item dash, and
   a soft tint for the current child - the solid accent pill above is meant
   for top-level items only, and reads far too heavy when nested. */
#navbar-nav .nav-sm {
    margin: 3px 0 6px 27px;
    padding: 0 0 0 12px;
    border-left: 1.5px solid rgba(255,255,255,.12);
}
/* !important karena tema memasang `padding: .55rem 1.5rem !important` di
   app.css:629 - inset 24px itu dibuat untuk garis strip per-item yang sudah
   diganti rel pemandu di atas. */
#navbar-nav .nav-sm .nav-link {
    min-height: 0;
    padding: 9px 10px !important;
    color: rgba(255,255,255,.72) !important;
    border-radius: 8px;
    font-size: 12.5px;
    font-weight: 500;
}
#navbar-nav .nav-sm .nav-link:before { display: none; }
#navbar-nav .nav-sm .nav-link:hover {
    color: #fff !important;
    background: rgba(255,255,255,.06) !important;
}
#navbar-nav .nav-sm .nav-link.active {
    color: #fff !important;
    background: rgba(255,255,255,.08) !important;
    box-shadow: none;
    font-weight: 700;
}

.header-item,
.btn-topbar { color: #56705d !important; }
.btn-topbar {
    width: 40px;
    height: 40px;
    border-radius: 10px !important;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
.btn-topbar:hover { background: var(--thi-green-soft) !important; color: var(--thi-green) !important; }
/* Keping pengguna ditata di bagian "Topbar" di bawah, bukan di sini. */
.topbar-user { margin-left: 14px !important; padding-left: 14px; border-left: 1px solid var(--thi-line); }

#notificationDropdown .dropdown-menu { border-radius: 14px; box-shadow: 0 18px 44px rgba(15, 23, 42, .16); }
#notification-badge-count { background-color: #dc2626 !important; }

.main-content { margin-left: var(--vz-vertical-menu-width); }
.page-content { padding: calc(72px + 26px) 26px 78px; }
.container-fluid { max-width: 1600px; }
.footer { border-top: 1px solid var(--thi-line); background: var(--thi-surface); }

/* Page headers and surfaces */
/* Theme renders the page head as a full-bleed white bar (negative margins +
   border + shadow). Sisto puts the title straight on the canvas, so strip the
   bar back to plain content. */
.page-title-box {
    min-height: auto;
    margin: 0 0 4px;
    padding: 0 0 20px;
    background: transparent;
    border-bottom: 0;
    box-shadow: none;
}
.page-title-box h4,
.page-title-box .mb-sm-0 {
    color: var(--thi-ink);
    /* Theme pins this at 15px !important and uppercases it. The size itself
       is set from --thi-fs-title in the shell-parity block below. */
    text-transform: none;
    letter-spacing: -.025em;
}
.breadcrumb-item,
.breadcrumb-item a { color: var(--thi-muted); font-size: var(--thi-fs-note); }
.breadcrumb-item.active { color: var(--thi-green); font-weight: 650; }

.card,
.accordion-item {
    border: 1px solid var(--thi-line);
    border-radius: var(--thi-radius);
    background: var(--thi-surface);
    box-shadow: 0 3px 14px rgba(20, 51, 28, .035);
}
.card { overflow: hidden; margin-bottom: 20px; }
.card-header {
    min-height: 58px;
    padding: 17px 20px;
    border-bottom: 1px solid var(--thi-line);
    background: var(--thi-surface);
}
.card-body { padding: 20px; }
.card-title,
.header-title h4,
.header-title h5,
.header-title h6 { color: var(--thi-ink); font-weight: 700; }
.header-title h8 { color: var(--thi-muted); font-size: 12px; }

/* Controls */
.btn { border-radius: 9px; font-weight: 650; letter-spacing: .005em; }
.btn-primary,
.btn-primary:focus,
.btn-primary:active {
    color: #fff;
    background-color: var(--thi-green) !important;
    border-color: var(--thi-green) !important;
    box-shadow: none !important;
}
.btn-primary:hover { background-color: var(--thi-green-deep) !important; border-color: var(--thi-green-deep) !important; }
.btn-soft-primary { color: var(--thi-green); background-color: var(--thi-green-soft); border-color: transparent; }
.btn-soft-primary:hover { color: #fff; background-color: var(--thi-green); border-color: var(--thi-green); }
.btn-outline-primary { color: var(--thi-green); border-color: #8bb99a; }
.btn-outline-primary:hover { color: #fff; background: var(--thi-green); border-color: var(--thi-green); }
/* The "Reset" button next to every filter. Its light fill is hardcoded, so it
   needs a dark-mode pair of its own or it stays a white slab. */
.btn-soft-dark { color: #435248; background: #eef3ef; border-color: #eef3ef; }
.btn-soft-dark:hover { color: #2a362e; background: #e2eae4; border-color: #e2eae4; }
:root[data-bs-theme="dark"] .btn-soft-dark { color: #c6d4ca; background: #2a3831; border-color: #2a3831; }
:root[data-bs-theme="dark"] .btn-soft-dark:hover { color: #e7f0e9; background: #35463c; border-color: #35463c; }

/* Row actions ship as amber .btn-warning for both Edit and Hapus, which
   clashes with the green palette and gives a destructive action the same
   weight as a benign one. Styled via the semantic hooks the scripts already
   emit, so .btn-warning keeps its meaning everywhere else. */
.editor_edit.btn,
.editor_remove.btn {
    border: 1px solid transparent;
    font-weight: 650;
}
.editor_edit.btn {
    /* text-emphasis flips per theme (deep green on light, mint on dark);
       --thi-green alone is green-on-green and unreadable in dark mode. */
    color: var(--vz-primary-text-emphasis) !important;
    background-color: var(--vz-primary-bg-subtle);
    border-color: var(--vz-primary-border-subtle);
}
.editor_edit.btn:hover {
    color: #fff !important;
    background-color: var(--thi-green);
    border-color: var(--thi-green);
}
.editor_remove.btn {
    color: #b42318 !important;
    background-color: rgba(240, 101, 72, .12);
    border-color: rgba(240, 101, 72, .28);
}
.editor_remove.btn:hover {
    color: #fff !important;
    background-color: #d92d20;
    border-color: #d92d20;
}
:root[data-bs-theme="dark"] .editor_remove.btn { color: #ffb4a6 !important; }

.form-control,
.form-select,
.select2-container--default .select2-selection--single,
.select2-container--default .select2-selection--multiple {
    min-height: 39px;
    color: var(--thi-ink);
    background-color: var(--thi-surface);
    border-color: var(--thi-line);
    border-radius: 9px;
    box-shadow: none;
}
.form-control:focus,
.form-select:focus {
    border-color: var(--thi-accent);
    background-color: var(--thi-surface);
    box-shadow: 0 0 0 .2rem rgba(25, 89, 41, .12);
}
.form-label,
label { color: var(--thi-ink); font-size: 12.5px; font-weight: 650; }
.form-check-input:checked { background-color: var(--thi-green); border-color: var(--thi-green); }

/* Data tables and lists */
.table { --vz-table-color: var(--thi-ink); --vz-table-border-color: var(--thi-line); }
/* Cell padding and the header's size/tracking come from the type scale in the
   shell-parity block below; this sets the colours only. */
.table thead th,
.table > thead > tr > th {
    color: var(--thi-muted);
    background: var(--thi-surface-2);
    /* 1,5px: kepala tabel perlu terpisah tegas dari baris pertama, terutama
       saat .table-striped membuat baris ganjil sewarna dengan kepalanya. */
    border-bottom: 1.5px solid var(--thi-line);
    text-transform: uppercase;
    white-space: nowrap;
}
.table-striped > tbody > tr:nth-of-type(odd) > * { --vz-table-accent-bg: var(--thi-stripe); }
.table-hover > tbody > tr:hover > *,
table.dataTable tbody tr:hover > * { --vz-table-accent-bg: var(--thi-green-pale) !important; color: var(--thi-ink) !important; }
.table-bordered > :not(caption) > * { border-width: 1px 0; }

/* The report scripts tag total/sum columns with .bg-info-subtle, which is
   Bootstrap blue and fights the green palette. Recoloured only inside tables,
   so genuine "info" badges and alerts elsewhere keep their meaning. */
.table .bg-info-subtle,
table.dataTable .bg-info-subtle {
    background-color: var(--vz-primary-bg-subtle) !important;
    color: var(--thi-ink);
}

/* DataTables' own chrome sits outside .table, so it needs the tokens too.
   Both plugin generations are handled together in the "DataTables chrome"
   block further down - 1.x names it .dataTables_wrapper/.dataTables_filter,
   2.x names it .dt-container/.dt-search. */

/* Tabs, accordions, modals, and feedback states */
.nav-tabs { border-bottom-color: var(--thi-line); }
.nav-tabs .nav-link { color: var(--thi-muted); border-radius: 8px 8px 0 0; font-weight: 600; }
.nav-tabs .nav-link:hover { color: var(--thi-green); border-color: transparent; }
.nav-tabs .nav-link.active { color: var(--thi-green); border-color: var(--thi-line) var(--thi-line) var(--thi-surface); }
.accordion-button { color: var(--thi-ink); background: var(--thi-surface); font-weight: 700; box-shadow: none !important; }
.accordion-button:not(.collapsed) { color: var(--thi-green); background: var(--thi-green-pale); }

/* .accordion-secondary paints the border with --vz-secondary, which is brand
   green here and reads as an error outline on a plain filter panel. */
.accordion-secondary .accordion-item { border-color: var(--thi-line); }

/* Opened, the same class paints the header #826f4f with !important - a brown
   bar with white text sitting over the filter form. Overridden at the theme's
   own specificity so the open and closed states differ only by a tint. */
.accordion-secondary .accordion-item .accordion-button:not(.collapsed) {
    /* text-emphasis, not --thi-green: the tint behind it is dark in dark mode,
       where green-on-green leaves the word "FILTER" unreadable. */
    color: var(--vz-primary-text-emphasis) !important;
    background-color: var(--thi-green-pale) !important;
}
.accordion-secondary .accordion-item .accordion-button::after { color: var(--thi-muted); }
.accordion-secondary .accordion-item .accordion-button:not(.collapsed)::after { color: var(--vz-primary-text-emphasis); }

/* custom-accordionwithicon swaps the caret for a Material Design Icons glyph,
   so it is text - the theme leaves it white, i.e. invisible on the white
   header. `filter:` does nothing to a glyph; it needs a colour. */
.custom-accordionwithicon .accordion-button::after { color: var(--thi-muted); filter: none; }
.custom-accordionwithicon .accordion-button:not(.collapsed)::after { color: var(--thi-green); }
.modal-content { color: var(--thi-ink); background: var(--thi-surface); border: 0; border-radius: var(--thi-radius); box-shadow: 0 18px 48px rgba(10, 39, 18, .22); }
/* Sisto gives modals a filled brand header with a white title; the theme
   leaves it plain white, so the heading reads as empty space. Skipped for
   headers that already carry a bg- utility (confirm/danger dialogs). */
.modal-header:not([class*="bg-"]) {
    align-items: center;
    gap: 11px;
    padding: 13px 18px 12px;
    color: #fff;
    background: var(--thi-green);
    border-bottom: none;
    border-radius: var(--thi-radius) var(--thi-radius) 0 0;
}
.modal-header:not([class*="bg-"]) > h1,
.modal-header:not([class*="bg-"]) > h2,
.modal-header:not([class*="bg-"]) > h3,
.modal-header:not([class*="bg-"]) > h4,
.modal-header:not([class*="bg-"]) > h5,
.modal-header:not([class*="bg-"]) > h6,
.modal-header:not([class*="bg-"]) .modal-title { color: #fff; font-weight: 800; font-size: var(--thi-fs-panel); }
/* Close glyph is a dark SVG; invert it so it shows on the green bar. */
.modal-header:not([class*="bg-"]) .btn-close { filter: invert(1) grayscale(100%) brightness(220%); opacity: .85; }
.modal-header:not([class*="bg-"]) .btn-close:hover { opacity: 1; }
/* Round avatar chip sitting in the header. */
.modal-header:not([class*="bg-"]) > img {
    width: 34px;
    height: 34px;
    object-fit: cover;
    border-radius: 50%;
    background: rgba(255, 255, 255, .16);
    padding: 2px;
}
.modal-body { background: var(--thi-surface); }
.modal-footer { border-top: 1.5px solid var(--thi-line); background: var(--thi-surface); gap: 10px; padding: 10px 18px; }
.dropdown-menu { color: var(--thi-ink); background: var(--thi-surface); border: 1px solid var(--thi-line); border-radius: 12px; box-shadow: 0 12px 28px rgba(18, 48, 25, .12); }
.dropdown-item:focus,
.dropdown-item:hover { color: var(--thi-green); background: var(--thi-green-pale); }
.badge.bg-primary { background-color: var(--thi-green) !important; }
.text-primary { color: var(--thi-green) !important; }
.bg-primary { background-color: var(--thi-green) !important; }

/* Beranda / welcome hero + quick access */
.thi-hero {
    position: relative;
    overflow: hidden;
    margin-bottom: 24px;
    padding: 34px 40px;
    border-radius: var(--thi-radius);
    background: linear-gradient(135deg, #103d1c 0%, #195929 55%, #2f7a41 100%);
    box-shadow: 0 18px 44px -18px rgba(9, 47, 20, .45);
}
.thi-hero:before {
    content: "";
    position: absolute;
    inset: 0;
    background-image: radial-gradient(circle at 18% 22%, rgba(255,255,255,.10) 0 1px, transparent 1.6px),
        radial-gradient(circle at 82% 68%, rgba(255,255,255,.08) 0 1px, transparent 1.6px);
    background-size: 42px 42px, 60px 60px;
    pointer-events: none;
}
.thi-hero__badge {
    position: relative;
    z-index: 1;
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 5px 12px;
    border: 1px solid rgba(255,255,255,.22);
    border-radius: 999px;
    background: rgba(255,255,255,.08);
    color: #e6f5e9;
    font-size: 10.5px;
    font-weight: 750;
    letter-spacing: .1em;
    text-transform: uppercase;
}
.thi-hero__dot { width: 6px; height: 6px; border-radius: 50%; background: #9fe3ac; box-shadow: 0 0 0 4px rgba(159,227,172,.18); }
.thi-hero__title { position: relative; z-index: 1; margin: 16px 0 0; color: #fff; font-size: 30px; font-weight: 800; letter-spacing: -.02em; }
.thi-hero__lead { position: relative; z-index: 1; margin: 10px 0 0; max-width: 560px; color: rgba(255,255,255,.80); font-size: 14px; line-height: 1.7; }
.thi-hero__actions { position: relative; z-index: 1; margin-top: 22px; display: flex; gap: 10px; flex-wrap: wrap; }
.thi-hero__actions .btn-light { border-radius: 10px; color: var(--thi-green-deep); }
.thi-hero__actions .btn-light:hover { background: #eef7ef; }
.thi-hero__mark {
    position: absolute;
    z-index: 1;
    right: 36px;
    top: 50%;
    transform: translateY(-50%);
    width: 104px;
    height: 104px;
    object-fit: contain;
    padding: 14px;
    border-radius: 18px;
    background: #fff;
    box-shadow: 0 16px 36px rgba(4, 29, 11, .28);
}
@media (max-width: 767.98px) { .thi-hero__mark { display: none; } }

.thi-quick__head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; margin-bottom: 14px; }
.thi-quick__head h2 { margin: 0; font-size: 16px; font-weight: 750; color: var(--thi-ink); }
.thi-quick__hint { font-size: 12px; color: var(--thi-muted); }

.thi-quick__card {
    display: flex;
    flex-direction: column;
    gap: 10px;
    height: 100%;
    padding: 18px 16px;
    border: 1px solid var(--thi-line);
    border-radius: var(--thi-radius);
    background: var(--thi-surface);
    box-shadow: 0 3px 14px rgba(20, 51, 28, .035);
    text-decoration: none;
    transition: transform .14s ease, box-shadow .14s ease, border-color .14s ease;
}
.thi-quick__card:hover {
    transform: translateY(-2px);
    border-color: #bcd9c2;
    box-shadow: 0 14px 30px -16px rgba(16, 61, 28, .35);
}
.thi-quick__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 38px;
    height: 38px;
    border-radius: 10px;
    background: var(--thi-green-soft);
    color: var(--thi-green);
    font-size: 19px;
}
.thi-quick__name { font-size: 13.5px; font-weight: 700; color: var(--thi-ink); }
.thi-quick__desc { font-size: 11.5px; color: var(--thi-muted); margin-top: -6px; }

/* Dashboard summary: KPI tiles + dark revenue card */
.thi-dash-head { margin-bottom: 18px; }
.thi-dash-head__title { margin: 0; font-size: 22px; font-weight: 800; color: var(--thi-ink); }
.thi-dash-head__sub { margin: 4px 0 0; font-size: 12.5px; color: var(--thi-muted); }

.thi-kpi-card {
    height: 100%;
    padding: 16px 18px;
    border: 1px solid var(--thi-line);
    border-radius: var(--thi-radius);
    background: var(--thi-surface);
    box-shadow: 0 3px 14px rgba(20, 51, 28, .035);
}
.thi-kpi-card__head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 4px; }
.thi-kpi-card__label { font-size: 12.5px; font-weight: 700; color: var(--thi-ink); }
.thi-kpi-card__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    border-radius: 9px;
    background: var(--thi-green-soft);
    color: var(--thi-green);
    font-size: 15px;
}

/* Login / authentication screen */
.auth-page-wrapper {
    position: relative;
    background: linear-gradient(135deg, #103d1c 0%, #195929 54%, #2f7a41 100%);
}
.auth-page-wrapper:before,
.auth-page-wrapper:after {
    content: "";
    position: absolute;
    border: 1px solid rgba(255,255,255,.11);
    border-radius: 50%;
    pointer-events: none;
}
.auth-page-wrapper:before { width: 560px; height: 560px; left: -210px; top: -150px; box-shadow: 0 0 0 80px rgba(255,255,255,.025), 0 0 0 160px rgba(255,255,255,.018); }
.auth-page-wrapper:after { width: 430px; height: 430px; right: -160px; bottom: -160px; box-shadow: 0 0 0 70px rgba(255,255,255,.025); }
.auth-page-wrapper .bg-overlay { opacity: 0; }
.auth-page-content { position: relative; z-index: 1; }
.auth-page-content .card {
    border: 1px solid rgba(255,255,255,.65);
    border-radius: 20px;
    box-shadow: 0 24px 65px rgba(4, 29, 11, .28);
}
.auth-page-content .card-bg-fill { background: rgba(255,255,255,.97); }
.auth-page-content .text-primary { color: var(--thi-green) !important; }

@media (max-width: 991.98px) {
    /* Page padding is driven by the --thi-pad* tokens in the shell block
       further down, so only the rail colour is restated here. */
    .app-menu.navbar-menu { background: var(--thi-green); }
}

@media (max-width: 575.98px) {
    .card-body { padding: 15px; }
    .card-header { padding: 14px 15px; }
}


/* ===========================================================================
   SISTO SHELL PARITY
   Everything below brings this panel in line with sisto-admin4's shell: the
   same geometry tokens, the same locked type scale, the same fixed header /
   scrolling content / fixed footer split, and the same treatment of the
   plugin chrome (DataTables, DataTables Editor, bootstrap-select, SweetAlert).
   Still presentation-only - no markup, id or class a script reads is changed.
   =========================================================================== */

/* ---------------------------------------------------------------------------
   Geometry and the type scale.

   Every page in this panel has the same anatomy (title -> description ->
   filter -> table), so sisto locks the sizes centrally instead of per page.
   The tokens below mirror its --sisto-* set one for one; rules in this file
   must use them rather than introducing new px values.
   --------------------------------------------------------------------------- */
:root {
    --thi-bar: 72px;    /* topbar height, matches .navbar-header above */
    --thi-foot: 50px;   /* fixed footer bar */
    --thi-padx: 26px;   /* page gutter */
    --thi-padtop: 26px;
    --thi-padbot: 40px;
    /* `none` lets page content follow the window width (fit-window). Give it
       a length (e.g. 1360px) to cap and centre every module at once. */
    --thi-wrap: none;

    --thi-fs-title: 27px;     /* page title */
    --thi-fs-section: 16.5px; /* section heading, large card, modal title */
    --thi-fs-panel: 14.5px;   /* filter panel + table card heading */
    --thi-fs-desc: var(--thi-fs-md);

    --thi-fs-md: 14px;        /* slightly larger body text */
    --thi-fs-body: 13.5px;    /* default text, buttons, inputs */
    --thi-fs-sm: 13px;        /* table cells, secondary text */
    --thi-fs-xs: 12.5px;      /* filter labels, table tools, pagination */
    --thi-fs-note: 12px;      /* breadcrumb, notes, small buttons */
    --thi-fs-meta: 11.5px;    /* captions under primary text */
    --thi-fs-mini: 11px;      /* badges, pills, tags */
    --thi-fs-th: 10.5px;      /* table headers (uppercase) */
    --thi-fs-micro: 10px;     /* smallest labels */
}

@media (max-width: 991.98px) {
    :root { --thi-padx: 20px; --thi-padtop: 24px; --thi-padbot: 32px; }
}

@media (max-width: 767.98px) {
    :root {
        --thi-fs-title: 22px;
        --thi-fs-section: 15.5px;
        --thi-padx: 16px;
        --thi-padtop: 18px;
        --thi-padbot: 30px;
    }
}

@media (max-width: 575.98px) {
    :root { --thi-padx: 14px; }
}

/* ---------------------------------------------------------------------------
   Fixed shell: the window no longer scrolls, the content column does.

   The theme scrolls the whole document, which puts page content underneath
   the footer and shifts the layout by the scrollbar width between pages that
   overflow and pages that don't. Sisto splits the viewport instead - fixed
   topbar, fixed footer, and one scroll area in between.

   Scoped to #layout-wrapper rather than html/body because the sign-in page is
   a standalone document that loads this same stylesheet and does need to
   scroll normally. Keeping the shell fixed inside its own wrapper leaves the
   body with no overflow of its own, so no scrollbar appears either.
   --------------------------------------------------------------------------- */
/* The window is pinned instead of the wrapper. An earlier version of this
   gave #layout-wrapper `position: fixed`, which works visually but breaks
   every dialog: a fixed element always opens a stacking context, so the
   modal's z-index 1055 was scoped *inside* the wrapper, while the
   .modal-backdrop Bootstrap appends to <body> (z-index 1050) sat outside it
   and painted over the whole subtree - the dialog was visible but nothing in
   it could be clicked. A static wrapper opens no stacking context, so the
   modal competes with the backdrop at the root again and wins.

   :has() keeps this to the app shell. The sign-in page is a standalone
   document loading this same stylesheet and has no #layout-wrapper, so it
   keeps scrolling normally. */
html:has(#layout-wrapper),
html:has(#layout-wrapper) body { height: 100%; overflow: hidden; }

#layout-wrapper {
    display: flex;
    flex-direction: column;
    height: 100vh;
    /* Reserves the fixed bars. Both #page-topbar and .app-menu are
       position:fixed, so .main-content is the only child in flow here. */
    padding-top: var(--thi-bar);
    padding-bottom: var(--thi-foot);
}

.main-content {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    overflow-x: hidden;
    overscroll-behavior: contain;
    /* Right edge stays clean, as in sisto. Scrolling itself is untouched:
       wheel, touch, keyboard and scrollIntoView all still work. */
    scrollbar-width: none;
    -ms-overflow-style: none;
}

.main-content::-webkit-scrollbar { width: 0; height: 0; }

/* The theme reserved room for its fixed topbar with padding-top on the page
   itself; that job now belongs to #layout-wrapper, so this is pure gutter. */
.page-content {
    padding: var(--thi-padtop) var(--thi-padx) var(--thi-padbot);
}

/* One container for every module. Bootstrap's own .container steps through
   540/720/960/1140/1320px, which made the content width jump as you moved
   between menus; inside the shell they all follow --thi-wrap instead, and
   their gutters are dropped because --thi-padx already spaces the edges. */
.page-content > .container-fluid,
.page-content > .container {
    width: 100%;
    max-width: var(--thi-wrap);
    margin-inline: auto;
    padding-left: 0;
    padding-right: 0;
}

/* Footer becomes the bar pinned to the bottom of the window. Its `left` is
   still the theme's, so it keeps tracking the rail width and the responsive
   breakpoints. z-index stays under .dropdown-menu (1000) so a select opened
   near the bottom of the screen is not covered by it. */
.footer {
    position: fixed;
    z-index: 900;
    display: flex;
    align-items: center;
    height: var(--thi-foot);
    padding: 0 var(--thi-padx);
    font-size: var(--thi-fs-xs);
    color: var(--thi-muted);
    background: var(--thi-surface);
    border-top: 1px solid var(--thi-line);
}

.footer > .container-fluid { flex: 1 1 auto; padding: 0; }
.footer .row { margin: 0; align-items: center; }
.footer .row > [class*="col-"] { padding: 0; font-weight: 600 !important; }

/* The theme's back-to-top button follows the window scroll, which no longer
   moves - so it could never do anything. */
#back-to-top,
.btn-scroll-top { display: none !important; }


/* ---------------------------------------------------------------------------
   Page head: breadcrumb above the title.

   The theme lays the head out as a row - title on the left, breadcrumb pushed
   to the right. Sisto stacks it: a small muted trail, then the title, then the
   description. The markup already carries both pieces (h4 + .page-title-right),
   so column-reverse reorders them without touching any view.
   --------------------------------------------------------------------------- */
.page-title-box {
    display: flex !important;
    flex-direction: column-reverse;
    align-items: flex-start !important;
    justify-content: flex-start !important;
    gap: 7px;
}

.page-title-box h4,
.page-title-box .mb-sm-0 {
    font-size: var(--thi-fs-title) !important;
    font-weight: 800;
    line-height: 1.15;
}

.page-title-box .page-title-right { margin: 0; }

.page-title-box .breadcrumb {
    --vz-breadcrumb-divider: "/";
    --bs-breadcrumb-divider: "/";
    margin: 0 !important;
    padding: 0;
    background: transparent;
    font-size: var(--thi-fs-note);
    font-weight: 600;
}

.breadcrumb-item + .breadcrumb-item::before { color: #c0d0c5; }
:root[data-bs-theme="dark"] .breadcrumb-item + .breadcrumb-item::before { color: #44584a; }

/* ---------------------------------------------------------------------------
   Filter panel.

   61 of the CRUD pages wrap their filter form in the same accordion. Sisto
   shows it as a compact panel whose header is a small uppercase toggle, so the
   accordion is restyled into that shape rather than rebuilt.
   --------------------------------------------------------------------------- */
.accordion-item { margin-bottom: 0; }

.accordion-button {
    min-height: 46px;
    padding: 0 18px;
    font-size: var(--thi-fs-xs) !important;
    font-weight: 750;
    letter-spacing: .07em;
    text-transform: uppercase;
}

.accordion-button i { font-size: 15px; color: var(--vz-primary-text-emphasis); }

/* The filter panel nests .accordion-body > .card-body, i.e. two paddings
   stacked. :has() keeps this to that one shape - accordions that put content
   straight into .accordion-body keep the theme's padding. */
.accordion-body:has(> .card-body) { padding: 0; }
.accordion-body > .card-body { padding: 18px 20px 2px; }

/* Filter fields. The markup is `<label>…</label><br><select>`, where the <br>
   plus the label's own margin produced uneven gaps between a labelled field
   and the buttons beside it. Dropping the break and giving every label the
   same block spacing lines the row up on one baseline. */
#form-filter br { display: none; }

#form-filter label,
#form-filter .form-label {
    display: block;
    margin-bottom: 7px;
    font-size: var(--thi-fs-xs);
    font-weight: 700;
    color: var(--thi-ink);
}

#form-filter .form-group { margin-bottom: 0; }

#form-filter .btn {
    height: 39px;
    padding-inline: 18px;
    font-size: var(--thi-fs-body);
}

/* ---------------------------------------------------------------------------
   Cards and the table card.
   --------------------------------------------------------------------------- */
.card-header {
    min-height: 54px;
    padding: 16px 20px;
}

.card-header .card-title,
.card-header h4,
.card-header h5,
.card-header h6 {
    margin-bottom: 0;
    font-size: var(--thi-fs-panel);
    font-weight: 700;
}

/* ---------------------------------------------------------------------------
   Tables.
   --------------------------------------------------------------------------- */
.table { font-size: var(--thi-fs-sm); }
/* vertical-align middle: sebagian besar tabel di sini mencampur teks satu
   baris dengan lencana dan tombol aksi yang lebih tinggi. Tanpa ini teksnya
   menempel ke atas sel dan barisnya terbaca miring. Sebagian view memasang
   .align-middle sendiri, sebagian tidak. */
.table > :not(caption) > * > * { padding: 11px 14px; vertical-align: middle; }

.table thead th,
.table > thead > tr > th {
    padding: 11px 14px;
    font-size: var(--thi-fs-th);
    font-weight: 800;
    /* .1em terlalu renggang untuk kapital 10,5px; acuannya memakai .05em. */
    letter-spacing: .05em;
}

.table-light,
.table .table-light > * { background: var(--thi-surface-2); }

/* Sorting affordance: the theme leaves sorted headers the same muted grey as
   the rest, so there is nothing to show which column the order came from. */
table.dataTable thead .sorting_asc,
table.dataTable thead .sorting_desc,
table.dataTable thead > tr > th.dt-ordering-asc,
table.dataTable thead > tr > th.dt-ordering-desc { color: var(--thi-green); }

/* Group rows. The listing scripts inject `<tr class="group">` before each new
   grouping value and make it clickable to flip the sort order; sisto renders
   the same idea as a tinted band, so it reads as a divider and not a record. */
.table tbody tr.group > td,
.table tbody tr.group:hover > td {
    padding: 9px 14px;
    font-size: var(--thi-fs-mini);
    font-weight: 800;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--vz-primary-text-emphasis);
    background: var(--thi-green-soft) !important;
}

.table tbody tr.group { cursor: pointer; }

/* Status words are rendered as bare text in most listings. */
.table td .badge { font-size: var(--thi-fs-mini); font-weight: 700; border-radius: 7px; }


/* ---------------------------------------------------------------------------
   DataTables chrome.

   Two versions are in use side by side: DataTables 1.11.5 on the pages built
   with DataTablesLibrarie::js() and DataTables 2.1.7 (+ Editor 2.3.2) on the
   pages built with js_editor(). They name their chrome differently -
   .dataTables_wrapper/.dataTables_filter in 1.x, .dt-container/.dt-search in
   2.x - so both naming schemes are covered here. Only the 2.x half is new;
   the 1.x half above this block was written against the older names and would
   otherwise leave the majority of pages on the plugin's default look.
   --------------------------------------------------------------------------- */
.dt-container,
.dataTables_wrapper { font-size: var(--thi-fs-xs); color: var(--thi-ink); }

/* The toolbar rows sit above and below the table. DataTables 2 emits
   .dt-layout-row/.dt-layout-cell but this build ships no rules for them
   beyond a couple of margins, so they stack as plain blocks - the search box
   landed on its own line under the buttons. Laying the row out is on us. */
.dt-container .dt-layout-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    row-gap: 12px;
}
/* Hairlines set the tools apart from the rows, the way sisto's table card
   separates its header and footer bars from the table itself. */
.dt-container > .dt-layout-row:first-child {
    padding-bottom: 14px;
    margin-bottom: 14px;
    border-bottom: 1px solid var(--thi-line);
}

.dt-container > .dt-layout-row:last-child {
    padding-top: 14px;
    margin-top: 14px;
    border-top: 1px solid var(--thi-line);
}

.dt-length label,
.dt-search label,
.dt-info,
.dataTables_wrapper .dataTables_filter label,
.dataTables_wrapper .dataTables_length label,
.dataTables_wrapper .dataTables_info {
    font-size: var(--thi-fs-xs);
    font-weight: 600;
    color: var(--thi-muted);
}

/* The label and its control are siblings, not nested, so the flex row has to
   be the .dt-length / .dt-search wrapper itself - on the label alone they
   stack. The cells hold the toolbar groups side by side. */
.dt-container .dt-layout-cell {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 14px;
}

.dt-container .dt-layout-cell.dt-layout-end { justify-content: flex-end; }
.dt-container .dt-layout-cell.dt-layout-full { display: block; }

.dt-length,
.dt-search { display: flex; align-items: center; gap: 8px; margin: 0; }
.dt-length label,
.dt-search label { margin: 0; white-space: nowrap; }

.dt-length select,
.dt-search input,
.dataTables_wrapper .dataTables_length select,
.dataTables_wrapper .dataTables_filter input {
    height: 38px;
    /* Right side stays clear of the select's own chevron. */
    padding: 0 30px 0 12px;
    font-family: inherit;
    font-size: var(--thi-fs-xs) !important;
    font-weight: 650;
    color: var(--thi-ink) !important;
    background-color: var(--thi-surface) !important;
    border: 1px solid var(--thi-line) !important;
    border-radius: 9px !important;
    box-shadow: none !important;
    outline: none;
}

/* Sisto's search box is a filled field rather than an outlined one, which
   separates "narrow what you see" from the form inputs in the filter panel. */
.dt-search input,
.dataTables_wrapper .dataTables_filter input {
    min-width: 240px;
    background-color: var(--thi-surface-2) !important;
}

.dt-search input,
.dataTables_wrapper .dataTables_filter input { padding-right: 12px; }
.dt-search input::placeholder { font-weight: 500; color: var(--thi-muted); }

.dt-length select:focus,
.dt-search input:focus,
.dataTables_wrapper .dataTables_length select:focus,
.dataTables_wrapper .dataTables_filter input:focus {
    border-color: var(--thi-accent) !important;
    background-color: var(--thi-surface) !important;
    box-shadow: 0 0 0 .2rem rgba(25, 89, 41, .12) !important;
}

/* Table action buttons. "Tambah" (Buttons' `create` extension) is the one
   primary action on a listing, so it keeps the brand fill; exports, print and
   column pickers stay quiet secondary buttons as they do in sisto. */
/* Buttons renders this as a .btn-group, where Bootstrap gives every child
   `flex: 1 1 auto` - as a block-level flex row that stretched each button
   across the full width of the toolbar. Kept inline, with the children at
   their natural size. */
.dt-buttons,
.dataTables_wrapper .dt-buttons { display: inline-flex; flex-wrap: wrap; gap: 8px; margin: 0; }

.dt-buttons > .dt-button,
.dataTables_wrapper .dt-buttons > .dt-button { flex: 0 0 auto; }

.dt-buttons .dt-button,
.dt-buttons .dt-button.btn,
.dataTables_wrapper .dt-buttons .dt-button {
    height: 38px;
    padding: 0 15px;
    font-family: inherit;
    font-size: var(--thi-fs-xs);
    font-weight: 700;
    color: var(--thi-ink);
    background: var(--thi-surface) !important;
    background-image: none !important;
    border: 1px solid var(--thi-line) !important;
    border-radius: 9px !important;
    box-shadow: none !important;
}

.dt-buttons .dt-button:hover {
    color: var(--thi-green);
    background: var(--thi-green-pale) !important;
    border-color: var(--vz-primary-border-subtle) !important;
}

.dt-buttons .dt-button.buttons-create,
.dt-buttons .dt-button.buttons-create.btn {
    color: #fff;
    background: var(--thi-green) !important;
    border-color: var(--thi-green) !important;
}

.dt-buttons .dt-button.buttons-create:hover {
    color: #fff;
    background: var(--thi-green-deep) !important;
    border-color: var(--thi-green-deep) !important;
}

.dt-buttons .dt-button i { margin-right: 5px; font-size: 14px; }

/* Collection dropdowns (column visibility, export groups). */
.dt-button-collection {
    padding: 7px;
    background: var(--thi-surface);
    border: 1px solid var(--thi-line);
    border-radius: 12px;
    box-shadow: 0 12px 28px rgba(18, 48, 25, .12);
}

.dt-button-collection .dt-button { width: 100%; justify-content: flex-start; border-color: transparent !important; }

/* Pagination. In 1.x `.paginate_button` and `.page-item` are both on the same
   <li> while `.page-link` is the <a> inside it, so bordering both draws a box
   inside a box - the <li> stays bare and only the link gets the pill. */
.dt-paging .pagination,
.dataTables_paginate .pagination { gap: 6px; margin: 0; flex-wrap: wrap; }

.dt-paging .page-item,
.dt-paging .dt-paging-button,
.dataTables_paginate .page-item,
.dataTables_paginate .paginate_button {
    padding: 0;
    background: transparent;
    border: none;
    border-radius: 0;
}

.dt-paging .page-link,
.dataTables_paginate .page-link {
    min-width: 34px;
    height: 34px;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0 11px;
    font-size: var(--thi-fs-xs);
    font-weight: 650;
    color: var(--thi-muted);
    background: var(--thi-surface);
    border: 1px solid var(--thi-line);
    border-radius: 8px;
}

.dt-paging .page-link:hover,
.dataTables_paginate .page-link:hover {
    color: var(--thi-green) !important;
    background: var(--thi-green-soft) !important;
    border-color: var(--vz-primary-border-subtle) !important;
}

.dt-paging .page-item.active .page-link,
.dt-paging .page-item.active .page-link:hover,
.dataTables_paginate .page-item.active .page-link {
    color: #fff !important;
    background-color: var(--thi-green) !important;
    border-color: var(--thi-green) !important;
}

.dt-paging .page-item.disabled .page-link,
.dataTables_paginate .page-item.disabled .page-link { opacity: .45; }

/* Penanda muat: skeleton, bukan pemutar.
   -----------------------------------------------------------------------
   Semua daftar di sini memakai serverSide, jadi penanda ini muncul pada
   setiap ketikan pencarian, ganti halaman, dan urut kolom - bukan sekali
   saat halaman dibuka. Pemutar yang berputar di tengah tidak memberi tahu
   apa pun selain "tunggu"; batang-batang abu seukuran baris memberi tahu
   bahwa yang sedang datang adalah baris tabel, dan tingginya tidak melompat
   saat data tiba.

   Dikerjakan tanpa mengubah markup: elemennya satu div kosong milik plugin,
   jadi batangnya digambar sebagai repeating-linear-gradient pada latar div
   itu, dan kilaunya memakai ::after yang tidak dipakai plugin.

   Elemen ini position:absolute, jadi pembungkusnya harus jadi leluhur yang
   berposisi - kalau tidak, ia mengukur diri terhadap halaman dan menutupi
   seluruh layar. */
.dt-container,
.dataTables_wrapper { position: relative; }

.dt-container .dt-processing,
.dataTables_wrapper .dataTables_processing {
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    width: auto;
    height: auto;
    margin: 0;
    padding: 0;
    display: block;
    overflow: hidden;
    border: none;
    box-shadow: none;
    border-radius: inherit;
    /* Teks bawaan ("Processing...") datang sebagai simpul teks telanjang di
       1.x, jadi tidak bisa disembunyikan lewat selektor anak. */
    color: transparent;
    font-size: 0;
    background-color: var(--thi-surface);
    /* Satu batang 14px tiap 40px - setara tinggi baris tabel di sini
       (padding 11px atas-bawah + teks 13,5px). Disisipkan 14px dari tepi
       agar sejajar dengan padding sel. */
    background-image: repeating-linear-gradient(
        to bottom,
        var(--thi-skeleton) 0 14px,
        transparent 14px 40px
    );
    background-position: 14px 16px;
    background-size: calc(100% - 28px) calc(100% - 16px);
    background-repeat: no-repeat;
}

/* Titik pemutar milik 2.1.7 dan pembungkus label - tidak dipakai lagi. */
.dt-container .dt-processing > *,
.dataTables_wrapper .dataTables_processing > * { display: none; }

/* Kilau yang menyapu dari kiri ke kanan. */
.dt-container .dt-processing::after,
.dataTables_wrapper .dataTables_processing::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(
        100deg,
        transparent 25%,
        var(--thi-skeleton-sheen) 50%,
        transparent 75%
    );
    transform: translateX(-100%);
    animation: thi-skeleton-sweep 1.3s ease-in-out infinite;
}

@keyframes thi-skeleton-sweep {
    to { transform: translateX(100%); }
}

/* Gerakan berulang tanpa henti termasuk yang dihindari pengaturan ini; tanpa
   animasi, batangnya tetap terbaca sebagai "sedang memuat". */
@media (prefers-reduced-motion: reduce) {
    .dt-container .dt-processing::after,
    .dataTables_wrapper .dataTables_processing::after { animation: none; }
}

td.dt-empty,
td.dataTables_empty {
    padding: 34px 16px !important;
    font-size: var(--thi-fs-sm);
    color: var(--thi-muted);
    text-align: center;
}


/* ---------------------------------------------------------------------------
   Bagian DataTables yang warnanya ditulis mati oleh pustakanya.

   Empat komponen di bawah ini tidak pernah tersentuh token tema: latar putih,
   teks abu gelap, dan aksen biru/merah/oranye yang dipilih pustaka. Di mode
   terang warnanya bentrok dengan hijau, dan di mode gelap menjadi lempengan
   putih di tengah halaman gelap. Semuanya dialihkan ke token, jadi kedua mode
   ikut sekaligus.
   --------------------------------------------------------------------------- */

/* --- tombol buka/tutup baris pada tabel responsif ---
   Pustakanya memberi lingkaran biru #337ab7 untuk "+" dan merah #d33333 untuk
   "-", bertepi putih dengan bayangan #444. Merah di sini bukan peringatan,
   hanya penanda "sedang terbuka", jadi keduanya dijadikan hijau dan yang
   terbuka cukup dibedakan tingkat kepekatannya. */
table.dataTable.dtr-inline.collapsed > tbody > tr > td.dtr-control:before,
table.dataTable.dtr-inline.collapsed > tbody > tr > th.dtr-control:before {
    color: #fff;
    background-color: var(--thi-green);
    border-color: var(--thi-surface);
    box-shadow: none;
}

table.dataTable.dtr-inline.collapsed > tbody > tr.parent > td.dtr-control:before,
table.dataTable.dtr-inline.collapsed > tbody > tr.parent > th.dtr-control:before {
    background-color: var(--thi-green-deep);
}

/* Baris anak yang terbuka: daftar label/nilai, bukan baris catatan baru. */
table.dataTable > tbody > tr.child ul.dtr-details { width: 100%; }

table.dataTable > tbody > tr.child ul.dtr-details > li {
    padding: 7px 0;
    border-bottom: 1px solid var(--thi-line);
}

table.dataTable > tbody > tr.child ul.dtr-details > li:last-child { border-bottom: none; }

table.dataTable > tbody > tr.child span.dtr-title {
    min-width: 30%;
    font-size: var(--thi-fs-xs);
    font-weight: 700;
    color: var(--thi-muted);
}

/* --- jendela detail baris responsif --- */
div.dtr-modal div.dtr-modal-display {
    color: var(--thi-ink);
    background-color: var(--thi-surface);
    border: 1px solid var(--thi-line);
    border-radius: 14px;
    box-shadow: 0 24px 60px -24px rgba(9, 47, 20, .55);
}

div.dtr-modal div.dtr-modal-close {
    color: var(--thi-ink);
    background-color: var(--thi-surface-2);
    border: 1px solid var(--thi-line);
    border-radius: 8px;
}

div.dtr-modal div.dtr-modal-close:hover { background-color: var(--thi-green-soft); }
div.dtr-modal div.dtr-modal-background { background: rgba(9, 47, 20, .45); }

/* --- pemberitahuan "tersalin" dari tombol Copy, dan tirai di balik menu
       kumpulan tombol --- */
div.dt-button-info {
    color: var(--thi-ink);
    background-color: var(--thi-surface);
    border: 1px solid var(--thi-line);
    border-radius: 14px;
    box-shadow: 0 24px 60px -24px rgba(9, 47, 20, .55);
    overflow: hidden;
}

div.dt-button-info h2 {
    padding: 13px 18px;
    font-size: var(--thi-fs-panel);
    font-weight: 800;
    color: var(--thi-ink);
    background-color: var(--thi-surface-2);
    border-bottom: 1px solid var(--thi-line);
}

div.dt-button-info > div { padding: 16px 18px; font-size: var(--thi-fs-sm); color: var(--thi-muted); }

div.dtb-popover-close {
    color: var(--thi-ink);
    background-color: var(--thi-surface-2);
    border: 1px solid var(--thi-line);
    border-radius: 8px;
}

div.dt-button-background { background: rgba(9, 47, 20, .45) !important; }

/* --- pemilih tanggal (dipakai field tanggal pada Editor) ---
   Yang paling mencolok: sorot tanggal memakai oranye #ff8000 dan tanggal
   terpilih memakai biru #4e6ca3 - dua warna yang tidak ada di palet ini. */
div.dt-datetime {
    color: var(--thi-ink);
    background-color: var(--thi-surface);
    border: 1px solid var(--thi-line);
    border-radius: 12px;
    box-shadow: 0 16px 40px -18px rgba(9, 47, 20, .5);
}

div.dt-datetime div.dt-datetime-title { font-size: var(--thi-fs-sm); font-weight: 700; color: var(--thi-ink); }
div.dt-datetime div.dt-datetime-buttons a { font-size: var(--thi-fs-xs); font-weight: 700; color: var(--thi-green); }
div.dt-datetime table th { color: var(--thi-muted); font-weight: 700; }
div.dt-datetime table td { color: var(--thi-ink); }
div.dt-datetime table td.selectable { background: var(--thi-surface-2); }

div.dt-datetime table td.selectable.disabled,
div.dt-datetime table td.selectable.disabled button:hover {
    color: var(--thi-muted);
    background: var(--thi-surface);
}

div.dt-datetime table td.selectable.now { background-color: var(--thi-green-soft); }

div.dt-datetime table td.selectable button:hover {
    color: #fff;
    background: var(--thi-accent);
    border-radius: 6px;
}

div.dt-datetime table td.selectable.selected button {
    color: #fff;
    background: var(--thi-green);
    border-radius: 6px;
}

div.dt-datetime div.dt-datetime-label:hover {
    background-color: var(--thi-surface-2);
    border: 1px solid var(--thi-line);
    border-radius: 6px;
}

/* Panah bulan dirender sebagai gambar latar gelap dengan opacity .3; di mode
   gelap praktis tak terlihat, jadi dibalik warnanya di sana. */
:root[data-bs-theme="dark"] div.dt-datetime div.dt-datetime-iconLeft,
:root[data-bs-theme="dark"] div.dt-datetime div.dt-datetime-iconRight { filter: invert(1); }


/* ---------------------------------------------------------------------------
   DataTables Editor dialog.

   Every CRUD page adds and edits records through this dialog, so it carries
   as much of the look as any page does - and out of the box it is the plugin's
   own 2010-era form: labels floated into a narrow left column, inputs at the
   browser default, radios in a bordered inset. Sisto stacks each field, gives
   the inputs the same shape as the rest of the forms, and turns radio groups
   into pickable cards. The green dialog header comes from the generic
   .modal-header rule further up (.DTE_Header also carries .modal-header), so
   only the body and footer are dealt with here.
   --------------------------------------------------------------------------- */
body .modal.DTED ~ .modal-backdrop,
body .modal-backdrop.DTED {
    background-color: rgba(10, 39, 18, .42) !important;
    opacity: 1 !important;
}

body .modal.DTED .modal-dialog,
body .modal.DTED .modal-dialog.modal-lg {
    max-width: min(560px, calc(100vw - 56px)) !important;
}

body .modal.DTED .modal-content { overflow: hidden; }

/* An icon chip in the header, as on sisto's dialogs: a pencil for create and
   edit, a bin for delete - the action is readable before the title is. */
body div.DTE div.DTE_Header:before {
    content: "";
    flex: 0 0 32px;
    width: 32px;
    height: 32px;
    border-radius: 9px;
    background:
        no-repeat center / 17px 17px url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M15.5 5.5 18.5 8.5M5 19h3l10-10-3-3L5 16z'/%3E%3C/svg%3E"),
        rgba(255, 255, 255, .16);
}

body div.DTE.DTE_Action_Remove div.DTE_Header:before {
    background:
        no-repeat center / 17px 17px url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M5 7.5h14M9.5 7.5V5.5h5v2M7 7.5 7.8 19h8.4L17 7.5M10.5 11v5M13.5 11v5'/%3E%3C/svg%3E"),
        rgba(255, 255, 255, .16);
}

body div.DTE div.DTE_Header div.DTE_Header_Content {
    flex: 1 1 auto;
    min-width: 0;
    font-size: var(--thi-fs-section);
    font-weight: 800;
    line-height: 1.25;
    color: #fff;
}

body div.DTE div.DTE_Body,
body div.DTE div.DTE_Body.modal-body { padding: 0 !important; }
body div.DTE div.DTE_Form_Content { padding: 0 !important; }

body div.DTE div.DTE_Body div.DTE_Body_Content {
    max-height: none;
    padding: 20px 22px;
    overflow: visible;
    background: var(--thi-surface);
}

body div.DTE div.DTE_Body div.DTE_Body_Content div.DTE_Form_Info {
    margin: 0 0 14px;
    padding: 12px 14px;
    font-size: var(--thi-fs-sm);
    font-weight: 600;
    color: var(--thi-muted);
    background: var(--thi-surface-2);
    border: 1px solid var(--thi-line);
    border-radius: 10px;
}

body div.DTE div.DTE_Body div.DTE_Body_Content div.DTE_Form_Info:empty { display: none !important; }

/* One field per row, label above input - the plugin's float/percent-width
   layout is unwound rather than tuned. */
body div.DTE div.DTE_Body div.DTE_Body_Content div.DTE_Field {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 7px;
    margin: 0;
    padding: 0 0 16px !important;
    background: transparent !important;
    border: none !important;
}

body div.DTE div.DTE_Body div.DTE_Body_Content div.DTE_Field:last-child { padding-bottom: 0 !important; }
body div.DTE div.DTE_Body div.DTE_Body_Content div.DTE_Field:after { display: none !important; }

body div.DTE div.DTE_Body div.DTE_Body_Content div.DTE_Field > label {
    float: none !important;
    width: auto !important;
    margin: 0;
    padding: 0 !important;
    font-size: var(--thi-fs-xs);
    font-weight: 700;
    color: var(--thi-ink);
}

body div.DTE div.DTE_Body div.DTE_Body_Content div.DTE_Field > div.DTE_Field_Input {
    float: none !important;
    width: auto !important;
    min-width: 0;
}

body div.DTE div.DTE_Field input[type="color"],
body div.DTE div.DTE_Field input[type="date"],
body div.DTE div.DTE_Field input[type="datetime"],
body div.DTE div.DTE_Field input[type="datetime-local"],
body div.DTE div.DTE_Field input[type="email"],
body div.DTE div.DTE_Field input[type="month"],
body div.DTE div.DTE_Field input[type="number"],
body div.DTE div.DTE_Field input[type="password"],
body div.DTE div.DTE_Field input[type="search"],
body div.DTE div.DTE_Field input[type="tel"],
body div.DTE div.DTE_Field input[type="text"],
body div.DTE div.DTE_Field input[type="time"],
body div.DTE div.DTE_Field input[type="url"],
body div.DTE div.DTE_Field input[type="week"],
body div.DTE div.DTE_Field select,
body div.DTE div.DTE_Field textarea {
    width: 100% !important;
    min-height: 42px;
    margin: 0 !important;
    padding: 10px 13px;
    font-family: inherit;
    font-size: var(--thi-fs-body);
    font-weight: 600;
    color: var(--thi-ink);
    background-color: var(--thi-surface);
    border: 1px solid var(--thi-line);
    border-radius: 9px;
    box-shadow: none;
    outline: none;
}

body div.DTE div.DTE_Field input:focus,
body div.DTE div.DTE_Field select:focus,
body div.DTE div.DTE_Field textarea:focus {
    border-color: var(--thi-accent);
    box-shadow: 0 0 0 .2rem rgba(25, 89, 41, .12);
}

/* Radio and checkbox groups become a two-column grid of pickable cards. The
   ACTIVE/INACTIVE pair every listing uses is the main beneficiary. */
body div.DTE div.DTE_Field_Type_radio div.DTE_Field_InputControl,
body div.DTE div.DTE_Field_Type_checkbox div.DTE_Field_InputControl {
    padding: 0 !important;
    background: transparent !important;
    border: none !important;
    box-shadow: none !important;
}

body div.DTE div.DTE_Field_Type_radio div.DTE_Field_InputControl > div,
body div.DTE div.DTE_Field_Type_checkbox div.DTE_Field_InputControl > div {
    display: grid !important;
    grid-template-columns: 1fr 1fr !important;
    gap: 9px !important;
    padding: 0 !important;
    background: transparent !important;
    border: none !important;
}

body div.DTE div.DTE_Field_Type_radio div.DTE_Field_InputControl > div > div,
body div.DTE div.DTE_Field_Type_checkbox div.DTE_Field_InputControl > div > div {
    display: flex !important;
    align-items: center !important;
    gap: 9px !important;
    margin: 0 !important;
    padding: 11px 13px !important;
    background: var(--thi-surface) !important;
    border: 1.5px solid var(--thi-line) !important;
    border-radius: 10px !important;
    box-shadow: none !important;
    cursor: pointer;
    transition: border-color 180ms ease, box-shadow 180ms ease;
}

body div.DTE div.DTE_Field_Type_radio div.DTE_Field_InputControl > div > div:has(input:checked),
body div.DTE div.DTE_Field_Type_checkbox div.DTE_Field_InputControl > div > div:has(input:checked) {
    background: var(--thi-green-pale) !important;
    border-color: var(--thi-green) !important;
    box-shadow: 0 0 0 2.5px rgba(25, 89, 41, .10) !important;
}

body div.DTE div.DTE_Field input[type="radio"],
body div.DTE div.DTE_Field input[type="checkbox"] {
    flex: 0 0 16px !important;
    width: 16px !important;
    height: 16px !important;
    min-height: 0 !important;
    margin: 0 !important;
    padding: 0 !important;
    accent-color: var(--thi-green);
}

body div.DTE div.DTE_Field_Type_radio label,
body div.DTE div.DTE_Field_Type_checkbox label {
    margin: 0 !important;
    font-size: var(--thi-fs-sm);
    font-weight: 700;
    color: var(--thi-ink);
    cursor: pointer;
}

body div.DTE div.DTE_Form_Error,
body div.DTE div.DTE_Field_Error {
    margin-top: 5px;
    font-size: var(--thi-fs-note);
    font-weight: 700;
    color: #d92d20;
}

body div.DTE div.DTE_Field_Info {
    margin-top: 4px;
    font-size: var(--thi-fs-meta);
    font-weight: 500;
    color: var(--thi-muted);
}

body div.DTE div.DTE_Processing_Indicator { color: var(--thi-green); }

body div.DTE div.DTE_Footer,
body div.DTE div.DTE_Footer.modal-footer {
    display: flex !important;
    align-items: center;
    justify-content: flex-end !important;
    gap: 10px;
    padding: 14px 22px !important;
    background: var(--thi-surface-2) !important;
    border-top: 1px solid var(--thi-line) !important;
}

body div.DTE div.DTE_Footer_Content { display: none !important; }

body div.DTE div.DTE_Form_Buttons {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: 10px;
}

body div.DTE div.DTE_Form_Buttons button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
    margin: 0 !important;
    padding: 11px 19px;
    font-family: inherit;
    font-size: var(--thi-fs-body);
    font-weight: 700;
    line-height: 1;
    color: #fff;
    background: var(--thi-green);
    border: 1.5px solid var(--thi-green);
    border-radius: 9px;
    cursor: pointer;
}

body div.DTE div.DTE_Form_Buttons button:hover {
    background: var(--thi-green-deep);
    border-color: var(--thi-green-deep);
}

/* Delete confirmation: a tighter dialog whose confirm button is the
   destructive one, so it cannot be mistaken for a save. */
body .modal.DTED:has(.DTE_Action_Remove) .modal-dialog,
body .modal.DTED:has(.DTE_Action_Remove) .modal-dialog.modal-lg {
    max-width: min(448px, calc(100vw - 40px)) !important;
}

body div.DTE.DTE_Action_Remove div.DTE_Header:not([class*="bg-"]) { background: #d92d20; }

body div.DTE.DTE_Action_Remove div.DTE_Body_Content {
    padding: 22px;
    font-size: var(--thi-fs-sm);
    font-weight: 500;
    line-height: 1.55;
    color: var(--thi-muted);
}

body div.DTE.DTE_Action_Remove div.DTE_Form_Buttons button {
    color: #fff;
    background: #d92d20;
    border-color: #d92d20;
}

body div.DTE.DTE_Action_Remove div.DTE_Form_Buttons button:hover { background: #b42318; border-color: #b42318; }

/* Inline editing (clicking a cell) and the bubble editor use the same inputs. */
body div.DTE_Inline input,
body div.DTE_Inline select,
body div.DTE_Bubble input,
body div.DTE_Bubble select {
    font-family: inherit;
    font-size: var(--thi-fs-sm);
    color: var(--thi-ink);
    background: var(--thi-surface);
    border: 1px solid var(--thi-accent);
    border-radius: 7px;
}

body div.DTE_Bubble div.DTE_Bubble_Liner {
    color: var(--thi-ink);
    background: var(--thi-surface);
    border: 1px solid var(--thi-line);
    border-radius: 12px;
    box-shadow: 0 14px 34px rgba(18, 48, 25, .18);
}


/* ---------------------------------------------------------------------------
   bootstrap-select (.selectpicker).

   63 views build their dropdowns with this plugin, so its button is the
   control people actually see - the .form-select rules above never reach it.
   The plugin copies the <select>'s classes onto its wrapper <div>, which means
   `form-control` lands there as well and draws a second border around the
   button; the wrapper is neutralised and only the button is styled.
   --------------------------------------------------------------------------- */
.bootstrap-select { width: 100% !important; }

.bootstrap-select.form-control,
.bootstrap-select.form-select {
    height: auto;
    min-height: 0;
    padding: 0;
    background: transparent;
    border: none;
    border-radius: 0;
    box-shadow: none;
}

.bootstrap-select > .dropdown-toggle {
    display: flex;
    align-items: center;
    width: 100%;
    min-height: 39px;
    padding: 0 38px 0 13px;
    font-family: inherit;
    font-size: var(--thi-fs-body);
    font-weight: 600;
    text-align: left;
    color: var(--thi-ink);
    background: var(--thi-surface);
    border: 1px solid var(--thi-line);
    border-radius: 9px;
    box-shadow: none;
    outline: none;
    /* One chevron for both the native selects and this button; the plugin's
       own triangle caret is hidden below. */
    -webkit-appearance: none;
    appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23708076' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 13px center;
    background-size: 15px 15px;
    transition: border-color 140ms ease, box-shadow 140ms ease;
}

/* Two default carets to suppress: .bs-caret from the plugin and ::after from
   Bootstrap's .dropdown-toggle. */
.bootstrap-select > .dropdown-toggle .bs-caret,
.bootstrap-select > .dropdown-toggle::after { display: none !important; }

.bootstrap-select > .dropdown-toggle:hover { border-color: #8bb99a; }

/* The plugin sets a thick default outline on :focus - replaced with the same
   focus ring the other form controls use. */
.bootstrap-select > .dropdown-toggle:focus,
.bootstrap-select > .dropdown-toggle:focus-visible,
.bootstrap-select.show > .dropdown-toggle {
    outline: none !important;
    outline-offset: 0 !important;
    color: var(--thi-ink);
    background-color: var(--thi-surface);
    border-color: var(--thi-accent);
    box-shadow: 0 0 0 .2rem rgba(25, 89, 41, .12);
}

/* .filter-option is given height:100% by the plugin, so inside a centred flex
   button it fills the box and its text sticks to the top edge. */
.bootstrap-select > .dropdown-toggle .filter-option {
    position: static;
    display: flex;
    align-items: center;
    flex: 1 1 auto;
    min-width: 0;
    height: 100%;
    padding: 0;
    overflow: hidden;
}

.bootstrap-select > .dropdown-toggle .filter-option-inner { min-width: 0; overflow: hidden; }

.bootstrap-select .filter-option-inner-inner {
    overflow: hidden;
    font-size: var(--thi-fs-body);
    font-weight: 600;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.bootstrap-select > .dropdown-toggle.bs-placeholder,
.bootstrap-select > .dropdown-toggle.bs-placeholder .filter-option-inner-inner { color: var(--thi-muted); font-weight: 500; }

.bootstrap-select .dropdown-menu {
    padding: 6px;
    font-size: var(--thi-fs-body);
    border-radius: 12px;
}

.bootstrap-select .dropdown-menu .dropdown-item {
    padding: 8px 11px;
    border-radius: 8px;
    font-size: var(--thi-fs-body);
    font-weight: 600;
}

.bootstrap-select .dropdown-menu .dropdown-item.selected,
.bootstrap-select .dropdown-menu .dropdown-item.active {
    color: var(--thi-green) !important;
    background: var(--thi-green-soft) !important;
}

.bootstrap-select .dropdown-menu .dropdown-header {
    padding: 8px 11px 5px;
    font-size: var(--thi-fs-mini);
    font-weight: 750;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--thi-muted);
}

.bootstrap-select .bs-searchbox { padding: 4px 4px 7px; }

.bootstrap-select .bs-searchbox .form-control {
    min-height: 36px;
    font-size: var(--thi-fs-body);
    background: var(--thi-surface-2);
    border-radius: 8px;
}

.bootstrap-select .bs-actionsbox .btn { font-size: var(--thi-fs-xs); border-radius: 8px; }
.bootstrap-select .no-results { font-size: var(--thi-fs-sm); color: var(--thi-muted); background: transparent; }

/* An open list has to clear the card below it. */
.bootstrap-select.show { position: relative; z-index: 1200; }

/* ---------------------------------------------------------------------------
   select2 and the date range picker - the two other dropdowns in use.
   --------------------------------------------------------------------------- */
.select2-container--default .select2-selection--single .select2-selection__rendered {
    line-height: 37px;
    font-size: var(--thi-fs-body);
    font-weight: 600;
    color: var(--thi-ink);
}

.select2-container--default .select2-selection--single .select2-selection__arrow { height: 37px; }

.select2-container--default.select2-container--focus .select2-selection--multiple,
.select2-container--default.select2-container--open .select2-selection--single {
    border-color: var(--thi-accent);
    box-shadow: 0 0 0 .2rem rgba(25, 89, 41, .12);
}

.select2-dropdown {
    color: var(--thi-ink);
    background: var(--thi-surface);
    border: 1px solid var(--thi-line);
    border-radius: 12px;
    box-shadow: 0 12px 28px rgba(18, 48, 25, .12);
}

.select2-container--default .select2-results__option { font-size: var(--thi-fs-body); }

.select2-container--default .select2-results__option--highlighted[aria-selected],
.select2-container--default .select2-results__option[aria-selected="true"] {
    color: var(--thi-green);
    background: var(--thi-green-soft);
}

.select2-container--default .select2-selection--multiple .select2-selection__choice {
    font-size: var(--thi-fs-xs);
    font-weight: 650;
    color: var(--thi-green);
    background: var(--thi-green-soft);
    border: 1px solid var(--vz-primary-border-subtle);
    border-radius: 7px;
}

.daterangepicker {
    font-family: var(--thi-font);
    font-size: var(--thi-fs-sm);
    color: var(--thi-ink);
    background: var(--thi-surface);
    border: 1px solid var(--thi-line);
    border-radius: 12px;
    box-shadow: 0 14px 34px rgba(18, 48, 25, .16);
}

.daterangepicker td.active,
.daterangepicker td.active:hover { background: var(--thi-green); }
.daterangepicker td.in-range { background: var(--thi-green-soft); color: var(--thi-ink); }
.daterangepicker .ranges li.active { background: var(--thi-green); }
.daterangepicker .drp-buttons .btn { font-size: var(--thi-fs-xs); border-radius: 8px; }

/* ---------------------------------------------------------------------------
   SweetAlert2 - every save, delete and error lands in one of these.
   --------------------------------------------------------------------------- */
.swal2-popup {
    font-family: var(--thi-font);
    font-size: var(--thi-fs-body);
    color: var(--thi-ink);
    background: var(--thi-surface);
    border-radius: 16px;
}

/* Disarangkan di bawah .swal2-popup: pustakanya sendiri memakai
   `.swal2-popup .swal2-title`, jadi selektor satu kelas kalah telak. */
.swal2-popup .swal2-title { font-size: var(--thi-fs-section); font-weight: 800; color: var(--thi-ink); }
.swal2-popup .swal2-html-container { font-size: var(--thi-fs-sm); color: var(--thi-muted); }

.swal2-popup .swal2-styled {
    font-family: inherit;
    font-size: var(--thi-fs-body);
    font-weight: 700;
    padding: 9px 18px;
    border-radius: 9px;
    box-shadow: none !important;
}

/* Warna tombol konfirmasi ditentukan pemanggilnya lewat customClass - hapus
   berarti .btn-danger, simpan berarti .btn-primary - jadi di sini hanya
   disediakan warna cadangan untuk pemanggil yang tidak menyebut kelas apa pun.
   Sebelumnya semua tombol konfirmasi dipaksa hijau dan semua tombol batal
   dipaksa merah, yang membalik maknanya: pada dialog keluar, "Ya" (tindakan
   yang mengakhiri sesi) tampak aman dan "Batal" tampak berbahaya. */
.swal2-popup .swal2-styled.swal2-confirm:not([class*="btn-"]) {
    color: #fff;
    background-color: var(--thi-green) !important;
}

/* "Batal" selalu tindakan yang aman, di dialog mana pun - jadi netral, dan
   tidak mengikuti kelas btn-* yang kebetulan dikirim pemanggil (pada dialog
   keluar yang dikirim .btn-warning). */
.swal2-popup .swal2-styled.swal2-cancel {
    color: var(--thi-ink) !important;
    background-color: var(--thi-surface-2) !important;
    border: 1px solid var(--thi-line) !important;
}

.swal2-popup .swal2-styled.swal2-cancel:hover { background-color: var(--thi-green-pale) !important; }
.swal2-icon.swal2-success [class^="swal2-success-line"] { background-color: var(--thi-green); }
.swal2-icon.swal2-success .swal2-success-ring { border-color: rgba(25, 89, 41, .3); }

/* ---------------------------------------------------------------------------
   Topbar: user chip and the notification panel.
   --------------------------------------------------------------------------- */
/* Topbar starts just right of the rail (the theme offsets #page-topbar by the
   menu width), so it carries an even gutter of its own rather than the
   theme's lopsided 12px/24px. */
.navbar-header { padding: 0 28px; gap: 20px; }

/* Keping pengguna, mengikuti .sisto-user: avatar 36px, nama di atas peran,
   seluruhnya satu keping bersudut 12px yang hanya menyala saat disentuh. */
.topbar-user > .btn {
    display: flex;
    align-items: center;
    gap: 11px;
    padding: 6px 10px 6px 6px;
    border-radius: 12px;
    background: transparent;
    box-shadow: none;
    transition: background 140ms ease;
}

.topbar-user > .btn:hover,
.topbar-user.show > .btn { background: var(--thi-canvas); }

.topbar-user .header-profile-user {
    width: 36px;
    height: 36px;
    flex: 0 0 36px;
    object-fit: cover;
    padding: 0;
    border: 0;
}

.topbar-user .btn > span.d-flex { gap: 11px; }
.topbar-user .text-start { display: flex; flex-direction: column; align-items: flex-start; gap: 1px; line-height: 1.25; }

/* Nama dan peran dibatasi lebarnya; peran panjang seperti
   "Admin IT Pusat (Super Administrator)" kalau dibiarkan akan mendorong
   keping ini melebar dan menggeser isi topbar. */
.topbar-user .user-name-text,
.topbar-user .user-name-sub-text {
    max-width: 190px;
    margin: 0 !important;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
/* !important: markup menempelkan .fw-medium pada nama, dan utilitas Bootstrap
   itu sendiri ber-!important. */
.topbar-user .user-name-text { font-size: var(--thi-fs-body); font-weight: 700 !important; color: var(--thi-ink); }
.topbar-user .user-name-sub-text { font-size: var(--thi-fs-meta) !important; font-weight: 500; color: var(--thi-muted); }

.dropdown-header {
    font-size: var(--thi-fs-mini);
    font-weight: 750;
    letter-spacing: .07em;
    text-transform: uppercase;
    color: var(--thi-muted);
}

.dropdown-item { font-size: var(--thi-fs-body); font-weight: 600; border-radius: 8px; }
.dropdown-menu { padding: 8px; }
.dropdown-menu.p-0 { padding: 0; }
.dropdown-divider { border-color: var(--thi-line); }

/* Menu pengguna, mengikuti .sisto-user-menu. Ukuran butirnya dikunci di sini
   saja, bukan pada .dropdown-item global - tinggi 40px akan menggelembungkan
   daftar panjang milik bootstrap-select dan panel notifikasi. */
.topbar-user .dropdown-menu {
    min-width: 220px;
    padding: 8px;
    border: 1px solid var(--thi-line);
    border-radius: 14px;
    box-shadow: 0 22px 56px -30px rgba(9, 47, 20, .55);
}

.topbar-user .dropdown-menu .dropdown-item {
    display: flex;
    align-items: center;
    min-height: 40px;
    padding: 9px 10px;
    border-radius: 10px;
    font-size: var(--thi-fs-sm);
    font-weight: 700;
}

.topbar-user .dropdown-menu .dropdown-divider { margin: 7px 0; }

/* The notification panel's head is painted with .bg-primary + .bg-pattern,
   which on the green brand needs no extra pattern to read as a header. */
#notificationDropdown .dropdown-head {
    background: linear-gradient(120deg, var(--thi-green-deep) 0%, var(--thi-green) 60%, var(--thi-accent) 100%) !important;
    border-radius: 12px 12px 0 0;
}

#notificationDropdown .dropdown-head .nav-tabs-custom .nav-link {
    font-size: var(--thi-fs-xs);
    font-weight: 700;
    color: rgba(255, 255, 255, .78);
    border: none;
}

#notificationDropdown .dropdown-head .nav-tabs-custom .nav-link.active {
    color: #fff;
    background: transparent;
    border-bottom: 2px solid #fff;
}

#notificationDropdown .notification-item,
#notificationDropdown .dropdown-item {
    padding: 11px 13px;
    border-bottom: 1px solid var(--thi-line);
    border-radius: 0;
}

#notificationDropdown .notification-item:last-child { border-bottom: none; }
.topbar-badge { font-size: var(--thi-fs-micro) !important; font-weight: 700; }

/* ---------------------------------------------------------------------------
   Remaining type-scale pass. These are the places the theme sets a size of its
   own that the tokens above would otherwise not reach.
   --------------------------------------------------------------------------- */
body { font-size: var(--thi-fs-body); }

.btn { font-size: var(--thi-fs-body); padding: 9px 16px; }
.btn-sm { font-size: var(--thi-fs-note); padding: 6px 12px; border-radius: 8px; }
.btn-lg { font-size: var(--thi-fs-md); padding: 12px 22px; border-radius: 11px; }
.btn-icon { padding: 0; }

.form-control,
.form-select { font-size: var(--thi-fs-body); font-weight: 600; }
.form-control-sm,
.form-select-sm { min-height: 34px; font-size: var(--thi-fs-xs); border-radius: 8px; }
.form-text { font-size: var(--thi-fs-meta); color: var(--thi-muted); }
.input-group-text {
    font-size: var(--thi-fs-body);
    color: var(--thi-muted);
    background: var(--thi-surface-2);
    border-color: var(--thi-line);
    border-radius: 9px;
}

.badge { font-size: var(--thi-fs-mini); font-weight: 700; border-radius: 7px; }
.nav-tabs .nav-link { font-size: var(--thi-fs-xs); font-weight: 700; }
.alert { font-size: var(--thi-fs-sm); border: none; border-radius: 12px; padding: 13px 16px; }
.modal-title { font-size: var(--thi-fs-section); }

/* Flash messages. The theme's subtle variants are tuned to its blue palette;
   success in particular came out close to the brand green, so the two could
   not be told apart. */
.alert-success { color: #0d6b3a; background: #e8f8ee; }
.alert-danger { color: #b42318; background: #fdecef; }
.alert-warning { color: #8a5300; background: #fdf3e4; }
.alert-info { color: var(--thi-green-deep); background: var(--thi-green-soft); }

:root[data-bs-theme="dark"] .alert-success { color: #9fe3ac; background: #1f3a28; }
:root[data-bs-theme="dark"] .alert-danger { color: #ffb4a6; background: #3a2220; }
:root[data-bs-theme="dark"] .alert-warning { color: #f5cd87; background: #38301c; }
:root[data-bs-theme="dark"] .alert-info { color: #9fe3ac; background: var(--thi-green-soft); }


/* ---------------------------------------------------------------------------
   Dialog rekam murid (SPMB & Data Murid).

   Isinya sebelas bagian dalam satu `ul.nav-pills#nav-tab`. Sebagai deretan pil
   mendatar, bagian terakhir membungkus ke baris kedua sehingga kepala dialog
   terlihat patah, dan tiap bagian hanya terbaca setelah matanya menyusuri satu
   baris penuh. Sisto menaruh daftar bagiannya di sisi kiri sebagai rel tegak -
   bentuk itu yang dipakai di sini, murni lewat CSS: markup, id, dan atribut
   data-bs-toggle yang dibaca Bootstrap tidak disentuh sama sekali.
   --------------------------------------------------------------------------- */

/* Dilebarkan dari .modal-xl supaya rel kiri tidak memakan ruang isian. */
.modal-dialog:has(#nav-tab) { max-width: min(1180px, calc(100vw - 48px)); }

/* Tinggi dialog dikunci. .modal-dialog-scrollable memang membuat pembungkusnya
   setinggi layar, tapi .modal-content di dalamnya tetap menyusut mengikuti
   isinya - sehingga pindah dari "Profil" (panjang) ke "Status Siswa" (dua
   isian) membuat kotaknya mengerut lalu menengah ulang, dan rel bagian di
   kiri ikut melompat. Dengan tinggi penuh, ukurannya sama di semua bagian;
   yang bergulir cukup panel kanannya. */
.modal-dialog:has(#nav-tab) .modal-content { height: 100%; }

/* Yang bergulir sekarang masing-masing kolom, bukan badan dialognya - kalau
   badan ikut bergulir, rel kiri ikut hanyut saat isian digulir. */
.modal-body:has(> #nav-tab) {
    display: flex;
    align-items: stretch;
    padding: 0;
    overflow: hidden;
}

.modal-dialog-scrollable .modal-body:has(> #nav-tab) { overflow: hidden; }

.modal-body > #nav-tab {
    flex: 0 0 236px;
    width: 236px;
    display: flex;
    flex-direction: column;
    flex-wrap: nowrap;
    gap: 3px;
    margin: 0;
    padding: 14px 12px 22px;
    overflow-y: auto;
    background: var(--thi-surface-2);
    border-right: 1px solid var(--thi-line);
}

.modal-body > #nav-tab .nav-item { width: 100%; }

.modal-body > #nav-tab .nav-link {
    display: block;
    padding: 10px 12px;
    border-radius: 10px;
    font-size: var(--thi-fs-sm);
    font-weight: 600;
    line-height: 1.4;
    text-align: left;
    color: var(--thi-muted);
    background: transparent;
}

.modal-body > #nav-tab .nav-link:hover { color: var(--thi-ink); background: var(--thi-green-pale); }

.modal-body > #nav-tab .nav-link.active {
    color: var(--thi-green) !important;
    background: var(--thi-surface) !important;
    font-weight: 700;
    box-shadow: inset 3px 0 0 var(--thi-green), 0 1px 2px rgba(18, 48, 25, .06);
}

:root[data-bs-theme="dark"] .modal-body > #nav-tab .nav-link.active { color: var(--vz-primary-text-emphasis) !important; }

/* Garis pemisah antara pil dan panel sudah digantikan tepi rel. */
.modal-body > #nav-tab + hr { display: none; }

.modal-body > #nav-tab ~ .tab-content {
    flex: 1 1 auto;
    min-width: 0;
    padding: 22px 26px 28px;
    overflow-y: auto;
    background: var(--thi-surface);
}

/* Batang gulir tipis di dalam dialog, bukan batang tebal bawaan sistem. */
.modal-body > #nav-tab::-webkit-scrollbar,
.modal-body > #nav-tab ~ .tab-content::-webkit-scrollbar { width: 8px; }

.modal-body > #nav-tab::-webkit-scrollbar-thumb,
.modal-body > #nav-tab ~ .tab-content::-webkit-scrollbar-thumb {
    background: rgba(112, 128, 118, .32);
    border: 2px solid transparent;
    border-radius: 8px;
    background-clip: content-box;
}

/* --- isian di dalam dialog --- */

/* .col-form-label dibuat untuk label yang sebaris dengan isiannya, jadi ia
   membawa padding tegak yang di sini hanya jadi jarak kosong. */
.modal-body > #nav-tab ~ .tab-content .col-form-label,
.modal-body > #nav-tab ~ .tab-content label {
    display: block;
    padding: 0;
    margin-bottom: 6px;
    font-size: var(--thi-fs-xs);
    font-weight: 700;
    line-height: 1.35;
    color: var(--thi-ink);
}

.modal-body > #nav-tab ~ .tab-content .form-group { margin-bottom: 0; }

/* Isian yang dikunci dibedakan, supaya terlihat memang tidak bisa diubah
   dan bukan sekadar kolom kosong. */
.modal-body .form-control:disabled,
.modal-body .form-control[readonly],
.modal-body .form-select:disabled {
    color: var(--thi-muted);
    background-color: var(--thi-surface-2);
    cursor: not-allowed;
}

/* Tombol simpan tiap bagian ditulis .w-100, jadi ia melintang selebar panel
   dan terbaca seperti spanduk, bukan tindakan. Dikembalikan ke lebar isinya
   dan didorong ke kanan - margin otomatis, bukan float, supaya tidak keluar
   dari alur dan menabrak isian di bawahnya. */
.modal-body > #nav-tab ~ .tab-content button[type="submit"].w-100 {
    display: block;
    width: auto !important;
    min-width: 210px;
    margin-left: auto;
}

/* --- layar sempit: daftar bagian kembali ke atas --- */
@media (max-width: 991.98px) {
    .modal-body:has(> #nav-tab) { flex-direction: column; }

    .modal-body > #nav-tab {
        flex: 0 0 auto;
        width: 100%;
        flex-direction: row;
        flex-wrap: wrap;
        gap: 5px;
        padding: 12px 14px;
        border-right: 0;
        border-bottom: 1px solid var(--thi-line);
    }

    .modal-body > #nav-tab .nav-item { width: auto; }
    .modal-body > #nav-tab .nav-link { padding: 7px 12px; font-size: var(--thi-fs-xs); }
    .modal-body > #nav-tab .nav-link.active { box-shadow: 0 1px 2px rgba(18, 48, 25, .1); }
    .modal-body > #nav-tab ~ .tab-content { padding: 18px 16px 22px; }
    .modal-body > #nav-tab ~ .tab-content button[type="submit"].w-100 { min-width: 0; width: 100% !important; }
}


/* ---------------------------------------------------------------------------
   Popover "Info Murid" (webui-popover).

   Dipanggil dari ikon info di kolom nama pada SPMB, Data Murid, dan Ekskul.
   Pluginnya memakai gaya bawaannya sendiri - kotak putih bersudut tajam dengan
   huruf tema lama - dan isinya datang dari server sebagai <table> berisi
   pasangan <b>Label</b> / ": nilai". Markup itu dirakit di controller dan
   tidak disentuh; yang diatur di sini hanya tampilannya.
   --------------------------------------------------------------------------- */
.webui-popover {
    padding: 0;
    font-family: var(--thi-font);
    font-size: var(--thi-fs-sm);
    color: var(--thi-ink);
    background: var(--thi-surface);
    border: 1px solid var(--thi-line);
    border-radius: 14px;
    box-shadow: 0 18px 44px rgba(18, 48, 25, .18);
}

.webui-popover .webui-popover-inner { border-radius: 14px; overflow: hidden; }

.webui-popover .webui-popover-title {
    padding: 12px 16px;
    font-family: inherit;
    font-size: var(--thi-fs-panel);
    font-weight: 800;
    color: #fff;
    background: var(--thi-green);
    border-bottom: none;
    border-radius: 0;
}

/* Tombol tutup bawaan berupa × gelap di atas bilah hijau. */
.webui-popover .close {
    margin: -2px 0 0;
    padding: 0 2px;
    font-size: 19px;
    font-weight: 400;
    line-height: 1;
    color: rgba(255, 255, 255, .8);
    text-shadow: none;
    opacity: 1;
}

.webui-popover .close:hover { color: #fff; }

.webui-popover .webui-popover-content {
    /* Lebar dasarnya mengikuti isi, dan kolom nilainya jadi terlalu sempit -
       alamat surel panjang terpotong di tengah kata. */
    min-width: min(690px, calc(100vw - 56px));
    max-width: 760px;
    max-height: min(62vh, 520px);
    padding: 16px 18px 18px;
    overflow: auto;
    font-size: var(--thi-fs-sm);
    line-height: 1.5;
}

.webui-popover .webui-arrow:after { border-top-color: var(--thi-surface); border-bottom-color: var(--thi-surface); }

/* --- pasangan label / nilai --- */

.webui-popover-content table { width: 100%; border-collapse: collapse; }

.webui-popover-content td {
    padding: 4px 10px 4px 0;
    vertical-align: top;
    border: none;
    background: transparent;
}

/* Sel label: <b> dibuat tenang supaya nilainya yang menonjol, bukan namanya. */
.webui-popover-content td > b {
    display: block;
    font-size: var(--thi-fs-xs);
    font-weight: 600;
    color: var(--thi-muted);
    white-space: nowrap;
}

/* Foto murid datang tanpa ukuran, jadi dirender sebesar berkas aslinya. */
.webui-popover-content img {
    width: 84px;
    height: 84px;
    margin-right: 6px;
    object-fit: cover;
    border-radius: 12px;
    background: var(--thi-surface-2);
}

/* --- blok kelengkapan data --- */

.webui-popover-content .badge { font-size: var(--thi-fs-mini); font-weight: 700; border-radius: 7px; }

/* Daftar kekurangan dikirim sebagai <small class="text-danger"> berisi butir
   dipisah <br>. Merah penuh untuk sepuluh baris terbaca seperti galat; di sini
   dijadikan satu blok peringatan bertepi, sejalan dengan baris berstatus lain
   di sistem ini. */
.webui-popover-content small.text-danger {
    display: block;
    margin-top: 7px;
    padding: 9px 11px;
    font-size: var(--thi-fs-meta);
    line-height: 1.55;
    color: #8a5300 !important;
    background: #fdf3e4;
    border-left: 3px solid #e8a33d;
    border-radius: 0 9px 9px 0;
}

:root[data-bs-theme="dark"] .webui-popover-content small.text-danger {
    color: #f5cd87 !important;
    background: #38301c;
}

@media (max-width: 767.98px) {
    .webui-popover { max-width: calc(100vw - 24px); }
    .webui-popover .webui-popover-content { max-width: none; padding: 14px; }
    .webui-popover-content img { width: 60px; height: 60px; }
}
