/*
 * Copyright (C) 2012-2013 Anton Simonov <untone@gmail.com>
 * Copyright (C) 2014-2015 Vsevolod Stakhov <vsevolod@highsecure.ru>
 */

/* stylelint-disable selector-id-pattern */

:root {
    font-size: 14px;

    /* Tweak bootstrap 5 colors for better accessibility */
    --bs-danger-rgb: 221, 0, 0;
    --bs-success-rgb: 40, 139, 69;

    /* Light mode (default) colors */
    --rspamd-bg-card-gradient-start: #f9f9f9;
    --rspamd-bg-card-gradient-end: #ededed;
    --rspamd-text-primary: #000000;
    --rspamd-text-secondary: #666666;
    --rspamd-nav-active-bg: #e7e7e7;
    --rspamd-sidebar-bg: #ffffee;
    --rspamd-symbol-description-color: #484848;
    --rspamd-symbol-negative-bg: #eef9e7;
    --rspamd-symbol-positive-bg: #fbe9e5;
    --rspamd-symbol-special-bg: #e2e9fe;
    --rspamd-symbol-hover-bg: #e6e6e6;
    --rspamd-table-danger-bg: #fbe9e5;
    --rspamd-table-success-bg: #eef9e7;
    --rspamd-table-warning-bg: #fff8e6;
    --rspamd-bs-table-bg: #f8f9fa;

    /* Per-type hover colors (light theme) */
    --rspamd-symbol-negative-hover-bg: #dcf9d3;
    --rspamd-symbol-positive-hover-bg: #fbd6d1;
    --rspamd-symbol-special-hover-bg: #cddbff;

    /* Light mode logo display rules */
    --rspamd-display-logo-light: inline;
    --rspamd-display-logo-dark: none;
}

[data-theme="dark"] {
    /* Dark mode colors */
    --rspamd-bg-card-gradient-start: #2a2a2a;
    --rspamd-bg-card-gradient-end: #252525;
    --rspamd-text-primary: #cccccc;
    --rspamd-text-secondary: #b0b0b0;
    --rspamd-nav-active-bg: #404040;
    --rspamd-sidebar-bg: #444422;
    --rspamd-symbol-description-color: #848484;
    --rspamd-symbol-negative-bg: #1a3a1a;
    --rspamd-symbol-positive-bg: #3a1a1a;
    --rspamd-symbol-special-bg: #3a3a5a;
    --rspamd-symbol-hover-bg: #000000;
    --rspamd-table-danger-bg: #390b00;
    --rspamd-table-success-bg: #102d00;
    --rspamd-table-warning-bg: #43380b;
    --rspamd-bs-table-bg: #272b2f;

    /* Per-type hover colors (dark theme) */
    --rspamd-symbol-negative-hover-bg: #274f27;
    --rspamd-symbol-positive-hover-bg: #4b2b2b;
    --rspamd-symbol-special-hover-bg: #41426a;

    /* Dark mode logo display rules */
    --rspamd-display-logo-light: none;
    --rspamd-display-logo-dark: inline;
}

/* bootstrap 4 overrides */
body {
    font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
}
code {
    font-size: 90%;
}
small,
.small {
    font-size: 85%;
}
.text-secondary {
    color: var(--rspamd-text-secondary) !important;
}
.navbar {
    padding-top: 0;
    padding-bottom: 0;
    margin-bottom: 20px;
}
.nav-pills .nav-link.active {
    background-color: var(--rspamd-nav-active-bg);
}
.danger > td {
    background-color: var(--rspamd-table-danger-bg);
}
.success > td {
    background-color: var(--rspamd-table-success-bg);
}
td.warning {
    background-color: var(--rspamd-table-warning-bg);
}
@media (max-width: 1199px) {
    .navbar-collapse.order-3 {
        border-top: 1px solid #dee2e6 !important;
    }
    /* Avoid navbar toggler hiding on navbar collapse */
    .navbar-toggler {
        display: block !important;
    }
}

