/* =============================================================================
   LMS theme: components.

   Reads ONLY the variables in tokens.css; no colour literal belongs in this
   file. Loaded last in the layout, after the UBold template (Bootstrap 4.5,
   compiled CSS) and site.css, so it wins on source order at equal specificity.

   !important is used only where the template or Bootstrap already uses it on
   the same property (utilities, table cell alignment, a few plugin rules);
   each such place is marked "beats template !important".

   This is a skin: it never changes markup, text, order or behaviour.
   ========================================================================== */


/* -----------------------------------------------------------------------------
   0. Base: font, canvas, text
   -------------------------------------------------------------------------- */

body {
    font-family: var(--font);
    font-size: var(--type-base);
    line-height: 1.5;
    color: var(--text);
    background-color: var(--bg);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-rendering: optimizeLegibility;
}

h1, h2, h3, h4, h5, h6,
.h1, .h2, .h3, .h4, .h5, .h6 {
    font-family: var(--font);
    letter-spacing: var(--tracking-tight);
}

/* Components the template gives a font of their own ("Cerebri Sans" / Nunito). */
#sidebar-menu > ul > li > a,
.topnav .navbar-nav .nav-link,
.font-family-primary,
.font-family-secondary,
.swal2-modal,
.swal2-popup,
.daterangepicker,
.jq-toast-single,
.select2-container,
.selectize-control,
.flatpickr-calendar,
.datepicker,
.dropdown-menu,
.popover,
.tooltip,
.jsgrid,
.fc {
    font-family: var(--font);
}

a {
    color: var(--accent);
    transition: color var(--fast);
}

a:hover {
    color: var(--primary);
}

::selection {
    background-color: var(--accent-soft);
}

.text-muted {
    color: var(--text-2) !important; /* beats template !important */
}

.text-primary { color: var(--primary) !important; }
.text-success { color: var(--success) !important; }
.text-danger  { color: var(--danger) !important; }
.text-warning { color: var(--warning) !important; }
.text-info    { color: var(--accent) !important; }
.bg-primary   { background-color: var(--primary) !important; }
.bg-success   { background-color: var(--success) !important; }
.bg-danger    { background-color: var(--danger) !important; }
.bg-warning   { background-color: var(--warning) !important; }
.border-primary { border-color: var(--primary) !important; }

.content-page {
    background-color: transparent;   /* body paints --bg; the footer (z-index:-1) shows through */
    /* The template pads the page 15px and the container inside it another 12px.
       One gutter token sets the total instead. */
    padding-left: calc(var(--page-gutter) - 12px);
    padding-right: calc(var(--page-gutter) - 12px);
}

.content-page {
    padding-bottom: calc(var(--footer-h) + 4px);   /* the footer sits right under the content */
}

.footer {
    /* site.css sets width:100%; with the collapsed rail's left:70px (template,
       !important) that ran 70px past the window and gave every page a sideways
       scroll. left + right:0 size it instead. */
    width: auto;
    height: var(--footer-h);
    padding: 0 var(--space-4);
    display: flex;
    align-items: center;
    justify-content: center;
    line-height: 1;
    background-color: transparent;
    color: var(--text-3);
    font-size: var(--type-sm);
    border-top: 1px solid var(--hairline-soft);
}

.footer a {
    color: var(--text-2);
}


/* -----------------------------------------------------------------------------
   1. Form fields
   -------------------------------------------------------------------------- */

/* Caption above the box. Covers .form-group labels and the stray
   label.control-label used outside a group. */
.form-group > label:not(.form-check-label):not(.custom-control-label),
label.control-label,
label.col-form-label,
.form-label {
    font-size: var(--type-label);
    font-weight: 600;
    line-height: 16px;
    color: var(--text-2);
    letter-spacing: var(--tracking);
    margin-bottom: var(--space-1);
}

/* Required marker. Views write it as an inline red span after (or inside) the
   label; inline style needs !important to be recoloured. */
label + span[style*="red"],
label > span[style*="red"],
label + .text-danger,
label .text-danger {
    color: var(--warning) !important;
    font-weight: 600;
    margin-left: 2px;
}

.form-group {
    margin-bottom: var(--space-4);
}

.form-control,
.custom-select {
    height: var(--control-h);
    padding: 0 var(--space-3);
    font-family: var(--font);
    font-size: var(--type-13);
    line-height: 1.4;
    letter-spacing: var(--tracking);
    color: var(--text);
    background-color: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-ctl);
    box-shadow: none;
    transition: border-color var(--fast), background-color var(--fast), box-shadow var(--fast);
}

.form-control-sm,
.form-control-lg {
    height: var(--control-h);
    padding: 0 var(--space-3);
    font-size: var(--type-13);
    border-radius: var(--radius-ctl);
}

textarea.form-control,
select.form-control[multiple],
select.form-control[size] {
    height: auto;
    min-height: var(--control-h);
    padding: var(--space-2) var(--space-3);
}

input[type="file"].form-control {
    height: auto;
    min-height: var(--control-h);
    padding: 5px var(--space-2);
}

.form-control:hover:not(:disabled),
.custom-select:hover:not(:disabled) {
    border-color: var(--border-hover);
}

/* Focus keeps the resting border; no blue ring. */
.form-control:focus,
.custom-select:focus {
    color: var(--text);
    background-color: var(--surface);
    border-color: var(--border);
    box-shadow: none;
    outline: 0;
}

.form-control::placeholder {
    color: var(--placeholder);
    opacity: 1;
}

.form-control:disabled {
    background-color: var(--fill);
    color: var(--text-3);
    cursor: not-allowed;
}

/* flatpickr marks its date inputs readonly; they must not look disabled. */
.form-control[readonly]:not(:disabled) {
    background-color: var(--surface-2);
}

/* Dropdown arrow drawn from two gradients so it takes the --icon token. */
select.form-control:not([multiple]):not([size]),
.custom-select {
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
    padding-right: 32px;
    background-image:
        linear-gradient(45deg, transparent 50%, var(--icon) 50%),
        linear-gradient(135deg, var(--icon) 50%, transparent 50%);
    background-position:
        calc(100% - 17px) 50%,
        calc(100% - 12px) 50%;
    background-size: 5px 5px, 5px 5px;
    background-repeat: no-repeat;
}

select.form-control::-ms-expand {
    display: none;
}

/* Invalid: a red outline. */
.form-control.is-invalid,
.was-validated .form-control:invalid,
.form-control.invalid,
.invalid {
    border-color: var(--danger);
}

.form-control.is-invalid:focus,
.was-validated .form-control:invalid:focus {
    border-color: var(--danger);
    box-shadow: none;
}

.invalid-feedback {
    color: var(--danger);
    font-size: var(--type-label);
}

.form-text,
.form-group small.text-muted {
    font-size: var(--type-label);
    color: var(--text-3) !important; /* beats .text-muted !important */
}

/* Numbers and money: right-aligned, no spinners. */
input[type="number"].form-control {
    text-align: right;
    -moz-appearance: textfield;
    appearance: textfield;
}

input[type="number"]::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button {
    -webkit-appearance: none;
    margin: 0;
}

/* Input groups: one height, square inner corners. */
.input-group > .form-control,
.input-group > .custom-select {
    height: var(--control-h);
}

.input-group-text {
    height: var(--control-h);
    font-size: var(--type-13);
    color: var(--text-2);
    background-color: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: var(--radius-ctl);
}

/* Checkboxes and radios ------------------------------------------------- */

input[type="checkbox"],
input[type="radio"] {
    accent-color: var(--accent);
}

.form-check {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    min-height: var(--control-h);
    padding-left: 0;
}

.form-check-inline {
    display: inline-flex;
    margin-right: var(--space-4);
}

.form-check .form-check-input {
    position: static;
    flex: none;
    width: 16px;
    height: 16px;
    margin: 0;
    cursor: pointer;
}

.form-check-label {
    margin: 0;
    font-size: var(--type-13);
    font-weight: 500;
    color: var(--text);
    cursor: pointer;
}

/* UBold's drawn checkbox (.checkbox .checkbox-success ...). */
.checkbox label {
    font-size: var(--type-13);
    font-weight: 500;
    color: var(--text);
}

.checkbox label::before {
    border: 1.5px solid var(--border-hover);
    border-radius: var(--radius-check);
    background-color: var(--surface);
    transition: background-color var(--fast), border-color var(--fast);
}

.checkbox.checkbox input[type="checkbox"]:checked + label::before {
    background-color: var(--accent);
    border-color: var(--accent);
}

.checkbox.checkbox input[type="checkbox"]:checked + label::after {
    border-color: var(--on-primary);
    color: var(--on-primary);
}

.radio.radio input[type="radio"]:checked + label::before {
    border-color: var(--accent);
}

.radio.radio input[type="radio"] + label::after,
.radio.radio input[type="radio"]:checked + label::after {
    background-color: var(--accent);
}

/* Bootstrap custom controls. */
.custom-control .custom-control-input:checked ~ .custom-control-label::before {
    background-color: var(--accent);
    border-color: var(--accent);
}

.custom-control .custom-control-input:focus ~ .custom-control-label::before {
    box-shadow: none;
}

.custom-checkbox .custom-control-label::before {
    border-radius: var(--radius-check);
}


