html, body { height: 100%; }

#app-loader { transition: opacity .25s ease; }
#app-loader.is-hidden { opacity: 0; pointer-events: none; }

#sidebar.is-open { transform: translateX(0); }
#sidebar-backdrop.is-open { display: block; }

/* Sidebar: tipis, tidak mengganggu konten */
.sidebar-scroll {
    scrollbar-width: thin;
    scrollbar-color: rgb(51 65 85 / 0.9) rgb(15 23 42 / 0.5);
}
.sidebar-scroll::-webkit-scrollbar {
    width: 6px;
}
.sidebar-scroll::-webkit-scrollbar-track {
    background: transparent;
}
.sidebar-scroll::-webkit-scrollbar-thumb {
    background-color: rgb(71 85 105 / 0.85);
    border-radius: 9999px;
}
.sidebar-scroll::-webkit-scrollbar-thumb:hover {
    background-color: rgb(100 116 139 / 0.95);
}

.text-right { text-align: right !important; }

table.dataTable thead th,
table.dataTable tbody td {
    border-color: #e2e8f0;
}
table.dataTable thead th {
    background-color: #f8fafc;
    color: #64748b;
    font-weight: 600;
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
}
table.dataTable tbody tr:hover { background-color: #f8fafc; }

.dataTables_wrapper .dataTables_length,
.dataTables_wrapper .dataTables_filter,
.dataTables_wrapper .dataTables_info,
.dataTables_wrapper .dataTables_paginate {
    color: #475569;
    font-size: 0.875rem;
}
.dataTables_wrapper .dataTables_filter input,
.dataTables_wrapper .dataTables_length select {
    border: 1px solid #cbd5e1;
    border-radius: 0.5rem;
    padding: 0.375rem 0.625rem;
    margin-left: 0.5rem;
}
.dataTables_wrapper .dataTables_filter input:focus,
.dataTables_wrapper .dataTables_length select:focus {
    outline: none;
    border-color: #3b82f6;
    box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.15);
}
.dataTables_wrapper .dataTables_paginate .paginate_button {
    border-radius: 0.5rem !important;
    border: 1px solid transparent !important;
    margin: 0 0.125rem;
    padding: 0.375rem 0.75rem !important;
}
.dataTables_wrapper .dataTables_paginate .paginate_button.current,
.dataTables_wrapper .dataTables_paginate .paginate_button.current:hover {
    background: #2563eb !important;
    border-color: #2563eb !important;
    color: #fff !important;
}
.dataTables_wrapper .dataTables_paginate .paginate_button:hover {
    background: #e2e8f0 !important;
    border-color: #e2e8f0 !important;
    color: #1e293b !important;
}