/* bootstrap 4 additionals */
.btn-group-xs > .btn,
.btn-xs {
    padding: .06rem .3rem;
    font-size: .875rem;
    line-height: 1.5;
    border-radius: .2rem;
}
.btn.disabled,
.btn[disabled],
fieldset[disabled] .btn {
    pointer-events: auto;
    cursor: not-allowed;
}
.card.disabled,
.input-group.disabled {
    cursor: not-allowed;
    opacity: 0.65;
}
.card.disabled *,
.input-group.disabled * {
    pointer-events: none;
}
.w-1 {
    width: 1%;
}

a {
    outline: none;
}
textarea {
    font-family: "Courier New", Courier, monospace;
    resize: vertical;
}

/*
 * Tabulator theme.
 * The bundled bootstrap5 theme hardcodes light colors (#fff, #dee2e6, ...),
 * which do not respond to data-bs-theme. Map them to Bootstrap CSS variables
 * (which flip with data-bs-theme) so light/dark follow automatically.
 * rspamd.css is loaded after tabulator_bs5.min.css, so these win the cascade.
 */
.tabulator {
    border: none;
    font-size: 11px;
}

/* Header */
.tabulator .tabulator-header {
    background-color: var(--bs-body-bg);
    border-top: none;
    border-bottom: 1px solid var(--bs-border-color);
    color: var(--bs-secondary-color);
}
.tabulator .tabulator-header .tabulator-col {
    background: var(--bs-body-bg);
    border-right: none;
}
.tabulator .tabulator-header .tabulator-col .tabulator-col-content {
    /* Lay out as a column that fills the header cell, so the header-filter can
       be pushed to a shared bottom baseline. Column titles wrap to differing
       numbers of lines, which otherwise leaves the filters misaligned. */
    display: flex;
    flex-direction: column;
    flex-grow: 1;
    padding: 8px;
}
/* Grow the title holder to fill the content cell so it pushes the
   header-filter (its following sibling) down to a shared bottom baseline.
   Column titles wrap to differing numbers of lines, which otherwise leaves
   the filters misaligned. Growing the holder is used instead of an auto
   margin on the filter: the cell's height comes from flex-grow, and auto
   margins don't distribute reliably against a flex-determined size. */
.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-title-holder {
    flex-grow: 1;
}
/* Keep the first glyph's left bearing clear of the title's overflow:hidden
   (e.g. the "W" in "Worker type" was clipped on the left). */
.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-title {
    padding-left: 1px;
    white-space: normal;
    overflow-wrap: break-word;
}
.tabulator .tabulator-header .tabulator-col.tabulator-sortable .tabulator-col-content .tabulator-col-title {
    padding-right: 15px;
}
/* Drop the filter to the bottom of the (flex-column) content so every
   column's filter shares one baseline, regardless of title wrap height. */
.tabulator .tabulator-header-filter {
    margin-top: auto;
}

/* Header filter input — render as a Bootstrap form-control.
   appearance:none drops the UA search-input chrome that ignored the
   dark background (input looked too light in dark mode).
   Scoped to text-like inputs so it does not strip the native checkbox
   (the action filter's "not" toggle) of its checkmark and stretch it.
   The full .tabulator > header > col > header-filter path is required:
   tabulator_bs5.min.css targets the input by that path with higher
   specificity, so a shorter selector is overridden. */
.tabulator .tabulator-header .tabulator-col .tabulator-header-filter input:not([type="checkbox"], [type="radio"]) {
    -webkit-appearance: none;
    appearance: none;
    width: 100%;
    /* Match Bootstrap .form-control-sm — the same metrics the action filter's
       form-select-sm uses — so text inputs share one size with the select and
       read smaller than the UA input default. */
    font-size: 0.875rem;
    line-height: 1.5;
    padding: 0.25rem 0.5rem;
    color: var(--bs-body-color);
    background-color: var(--bs-body-bg);
    border: 1px solid var(--bs-border-color);
    border-radius: 0.25rem;
}

/* Table body */
/* Tabulator sets the tableholder height via inline JS (getHeight()), computed
   at init when the table is inline-block — that includes a 1px descender, so
   the holder ends up 1px taller than the table content, leaving a sliver above
   the footer (visible on row hover). Size the holder to its content (overrides
   the inline height) and make the table a block (no descender). Safe for
   paginated tables without a fixed height (no virtual DOM). */