/* -----------------------------------------------------------------------------
   2. Buttons
   Roles follow the class each view already uses:
     primary   .btn-primary .btn-info .btn-success .btn-blue .btn-olive
               .btn-olive-light .btn-lime .btn-confirm   (Save, Add, Search, Edit...)
     secondary .btn-secondary                             (Cancel, Close)
     outline   .btn-light .btn-white .btn-default .btn-outline-secondary
     danger    .btn-danger                                (Delete)
     warning   .btn-warning
   -------------------------------------------------------------------------- */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    min-height: var(--control-h);
    padding: 0 var(--space-4);
    font-family: var(--font);
    font-size: var(--type-13);
    font-weight: 500;
    line-height: 1.2;
    letter-spacing: var(--tracking);
    border-radius: var(--radius-ctl);
    box-shadow: none;
    transition: background-color var(--fast), border-color var(--fast), color var(--fast), box-shadow var(--fast);
}

.btn-sm,
.btn-group-sm > .btn,
.btn-lg,
.btn-group-lg > .btn {
    min-height: var(--control-h);
    padding: 0 var(--space-3);
    font-size: var(--type-13);
    border-radius: var(--radius-ctl);
}

.btn-xs {
    min-height: 26px;
    padding: 0 var(--space-2);
    font-size: var(--type-xs);
    border-radius: var(--radius-ctl);
}

.btn-block {
    display: flex;
    width: 100%;
}

/* Icons: 18px, left of the label, spaced by the gap. Many buttons put the
   label inside the <i>; site.css forces .mr-1 to 12px !important, so the
   element is reset to the button's size and only the glyph is enlarged. */
.btn i {
    font-size: inherit !important; /* beats site.css .mr-1 !important */
    font-style: normal;
    line-height: 1;
}

.btn > i.mr-1,
.btn > i.mr-2,
.btn > i.ml-1 {
    margin-left: 0 !important;  /* beats Bootstrap spacing !important; the gap spaces it */
    margin-right: 0 !important;
}

.btn [class*="mdi-"]::before,
.btn [class^="fe-"]::before,
.btn [class*=" fe-"]::before,
.btn .fa::before,
.btn .fas::before,
.btn .far::before {
    font-size: var(--icon-size);
    line-height: 1;
    vertical-align: -3px;
}

.btn i:not(:empty)::before {
    margin-right: 6px;
}

.btn-xs [class*="mdi-"]::before,
.btn-xs [class^="fe-"]::before,
.btn-xs [class*=" fe-"]::before {
    font-size: 15px;
}

/* Feather sets its icon font on the element itself, so a label written
   inside the <i> fell back to the browser serif. Keep the glyph, fix the text. */
.btn [class^="fe-"],
.btn [class*=" fe-"] {
    font-family: var(--font) !important; /* beats icons.css !important */
}

.btn [class^="fe-"]::before,
.btn [class*=" fe-"]::before {
    font-family: "feather" !important;
}

/* Role colours, as variables, applied by one rule set below. */
.btn-primary, .btn-info, .btn-success, .btn-blue,
.btn-olive, .btn-olive-light, .btn-lime, .btn-confirm {
    --btn-bg: var(--primary);
    --btn-bg-hover: var(--primary-hover);
    --btn-fg: var(--on-primary);
    --btn-border: var(--primary);
    --btn-border-hover: var(--primary-hover);
}

.btn-secondary {
    --btn-bg: var(--secondary);
    --btn-bg-hover: var(--secondary-hover);
    --btn-fg: var(--on-primary);
    --btn-border: var(--secondary);
    --btn-border-hover: var(--secondary-hover);
}

.btn-danger {
    --btn-bg: var(--danger);
    --btn-bg-hover: var(--danger-hover);
    --btn-fg: var(--on-primary);
    --btn-border: var(--danger);
    --btn-border-hover: var(--danger-hover);
}

.btn-warning {
    --btn-bg: var(--warning);
    --btn-bg-hover: var(--warning-hover);
    --btn-fg: var(--on-primary);
    --btn-border: var(--warning);
    --btn-border-hover: var(--warning-hover);
}

.btn-light, .btn-white, .btn-default, .btn-outline-secondary, .btn-outline-light, .btn-outline-dark {
    --btn-bg: var(--surface);
    --btn-bg-hover: var(--surface-3);
    --btn-fg: var(--text);
    --btn-border: var(--border);
    --btn-border-hover: var(--border-hover);
}

.btn-outline-primary, .btn-outline-info, .btn-outline-success {
    --btn-bg: var(--surface);
    --btn-bg-hover: var(--primary);
    --btn-fg: var(--primary);
    --btn-fg-hover: var(--on-primary);
    --btn-border: var(--primary);
    --btn-border-hover: var(--primary);
}

.btn-outline-danger {
    --btn-bg: var(--surface);
    --btn-bg-hover: var(--danger);
    --btn-fg: var(--danger);
    --btn-fg-hover: var(--on-primary);
    --btn-border: var(--danger);
    --btn-border-hover: var(--danger);
}

.btn-outline-warning {
    --btn-bg: var(--surface);
    --btn-bg-hover: var(--warning);
    --btn-fg: var(--warning);
    --btn-fg-hover: var(--on-primary);
    --btn-border: var(--warning);
    --btn-border-hover: var(--warning);
}

.btn:is(.btn-primary, .btn-info, .btn-success, .btn-blue, .btn-olive, .btn-olive-light, .btn-lime, .btn-confirm,
        .btn-secondary, .btn-danger, .btn-warning,
        .btn-light, .btn-white, .btn-default, .btn-outline-secondary, .btn-outline-light, .btn-outline-dark,
        .btn-outline-primary, .btn-outline-info, .btn-outline-success, .btn-outline-danger, .btn-outline-warning) {
    color: var(--btn-fg);
    background-color: var(--btn-bg);
    background-image: none;
    border-color: var(--btn-border);
}

.btn:is(.btn-primary, .btn-info, .btn-success, .btn-blue, .btn-olive, .btn-olive-light, .btn-lime, .btn-confirm,
        .btn-secondary, .btn-danger, .btn-warning,
        .btn-light, .btn-white, .btn-default, .btn-outline-secondary, .btn-outline-light, .btn-outline-dark,
        .btn-outline-primary, .btn-outline-info, .btn-outline-success, .btn-outline-danger, .btn-outline-warning):is(:hover, :focus, .focus),
.btn:is(.btn-primary, .btn-info, .btn-success, .btn-blue, .btn-olive, .btn-olive-light, .btn-lime, .btn-confirm,
        .btn-secondary, .btn-danger, .btn-warning,
        .btn-light, .btn-white, .btn-default, .btn-outline-secondary, .btn-outline-light, .btn-outline-dark,
        .btn-outline-primary, .btn-outline-info, .btn-outline-success, .btn-outline-danger, .btn-outline-warning):not(:disabled):not(.disabled):is(:active, .active),
.show > .btn:is(.btn-primary, .btn-info, .btn-success, .btn-blue, .btn-olive, .btn-olive-light, .btn-lime, .btn-confirm,
        .btn-secondary, .btn-danger, .btn-warning,
        .btn-light, .btn-white, .btn-default, .btn-outline-secondary, .btn-outline-light, .btn-outline-dark,
        .btn-outline-primary, .btn-outline-info, .btn-outline-success, .btn-outline-danger, .btn-outline-warning).dropdown-toggle {
    color: var(--btn-fg-hover, var(--btn-fg));
    background-color: var(--btn-bg-hover);
    border-color: var(--btn-border-hover);
    box-shadow: none;
}

/* Labelled Delete sits slightly raised. */
.btn.btn-danger {
    box-shadow: var(--shadow-raised);
}

.btn:disabled,
.btn.disabled {
    opacity: .5;
    box-shadow: none;
}

/* Keyboard users still get a visible focus on buttons; mouse users never see it. */
.btn:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

.btn-link {
    color: var(--accent);
    font-weight: 500;
}

.btn-link:hover {
    color: var(--primary);
}

/* Buttons inside a grid row stay compact so rows keep their height. */
.table .btn,
.jsgrid .btn {
    min-height: var(--control-h-compact);
    white-space: nowrap;
    padding: 0 var(--space-2);
    font-size: var(--type-sm);
}

/* Row commands: edit in primary, delete in danger. */
.action-icon {
    color: var(--primary);
    font-size: var(--icon-size);
    transition: color var(--fast);
}

.action-icon:hover {
    color: var(--primary-hover);
}

.action-icon .mdi-delete,
.action-icon .mdi-delete-outline,
.action-icon .mdi-trash-can,
.action-icon .mdi-trash-can-outline,
.action-icon .fe-trash,
.action-icon .fe-trash-2,
.action-icon .fa-trash,
.action-icon .fa-trash-alt,
.action-icon.text-danger {
    color: var(--danger);
}


/* -----------------------------------------------------------------------------
   3. Shell, title band, cards
   -------------------------------------------------------------------------- */

/* Top bar. The template hard-codes 70px in each of these; one token sets them all. */
.navbar-custom {
    height: var(--topbar-h);
    background-color: var(--topbar-bg);
    border-bottom: 1px solid var(--hairline-soft);
    box-shadow: var(--shadow-xs);
}

.content-page {
    margin-top: var(--topbar-h);
}

.left-side-menu {
    top: var(--topbar-h);
}

.logo-box {
    height: var(--topbar-h);
}

/* No display rule here: the template shows one of two logo copies (light / dark
   top bar) by toggling display, and overriding it showed both. */
.logo-box .logo {
    line-height: var(--topbar-h);
}

.logo-box .logo-lg img {
    height: var(--logo-h);
    width: auto;
    vertical-align: middle;
}

