Refactor page structure: Update page classes for consistency

- Changed class from "ots-displays-page" to "ots-static-page ots-displays-page" in multiple Twig view files to standardize page layout.
- Enhanced schedule-page.twig with improved calendar navigation and dropdown management.
- Added global dropdown dismissal functionality to improve user experience across modals and dropdowns.
This commit is contained in:
Matt Batchelder
2026-02-11 20:47:09 -05:00
parent 29b56bef4f
commit b766487411
34 changed files with 4506 additions and 141 deletions

View File

@@ -970,6 +970,104 @@ textarea:focus {
outline: none !important;
}
/* --- Bootstrap Tagsinput / Tokenfield inside modals --- */
.modal-body .bootstrap-tagsinput,
.modal-body .tagsinput,
.modal-body .tokenfield {
background-color: var(--modal-input-bg, var(--ots-bg)) !important;
border: 1px solid var(--modal-input-border, var(--ots-border)) !important;
border-radius: var(--ots-radius-sm) !important;
color: var(--modal-input-text, var(--ots-text)) !important;
min-height: 36px;
padding: 4px 8px !important;
box-shadow: none !important;
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 4px;
}
.modal-body .bootstrap-tagsinput:focus-within,
.modal-body .tagsinput:focus-within,
.modal-body .tokenfield:focus-within {
border-color: var(--modal-input-focus-border, var(--ots-primary)) !important;
box-shadow: 0 0 0 3px var(--modal-input-focus-ring, rgba(79, 140, 255, 0.2)) !important;
}
.modal-body .bootstrap-tagsinput input,
.modal-body .tagsinput input,
.modal-body .tokenfield input.token-input {
background: transparent !important;
color: var(--modal-input-text, var(--ots-text)) !important;
border: none !important;
box-shadow: none !important;
outline: none !important;
margin: 0 !important;
padding: 2px 4px !important;
}
.modal-body .bootstrap-tagsinput input::placeholder,
.modal-body .tagsinput input::placeholder,
.modal-body .tokenfield input.token-input::placeholder {
color: var(--ots-text-faint, #7f8aa3) !important;
}
.modal-body .bootstrap-tagsinput .tag,
.modal-body .bootstrap-tagsinput .badge,
.modal-body .tagsinput .tag,
.modal-body .tokenfield .token {
background: rgba(79, 140, 255, 0.18) !important;
border: 1px solid rgba(79, 140, 255, 0.35) !important;
color: var(--ots-primary, #4f8cff) !important;
border-radius: 999px !important;
padding: 2px 8px !important;
font-size: 0.8rem;
line-height: 1.5;
}
.modal-body .bootstrap-tagsinput .tag [data-role="remove"],
.modal-body .bootstrap-tagsinput .badge [data-role="remove"],
.modal-body .tokenfield .token .close {
color: var(--ots-primary, #4f8cff) !important;
opacity: 0.7;
margin-left: 4px;
cursor: pointer;
}
.modal-body .bootstrap-tagsinput .tag [data-role="remove"]:hover,
.modal-body .bootstrap-tagsinput .badge [data-role="remove"]:hover,
.modal-body .tokenfield .token .close:hover {
opacity: 1;
}
/* Global bootstrap-tagsinput theming (outside modals too) */
.bootstrap-tagsinput,
.tagsinput,
.tokenfield {
background-color: var(--modal-input-bg, var(--ots-bg)) !important;
border: 1px solid var(--modal-input-border, var(--ots-border)) !important;
border-radius: var(--ots-radius-sm) !important;
color: var(--modal-input-text, var(--ots-text)) !important;
box-shadow: none !important;
}
.bootstrap-tagsinput input,
.tagsinput input,
.tokenfield input.token-input {
background: transparent !important;
color: var(--modal-input-text, var(--ots-text)) !important;
}
.bootstrap-tagsinput .tag,
.bootstrap-tagsinput .badge,
.tagsinput .tag,
.tokenfield .token {
background: rgba(79, 140, 255, 0.18) !important;
border: 1px solid rgba(79, 140, 255, 0.35) !important;
color: var(--ots-primary, #4f8cff) !important;
border-radius: 999px !important;
}
/* --- Close button --- */
.modal-header .close,
.modal-header [data-dismiss="modal"] {
@@ -1369,3 +1467,66 @@ html[style], body[style] {
background-color: var(--color-background) !important;
}
/* =============================================================================
OTS UPLOAD MODAL Dark-mode refinements
Supplements override-styles.twig which uses CSS variables for auto theming.
These rules guarantee the upload modal stays dark when override-dark.css loads.
============================================================================= */
.ots-upload-content {
background: var(--ots-surface, #141c2b);
border-color: var(--ots-border, #2c3a54);
}
.ots-upload-header {
background: var(--ots-bg, #0b111a);
border-bottom-color: var(--ots-border, #2c3a54);
}
.ots-upload-title {
color: var(--ots-text, #e6eefb);
}
.ots-upload-body {
background: var(--ots-surface, #141c2b);
color: var(--ots-text, #e6eefb);
}
.ots-upload-dropzone {
border-color: var(--ots-border, #2c3a54);
background: rgba(79,140,255,0.03);
}
.ots-upload-dropzone:hover,
.ots-upload-dropzone:focus-visible {
border-color: var(--ots-primary, #4f8cff);
background: rgba(79,140,255,0.07);
}
.ots-upload-dropzone--over {
border-color: var(--ots-primary, #4f8cff) !important;
background: rgba(79,140,255,0.12) !important;
}
.ots-upload-file-item {
background: var(--ots-bg, #0b111a);
border-color: var(--ots-border-soft, #243047);
}
.ots-upload-file-name {
color: var(--ots-text, #e6eefb);
}
.ots-upload-file-meta {
color: var(--ots-text-muted, #a9b6cc);
}
.ots-upload-footer {
background: var(--ots-bg, #0b111a);
border-top-color: var(--ots-border, #2c3a54);
}
.ots-upload-btn-cancel {
color: var(--ots-text-muted, #a9b6cc);
border-color: var(--ots-border, #2c3a54);
}
.ots-upload-btn-cancel:hover {
background: rgba(255,255,255,0.06);
color: var(--ots-text, #e6eefb);
}
.ots-upload-option {
background: rgba(79,140,255,0.04);
border-color: rgba(79,140,255,0.08);
color: var(--ots-text, #e6eefb);
}
.ots-upload-option small {
color: var(--ots-text-muted, #a9b6cc);
}

View File

@@ -186,15 +186,31 @@ body {
pointer-events: auto !important;
}
/* Hide the rowMenu column header completely */
th.rowMenu,
td.rowMenu {
display: none !important;
visibility: hidden !important;
width: 0 !important;
padding: 0 !important;
margin: 0 !important;
border: 0 !important;
/* The rowMenu th is the empty header for the per-row action dropdown.
Keep it in flow so column count matches tbody, but make it minimal.
The matching td (last-child) holds the action button and must stay visible.
NOTE: No background set here — inherits from .ots-table-card .table thead th rules. */
th.rowMenu {
width: 40px !important;
min-width: 40px !important;
max-width: 40px !important;
padding: 4px !important;
text-align: center !important;
box-sizing: border-box !important;
border-left: none !important;
border-right: none !important;
border-top: none !important;
}
/* Style the action-button td to match the header width */
table:has(th.rowMenu) > tbody > tr > td:last-child {
width: 40px !important;
min-width: 40px !important;
max-width: 40px !important;
padding: 4px !important;
text-align: center !important;
box-sizing: border-box !important;
overflow: visible !important;
}
/* Ensure floating menu children aren't clipped (scoped to floated menus only) */
@@ -3784,14 +3800,40 @@ body.ots-sidebar-open .ots-topbar {
overflow: hidden;
}
.dashboard-card {
transition: transform var(--transition-base), box-shadow var(--transition-base), border-color var(--transition-base);
/* Card hover behavior is handled in override-styles.twig (loaded last) */
/* ── .ots-static-page: kill card hover on non-dashboard pages (backup) ────── */
.ots-static-page .dashboard-card,
.ots-static-page .content-card,
.ots-static-page .action-card,
.ots-static-page .action-card--modern,
.ots-static-page .kpi-card,
.ots-static-page .dashboard-chart-card,
.ots-static-page .widget,
.ots-static-page .card,
.ots-static-page .panel,
.ots-static-page .media-item,
.ots-static-page [class*="-card"],
.ots-static-page [class*="card-"] {
transition: none !important;
transform: none !important;
}
.dashboard-card:hover {
transform: translateY(-2px);
box-shadow: 0 22px 50px rgba(8, 15, 30, 0.45);
border-color: rgba(59, 130, 246, 0.45);
.ots-static-page .dashboard-card:hover,
.ots-static-page .content-card:hover,
.ots-static-page .action-card:hover,
.ots-static-page .action-card--modern:hover,
.ots-static-page .kpi-card:hover,
.ots-static-page .dashboard-chart-card:hover,
.ots-static-page .widget:hover,
.ots-static-page .card:hover,
.ots-static-page .panel:hover,
.ots-static-page .media-item:hover,
.ots-static-page [class*="-card"]:hover,
.ots-static-page [class*="card-"]:hover {
transform: none !important;
transition: none !important;
}
.dashboard-card .panel-header,
@@ -3837,6 +3879,15 @@ body.ots-sidebar-open .ots-topbar {
min-width: 0;
flex: 1;
overflow: visible;
background-color: transparent !important;
}
/* Force XiboData card variant to be transparent */
.XiboData.card,
.XiboData.card.py-3,
div.XiboData {
background-color: transparent !important;
background: transparent !important;
}
.kpi-card--modern {
@@ -3874,11 +3925,7 @@ body.ots-sidebar-open .ots-topbar {
box-shadow: 0 14px 30px rgba(8, 15, 30, 0.35);
}
.action-card--modern:hover {
transform: translateY(-4px);
border-color: rgba(59, 130, 246, 0.45);
box-shadow: 0 20px 36px rgba(8, 15, 30, 0.45);
}
/* Hover effect moved to dashboard-page specific rules at end of file */
/* OTS dashboard message (theme-dashboard-message.twig) */
.ots-dashboard-message {
@@ -3938,13 +3985,10 @@ body.ots-sidebar-open .ots-topbar {
border: 1px solid var(--color-border);
border-radius: 8px;
padding: 20px;
transition: all var(--transition-base);
transition: none;
}
.kpi-card:hover {
border-color: var(--color-primary);
box-shadow: 0 0 0 1px var(--color-primary);
}
/* Hover effect moved to dashboard-page specific rules at end of file */
.kpi-header {
display: flex;
@@ -4220,14 +4264,11 @@ body.ots-sidebar-open .ots-topbar {
/* Enhanced chart container styling */
.dashboard-chart-card {
transition: all 300ms cubic-bezier(0.4, 0, 0.2, 1) !important;
transition: none !important;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15) !important;
}
.dashboard-chart-card:hover {
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.25) !important;
transform: translateY(-2px);
}
/* Hover effect moved to dashboard-page specific rules at end of file */
/* Chart action improvements */
.dashboard-chart-actions {
@@ -4464,16 +4505,11 @@ body.ots-sidebar-open .ots-topbar {
border-radius: 8px;
text-decoration: none;
color: var(--color-text-primary);
transition: all var(--transition-base);
transition: none;
cursor: pointer;
}
.action-card:hover {
border-color: var(--color-primary);
background-color: rgba(59, 130, 246, 0.05);
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}
/* Hover effect moved to dashboard-page specific rules at end of file */
.action-icon {
width: 40px;
@@ -4535,15 +4571,13 @@ body.ots-sidebar-open .ots-topbar {
box-shadow: var(--ots-shadow-md, 0 8px 18px rgba(0,0,0,0.12));
margin-bottom: 0;
border-radius: 12px;
overflow: hidden;
overflow: visible !important;
}
/* Strongly remove any remaining gradients / shadows inside filters */
.ots-filter-card *,
.ots-filter-card *::before,
.ots-filter-card *::after {
background-image: none !important;
background: transparent !important;
box-shadow: none !important;
}
@@ -4631,8 +4665,8 @@ body.ots-sidebar-open .ots-topbar {
align-items: center;
justify-content: space-between;
padding: 14px 16px;
border-bottom: none;
background: transparent;
border-bottom: 1px solid var(--color-border);
background: var(--color-surface-elevated);
}
.ots-filter-title {
@@ -4669,6 +4703,7 @@ body.ots-sidebar-open .ots-topbar {
overflow: visible;
transition: max-height 300ms ease-out, padding 300ms ease-out;
display: block;
background: var(--color-surface-elevated) !important;
}
.ots-filter-content.collapsed {
@@ -4679,6 +4714,22 @@ body.ots-sidebar-open .ots-topbar {
display: none;
}
/* Ensure FilterDiv and all nested card-body elements inherit the filter background */
.ots-filter-card .FilterDiv,
.ots-filter-card .card-body,
.ots-filter-card .FilterDiv.card-body {
background: var(--color-surface-elevated) !important;
background-color: var(--color-surface-elevated) !important;
}
/* Ensure form elements have proper container backgrounds */
.ots-filter-card form,
.ots-filter-card .form-inline,
.ots-filter-card .tab-content,
.ots-filter-card .tab-pane {
background: transparent !important;
}
.ots-filter-card .nav-tabs {
border-bottom: 1px solid var(--color-border);
gap: 8px;
@@ -4846,6 +4897,7 @@ body.ots-sidebar-open .ots-topbar {
gap: 32px;
align-items: start;
width: 100%;
min-width: 0;
transition: grid-template-columns 200ms ease-out;
}
@@ -4912,6 +4964,7 @@ body.ots-sidebar-open .ots-topbar {
/* DataTables controls */
.dataTables_wrapper {
color: var(--color-text-primary) !important;
background: transparent !important;
}
.dataTables_wrapper .dataTables_length,
@@ -4919,6 +4972,17 @@ body.ots-sidebar-open .ots-topbar {
.dataTables_wrapper .dataTables_info,
.dataTables_wrapper .dataTables_paginate {
color: var(--color-text-secondary) !important;
background: transparent !important;
}
/* Ensure all DataTables control wrappers and button areas have transparent backgrounds */
.dataTables_wrapper > *,
.dataTables_wrapper .dataTables_buttons,
.dataTables_buttons,
.dt-buttons,
.buttons-collection {
background: transparent !important;
background-color: transparent !important;
}
.dataTables_wrapper .dataTables_filter input,
@@ -4935,11 +4999,36 @@ body.ots-sidebar-open .ots-topbar {
flex: 1;
min-width: 0;
overflow: hidden;
background: transparent !important;
}
/* Ensure XiboData cards are transparent */
.XiboData.card,
.XiboData.card.py-3,
div.XiboData.card {
background: transparent !important;
background-color: transparent !important;
border: none !important;
box-shadow: none !important;
}
#datatable-container {
width: 100%;
min-width: 0;
overflow-x: auto;
overflow-y: visible;
background: transparent !important;
}
/* Ensure all child elements of datatable-container have transparent backgrounds */
#datatable-container > *,
#datatable-container .XiboData,
#datatable-container .XiboData > *,
#datatable-container .card,
#datatable-container .dataTables_wrapper,
#datatable-container .dataTables_wrapper > * {
background: transparent !important;
background-color: transparent !important;
}
.ots-table-card .table thead th {
@@ -5077,6 +5166,77 @@ body.ots-light-mode .ots-table-toolbar .btn-primary {
color: #ffffff !important;
}
/* Map and list view toggle buttons */
#map_button,
#list_button {
background-color: var(--color-primary) !important;
border-color: var(--color-primary) !important;
color: #ffffff !important;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2) !important;
transition: all 0.15s ease !important;
}
#map_button:hover,
#list_button:hover {
background-color: var(--color-primary-light) !important;
border-color: var(--color-primary-light) !important;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3) !important;
transform: translateY(-1px);
}
#map_button:active,
#list_button:active {
transform: translateY(0);
}
/* Active state for map/list toggle buttons */
#map_button.active,
#list_button.active {
background-color: #0c7a2a !important;
border-color: #0c7a2a !important;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4) inset !important;
}
/* Dark mode toolbar button styles - ensure consistent colors across all pages */
.ots-table-toolbar .btn-success {
background-color: #10b981 !important;
border-color: #10b981 !important;
color: #ffffff !important;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2) !important;
}
.ots-table-toolbar .btn-success:hover {
background-color: #059669 !important;
border-color: #059669 !important;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3) !important;
}
.ots-table-toolbar .btn-primary {
background-color: #3b82f6 !important;
border-color: #3b82f6 !important;
color: #ffffff !important;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2) !important;
}
.ots-table-toolbar .btn-primary:hover {
background-color: #2563eb !important;
border-color: #2563eb !important;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3) !important;
}
.ots-table-toolbar .btn-warning {
background-color: #f59e0b !important;
border-color: #f59e0b !important;
color: #ffffff !important;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2) !important;
}
.ots-table-toolbar .btn-warning:hover {
background-color: #d97706 !important;
border-color: #d97706 !important;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3) !important;
}
.ots-table-card .dataTables_wrapper,
.ots-table-card .dataTables_wrapper * {
color: #e2e8f0 !important;
@@ -5134,6 +5294,7 @@ body.ots-light-mode .ots-table-toolbar .btn-primary {
.ots-map-card {
margin-top: 16px;
height: 600px;
min-height: 360px;
background: rgba(15, 23, 42, 0.6);
border: 1px solid rgba(148, 163, 184, 0.2);
@@ -5254,6 +5415,7 @@ body.ots-light-mode .ots-displays-page #datatable-container .XiboData table.data
width: 18px;
height: 18px;
flex-shrink: 0;
color: yellow;
}
.folder-name {
@@ -5970,9 +6132,16 @@ textarea {
.panel,
.panel-body,
.table-wrapper,
.dataTables_wrapper,
.dataTables_wrapper *,
.dataTables_wrapper .dataTables_scroll,
.dataTables_wrapper .dataTables_scroll *,
.dataTables_wrapper .dataTables_scrollBody,
.dataTables_wrapper .dataTables_scrollHead,
.dataTables_wrapper .dataTables_scrollHead table {
.dataTables_wrapper .dataTables_scrollHeadInner,
.dataTables_wrapper .dataTables_scrollHeadInner *,
.dataTables_wrapper .dataTables_scrollHead table,
.dataTables_wrapper .dataTables_scrollHead table * {
opacity: 1 !important;
background: transparent !important;
}
@@ -6142,13 +6311,29 @@ legend {
/* Dropdowns, modals, and popovers */
.dropdown-menu,
.dropdown-toggle,
.popover {
background-color: var(--color-surface) !important;
color: var(--color-text-primary) !important;
border: 1px solid var(--color-border) !important;
}
/* Dropdown toggles: only style those NOT inside tables or topbar.
Table action buttons should inherit their row background.
Topbar nav links have their own styling. */
.dropdown-toggle:not(table .dropdown-toggle):not(.ots-table-card .dropdown-toggle):not(.ots-topbar .dropdown-toggle):not(.navbar-nav .dropdown-toggle) {
background-color: var(--color-surface) !important;
color: var(--color-text-primary) !important;
border: 1px solid var(--color-border) !important;
}
/* DataTable row action buttons — no background box */
.ots-table-card .dropdown-toggle,
table .btn-group .dropdown-toggle,
.dataTables_wrapper .dropdown-toggle {
background-color: transparent !important;
border: none !important;
}
.modal,
.modal-body,
.modal-footer {
@@ -6622,6 +6807,20 @@ a.text-muted {
color: var(--color-text-secondary) !important;
}
/* Folder tree icons - tan color like Windows Explorer */
#container-folder-tree .fa,
#grid-folder-filter .fa,
.grid-folder-tree-container .fa {
color: #D4AF85 !important;
font-size: 1.5em !important;
}
/* Folder action button icon - match folder tree tan color */
#folder-tree-select-folder-button .fa,
#folder-tree-select-folder-button .fas {
color: #D4AF85 !important;
}
/* Tidy (library) button - broom icon and amber colouring */
.btn-tidy {
background-color: var(--color-warning) !important;
@@ -6788,52 +6987,7 @@ body.ots-light-mode .ots-displays-page #datatable-container .XiboData table.data
/* ============================================================================
Remove hover animations inside the page wrapper
This prevents elements inside `#page-wrapper` from animating on hover
while keeping other site transitions intact.
============================================================================ */
#page-wrapper *:hover {
transition: none !important;
transform: none !important;
animation: none !important;
box-shadow: none !important;
}
#page-wrapper,
#page-wrapper * {
will-change: auto !important;
}
/* Re-enable hover/transform/animation behavior inside dashboard areas only */
#page-wrapper .dashboard-page *:hover,
#page-wrapper .dashboard-card *:hover,
#page-wrapper .dashboard-panels *:hover,
#page-wrapper .dashboard-chart-card *:hover {
transition: initial !important;
transform: initial !important;
animation: initial !important;
box-shadow: initial !important;
}
#page-wrapper .dashboard-page,
#page-wrapper .dashboard-card,
#page-wrapper .dashboard-panels,
#page-wrapper .dashboard-chart-card {
will-change: auto !important;
}
/* Content cards are static no hover animation */
.content-card {
transition: none !important;
}
.content-card:hover {
transform: none !important;
box-shadow: 0 18px 40px rgba(8, 15, 30, 0.35) !important;
border-color: rgba(148, 163, 184, 0.18) !important;
}
/* Card hover behavior is handled in override-styles.twig (loaded last) */
/* Ensure the very bottom of the page follows the theme variables (light/dark)
by forcing html/body and shell containers to use the variable-driven
@@ -7478,6 +7632,76 @@ body.ots-light-mode .modal-header .btn-close:hover {
box-shadow: 0 0 0 3px var(--modal-input-focus-ring) !important;
}
/* ---------- Bootstrap Tagsinput / Tokenfield inside modals ----------------- */
.modal-body .bootstrap-tagsinput,
.modal-body .tagsinput,
.modal-body .tokenfield {
background-color: var(--modal-input-bg) !important;
border: 1px solid var(--modal-input-border) !important;
border-radius: var(--ots-radius-sm) !important;
color: var(--modal-input-text) !important;
min-height: 36px;
padding: 4px 8px !important;
box-shadow: none !important;
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 4px;
}
.modal-body .bootstrap-tagsinput:focus-within,
.modal-body .tagsinput:focus-within,
.modal-body .tokenfield:focus-within {
border-color: var(--modal-input-focus-border) !important;
box-shadow: 0 0 0 3px var(--modal-input-focus-ring) !important;
}
.modal-body .bootstrap-tagsinput input,
.modal-body .tagsinput input,
.modal-body .tokenfield input.token-input {
background: transparent !important;
color: var(--modal-input-text) !important;
border: none !important;
box-shadow: none !important;
outline: none !important;
margin: 0 !important;
padding: 2px 4px !important;
}
.modal-body .bootstrap-tagsinput input::placeholder,
.modal-body .tagsinput input::placeholder,
.modal-body .tokenfield input.token-input::placeholder {
color: var(--ots-text-faint, #64748b) !important;
}
.modal-body .bootstrap-tagsinput .tag,
.modal-body .bootstrap-tagsinput .badge,
.modal-body .tagsinput .tag,
.modal-body .tokenfield .token {
background: rgba(79, 140, 255, 0.15) !important;
border: 1px solid rgba(79, 140, 255, 0.3) !important;
color: var(--ots-primary, #3b82f6) !important;
border-radius: 999px !important;
padding: 2px 8px !important;
font-size: 0.8rem;
line-height: 1.5;
}
.modal-body .bootstrap-tagsinput .tag [data-role="remove"],
.modal-body .bootstrap-tagsinput .badge [data-role="remove"],
.modal-body .tokenfield .token .close {
color: var(--ots-primary, #3b82f6) !important;
opacity: 0.7;
margin-left: 4px;
cursor: pointer;
}
.modal-body .bootstrap-tagsinput .tag [data-role="remove"]:hover,
.modal-body .bootstrap-tagsinput .badge [data-role="remove"]:hover,
.modal-body .tokenfield .token .close:hover {
opacity: 1;
}
/* ---------- Tabs inside modals --------------------------------------------- */
.modal-body .nav-tabs {
border-bottom: 1px solid var(--modal-border) !important;