.tabulator .tabulator-tableholder {
    height: auto !important;
}
.tabulator .tabulator-tableholder .tabulator-table {
    background-color: var(--bs-body-bg);
    color: var(--bs-body-color);
    display: block;
}
.tabulator-row {
    background-color: var(--bs-body-bg);
    border-bottom: none;
    min-height: 0;
}
/* Zebra striping (light theme — rspamd palette) */
.tabulator-row.tabulator-row-even {
    background-color: var(--rspamd-bs-table-bg);
}
/* Rows are non-interactive (selectable:false): highlight on hover in the
   rspamd palette and a neutral cursor (no misleading pointer). The
   .tabulator-selectable variant is covered in case rows still carry it. */
@media (hover: hover) and (pointer: fine) {
    .tabulator-row:hover,
    .tabulator-row.tabulator-selectable:hover {
        cursor: default;
    }
}

.tabulator-row .tabulator-cell {
    padding: 4px;
    border-right: none;
    white-space: normal;
    overflow-wrap: break-word;
}
/* Horizontal separators between rows; no vertical dividers.
   Only between adjacent rows, so no double line at header/footer edges. */
.tabulator-row + .tabulator-row {
    border-top: 1px solid var(--bs-border-color);
}

/* ── Hover backgrounds intentionally disabled ──────────────────────────────
 *
 * Tabulator scrolls the page internally on row interactions (sort, expand,
 * Update). The call lives inside its render/adjustTableSize path and could not
 * be stopped at the source: overriding Element.prototype.scrollIntoView and
 * HTMLElement.prototype.focus, and stripping tabindex (tableholder/header) all
 * failed to prevent it. To keep the page from jumping to the top (the original
 * complaint), history.js counters the scroll by preserving & restoring
 * window.scrollY around clicks/renderStarted.
 *
 * That counter restores one frame late for the expand scroll: for one frame
 * the page is shifted, the element under the cursor changes, and its :hover
 * background flashed (the sortable column's header cell; the top data row).
 * The first (non-sortable) column never flashed because it had no hover bg.
 *
 * So the hover backgrounds below are removed to kill the flash; the page still
 * doesn't scroll (the counter handles that). If the expand-scroll source is
 * ever found and prevented at the root — so the scroll counter can be removed
 * — restore the hover backgrounds:
 *   sortable col:  .tabulator-col.tabulator-sortable.tabulator-col-sorter-element:hover
 *                  { background-color: var(--rspamd-nav-active-bg) }
 *   rows (light):  .tabulator-row:hover { background-color: var(--rspamd-nav-active-bg) }
 *   rows (dark):   [data-theme="dark"] .tabulator .tabulator-row:hover { ... }
 * ──────────────────────────────────────────────────────────────────────────── */

/* Override the bs5 theme's OWN hover backgrounds (#e6e6e6 on sortable cols,
   #ced4da on .tabulator-selectable rows) with the element's normal background,
   so hover causes no visible change. !important is needed to beat the theme's
   high-specificity :hover selectors; without this the theme's default hover
   color still flashes during the expand-scroll (see the note above). */
.tabulator-row:hover,
.tabulator-row.tabulator-selectable:hover,
.tabulator .tabulator-header .tabulator-col:hover {
    background-color: var(--bs-body-bg) !important;
}
.tabulator-row.tabulator-row-even:hover,
.tabulator-row.tabulator-selectable.tabulator-row-even:hover {
    background-color: var(--rspamd-bs-table-bg) !important;
}
/* Row hover background is applied to the CELLS in the bs5 theme (not the row),
   so the row override above doesn't reach it. Make cells transparent on hover
   so the row's own background (body-bg / zebra) shows through, unchanged. */
.tabulator-row:hover .tabulator-cell,
.tabulator-row.tabulator-selectable:hover .tabulator-cell {
    background-color: transparent !important;
}

/* Dark mode: the bs5 theme forces a flat #212529 onto rows and cells at high
   specificity (html[data-bs-theme=dark] .tabulator .tabulator-row/.tabulator-cell),
   which hides zebra and hover. Re-apply them under [data-theme="dark"] (set on
   <body> by the rspamd theme), which wins the cascade. */