.logo-box .logo-sm img {
    height: var(--logo-h-sm);
    width: auto;
    vertical-align: middle;
}

.navbar-custom .topnav-menu .nav-link {
    line-height: var(--topbar-h);
    max-height: var(--topbar-h);
}

.navbar-custom .button-menu-mobile {
    height: var(--topbar-h);
    line-height: var(--topbar-h);
}

.notification-list .noti-icon-badge {
    top: calc((var(--topbar-h) - 70px) / 2 + 16px);
}

.navbar-custom .topnav-menu .nav-link,
.navbar-custom .button-menu-mobile,
.navbar-custom .noti-icon,
.navbar-custom .nav-user,
.navbar-custom .pro-user-name {
    color: var(--topbar-fg) !important; /* beats template !important (dark topbar) */
}

.navbar-custom .topnav-menu .nav-link:hover,
.navbar-custom .button-menu-mobile:hover {
    color: var(--on-primary-muted) !important;
}

/* On desktop the sidebar opens on hover, so the ☰ toggle is not needed. Phones
   and tablets keep it: there is no hover there, and it is the only way in. */
@media (min-width: 993px) {
    body[data-keep-enlarged] .navbar-custom .button-menu-mobile {
        display: none;
    }
}

/* Hover-to-open sidebar (site.js adds .lms-sidebar-peek while the pointer is
   over the collapsed rail). The full menu slides over the page; the page and
   the top bar stay where they are. */
body.lms-sidebar-peek .content-page {
    margin-left: 70px !important; /* beats template !important */
}

body.lms-sidebar-peek .left-side-menu {
    z-index: 1003;
    box-shadow: var(--shadow-lg);
}

body.lms-sidebar-peek .logo-box {
    width: 70px !important;
}

body.lms-sidebar-peek .logo-box .logo-lg {
    display: none !important;
}

body.lms-sidebar-peek .logo-box .logo-sm {
    display: block !important;
}

.navbar-custom .logo-box {
    background-color: var(--topbar-bg);
}

/* Sidebar icons sit in soft coloured tiles, cycling through eight hues. */
#sidebar-menu #side-menu > li > a > i {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    margin-right: var(--space-2);
    font-size: 16px;
    border-radius: var(--radius-sm);
    color: var(--tile, var(--tile-1));
    background-color: color-mix(in srgb, var(--tile, var(--tile-1)) 12%, var(--surface));
    border: 1px solid color-mix(in srgb, var(--tile, var(--tile-1)) 22%, var(--surface));
}

#side-menu > li:nth-child(8n+1) { --tile: var(--tile-1); }
#side-menu > li:nth-child(8n+2) { --tile: var(--tile-2); }
#side-menu > li:nth-child(8n+3) { --tile: var(--tile-3); }
#side-menu > li:nth-child(8n+4) { --tile: var(--tile-4); }
#side-menu > li:nth-child(8n+5) { --tile: var(--tile-5); }
#side-menu > li:nth-child(8n+6) { --tile: var(--tile-6); }
#side-menu > li:nth-child(8n+7) { --tile: var(--tile-7); }
#side-menu > li:nth-child(8n+8) { --tile: var(--tile-8); }

/* Collapsed rail: centre the tiles. */
body[data-sidebar-size="condensed"] .left-side-menu #sidebar-menu > ul > li > a {
    display: flex;
    align-items: center;
    padding: 10px 0 10px 18px;
}

body[data-sidebar-size="condensed"] .left-side-menu #sidebar-menu > ul > li > a > i {
    margin: 0;
    font-size: 16px;
}

/* Sidebar */
.left-side-menu {
    background-color: var(--surface);
    border-right: 1px solid var(--hairline-soft);
    box-shadow: none;
}

#sidebar-menu > ul > li > a {
    color: var(--label);
    font-size: var(--type-base);
    font-weight: 500;
    letter-spacing: var(--tracking);
    transition: color var(--fast), background-color var(--fast);
}

#sidebar-menu > ul > li > a:is(:hover, :focus, :active),
#sidebar-menu .nav-second-level li a:is(:hover, :focus) {
    color: var(--primary);
}

#sidebar-menu .menuitem-active > a,
#sidebar-menu .menuitem-active .active,
#sidebar-menu a.active,
#sidebar-menu > ul > li > a.mm-active {
    color: var(--primary);
    font-weight: 600;
}

#sidebar-menu .nav-second-level li a {
    color: var(--text-2);
    font-size: var(--type-13);
    transition: color var(--fast), background-color var(--fast);
}

#sidebar-menu .menu-title {
    font-size: var(--type-xs);
    font-weight: 600;
    letter-spacing: var(--tracking-caps);
    color: var(--text-3);
}

/* Rounded item pills only in the full-width sidebar; the condensed (icon)
   sidebar positions its items itself. */
body:not([data-sidebar-size="condensed"]) #sidebar-menu > ul > li > a {
    margin: 1px var(--space-2);
    padding: 10px var(--space-3);
    border-radius: var(--radius-sm);
}

body:not([data-sidebar-size="condensed"]) #sidebar-menu > ul > li > a:hover {
    background-color: var(--surface-3);
}

/* An open section's parent is marked by colour only; the page you are on
   (the leaf) carries the filled pill, so there is one highlight, not two. */
body:not([data-sidebar-size="condensed"]) #sidebar-menu > ul > li:not(:has(.nav-second-level)).menuitem-active > a,
body:not([data-sidebar-size="condensed"]) #sidebar-menu > ul > li:not(:has(.nav-second-level)) > a.mm-active {
    background-color: var(--primary-soft);
}

body:not([data-sidebar-size="condensed"]) #sidebar-menu .nav-second-level li a {
    margin: 1px var(--space-2) 1px 0;
    padding: 7px var(--space-3);
    border-radius: var(--radius-sm);
}

body:not([data-sidebar-size="condensed"]) #sidebar-menu .nav-second-level li a:hover {
    background-color: var(--surface-3);
}

body:not([data-sidebar-size="condensed"]) #sidebar-menu .nav-second-level li.menuitem-active > a,
body:not([data-sidebar-size="condensed"]) #sidebar-menu .nav-second-level li a.active {
    color: var(--primary);
    font-weight: 600;
    background-color: var(--primary-soft);
}

/* Title band: solid primary, white bold 16px title, same space on every page. */
.page-title-box {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-1) var(--space-3);
    margin: var(--band-margin-top) 0 var(--band-margin-bottom);
    padding: var(--band-pad-y) var(--space-5);
    background-color: var(--primary);
    background-image: var(--band-gradient);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-band);
}

/* Everything written on the band is light. Pages put extra headings in
   .page-title-right (e.g. "[Timings Below: UAE GMT+4]" as an <h4>), and the
   template colours every h4 dark grey, which vanished into the olive. */
.page-title-box :is(h1, h2, h3, h4, h5, h6, b, strong, span, label, div, ol, li):not(.page-title):not(.badge):not(.btn):not(.btn *):not(.badge *):not(.dropdown-menu *):not(.form-control) {
    color: var(--on-primary-muted);
}

.page-title-box .page-title-right :is(h1, h2, h3, h4, h5, h6) {
    margin: 0;
    font-size: var(--type-13);
    font-weight: 600;
    line-height: 24px;
}

.page-title-box .text-dark,
.page-title-box .text-body,
.page-title-box .text-muted {
    color: var(--on-primary-muted) !important; /* beats utility !important */
}

.page-title-box .page-title {
    margin: 0;
    font-size: var(--type-title);
    font-weight: 700;
    line-height: 24px;
    letter-spacing: var(--tracking-tight);
    color: var(--on-primary);
    white-space: normal;
    overflow: visible;
}

/* Optional description beside the title. */
.page-title-box p,
.page-title-box small,
.page-title-box .text-muted {
    margin: 0;
    font-size: var(--type-13);
    color: var(--on-primary-muted) !important; /* beats .text-muted !important */
}

.page-title-box .page-title-right {
    order: 2;
    float: none;
    margin: 0 0 0 auto;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2);
}

.page-title-box .breadcrumb {
    margin: 0;
    padding: 0;
    background: transparent;
    font-size: var(--type-sm);
}

.page-title-box .breadcrumb-item,
.page-title-box .breadcrumb-item a,
.page-title-box .breadcrumb-item + .breadcrumb-item::before {
    color: var(--on-primary-muted);
}

.page-title-box .breadcrumb-item.active {
    color: var(--on-primary);
}

/* Buttons that sit on the band invert, or they would vanish into it. */
.page-title-box .btn:is(.btn-primary, .btn-info, .btn-success, .btn-blue, .btn-olive, .btn-olive-light, .btn-lime, .btn-confirm) {
    --btn-bg: var(--surface);
    --btn-bg-hover: var(--surface-3);
    --btn-fg: var(--primary);
    --btn-border: var(--surface);
    --btn-border-hover: var(--surface-3);
}

.page-title-box .btn:is(.btn-light, .btn-white, .btn-default, .btn-outline-secondary, .btn-outline-light) {
    --btn-bg: var(--on-primary-fill);
    --btn-bg-hover: var(--on-primary-divider);
    --btn-fg: var(--on-primary);
    --btn-border: var(--on-primary-divider);
    --btn-border-hover: var(--on-primary-muted);
}

@media (max-width: 767.98px) {
    .page-title-box .page-title {
        line-height: 24px;
        white-space: normal;
    }
}

/* Cards */
.card {
    background-color: var(--surface);
    border: 1px solid var(--hairline-soft);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    margin-bottom: var(--space-5);
}