/* Changelog rich-text content (Quill output) */
.changelog-content p { margin: 0 0 0.25rem 0; }
.changelog-content ul { list-style: disc; padding-left: 1.25rem; margin: 0.25rem 0; }
.changelog-content ol { list-style: decimal; padding-left: 1.25rem; margin: 0.25rem 0; }
.changelog-content li { margin-bottom: 0.125rem; }
.changelog-content h2 { font-size: 0.95rem; font-weight: 700; margin: 0.5rem 0 0.25rem 0; }
.changelog-content h3 { font-size: 0.85rem; font-weight: 600; margin: 0.5rem 0 0.25rem 0; }
.changelog-content a { color: #2563eb; text-decoration: underline; }
.changelog-content a:hover { color: #1d4ed8; }
.changelog-content blockquote {
    border-left: 3px solid #cbd5e1;
    padding-left: 0.75rem;
    margin: 0.25rem 0;
    color: #475569;
    font-style: italic;
}
.changelog-content code {
    background: #f1f5f9;
    padding: 0.125rem 0.25rem;
    border-radius: 0.25rem;
    font-family: ui-monospace, monospace;
    font-size: 0.85em;
}
.changelog-content pre {
    background: #0f172a;
    color: #e2e8f0;
    padding: 0.5rem 0.75rem;
    border-radius: 0.375rem;
    overflow-x: auto;
    margin: 0.25rem 0;
}
.changelog-content strong { font-weight: 700; }
.changelog-content em { font-style: italic; }

/* ===========================================================================
   Standardized searchable dropdowns (TomSelect) — consistent look app-wide,
   matched to the native input style (rounded-lg, slate borders, ~38px).
   =========================================================================== */
/* TomSelect copies the original <select>'s classes onto the .ts-wrapper — incl.
   Tailwind's px-3 py-2 border, which would add padding+border AROUND the control
   and make the whole thing render far taller than native inputs. Neutralize the
   wrapper's box model; the .ts-control below is the visible styled element. */
.ts-wrapper{min-width:9rem;padding:0 !important;border:0 !important;background:transparent !important;box-shadow:none !important;}
.ts-wrapper .ts-control{
    border:1px solid #cbd5e1;border-radius:.5rem;background:#fff;color:#0f172a;
    min-height:38px;padding:.25rem .625rem;font-size:.875rem;line-height:1.25rem;
    box-shadow:0 1px 2px 0 rgb(0 0 0/.05);gap:.25rem;
}
/* Single-select control: the tom-select "default" theme styles
   `.ts-wrapper.single .ts-control` at high specificity (gray gradient bg,
   #b8b8b8 border, taller box). Override it here at equal specificity so the
   control is a flat fill matching the native inputs, at the same 38px height. */
.ts-wrapper.single .ts-control{
    min-height:38px !important;height:38px !important;box-sizing:border-box;
    padding-top:0 !important;padding-bottom:0 !important;align-items:center;
    flex-wrap:nowrap;overflow:hidden;
    background:#fff;background-image:none;border-color:#cbd5e1;
    box-shadow:0 1px 2px 0 rgb(0 0 0/.05);
}
.dark .ts-wrapper.single .ts-control{background:#0f172a;background-image:none;border-color:#475569;box-shadow:none;}
.ts-wrapper.single .ts-control > .item{margin:0;padding:0;min-height:0;line-height:1.25rem;background:transparent;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:100%;}
.ts-wrapper.single .ts-control > input{margin:0;padding:0;min-height:0;min-width:0 !important;line-height:1.25rem;background:transparent;}
/* While searching (input focused/active), hide the selected item so the typed
   query replaces the displayed value instead of appearing appended after it. */
.ts-wrapper.single.input-active .ts-control > .item{display:none;}
.ts-wrapper.focus .ts-control{border-color:#3b82f6;box-shadow:0 0 0 2px rgb(59 130 246/.2);}
.ts-wrapper .ts-control input{color:#0f172a;font-size:.875rem;}
.ts-wrapper .ts-control input::placeholder{color:#94a3b8;}
.ts-wrapper.multi .ts-control .item{background:#eff6ff;color:#1d4ed8;border-radius:.375rem;padding:0 .4rem;font-weight:500;}
.ts-wrapper.multi .ts-control .item .remove{border-left-color:#bfdbfe;}
/* High z-index because dropdownParent:'body' renders panels on <body> — must sit
   above app modals (z-50) and SweetAlert (~z-1060). */
/* position:absolute + background here (not only in the vendor tom-select CSS) so
   the dropdown still anchors under its control and stays opaque even if the vendor
   stylesheet fails to load — without this, a body-parented panel falls to the
   bottom of the page, full-width. TomSelect sets inline top/left/width on open. */
.ts-dropdown{position:absolute;background:#fff;border:1px solid #cbd5e1;border-radius:.5rem;font-size:.875rem;box-shadow:0 8px 24px -8px rgb(0 0 0/.25);overflow:hidden;z-index:1100;}
.ts-wrapper{position:relative;}
.ts-dropdown .option{padding:.45rem .625rem;}
.ts-dropdown .option:hover,.ts-dropdown .option.active{background:#dbeafe;color:#1e40af;}
.ts-dropdown .no-results{padding:.5rem .625rem;color:#94a3b8;}
/* Dark mode — match native inputs (dark:bg-slate-900 #0f172a) so the control
   stands out from the slate-800 card instead of blending into it. */
.dark .ts-wrapper .ts-control{background:#0f172a;border-color:#475569;color:#e2e8f0;box-shadow:none;}
.dark .ts-wrapper.focus .ts-control{border-color:#3b82f6;}
.dark .ts-wrapper .ts-control input{color:#e2e8f0;}
.dark .ts-wrapper.multi .ts-control .item{background:#1d4ed8;color:#fff;}
.dark .ts-dropdown{background:#0f172a;border-color:#475569;color:#e2e8f0;}
.dark .ts-dropdown .option:hover,.dark .ts-dropdown .option.active{background:#1e3a8a;color:#fff;}
.dark .ts-dropdown .optgroup-header{background:#0f172a;color:#94a3b8;}

/* ===========================================================================
   Sidebar collapse (icon-only) — desktop only (lg+). Mobile drawer unchanged.
   =========================================================================== */
#sidebar { transition: width .2s ease, transform .2s ease; }
#app-shell { transition: padding-left .2s ease; }

@media (min-width: 1024px) {
    html.sidebar-collapsed #sidebar { width: 4rem; }
    html.sidebar-collapsed #app-shell { padding-left: 4rem; }

    /* Hide all text-ish bits when collapsed */
    html.sidebar-collapsed #sidebar .sidebar-label,
    html.sidebar-collapsed #sidebar .sidebar-search-wrap,
    html.sidebar-collapsed #sidebar .sidebar-brand-text,
    html.sidebar-collapsed #sidebar .sidebar-version-row,
    html.sidebar-collapsed #sidebar .sidebar-badge,
    html.sidebar-collapsed #sidebar .sidebar-submenu-chevron,
    html.sidebar-collapsed #sidebar .sidebar-chevron-btn,
    html.sidebar-collapsed #sidebar .sidebar-active-arrow {
        display: none !important;
    }

    /* Center icons, tighten horizontal padding */
    html.sidebar-collapsed #sidebar nav a,
    html.sidebar-collapsed #sidebar nav button,
    html.sidebar-collapsed #sidebar nav span.group {
        justify-content: center;
        padding-left: .5rem;
        padding-right: .5rem;
        gap: 0;
    }

    /* Collapsed: don't render nested submenu panels (they'd overflow 4rem) */
    html.sidebar-collapsed #sidebar .sidebar-submenu-panel { display: none !important; }

    /* Collapsed: category headers become thin dividers between icon groups */
    html.sidebar-collapsed #sidebar .sidebar-cat-header {
        font-size: 0 !important;
        height: 0;
        padding: 0 !important;
        margin: .5rem .75rem !important;
        border-top: 1px solid rgb(71 85 105 / .4);
    }

    /* Brand block centers its logo */
    html.sidebar-collapsed #sidebar .sidebar-brand-link { justify-content: center; }
    html.sidebar-collapsed #sidebar .sidebar-version-footer { padding-left: 0; padding-right: 0; text-align: center; }
}

/* Submenu indentation: deeper levels indent progressively + clearer rail */
#sidebar .sidebar-submenu-panel { border-left-color: rgb(71 85 105 / .5); }
#sidebar .sidebar-submenu-panel .sidebar-submenu-panel { margin-left: .75rem; }

/* ===========================================================================
   Dark-mode DataTables consistency (CDN DataTables ships light-only CSS)
   =========================================================================== */
.dark table.dataTable thead th,
.dark table.dataTable tbody td { border-color: #334155; color: #e2e8f0; }
.dark table.dataTable thead th { background-color: #1e293b; color: #94a3b8; }
.dark table.dataTable tbody tr { background-color: transparent; }
.dark table.dataTable tbody tr:hover { background-color: #1e293b; }
.dark .dataTables_wrapper .dataTables_length,
.dark .dataTables_wrapper .dataTables_filter,
.dark .dataTables_wrapper .dataTables_info,
.dark .dataTables_wrapper .dataTables_paginate { color: #94a3b8; }
.dark .dataTables_wrapper .dataTables_filter input,
.dark .dataTables_wrapper .dataTables_length select {
    background-color: #0f172a;
    border-color: #334155;
    color: #e2e8f0;
}
.dark .dataTables_wrapper .dataTables_paginate .paginate_button { color: #cbd5e1 !important; }
.dark .dataTables_wrapper .dataTables_paginate .paginate_button:hover {
    background: #334155 !important;
    border-color: #334155 !important;
    color: #f1f5f9 !important;
}
.dark .dataTables_wrapper .dataTables_paginate .paginate_button.current,
.dark .dataTables_wrapper .dataTables_paginate .paginate_button.current:hover {
    background: #2563eb !important;
    border-color: #2563eb !important;
    color: #fff !important;
}