[data-theme="dark"] .tabulator .tabulator-row .tabulator-cell {
    background-color: transparent;
}
[data-theme="dark"] .tabulator .tabulator-row.tabulator-row-even {
    background-color: #343a40;
}
[data-theme="dark"] .tabulator .tabulator-row.tabulator-row-even:hover {
    background-color: #343a40 !important;
}
@media (hover: hover) and (pointer: fine) {
    [data-theme="dark"] .tabulator .tabulator-row:hover {
        cursor: default;
    }
}

/* Responsive collapse (detail row) */
.tabulator-row .tabulator-responsive-collapse {
    border-bottom: 1px solid var(--bs-border-color);
    background-color: var(--bs-body-bg);
    color: var(--bs-body-color);
}
.tabulator-row .tabulator-responsive-collapse table {
    font-size: 11px;
    border-collapse: collapse;
}
/* Separator between the detail rows (one per collapsed column); except for
   the first row, whose top border is omitted to avoid doubling the detail's top edge. */
.tabulator-row .tabulator-responsive-collapse tr:not(:first-child) {
    border-top: 1px solid var(--bs-border-color);
}

/* Footer / pagination */
.tabulator .tabulator-footer {
    background-color: var(--bs-tertiary-bg);
    border-top: 1px solid var(--bs-border-color);
    color: var(--bs-secondary-color);
}
.tabulator .tabulator-footer .tabulator-paginator {
    color: var(--bs-secondary-color);
}
.tabulator .tabulator-footer .tabulator-page {
    background-color: var(--bs-body-bg);
    border: 1px solid var(--bs-border-color);
    color: var(--bs-body-color);
}
@media (hover: hover) and (pointer: fine) {
    .tabulator .tabulator-footer .tabulator-page:hover {
        background-color: var(--bs-tertiary-bg);
        color: var(--bs-body-color);
    }
}

/* "No data" placeholder */
.tabulator .tabulator-placeholder .tabulator-placeholder-contents {
    color: var(--bs-secondary-color);
}

/* local overrides */
.navbar-brand > img {
    height: 50px;
}
.logo-light {
    display: var(--rspamd-display-logo-light);
}
.logo-dark {
    display: var(--rspamd-display-logo-dark);
}
.btn-group > .btn.radius-right {
    border-top-right-radius: var(--bs-btn-border-radius) !important;
    border-bottom-right-radius: var(--bs-btn-border-radius) !important;
}

input.form-control[type="number"] {
    width: 4em;
    padding-left: 0;
    padding-right: 0;
    text-align: center;
}
input.action-scores {
    margin: 5px -7em 5px 0;
}
#symbolsTable input[type="number"] {
    width: 6em;
    font-size: 11px;
}

.notification-area {
    position: fixed;
    z-index: 1050;
    top: 44px;
    left: 0;
    right: 0;
    padding: 8px;
}
.alert {
    margin-bottom: 4px;
}
.alert.alert-modal {
    top: 0;
}
.alert strong {
    display: inline-block;
    padding-left: 35px;
}
[data-theme="light"] .alert-success {
    color: #468847;
    background: #dff0d8;
    border-color: #d6e9c6;
}
[data-theme="light"] .alert-danger {
    color: #b94a48;
    background: #f2dede;
    border-color: #eed3d7;
}
[data-theme="light"] .alert-warning {
    color: #c09853;
}
[data-theme="light"] .alert-info {
    color: #3a87ad;
    background: #d9edf7;
    border-color: #bce8f1;
}

#authInvalidCharFeedback,
#authUnauthorizedFeedback {
    position: unset;
    padding-top: 0.1rem;
    padding-bottom: 0.1rem;
}

.card-header,
.modal-header {
    background-image: linear-gradient(to bottom, var(--rspamd-bg-card-gradient-start), var(--rspamd-bg-card-gradient-end));
}
.card-header .h6 {
    font-size: 0.857rem;
}

.stat-box {
    background-image: linear-gradient(to bottom, var(--rspamd-bg-card-gradient-start), var(--rspamd-bg-card-gradient-end));
    line-height: 1;
}
.stat-box:not(.float-end) {
    min-width: 90px;
}
.stat-box .widget {
    font-size: 10px;
}
.stat-box .widget strong {
    font-size: 26px;
}