.card-body {
    padding: var(--space-5);
}

.card-header {
    background-color: var(--surface-header);
    border-bottom: 1px solid var(--divider);
    font-weight: 600;
}

.card-header:first-child {
    border-radius: calc(var(--radius) - 1px) calc(var(--radius) - 1px) 0 0;
}

/* Section headers. ~95 card headers paint themselves bg-info (light cyan,
   usually with dark text), bg-blue (light olive with white text, 2.5:1) or
   bg-primary. They all become one readable section header: light band, bold
   dark title, dark icons. Red / orange headers keep their meaning (solid,
   white text). */
.card-header:is(.bg-info, .bg-blue, .bg-primary, .bg-light, .bg-secondary) {
    background-color: var(--surface-header) !important; /* beats utility !important */
    color: var(--text) !important;
    border-bottom: 1px solid var(--divider);
}

.card-header:is(.bg-info, .bg-blue, .bg-primary, .bg-light, .bg-secondary) :is(h1, h2, h3, h4, h5, h6, .card-title, .header-title, span, b, strong, label, .text-white) {
    color: var(--text) !important; /* beats .text-white !important */
}

.card-header :is(.card-title, .header-title, h4, h5) {
    font-size: var(--type-title);
    font-weight: 600;
    letter-spacing: var(--tracking-tight);
}

.card-header :is(.card-widgets a, .card-widgets i) {
    color: var(--icon) !important; /* beats .text-white !important */
    transition: color var(--fast);
}

.card-header .card-widgets a:hover i {
    color: var(--primary) !important;
}

.card-header:is(.bg-danger, .bg-warning, .bg-success),
.card-header:is(.bg-danger, .bg-warning, .bg-success) :is(h1, h2, h3, h4, h5, h6, .card-title, span, a, i) {
    color: var(--on-primary) !important;
}

.card-footer {
    background-color: var(--surface);
    border-top: 1px solid var(--divider);
}

.card-footer:last-child {
    border-radius: 0 0 calc(var(--radius) - 1px) calc(var(--radius) - 1px);
}

.card-title,
.header-title {
    font-size: var(--type-title);
    font-weight: 600;
    letter-spacing: var(--tracking-tight);
    color: var(--text);
}

/* Tabs and pills */
.nav-tabs {
    border-bottom: 1px solid var(--divider);
}

.nav-tabs .nav-link {
    color: var(--text-2);
    font-weight: 500;
    border: 0;
    border-bottom: 2px solid transparent;
    border-radius: 0;
    background-color: transparent;
    transition: color var(--fast), border-color var(--fast);
}

.nav-tabs .nav-link:hover {
    color: var(--primary);
    border-bottom-color: var(--hairline);
}

.nav-tabs .nav-link.active,
.nav-tabs .nav-item.show .nav-link {
    color: var(--primary);
    font-weight: 600;
    background-color: transparent;
    border-bottom-color: var(--primary);
}

.nav-pills .nav-link {
    border-radius: var(--radius-sm);
    transition: color var(--fast), background-color var(--fast);
}

.nav-pills .nav-link.active,
.nav-pills .show > .nav-link {
    color: var(--on-primary);
    background-color: var(--primary);
    border-color: var(--primary);
}

/* Menus (visuals only; the template's positioning is left alone) */
.dropdown-menu {
    padding: 6px;
    font-size: var(--type-13);
    border: 1px solid var(--hairline-soft);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-lg);
}

.dropdown-item {
    padding: 7px var(--space-3);
    color: var(--text);
    border-radius: 6px;
    transition: background-color var(--fast), color var(--fast);
}

.dropdown-item:hover,
.dropdown-item:focus {
    color: var(--text);
    background-color: var(--surface-3);
}

.dropdown-item.active,
.dropdown-item:active {
    color: var(--accent);
    background-color: var(--accent-soft);
}

/* Badges: soft pills in the page body; the topbar counters stay solid. */
.badge {
    border: 0;  /* the template draws a black border on every badge */
    border-radius: var(--radius-pill);
    padding: 4px 10px;
    font-size: var(--type-xs);
    font-weight: 600;
    letter-spacing: var(--tracking-caps);
}

.content-page .badge-success { color: var(--success); background-color: var(--success-soft); }
.content-page .badge-danger  { color: var(--danger);  background-color: var(--danger-soft); }
.content-page .badge-warning { color: var(--warning); background-color: var(--warning-soft); }
.content-page .badge-primary { color: var(--primary); background-color: var(--primary-soft); }
.content-page .badge-info    { color: var(--accent);  background-color: var(--info-soft); }
.content-page .badge-secondary { color: var(--text-2); background-color: var(--fill); }

.progress-bar {
    background-color: var(--primary);
}

.list-group-item.active {
    background-color: var(--primary);
    border-color: var(--primary);
}


/* -----------------------------------------------------------------------------
   4. Data grid
   Applies to every Bootstrap .table (the jQuery-built grids in #gridPanel and
   the static ones) and to jsGrid. Doubled class selectors out-rank the old
   .lms-table-main zebra rules without !important.
   -------------------------------------------------------------------------- */

.table.table {
    --cell-pad-x: var(--grid-cell-pad-x);
    color: var(--text);
    font-size: var(--grid-cell-font);
    font-weight: 400;  /* .lms-table-main made every cell bold */
    background-color: var(--surface);
}

/* Dense grids (8+ columns) tighten their side padding so they still fit the
   card instead of running off the right edge. */
.table.table:has(thead tr > :nth-child(8)) {
    --cell-pad-x: var(--grid-cell-pad-x-dense);
}

.table.table:not(.table-bordered) {
    border-collapse: separate;
    border-spacing: 0;
}

.table.table thead th {
    position: relative;
    padding: var(--grid-head-pad-y) var(--cell-pad-x);
    font-size: var(--grid-head-font);
    font-weight: 700;
    letter-spacing: var(--tracking);
    color: var(--on-primary);
    background-color: var(--primary);
    background-image: var(--band-gradient);
    border: 0;
    vertical-align: middle !important; /* beats template !important */
    white-space: nowrap;
}

.table.table thead th a,
.table.table thead th i {
    color: var(--on-primary);
}

/* Column separator: a short bar, 40% of the header height. */
.table.table thead th + th::before {
    content: "";
    position: absolute;
    left: 0;
    top: 30%;
    height: 40%;
    width: var(--grid-separator-w);
    border-radius: 1px;
    background-color: var(--on-primary-divider);
}

.table.table td,
.table.table tbody th {
    padding: var(--grid-cell-pad-y) var(--cell-pad-x);
    vertical-align: middle !important; /* beats template !important */
    white-space: normal;
    border-top: 0;
    border-bottom: 1px solid var(--row-border);
}

/* Compact grids (.table-sm) get shorter rows. */
.table.table.table-sm td,
.table.table.table-sm tbody th {
    padding-top: var(--grid-cell-pad-y-compact);
    padding-bottom: var(--grid-cell-pad-y-compact);
}

/* Grids wrap status badges in <h5>, and the template's heading margin made every
   such row ~20px taller. Headings inside a cell sit on the row like text. */
.table.table td :is(h1, h2, h3, h4, h5, h6) {
    margin: 0;
    line-height: inherit;
}

/* Grids that ask for single-line cells keep them. */
.table.table.table-nowrap td,
.table.table.table-nowrap th {
    white-space: nowrap;
}

/* The grid panel. A grid inside a card body, a dialog or #gridPanel is its own
   rounded, bordered panel: rounded header on top, rows, and (when the page has
   one) the pager as the panel's footer bar. Tables laid flush into a card
   (no card-body) keep the card's edge instead of drawing a second one. */
:is([id^="gridPanel"], .card-body, .modal-body, .tab-pane) > .table.table:not(.table-bordered),
:is([id^="gridPanel"], .card-body, .modal-body, .tab-pane) > .table-responsive > .table.table:not(.table-bordered) {
    --grid-r: var(--grid-radius);
    border: 1px solid var(--hairline);
    border-radius: var(--grid-r);
    box-shadow: var(--shadow-xs);
}

:is([id^="gridPanel"], .card-body, .modal-body, .tab-pane) > .table.table:not(.table-bordered) thead tr:first-child th:first-child,
:is([id^="gridPanel"], .card-body, .modal-body, .tab-pane) > .table-responsive > .table.table:not(.table-bordered) thead tr:first-child th:first-child {
    border-top-left-radius: calc(var(--grid-r) - 1px);
}

:is([id^="gridPanel"], .card-body, .modal-body, .tab-pane) > .table.table:not(.table-bordered) thead tr:first-child th:last-child,
:is([id^="gridPanel"], .card-body, .modal-body, .tab-pane) > .table-responsive > .table.table:not(.table-bordered) thead tr:first-child th:last-child {
    border-top-right-radius: calc(var(--grid-r) - 1px);
}

/* Inside the panel the last row needs no line of its own: the panel edge is it. */
:is([id^="gridPanel"], .card-body, .modal-body, .tab-pane) > .table.table:not(.table-bordered) tbody tr:last-child > *,
:is([id^="gridPanel"], .card-body, .modal-body, .tab-pane) > .table-responsive > .table.table:not(.table-bordered) tbody tr:last-child > * {
    border-bottom: 0;
}

:is([id^="gridPanel"], .card-body, .modal-body, .tab-pane) > .table.table:not(.table-bordered) tbody tr:last-child > :first-child {
    border-bottom-left-radius: calc(var(--grid-r) - 1px);
}

:is([id^="gridPanel"], .card-body, .modal-body, .tab-pane) > .table.table:not(.table-bordered) tbody tr:last-child > :last-child {
    border-bottom-right-radius: calc(var(--grid-r) - 1px);
}

/* Pager as the panel footer: #page right after #gridPanel, once it has pages. */
#gridPanel:has(> .table) + #page:has(.pagination li) {
    display: flex;
    justify-content: flex-end;
    align-items: center;
    padding: 10px var(--space-4);
    background-color: var(--surface);
    border: 1px solid var(--hairline);
    border-top: 0;
    border-radius: 0 0 var(--grid-radius) var(--grid-radius);
    box-shadow: var(--shadow-xs);
}

#gridPanel:has(> .table) + #page .pagination {
    margin: 0;
}

/* With the footer attached, the table's own bottom edge is the line between
   the rows and the footer, so its lower corners go square. */
#gridPanel:has(+ #page .pagination li) > .table.table {
    margin-bottom: 0;  /* the grids' class string is malformed, so .mb-0 never applies */
    border-bottom-left-radius: 0;
    border-bottom-right-radius: 0;
}

#gridPanel:has(+ #page .pagination li) > .table.table tbody tr:last-child > * {
    border-radius: 0;
}

/* All rows white; no zebra striping. */
.table.table tbody tr,
.table.table tbody tr:nth-child(n),
.table.table.table-striped tbody tr:nth-of-type(odd) {
    background-color: var(--surface);
    transition: background-color var(--fast);
}

.table.table tbody tr:hover,
.table.table tbody tr:nth-child(n):hover {
    background-color: var(--row-hover);
}

.table.table-bordered,
.table.table-bordered td,
.table.table-bordered th {
    border-color: var(--row-border);
}

/* Empty-state row ("No records found") */
.table.table td[colspan].text-center {
    color: var(--text-3);
    padding-top: var(--space-6);
    padding-bottom: var(--space-6);
}

/* Bare section: a card reduced to just its grid (admin dashboard timetable).
   No card chrome, no header; the grid panel is the whole section. */
.card.card-bare {
    background-color: transparent;
    border: 0;
    box-shadow: none;
}

.card.card-bare .table-responsive,
.card.card-bare [id^="gridPanel"] {
    padding: 0;
}

.card.card-bare .row {
    margin: 0;
}

.card.card-bare [id^="gridPanel"] > .table.table {
    margin-bottom: 0;
    box-shadow: var(--shadow);
}

/* Section heading above a bare grid: accent bar, title, hairline to the edge.
   Reads as a heading without bringing back a panel. */
.card.card-bare .grid-section-title {
    display: flex;
    align-items: center;
    gap: 10px;
    margin: var(--space-1) 0 var(--space-2);
    font-size: var(--type-section);
    font-weight: 600;
    line-height: 20px;
    letter-spacing: var(--tracking-tight);
    color: var(--text);
}

.card.card-bare .grid-section-title::before {
    content: "";
    flex: none;
    width: 4px;
    height: 16px;
    border-radius: 2px;
    background-color: var(--highlight);
}

.card.card-bare .grid-section-count {
    display: inline-flex;
    align-items: center;
    height: 20px;
    margin-left: -2px;
    padding: 0 8px;
    font-size: var(--type-label);
    font-weight: 600;
    letter-spacing: 0;
    color: var(--text-2);
    background-color: var(--fill);
    border-radius: var(--radius-pill);
}

.card.card-bare .grid-section-count:empty {
    display: none;
}

.card.card-bare .grid-section-title::after {
    content: "";
    flex: 1;
    height: 1px;
    background-color: var(--hairline);
}

.card.card-bare {
    margin-bottom: var(--space-4);
}

/* Collapse control in the grid header (last column). */
.table.table thead th.th-with-toggle {
    padding-right: calc(var(--cell-pad-x) + 28px);
}

.table.table thead th .grid-collapse-toggle {
    position: absolute;
    top: 50%;
    right: var(--cell-pad-x);
    transform: translateY(-50%);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    color: var(--on-primary);
    border-radius: var(--radius-ctl);
    transition: background-color var(--fast);
}

.table.table thead th .grid-collapse-toggle:hover {
    background-color: var(--on-primary-fill);
    color: var(--on-primary);
}

.table.table thead th .grid-collapse-toggle i {
    font-size: var(--icon-size);
    line-height: 1;
}

/* Collapsed: only the header bar remains, fully rounded. */
[id^="gridPanel"] > .table.table.is-collapsed thead tr:first-child th:first-child {
    border-bottom-left-radius: calc(var(--grid-r, var(--grid-radius)) - 1px);
}

[id^="gridPanel"] > .table.table.is-collapsed thead tr:first-child th:last-child {
    border-bottom-right-radius: calc(var(--grid-r, var(--grid-radius)) - 1px);
}

/* Frozen first two columns (site.css .lms-sticky-2col): match the white rows. */
.table.lms-sticky-2col tbody tr td:nth-child(-n+2) {
    background-color: var(--surface);
}

.table.lms-sticky-2col tbody tr:hover td:nth-child(-n+2) {
    background-color: var(--row-hover);
}

.table.lms-sticky-2col th:nth-child(2),
.table.lms-sticky-2col td:nth-child(2) {
    border-right: 1px solid var(--hairline);
}

/* Old header-strip class still used on a few frozen grids. */
.th-collapse-fixed {
    background-color: var(--primary);
    color: var(--on-primary);
}

/* Paginator (twbsPagination renders Bootstrap .pagination) */
.pagination {
    flex-wrap: wrap;
    gap: var(--space-1);
    margin-top: var(--space-3);
}

.pagination .page-item .page-link {
    display: flex;
    align-items: center;
    justify-content: center;
    min-width: 32px;
    height: 32px;
    margin: 0;
    padding: 0 10px;
    font-size: var(--type-13);
    font-weight: 500;
    color: var(--text);
    background-color: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-ctl);
    box-shadow: none;
    transition: background-color var(--fast), border-color var(--fast), color var(--fast);
}

.pagination .page-item .page-link:hover {
    background-color: var(--surface-3);
    border-color: var(--border-hover);
    color: var(--text);
}

.pagination .page-item.active .page-link {
    color: var(--on-primary);
    background-color: var(--primary);
    border-color: var(--primary);
}

.pagination .page-item.disabled .page-link {
    color: var(--text-3);
    background-color: var(--surface);
    border-color: var(--hairline-soft);
}

/* jsGrid */
.jsgrid .jsgrid-grid-header,
.jsgrid .jsgrid-grid-body {
    border-color: var(--hairline-soft);
}

.jsgrid .jsgrid-header-row > .jsgrid-header-cell {
    padding: 11px var(--space-3);
    font-size: var(--type-sm);
    font-weight: 600;
    color: var(--on-primary);
    background-color: var(--primary);
    border-color: var(--on-primary-divider);
}

.jsgrid .jsgrid-filter-row > .jsgrid-cell,
.jsgrid .jsgrid-insert-row > .jsgrid-cell {
    background-color: var(--surface-2);
    border-color: var(--row-border);
}

.jsgrid .jsgrid-row > .jsgrid-cell,
.jsgrid .jsgrid-alt-row > .jsgrid-cell {
    font-size: var(--type-13);
    color: var(--text);
    background-color: var(--surface);
    border-color: var(--row-border);
}

.jsgrid .jsgrid-row:hover > .jsgrid-cell,
.jsgrid .jsgrid-alt-row:hover > .jsgrid-cell {
    background-color: var(--row-hover);
}

.jsgrid .jsgrid-selected-row > .jsgrid-cell {
    background-color: var(--accent-soft);
    border-color: var(--row-border);
}

.jsgrid .jsgrid-pager-current-page {
    color: var(--on-primary);
    background-color: var(--primary);
    border-color: var(--primary);
}

.jsgrid .jsgrid-pager-nav-button a:hover,
.jsgrid .jsgrid-pager-page a:hover {
    color: var(--primary);
}


/* -----------------------------------------------------------------------------
   5. Dialogs
   -------------------------------------------------------------------------- */

.modal-backdrop.show {
    background-color: var(--scrim);
    opacity: 1;
}

.modal-content {
    background-color: var(--surface);
    border: 0;
    border-radius: var(--radius);
    box-shadow: var(--shadow-lg);
}

.modal-header {
    align-items: center;
    padding: 14px var(--space-5);
    background-image: linear-gradient(135deg, var(--primary), var(--primary-hover));
    background-color: var(--primary);
    border-bottom: 0;
    border-radius: var(--radius) var(--radius) 0 0;
}

.modal-header .modal-title,
.modal-header h4,
.modal-header h5 {
    margin: 0;
    font-size: var(--type-title);
    font-weight: 700;
    letter-spacing: var(--tracking-tight);
    color: var(--on-primary);
}

.modal-header .close {
    color: var(--on-primary);
    text-shadow: none;
    opacity: .75;
    transition: opacity var(--fast);
}

.modal-header .close:hover {
    color: var(--on-primary);
    opacity: 1;
}

/* No close X when the footer already has a button that closes the dialog.
   Dialogs whose only way out is the X keep it. */
.modal-content:has(.modal-footer [data-dismiss="modal"]) .modal-header .close {
    display: none;
}

.modal-body {
    background-color: var(--bg);
}

.modal-body:last-child {
    border-radius: 0 0 var(--radius) var(--radius);
}

.modal-body .card {
    box-shadow: var(--shadow-xs);
}