/* Symbols coloring */
.symbol-default {
    border-radius: 2px;
    padding-left: 2px;
    padding-right: 2px;
}
.symbol-default:hover {
    background-color: var(--rspamd-symbol-hover-bg);
}
.symbol-negative.symbol-negative {
    background-color: var(--rspamd-symbol-negative-bg);
}
.symbol-positive.symbol-positive {
    background-color: var(--rspamd-symbol-positive-bg);
}
.symbol-special {
    background-color: var(--rspamd-symbol-special-bg);
}
.symbol-negative:hover {
    background-color: var(--rspamd-symbol-negative-hover-bg);
}
.symbol-positive:hover {
    background-color: var(--rspamd-symbol-positive-hover-bg);
}
.symbol-special:hover {
    background-color: var(--rspamd-symbol-special-hover-bg);
}

/* Disable individual cell hover in status tables - use table-hover-cell instead */
.status-table tbody .symbol-negative:hover {
    background-color: var(--rspamd-symbol-negative-bg);
}
.status-table tbody .symbol-positive:hover {
    background-color: var(--rspamd-symbol-positive-bg);
}

/* For symbol description display on hover/focus */
.symbol-default.has-description:not(:focus) strong {
    text-decoration: underline dotted;
}
.symbol-description {
    display: none;
    color: var(--rspamd-symbol-description-color);
}
.symbol-default:hover .symbol-description,
.symbol-default:focus .symbol-description {
    display: unset;
}

.map-link {
    display: block;
    color: #0088cc;
    cursor: pointer;
}
.map-link:hover,
.map-link:focus {
    color: #005580;
    text-decoration: underline;
}

/* Font Awesome icons size */
.svg-inline--fa { /* stylelint-disable-line selector-class-pattern */
    font-size: 16px;
}
/* Increase refresh button spinner speed */
#refresh .fa-spin {
    -webkit-animation: fa-spin 1s linear infinite;
    animation: fa-spin 1s linear infinite;
}

/* Some spacing tweaks */
.notification-area div > button:not(.close) {
    margin-right: 9px;
}

.status-table thead th:first-child,
.status-table td:first-child {
    border-left: none;
}
.status-table thead th:last-child,
.status-table td:last-child {
    border-right: none;
}
/* stylelint-disable no-descending-specificity -- tabulator selectors are grouped before the .status-table rules below */
.status-table thead tr {
    border-top: none;
}
.status-table tr:last-child,
.status-table tr:last-child td {
    border-bottom: none;
}
/* stylelint-enable no-descending-specificity */

.status-table tr:last-child td:last-child {
    border-radius: 0 0 calc(var(--bs-border-radius) + 1px);
}
.status-table :not(:has([rowspan])) tr:last-child td:first-child,
.status-table :nth-last-child(1 of tr:has([rowspan])) td:first-child  {
    border-radius: 0 0 0 calc(var(--bs-border-radius) + 1px);
}

/* Hover effect for table cells in tables with rowspan groups */
.status-table tbody td.table-hover-cell {
    --bs-table-color-state: var(--bs-table-hover-color);
    --bs-table-bg-state: var(--bs-table-hover-bg);
}

/* RRD summary */
#summary-row {
    padding-left: 50px;
    padding-right: 50px;
}
.col-fixed,
.col-fluid {
    position: relative;
    float: left;
}
.col-fixed {
    width: 192px;
    min-height: 1px; /* make an empty div take space */
}
.col-fluid {
    width: calc(100% - 200px);
}
#rrd-table_toggle {
    position: absolute;
    top: 0;
    height: 100%;
    width: 100%;
}
#rrd-table {
    margin-bottom: 2px;
    width: 100% !important;
    text-align: left;
    z-index: 100;

    --bs-table-bg: var(--rspamd-bs-table-bg);
}
#rrd-table .tabulator-row,
#rrd-table .tabulator-row .tabulator-cell {
    color: var(--rrd-row-color, inherit);
}
#rrd-table .tabulator-row:hover,
#symbolsTable .tabulator-row:hover {
    background-color: var(--rspamd-nav-active-bg) !important;
}
#rrd-table .tabulator-row .tabulator-cell {
    padding-top: 2px;
    padding-bottom: 2px;
}
#rrd-total {
    padding-left: 8px;
    margin-bottom: 10px;
    text-align: left;
    font-size: 12px;
}

/* Throughput graph controls */
#graph_controls select {
    margin: 10px 20px 0;
    display: inline-block;
    width: auto;
    border: 1px solid grey;
}

/* history table */
.fuzzy-hash-actions .btn-xs {
    padding: 1px 0.3rem;
    font-size: 0.75rem;
    line-height: 1;
}
.fuzzy-hash-actions .btn-xs svg {
    height: 0.65rem;
    vertical-align: baseline;
}

.search-syntax-icon {
    position: absolute;
    top: 50%;
    transform: translate(-150%, -50%);
    z-index: 3;
    opacity: 0.3;
    cursor: help;
    transition: opacity 0.2s ease-in-out;
}
.search-syntax-icon:hover {
    opacity: 0.6;
}

#history-from,
#history-count,
#history_page_size {
    width: 6em;
    text-align: center;
}

.outline-dashed-primary { outline: 2px dashed var(--bs-primary); }

#scanMsgSource:placeholder-shown,
#selectorsMsgArea:placeholder-shown {
  background-image: url("../img/drop-area.svg");
  background-repeat: no-repeat;
  background-position: center;
  opacity: 0.8;
}

#scanMsgSource:not(:placeholder-shown),
#selectorsMsgArea:not(:placeholder-shown) {
  background-image: none;
}

/* Tabulator's input styling has higher specificity than .scorebar-*, so
   scope these to #symbolsTable to win the cascade. scorebar is used
   exclusively in the symbols table. */
#symbolsTable .scorebar-spam {
    background-color: rgb(240 0 0 / 0.1) !important;
}
#symbolsTable .scorebar-ham {
    background-color: rgb(100 230 80 / 0.1) !important;
}

.danger .icon {
    color: #b94a48;
}
.success .icon {
    color: #468847;
}

#learnServers {
    display: flex;
}

#nprogress .bar {
    height: 1px;
}

@media (min-width: 992px) {
    #selectors > .card {
        height: calc(100vh - 96px);
    }
    #row-main {
        /* necessary to hide collapsed sidebar */
        overflow-x: hidden;
    }
    #content > div {
        display: flex;
    }
}
#content {
    transition: all 0.3s ease;
    transition-property: flex-basis, max-width, width;
}

.sidebar,
#sidebar-tab-left > a,
#sidebar-tab-right > a {
    background-color: var(--rspamd-sidebar-bg);
}
.sidebar {
    padding: 8px;
    transition: margin 0.3s ease;
}
.collapsed {
    /* hide it for small displays */
    display: none;
}
@media (min-width: 992px) {
    .collapsed {
        display: block;
    }
    #sidebar-left.collapsed {
        /* same width as sidebar */
        margin-left: -25%;
    }
    #sidebar-right.collapsed {
        /* same width as sidebar */
        margin-right: -25%;
    }
}

#selectors > .card > .card-body {
    min-height: 0;
}

.sidebar-nav {
    width: 20px;
}
.sidebar-nav .nav-link,
.sidebar-nav .nav-link:hover {
    border: 1px solid var(--bs-card-border-color);
}
#sidebar-tab-left > a,
#sidebar-tab-right > a {
    margin-left: 12px;
    margin-right: 12px;
}
#sidebar-tab-left {
    transform: rotate(180deg);
}
#sidebar-tab-text-left {
    transform: rotate(180deg);
}
@media (min-width: 992px) {
    #sidebar-left {
        border-bottom-left-radius: 3.5px;
    }
    #sidebar-right {
        border-bottom-right-radius: 3.5px;
    }
    .sidebar-nav {
        padding-right: 0;
        display: block;
    }
    #content {
        border-left: 1px solid var(--bs-card-border-color);
        border-right: 1px solid var(--bs-card-border-color);
    }
    #sidebar-tab-left {
        display: flex;
        transform: translateX(-50%) rotate(90deg) translate(50%, -50%);
    }
    #sidebar-tab-right {
        float: right;
        transform: translateX(50%) rotate(-90deg)  translate(-50%, -50%);
    }
}
@media (max-width: 991.98px) {
    #sidebar-right {
        border-bottom-left-radius: 3.5px;
        border-bottom-right-radius: 3.5px;
    }
    #content {
        border-top: 1px solid var(--bs-card-border-color);
        border-bottom: 1px solid var(--bs-card-border-color);
    }
    #sidebar-tab-right {
        bottom: 0;
        right: 0;
    }
}