.modal-footer {
    gap: var(--space-2);
    padding: var(--space-3) var(--space-5);
    background-color: var(--surface);
    border-top: 1px solid var(--divider);
    border-radius: 0 0 var(--radius) var(--radius);
}

.modal-footer > * {
    margin: 0;
}

/* SweetAlert2 11 (admin pages): point its own theming variables at the tokens. */
:root {
    --swal2-background: var(--surface);
    --swal2-color: var(--text);
    --swal2-border-radius: var(--radius);
    --swal2-backdrop: var(--scrim);
    --swal2-confirm-button-background-color: var(--primary);
    --swal2-confirm-button-color: var(--on-primary);
    --swal2-confirm-button-border-radius: var(--radius-ctl);
    --swal2-cancel-button-background-color: var(--secondary);
    --swal2-cancel-button-color: var(--on-primary);
    --swal2-cancel-button-border-radius: var(--radius-ctl);
    --swal2-deny-button-background-color: var(--danger);
    --swal2-deny-button-border-radius: var(--radius-ctl);
    --swal2-input-border: 1px solid var(--border);
    --swal2-input-border-radius: var(--radius-ctl);
    --swal2-input-focus-border: 1px solid var(--border);
    --swal2-input-focus-box-shadow: none;
    --swal2-action-button-focus-box-shadow: 0 0 0 2px var(--accent-soft);
}

.swal2-popup {
    box-shadow: var(--shadow-lg);
}

.swal2-popup .swal2-title {
    font-size: 18px;
    font-weight: 600;
    letter-spacing: var(--tracking-tight);
    color: var(--text);
}

.swal2-popup .swal2-html-container {
    font-size: var(--type-base);
    color: var(--text-2);
}

.swal2-popup .swal2-styled {
    min-height: var(--control-h);
    padding: 0 var(--space-5);
    font-size: var(--type-13);
    font-weight: 500;
    transition: background-color var(--fast), border-color var(--fast);
}

/* Cancel / No: solid red like every Cancel button. */
.swal2-popup .swal2-styled.swal2-cancel {
    border: 1px solid transparent;
}

/* 113 confirms hard-code confirmButtonColor "#3085d6" (Bootstrap-ish blue) and
   112 cancels "#d33". SweetAlert writes them as inline variables, so they are
   remapped here: blue confirm -> primary, any cancel -> the red Cancel colour. A RED
   CONFIRM (a destructive "Yes, delete") is deliberately left red. */
.swal2-popup .swal2-confirm[style*="3085d6"] {
    --swal2-confirm-button-background-color: var(--primary) !important; /* beats inline */
}

.swal2-popup .swal2-cancel[style*="d33"],
.swal2-popup .swal2-cancel[style*="3085d6"] {
    --swal2-cancel-button-background-color: var(--secondary) !important; /* beats inline */
}

.swal2-popup .swal2-cancel[style*="d33"],
.swal2-popup .swal2-cancel[style*="3085d6"] {
    color: var(--on-primary);
}

.swal2-popup .swal2-input,
.swal2-popup .swal2-textarea,
.swal2-popup .swal2-select {
    font-size: var(--type-13);
}


/* -----------------------------------------------------------------------------
   6. Feedback
   -------------------------------------------------------------------------- */

.alert {
    border: 1px solid transparent;
    border-radius: var(--radius-sm);
    font-size: var(--type-13);
}

.alert-success { color: var(--success); background-color: var(--success-soft); }
.alert-danger  { color: var(--danger);  background-color: var(--danger-soft); }
.alert-warning { color: var(--warning); background-color: var(--warning-soft); }
.alert-info    { color: var(--accent);  background-color: var(--info-soft); }

/* _ViewMessage writes "alert alert-success bg-success text-white": solid. */
.alert.bg-success,
.alert.bg-danger {
    color: var(--on-primary);
}

.spinner-border.text-success,
.spinner-border.text-primary {
    color: var(--primary) !important; /* beats utility !important */
}


/* -----------------------------------------------------------------------------
   7. Plugins
   -------------------------------------------------------------------------- */

/* Select2 */
.select2-container .select2-selection--single,
.select2-container .select2-selection--multiple {
    min-height: var(--control-h);
    border: 1px solid var(--border) !important; /* beats template !important (multiple) */
    border-radius: var(--radius-ctl);
    background-color: var(--surface);
    transition: border-color var(--fast);
}

.select2-container .select2-selection--single {
    height: var(--control-h);
}

.select2-container .select2-selection--single:hover,
.select2-container .select2-selection--multiple:hover {
    border-color: var(--border-hover) !important; /* beats template !important */
}

.select2-container .select2-selection--single .select2-selection__rendered {
    line-height: 34px;
    padding-left: var(--space-3);
    font-size: var(--type-13);
    color: var(--text);
}

.select2-container .select2-selection--single .select2-selection__placeholder {
    color: var(--placeholder);
}

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

.select2-container .select2-selection--single .select2-selection__arrow b {
    border-top-color: var(--icon);
    border-width: 5px 5px 0 5px;
}

.select2-container .select2-selection--multiple .select2-selection__choice {
    color: var(--text);
    font-size: var(--type-sm);
    background-color: var(--surface-3);
    border: 1px solid var(--hairline);
    border-radius: var(--radius-pill);
}

.select2-dropdown {
    border: 1px solid var(--hairline-soft);
    border-radius: var(--radius-ctl);
    box-shadow: var(--shadow-lg);
    font-size: var(--type-13);
}

.select2-container--default .select2-search--dropdown .select2-search__field {
    height: 32px;
    border: 1px solid var(--border);
    border-radius: var(--radius-ctl);
    color: var(--text);
}

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

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

/* Selectize */
.selectize-input,
.selectize-control.single .selectize-input.input-active {
    min-height: var(--control-h);
    border: 1px solid var(--border);
    border-radius: var(--radius-ctl);
    box-shadow: none;
    font-size: var(--type-13);
}

.selectize-control.multi .selectize-input > div.active,
.selectize-dropdown .active {
    color: var(--text);
    background-color: var(--row-hover);
}

/* flatpickr */
.flatpickr-calendar {
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-lg);
}

.flatpickr-calendar .flatpickr-day:is(.selected, .startRange, .endRange),
.flatpickr-calendar .flatpickr-day:is(.selected, .startRange, .endRange):hover {
    color: var(--on-primary);
    background-color: var(--primary);
    border-color: var(--primary);
}

.flatpickr-calendar .flatpickr-day.today {
    border-color: var(--accent);
}

.flatpickr-calendar .flatpickr-day:hover {
    background-color: var(--row-hover);
    border-color: var(--row-hover);
}

/* bootstrap-datepicker */
.datepicker.dropdown-menu {
    padding: var(--space-2);
}

.datepicker table tr td.active,
.datepicker table tr td.active:hover,
.datepicker table tr td.active.active,
.datepicker table tr td span.active,
.datepicker table tr td span.active:hover {
    color: var(--on-primary) !important;            /* beats template !important */
    background-color: var(--primary) !important;
    background-image: none !important;
    text-shadow: none;
}

.datepicker table tr td.today {
    background-color: var(--row-hover) !important;  /* beats template !important */
    background-image: none !important;
}

/* FullCalendar (topbar calendar) */
.fc-toolbar .fc-today-button,
.fc-event .fc-content {
    background-color: var(--primary);
    color: var(--on-primary);
}

.fc-toolbar .fc-prev-button,
.fc-toolbar .fc-next-button,
.fc-ltr .fc-dayGrid-view .fc-day-top .fc-day-number {
    background-color: var(--primary-hover);
    color: var(--on-primary);
}

.fc-unthemed td.fc-today {
    background-color: var(--row-hover);
}


/* -----------------------------------------------------------------------------
   8. Dashboard grids on phones: each row becomes a card
   A 7-8 column grid cannot fit a phone, and the Join link ended up off-screen
   to the right. Under 768px the rows of the dashboard sections stack as cards
   with the actions as real buttons. CSS only: the same table markup.
   -------------------------------------------------------------------------- */