#navBar .navbar-nav .nav-link {
    padding: 15px;
}

#modalDialog > .modal-dialog {
    /* Center the modal vertically */
    top: 50%;
    transform: translate(0, -50%);
    -webkit-transform: translate(0, -50%);
}

.codejar-wrap,
#editor.map-textarea {
    border-radius: 6px;
    max-height: calc(100vh - 178px);
    max-width: 100%;
    min-width: 100%;
    overflow: auto;
    resize: both;
}
#editor.map-textarea {
    height: calc(100vh - 178px);
    width: calc(100vw - 36px - 3rem);
}
.codejar-wrap,
#editor.map-textarea,
#editor.map-textarea:focus {
    background: rgb(0 47 79);
    color: silver;
}
.codejar-wrap {
    /* Fix line wrapping */
    scrollbar-width: thin;
}
.codejar-linenumbers-inner-wrap {
    bottom: unset;
}
.codejar-linenumbers {
    background: rgb(255 255 255 / 0.07) !important;
}
.codejar-linenumber {
    color: rgb(120 120 120 / 1) !important;
    text-align: right;
}
.editor {
    font-family: monospace;
    font-size: 14px;
    font-weight: 400;
    letter-spacing: normal;
    margin-left: 10px;
    margin-right: 10px;
    resize: unset !important;
    tab-size: 4;
    -moz-tab-size: 4;
    overflow: unset !important;
}

/* Prism show-invisibles plugin overrides */
.token.tab:not(:empty)::before {
    content: "\23af\27F6";
}
/* Temporarily remove CR and LF tokens as they overflow line width */
.token.cr::before,
.token.crlf::before,
.token.lf::before {
    content: "";
}

/* Preloader */
.blinking {
    animation: blinker 1.2s ease-in-out infinite;
}
@keyframes blinker {
    50% {
        -webkit-filter: invert(1);
        filter: invert(1);
    }
}

/* Error log badge: enable hover effect on semi-transparent button */
#error-log-badge .btn:hover {
    background-color: var(--bs-danger) !important;
    color: var(--bs-white) !important;
}
[data-theme="dark"] #error-log-badge .btn:hover {
    border-color: var(--bs-light);
}

/* Dark mode overrides for Bootstrap tables */
[data-theme="dark"] .table {
    --bs-table-color-state: var(--rspamd-text-primary);
}

/* Dark mode overrides for D3Evolution */
[data-theme="dark"] .d3evolution .grid line {
    stroke: #404040;
}
[data-theme="dark"] .d3evolution .cursor .background {
    stroke: #1a1a1a;
}
[data-theme="dark"] .d3evolution .cursor .x.foreground {
    stroke: #4db8ff;
}
[data-theme="dark"] .d3evolution .cursor circle.foreground {
    stroke: white;
}
[data-theme="dark"] .d3evolution .chart-title,
[data-theme="dark"] .d3evolution .axis,
[data-theme="dark"] .d3evolution .legend,
[data-theme="dark"] .d3evolution .y.label,
[data-theme="dark"] .d3evolution .cursor-time {
    fill: var(--rspamd-text-primary);
}

/* Dark mode overrides for D3Pie */
[data-theme="dark"] .d3pie .chart-title,
[data-theme="dark"] .d3pie .outer-label,
[data-theme="dark"] .d3pie .total-text,
[data-theme="dark"] .d3pie .total-value {
    fill: var(--rspamd-text-primary);
}
[data-theme="dark"] .d3pie .slice-g.first-slice .inner-label {
    fill: #666666;
}
[data-theme="dark"] .d3pie-tooltip {
    background-color: rgb(80 80 80 / 80%);
}

/* Dark mode for NProgress */
[data-theme="dark"] #nprogress .bar {
    background: #4db8ff;
}