@media (max-width: 767.98px) {
    .card-bare :is(.tblTimeTable, .tblEvents, .tblExams, .tblAssignments, .tblQuiz, .tblNotifications).table.table {
        display: block;
        width: 100% !important;      /* site.css gives #gridPanel tables max-content on phones */
        min-width: 0 !important;
        border: 0;
        box-shadow: none;
        background: transparent;
    }

    .card-bare :is(.tblTimeTable, .tblEvents, .tblExams, .tblAssignments, .tblQuiz, .tblNotifications) thead {
        display: none;
    }

    .card-bare :is(.tblTimeTable, .tblEvents, .tblExams, .tblAssignments, .tblQuiz, .tblNotifications) tbody {
        display: flex;
        flex-direction: column;
        gap: var(--space-2);
    }

    .card-bare :is(.tblTimeTable, .tblEvents, .tblExams, .tblAssignments, .tblQuiz, .tblNotifications).table.table tbody tr {
        display: grid;
        grid-template-columns: auto minmax(0, 1fr) auto;  /* title spans into the flexible track, so it wraps */
        gap: 6px var(--space-3);
        align-items: center;
        padding: var(--space-3) 14px;
        background-color: var(--surface);
        border: 1px solid var(--hairline-soft);
        border-radius: var(--radius-md);
        box-shadow: var(--shadow-xs);
    }

    .card-bare :is(.tblTimeTable, .tblEvents, .tblExams, .tblAssignments, .tblQuiz, .tblNotifications).table.table tbody td {
        display: block;
        min-width: 0;
        padding: 0 !important;           /* beats the grid cell padding */
        border: 0 !important;
        border-radius: 0 !important;
        white-space: normal;
        background: transparent;
    }

    /* Cells Bootstrap hides on phones (Class, Teacher, Subject) are wanted on the card. */
    .card-bare :is(.tblTimeTable, .tblEvents, .tblExams, .tblAssignments, .tblQuiz, .tblNotifications) td.d-none.d-sm-table-cell {
        display: block !important;       /* beats .d-none !important */
    }

    /* Empty-state row: plain centred text, full width. */
    .card-bare :is(.tblTimeTable, .tblEvents, .tblExams, .tblAssignments, .tblQuiz, .tblNotifications) tbody td[colspan] {
        grid-column: 1 / -1;
        text-align: center;
        color: var(--text-3);
    }

    /* --- Timetable + Events: Day | Time | Subject | Class | Teacher | Link | (Attendance) | Status */
    .card-bare :is(.tblTimeTable, .tblEvents) tbody tr {
        grid-template-areas:
            "title  title   status"
            "day    time    time"
            "room   teacher teacher"
            "link   attend  attend";
    }

    .card-bare :is(.tblTimeTable, .tblEvents) td:nth-child(1) { grid-area: day; color: var(--text-2); font-size: var(--type-13); }
    .card-bare :is(.tblTimeTable, .tblEvents) td:nth-child(2) { grid-area: time; color: var(--text-2); font-size: var(--type-13); }
    .card-bare :is(.tblTimeTable, .tblEvents) td:nth-child(3) { grid-area: title; font-weight: 600; line-height: 1.35; }
    .card-bare :is(.tblTimeTable, .tblEvents) td:nth-child(4) { grid-area: room; color: var(--text-2); font-size: var(--type-13); }
    .card-bare :is(.tblTimeTable, .tblEvents) td:nth-child(5) { grid-area: teacher; color: var(--text-2); font-size: var(--type-13); }
    .card-bare :is(.tblTimeTable, .tblEvents) td:nth-child(5)::before { content: "·"; margin-right: 6px; color: var(--text-3); }
    .card-bare :is(.tblTimeTable, .tblEvents) td:nth-child(6) { grid-area: link; }
    .card-bare :is(.tblTimeTable, .tblEvents) td:nth-child(7):not(:last-child) { grid-area: attend; }
    .card-bare :is(.tblTimeTable, .tblEvents) td:last-child { grid-area: status; justify-self: end; align-self: start; }

    /* Join / Attendance links become buttons; empty ones (class not started) disappear. */
    .card-bare :is(.tblTimeTable, .tblEvents) td:nth-child(n) a.action-icon:empty,
    .card-bare :is(.tblTimeTable, .tblEvents) td:nth-child(n) a.action-icon:empty::after {
        display: none;
    }

    .card-bare :is(.tblTimeTable, .tblEvents) td:nth-child(6) a.action-icon,
    .card-bare .tblTimeTable td:nth-child(7):not(:last-child) a.action-icon {
        display: inline-flex;
        align-items: center;
        gap: 6px;
        min-height: var(--control-h);
        margin-top: var(--space-1);
        padding: 0 var(--space-4);
        font-size: var(--type-13);
        font-weight: 600;
        border-radius: var(--radius-ctl);
        transition: background-color var(--fast);
    }

    .card-bare :is(.tblTimeTable, .tblEvents) td:nth-child(6) a.action-icon {
        color: var(--on-primary);
        background-color: var(--primary);
    }

    .card-bare :is(.tblTimeTable, .tblEvents) td:nth-child(6) a.action-icon::after {
        content: "Join class";
    }

    .card-bare .tblTimeTable td:nth-child(7):not(:last-child) a.action-icon {
        color: var(--text);
        background-color: var(--surface);
        border: 1px solid var(--border);
    }

    .card-bare .tblTimeTable td:nth-child(7):not(:last-child) a.action-icon::after {
        content: "Attendance";
    }

    /* --- Pending Exam / Assignment / Quiz: Subject | Name | Due Date | Due Time | Status | View | Submit */
    .card-bare :is(.tblExams, .tblAssignments, .tblQuiz) tbody tr {
        grid-template-areas:
            "name    name   status"
            "subject subject subject"
            "date    time   time"
            "view    submit submit";
    }

    .card-bare :is(.tblExams, .tblAssignments, .tblQuiz) td:nth-child(1) { grid-area: subject; color: var(--text-2); font-size: var(--type-13); }
    .card-bare :is(.tblExams, .tblAssignments, .tblQuiz) td:nth-child(2) { grid-area: name; font-weight: 600; line-height: 1.35; }
    .card-bare :is(.tblExams, .tblAssignments, .tblQuiz) td:nth-child(3) { grid-area: date; color: var(--text-2); font-size: var(--type-13); }
    .card-bare :is(.tblExams, .tblAssignments, .tblQuiz) td:nth-child(4) { grid-area: time; color: var(--text-2); font-size: var(--type-13); }
    .card-bare :is(.tblExams, .tblAssignments, .tblQuiz) td:nth-child(5) { grid-area: status; justify-self: end; align-self: start; }
    .card-bare :is(.tblExams, .tblAssignments, .tblQuiz) td:nth-child(6) { grid-area: view; }
    .card-bare :is(.tblExams, .tblAssignments, .tblQuiz) td:nth-child(7) { grid-area: submit; }

    .card-bare :is(.tblExams, .tblAssignments, .tblQuiz) td :is(.btn-xs) {
        min-height: var(--control-h);
        padding: 0 var(--space-4);
        font-size: var(--type-13);
    }

    /* --- Announcements: Title (+ read more) | Priority | Due Date */
    .card-bare .tblNotifications tbody tr {
        grid-template-areas:
            "title title priority"
            "due   due   due";
    }

    .card-bare .tblNotifications td:nth-child(1) { grid-area: title; font-weight: 600; line-height: 1.35; }
    .card-bare .tblNotifications td:nth-child(1) a { font-weight: 500; white-space: nowrap; }
    .card-bare .tblNotifications td:nth-child(2) { grid-area: priority; justify-self: end; align-self: start; font-size: var(--type-sm); font-weight: 600; }
    .card-bare .tblNotifications td:nth-child(3) { grid-area: due; color: var(--text-2); font-size: var(--type-13); }

    /* Student version has a 4th column (Action). */
    .card-bare .tblNotifications tbody tr:has(> td:nth-child(4)) {
        grid-template-areas:
            "title  title  priority"
            "due    due    due"
            "action action action";
    }

    .card-bare .tblNotifications td:nth-child(4) { grid-area: action; }

    /* Collapse lives in the (hidden) header on phones; the title row is the anchor. */
    .card.card-bare .grid-section-title {
        margin-top: var(--space-2);
    }
}


/* -----------------------------------------------------------------------------
   9. SweetAlert2 v8 (teacher / student / login layouts)
   v8 has no theming variables and writes confirmButtonColor as an inline
   background-color. The default colours read the same --swal2-* variables v11
   uses (set in :root above), so one rule serves both versions; v11's inline
   variable (e.g. a red destructive confirm) still wins through the var().
   -------------------------------------------------------------------------- */

.swal2-popup .swal2-styled.swal2-confirm {
    background-color: var(--swal2-confirm-button-background-color);
    color: var(--on-primary);
    border-radius: var(--radius-ctl);
}

.swal2-popup .swal2-styled.swal2-cancel {
    background-color: var(--swal2-cancel-button-background-color);
    color: var(--on-primary);
    border: 1px solid transparent;
    border-radius: var(--radius-ctl);
}

/* v8 inline colours: blue confirm -> primary; red / blue cancel -> the red Cancel colour.
   A red v8 confirm ("Yes, delete") is left red. Not while v8 shows its spinner. */
.swal2-popup:not(.swal2-loading) .swal2-styled.swal2-confirm[style*="background-color: rgb(48, 133, 214)"] {
    background-color: var(--primary) !important; /* beats inline */
}

.swal2-popup .swal2-styled.swal2-cancel[style*="background-color: rgb(221, 51, 51)"],
.swal2-popup .swal2-styled.swal2-cancel[style*="background-color: rgb(48, 133, 214)"] {
    background-color: var(--secondary) !important; /* beats inline */
    color: var(--on-primary) !important;
}

.swal2-popup .swal2-styled:focus {
    box-shadow: 0 0 0 2px var(--accent-soft);
}


/* -----------------------------------------------------------------------------
   10. .card-box (UBold's other card) and collapsible Search Filters
   Markup pattern (see Views/Student/Index.cshtml):
     <div class="lms-filters is-collapsed" data-lms-filters>
       <div class="lms-filters-bar">
         <button type="button" class="lms-filters-toggle" aria-expanded="false">
           <i class="mdi mdi-filter-variant"></i><span>Search Filters</span>
           <span class="lms-filters-active"></span><i class="mdi mdi-chevron-down lms-filters-chevron"></i>
         </button>
         <div class="lms-filters-actions"> page actions that stay visible (Add, Export, menus) </div>
       </div>
       <div class="lms-filters-body"> the page's filter controls + Search, unchanged </div>
     </div>
   Leave out "is-collapsed" on pages that need a filter choice before showing data.
   -------------------------------------------------------------------------- */

.card-box {
    padding: var(--space-5);
    margin-bottom: var(--space-5);
    background-color: var(--surface);
    border: 1px solid var(--hairline-soft);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
}

.lms-filters {
    margin-bottom: var(--space-4);
    background-color: var(--surface);
    border: 1px solid var(--hairline-soft);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-xs);
}

.lms-filters-bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2);
    min-height: 52px;
    padding: var(--space-2) var(--space-3);
}

.lms-filters-toggle {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    padding: 6px var(--space-2);
    font-family: var(--font);
    font-size: var(--type-base);
    font-weight: 600;
    letter-spacing: var(--tracking);
    color: var(--text);
    background: transparent;
    border: 0;
    border-radius: var(--radius-sm);
    cursor: pointer;
    transition: background-color var(--fast);
}

.lms-filters-toggle:hover {
    background-color: var(--surface-3);
}

.lms-filters-toggle:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

.lms-filters-toggle > .mdi {
    font-size: var(--icon-size);
    color: var(--icon);
}

.lms-filters-chevron {
    transition: transform var(--fast);
}

.lms-filters.is-collapsed .lms-filters-chevron {
    transform: rotate(-90deg);
}

/* "2 active" while collapsed, so applied filters are never invisible. */
.lms-filters-active {
    padding: 2px 8px;
    font-size: var(--type-xs);
    font-weight: 600;
    color: var(--accent);
    background-color: var(--accent-soft);
    border-radius: var(--radius-pill);
}

.lms-filters-active:empty {
    display: none;
}

.lms-filters-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2);
    margin-left: auto;
}

.lms-filters-body {
    padding: var(--space-3) var(--space-4) var(--space-4);
    border-top: 1px solid var(--divider);
}

.lms-filters.is-collapsed .lms-filters-body {
    display: none;
}

/* select2 measures its width when it is set up; inside a collapsed body that is 0. */
.lms-filters-body .select2-container {
    width: 100% !important; /* beats select2's inline width */
}


/* -----------------------------------------------------------------------------
   11. List pages: dashboard-style density and a grid that fills the screen
   A card that wraps a grid stops being a card: filters, tabs and the grid
   panel sit straight on the canvas like the dashboard sections. site.js sizes
   each list grid down to the footer; rows scroll inside it.
   -------------------------------------------------------------------------- */

.card-box:has([id^="gridPanel"]),
.card:has(> .card-body [id^="gridPanel"]) {
    padding: 0;
    background: transparent;
    border: 0;
    box-shadow: none;
}

.card:has(> .card-body [id^="gridPanel"]) > .card-body {
    padding: 0;
}

.lms-filters {
    margin-bottom: var(--space-2);
}

.lms-filters-bar {
    min-height: 46px;
    padding: 6px var(--space-3);
}

/* Tabs above a grid: no extra air. */
.tab-content {
    padding-top: var(--space-2);
}

.nav-tabs .nav-link {
    padding: 8px var(--space-4);
}

[id^="gridPanel"].mt-2,
[id^="gridPanel"].mt-3 {
    margin-top: 0 !important; /* beats utility !important */
}

/* Buttons on the title band are compact. */
.page-title-box .btn {
    min-height: 28px;
    padding: 0 var(--space-3);
    font-size: var(--type-sm);
}

/* Fitted grid (site.js adds .lms-grid-fit): scrolls inside, header stays put. */
.lms-grid-fit {
    overflow: auto !important;     /* beats inline overflow:scroll on some grids */
    background-color: var(--surface);
    border: 1px solid var(--hairline);
    border-radius: var(--grid-radius);
    box-shadow: var(--shadow-xs);
}

.lms-grid-fit > .table.table {
    border: 0 !important;
    border-radius: 0 !important;
    box-shadow: none !important;
    margin-bottom: 0;
}

.lms-grid-fit > .table.table thead th {
    position: sticky;
    top: 0;
    z-index: 4;
}

.lms-grid-fit > .table.table thead tr:first-child th:first-child,
.lms-grid-fit > .table.table thead tr:first-child th:last-child {
    border-radius: 0;
}

/* Frozen first columns keep their stacking above the scrolling header cells. */
.lms-grid-fit > .table.lms-sticky-2col thead th:nth-child(-n+2) {
    z-index: 5;
}

/* The pager under a fitted grid joins it as its footer bar. */
.lms-grid-fit + .lms-grid-pager {
    display: flex;
    justify-content: flex-end;
    align-items: center;
    padding: 6px var(--space-3);
    background-color: var(--surface);
    border: 1px solid var(--hairline);
    border-top: 0;
    border-radius: 0 0 var(--grid-radius) var(--grid-radius);
}

.lms-grid-fit:has(+ .lms-grid-pager li) {
    border-bottom-left-radius: 0;
    border-bottom-right-radius: 0;
}

.lms-grid-fit + .lms-grid-pager .pagination {
    margin: 0;
}

/* Pagers wrap the page buttons in <div style="float:right;margin-top:15px">;
   inside the attached pager bar that margin is just a gap. */
.lms-grid-fit + .lms-grid-pager > div,
.lms-grid-fit + .lms-grid-pager nav {
    margin-top: 0 !important;      /* beats inline margin-top */
    margin-bottom: 0 !important;
}

/* The template gives the whole page min-height:1750px while the sidebar is
   collapsed (room for its pop-out submenus), which pushed the footer far below
   short pages. Our rail opens the full menu on hover instead, so the page keeps
   its natural height and the rail is pinned to the window, scrolling within
   itself when there are more items than fit. */
@media (min-width: 768px) {
    body[data-sidebar-size="condensed"]:not([data-layout="compact"]) {
        min-height: 0;
    }

    body[data-sidebar-size="condensed"] .left-side-menu {
        position: fixed;
        top: var(--topbar-h);
        bottom: 0;
        overflow-x: hidden;
        overflow-y: auto;
    }
}

/* A list page's bare card adds no margin under the grid; the pager bar meets
   the footer. */
.card-box:has([id^="gridPanel"]),
.card:has(> .card-body [id^="gridPanel"]) {
    margin-bottom: 0;
}

/* site.css gives <body> margin-bottom:60px for a sticky footer anchored to <html>;
   with the content area's own reserve that left a band between grid and footer.
   The content area alone reserves the footer's height now. */
body {
    margin-bottom: 0;
}

/* Tight vertical rhythm on list pages: title band -> filters -> tabs -> grid. */
.lms-filters {
    margin-bottom: 6px;
}

.tab-content {
    padding-top: 6px;
}

/* Spacing utilities pages put between the filter bar, the tabs and the grid. */
.card-box:has([id^="gridPanel"]) > .row > [class*="col"]:is(.mt-2, .mt-3, .mt-4),
.card-box:has([id^="gridPanel"]) .tab-content > .tab-pane > .row > [class*="col"]:is(.mt-2, .mt-3),
.card:has(> .card-body [id^="gridPanel"]) > .card-body > .row > [class*="col"]:is(.mt-2, .mt-3, .mt-4) {
    margin-top: 0 !important;      /* beats utility !important */
}

.card-box:has([id^="gridPanel"]) .nav-tabs,
.card:has(> .card-body [id^="gridPanel"]) .nav-tabs {
    margin-bottom: 0;
}

/* Collapsed rail scrolls without a visible scrollbar; the menu that opens on
   hover keeps its normal scrollbar. */
@media (min-width: 768px) {
    body[data-sidebar-size="condensed"] .left-side-menu {
        scrollbar-width: none;
    }

    body[data-sidebar-size="condensed"] .left-side-menu::-webkit-scrollbar {
        width: 0;
        height: 0;
    }

    body[data-sidebar-size="condensed"] .left-side-menu .simplebar-track {
        display: none;
    }
}

/* Any fitted list (not only #gridPanel ones) sits on the canvas like the dashboard. */
.card-box:has(.lms-grid-fit),
.card:has(> .card-body .lms-grid-fit) {
    padding: 0;
    margin-bottom: 0;
    background: transparent;
    border: 0;
    box-shadow: none;
}

.card:has(> .card-body .lms-grid-fit) > .card-body {
    padding: 0;
}

.lms-client-pager {
    margin-top: var(--space-2);
}

/* Compact dialog header and footer. */
.modal-header {
    padding: var(--dialog-head-pad-y) var(--dialog-pad-x);
}

.modal-header .modal-title,
.modal-header h4,
.modal-header h5 {
    font-size: var(--type-title);
    line-height: 22px;
}

.modal-header .close {
    padding: var(--dialog-head-pad-y) var(--dialog-pad-x);
    margin: calc(-1 * var(--dialog-head-pad-y)) calc(-1 * var(--dialog-pad-x)) calc(-1 * var(--dialog-head-pad-y)) auto;
}

.modal-footer {
    padding: var(--dialog-foot-pad-y) var(--dialog-pad-x);
}

/* Footers hold spinners with "m-2"; while hidden they are display:none, but
   when a footer holds an empty status line it must not add height. */
.modal-footer > :empty:not(.btn):not(.spinner-border) {
    display: none;
}

/* Many dialogs add padding utilities to the header/footer ("modal-footer p-3",
   p-4 ...), which are !important; the compact sizes win over them here. */
.modal-content .modal-header:is([class*=" p-"], [class*=" py-"], [class*=" pt-"], [class*=" pb-"]) {
    padding: var(--dialog-head-pad-y) var(--dialog-pad-x) !important;  /* beats utility !important */
}

.modal-content .modal-footer:is([class*=" p-"], [class*=" py-"], [class*=" pt-"], [class*=" pb-"]) {
    padding: var(--dialog-foot-pad-y) var(--dialog-pad-x) !important;  /* beats utility !important */
}
