/*
 * Element-level polish (formerly polish.css): Bootstrap cards, buttons, inputs, Select2, badges,
 * dropdowns, modals, DataTables chrome, pagination. Tokens live in tokens.css.
 *
 * Radius/border rules on .btn, .form-control and .form-select deliberately stay at
 * single-class specificity so Bootstrap's input-group / btn-group joins keep winning.
 */

/* ---------- Cards ---------- */
.content .card {
    border: 0;
    border-radius: var(--ui-radius);
    box-shadow: var(--ui-shadow);
}

.content .card > .card-header {
    background: transparent;
    border-bottom: 1px solid var(--ui-border);
    border-top-left-radius: var(--ui-radius);
    border-top-right-radius: var(--ui-radius);
}

.content .card > .card-footer {
    background: transparent;
    border-top: 1px solid var(--ui-border);
}

.content .card .card-title,
.content .card-container .card-title {
    font-size: .9rem;
    font-weight: 700;
    color: var(--ui-text);
}

/* ---------- Buttons ---------- */
.btn {
    border-radius: var(--ui-radius-md);
    font-weight: 600;
    transition: background-color var(--ui-ease), border-color var(--ui-ease), color var(--ui-ease), box-shadow var(--ui-ease);
}

.btn-sm {
    border-radius: var(--ui-radius-sm);
}

/* One button scale, so a button next to a field lines up with it and pages don't mix 26/31/38px buttons:
   default = the control height (40), small 32, large 48. Table-row buttons, button groups, input-group addons,
   DataTables toolbars and pagers keep their own sizes. <a class="btn"> centres its label like a <button>. */
@media (hover: hover), (pointer: fine) {
:is(.content, .modal, .offcanvas) .btn:not(.btn-sm):not(.btn-lg):not(.btn-link):not(.btn-close):not(.dropdown-item):not(.page-link):not(td .btn):not(.btn-group > .btn):not(.input-group > .btn):not(.dt-buttons .btn):not(.dt-button) {
        min-height: var(--ui-control-h);
    }
    :is(.content, .modal, .offcanvas) .btn-sm:not(td .btn):not(.btn-group > .btn):not(.input-group > .btn):not(.dt-buttons .btn):not(.dt-button) {
        min-height: 32px;
    }
    :is(.content, .modal, .offcanvas) .btn-lg:not(td .btn) {
        min-height: 48px;
    }
}
:is(.content, .modal, .offcanvas) a.btn:not(td .btn) {
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
:is(.content, .modal, .offcanvas) a.btn.text-start:not(td .btn) {
    justify-content: flex-start;
}

/* The grey "secondary" button used across the platform becomes a quiet outline button.
   style.css sets .btn-light with !important, so these have to match it. */
.btn-light {
    background-color: var(--ui-surface) !important;
    border: 1px solid var(--ui-border-strong) !important;
    color: var(--ui-text) !important;
}

/* Quiet destructive action (Deactivate, Disconnect, Remove): neutral button, red label */
.btn-light.text-danger {
    color: var(--ui-danger) !important;
}

.btn-light:hover,
.btn-light:focus,
.btn-light.show,
.btn-light:not(:disabled):not(.disabled):active {
    background-color: var(--ui-subtle) !important;
    border-color: var(--ui-faint) !important;
    color: var(--ui-text) !important;
}

.btn-light i,
.btn-light .button-icon {
    color: var(--ui-muted);
}

/* Page header actions: normal-size buttons, the primary one keeps the accent */
.main-buttons .btn,
.main-buttons .btn-lg {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    min-height: var(--ui-control-h);
    padding: 0 14px;
    border-radius: var(--ui-radius);
    font-size: .85rem;
}

.main-buttons .btn-group > .btn:not(:last-child):not(.dropdown-toggle) {
    border-top-right-radius: 0;
    border-bottom-right-radius: 0;
}

.main-buttons .btn-group > .btn:not(:first-child) {
    border-top-left-radius: 0;
    border-bottom-left-radius: 0;
}

/* page header buttons look like every other button: the border is the edge, no card shadow on top of it */
:is(.main-buttons, .page-header-toolbar) .btn:not(.btn-link):not(.btn-close):not(:disabled):not(.disabled) {
    box-shadow: none;
}
/* a button inside a group (a dropdown is a group of one) leaves the shadow to the group, or it shows twice */
:is(.main-buttons, .page-header-toolbar) :is(.btn-group, .batch-sync-toolbar) > .btn:not(.btn-link):not(.btn-close),
:is(.main-buttons, .page-header-toolbar) .btn-group .btn-group {
    box-shadow: none !important;
}
:is(.main-buttons, .page-header-toolbar) .btn-group {
    box-shadow: none;
    border-radius: var(--ui-radius-md);
}

/* ---------- Inputs ---------- */
.form-control,
.form-select {
    border-color: var(--ui-field-border);
    border-radius: var(--ui-radius-md);
    font-size: .85rem;
}

/* Room for the arrow: legacy style.css gives every select 12.5px right padding, so long values ran
   underneath the chevron */
.form-select:not([multiple]):not([size]) {
    padding-right: 2.25rem;
    text-overflow: ellipsis;
}

/* Standard control height. Textareas, explicit -sm/-lg sizes, multi-row selects and floating-label
   fields keep their own sizing. */
.form-control:not(textarea):not(.form-control-sm):not(.form-control-lg):not([type=file]):not([type=color]):not(.form-floating > .form-control),
.form-select:not(.form-select-sm):not(.form-select-lg):not([multiple]):not([size]):not(.form-floating > .form-select) {
    height: var(--ui-control-h);
    min-height: var(--ui-control-h);
    padding-top: 0;
    padding-bottom: 0;
}

.input-group > .input-group-text,
.input-group > .btn {
    min-height: var(--ui-control-h);
}

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

.select2-container--default .select2-selection--single .select2-selection__rendered {
    line-height: calc(var(--ui-control-h) - 2px);
    padding-left: 12px;
}

.select2-container--default .select2-selection--single .select2-selection__arrow {
    height: calc(var(--ui-control-h) - 2px);
    width: 2.25rem;
    right: 0;
}

/* Same chevron as a native .form-select (Select2 shipped a small black triangle, so two selects side by side
   looked different); a mask so it takes the text colour in dark mode, flipped while the list is open */
.select2-container--default .select2-selection--single .select2-selection__arrow b {
    display: none;
}
.select2-container--default .select2-selection--single .select2-selection__arrow::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    width: 16px;
    height: 12px;
    transform: translate(-50%, -50%);
    background-color: var(--ui-text);
    -webkit-mask: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23000' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e") center / 16px 12px no-repeat;
    mask: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23000' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e") center / 16px 12px no-repeat;
    pointer-events: none;
}
.select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow::after {
    transform: translate(-50%, -50%) rotate(180deg);
}
.select2-container--default.select2-container--disabled .select2-selection--single .select2-selection__arrow::after {
    opacity: .45;
}

.select2-container--default .select2-selection--multiple {
    min-height: var(--ui-control-h);
    display: flex;
    align-items: center;
    padding: 3px 8px;
}

.select2-container--default .select2-selection--multiple .select2-selection__rendered {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 4px;
    margin: 0;
    padding: 0;
}

.select2-container--default .select2-selection--multiple .select2-selection__choice {
    margin: 0;
}

/* Chips in multi-selects: soft pills with the remove × after the name (select2 drew a boxed × with a dotted
   divider in front of it) */
.select2-container--default .select2-selection--multiple .select2-selection__choice {
    display: inline-flex;
    align-items: center;
    gap: 2px;
    max-width: 100%;
    padding: 2px 4px 2px 10px !important;
    border: 0 !important;
    border-radius: var(--ui-radius-pill);
    background: var(--ui-subtle) !important;
    color: var(--ui-text);
    font-size: var(--ui-fs-sm);
    font-weight: 500;
    line-height: 1.5;
}
.select2-container--default .select2-selection--multiple .select2-selection__choice__display {
    padding: 0 !important;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.select2-container--default .select2-selection--multiple .select2-selection__choice__remove {
    position: static !important;
    order: 2;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 18px;
    height: 18px;
    padding: 0 !important;
    border: 0 !important;
    border-radius: 50%;
    background: transparent !important;
    color: transparent !important; /* the "×" glyph sits high in most fonts: drawn as a centred icon instead */
    font-size: 0;
    line-height: 0;
}
.select2-container--default .select2-selection--multiple .select2-selection__choice__remove::before {
    content: "";
    width: 8px;
    height: 8px;
    background: var(--ui-muted);
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 10'%3E%3Cpath d='M1 1l8 8M9 1l-8 8' stroke='black' stroke-width='1.6' stroke-linecap='round'/%3E%3C/svg%3E") center / contain no-repeat;
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 10'%3E%3Cpath d='M1 1l8 8M9 1l-8 8' stroke='black' stroke-width='1.6' stroke-linecap='round'/%3E%3C/svg%3E") center / contain no-repeat;
}
.select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover::before {
    background: var(--ui-text);
}
.select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover {
    background: rgba(var(--ui-ink-rgb, 15, 23, 42), .08) !important;
}

/* filter rows: fields that wrap onto a second line keep a gap between them (columns use mt-md-0) */
.row.page-filter-row {
    row-gap: var(--ui-space-3);
}

/* Select2 4.1 renders this as a <textarea>: text sits at the top unless line-height matches */
.select2-container .select2-search--inline .select2-search__field {
    height: 28px;
    margin: 0;
    padding: 0 0 0 4px;
    line-height: 28px;
    overflow: hidden;
    resize: none;
    vertical-align: middle;
}

.form-control:focus,
.form-select:focus {
    border-color: var(--ui-primary);
    box-shadow: var(--ui-focus-ring);
}

.select2-container--default .select2-selection--single,
.select2-container--default .select2-selection--multiple {
    border-color: var(--ui-field-border);
    border-radius: var(--ui-radius-md);
}

.select2-container--default.select2-container--focus .select2-selection--multiple,
.select2-container--default.select2-container--open .select2-selection--single {
    border-color: var(--ui-primary);
}

/* Select2's inline search field (multi-selects) doesn't inherit the page font and falls back to
   the browser's sans-serif; match it to the other controls, placeholder included */
.select2-container .select2-search--inline .select2-search__field {
    font-family: inherit;
    font-size: inherit;
    font-weight: 600;
    color: var(--ui-text);
}

.select2-container .select2-search--inline .select2-search__field::placeholder,
.select2-container--default .select2-selection--single .select2-selection__placeholder {
    font-family: inherit;
    font-weight: 400;
    color: var(--ui-muted);
    opacity: 1;
}

/* style.css has two older filter "standards" (.filter-section ≈38px with padded Select2 internals,
   .page-filter-row 2.75rem); fold both into --ui-control-h */
.page-filter-row {
    --page-filter-control-height: var(--ui-control-h);
}

.filter-section .select2-container .select2-selection,
.page-filter-row .select2-container .select2-selection {
    min-height: var(--ui-control-h);
}

.filter-section .select2-container .select2-selection__rendered,
.filter-section .select2-container--default .select2-selection--single .select2-selection__rendered {
    min-height: 0;
    padding: 0 12px;
}

.filter-section .select2-container--default .select2-selection--multiple .select2-selection__rendered {
    min-height: 0;
    padding: 0;
}

.filter-section .select2-container--default .select2-selection--multiple .select2-selection__choice,
.filter-section .select2-container .select2-search--inline {
    margin: 0;
}

.filter-section .select2-container .select2-search--inline .select2-search__field,
.page-filter-row .select2-container .select2-search--inline .select2-search__field {
    height: 28px;
    margin: 0;
    line-height: 28px;
}

.select2-dropdown {
    border-color: var(--ui-border);
    border-radius: var(--ui-radius-md);
    box-shadow: var(--ui-shadow-pop);
    overflow: hidden;
}

/* Filter panels (label with icon above a control) */
.filter-label {
    font-size: .75rem;
    font-weight: 600;
    color: var(--ui-muted);
}

.filter-label i {
    font-size: .7rem;
    color: var(--ui-faint);
}

/* ---------- Badges ---------- */
.badge {
    border-radius: 999px;
    font-weight: 600;
}

/* ---------- Dropdowns ---------- */
.content .dropdown-menu,
.modal .dropdown-menu,
.dt-button-collection.dropdown-menu {
    border: 0;
    border-radius: var(--ui-radius);
    box-shadow: var(--ui-shadow-pop);
    padding: 6px;
}

.content .dropdown-menu .dropdown-item,
.modal .dropdown-menu .dropdown-item,
.dt-button-collection .dropdown-item {
    border-radius: var(--ui-radius-sm);
    font-size: .85rem;
    padding: 7px 10px;
}

/* light/dark.css open menus with a transform keyframe (fill-mode forwards), which replaces Popper's
   positioning transform: the menu then lands on top of its own toggle. Slide with the separate
   translate property instead, which stacks with Popper's transform. */
@keyframes uiDropdownIn {
    from {
        opacity: 0;
        translate: 0 -8px;
    }

    to {
        opacity: 1;
        translate: 0 0;
    }
}

.dropdown .dropdown-menu.show {
    animation-name: uiDropdownIn;
}

.content .dropdown-menu .dropdown-item > i:first-child {
    color: var(--ui-faint);
}

.content .dropdown-menu .dropdown-item:hover > i:first-child {
    color: inherit;
}

/* Modals, tooltips and toasts: see overlays.css */

/* ---------- DataTables ---------- */
/* Table toolbar (page size, buttons, search): one quiet row. Every control is 36px with a soft
   border and medium-weight 13px text, icons and carets are muted, and one 8px gap separates them. */
.dataTables_wrapper {
    --ui-tb-h: 36px;
    --ui-tb-fs: 0.8125rem;
}

div.dataTables_wrapper div.dataTables_filter input,
div.dataTables_wrapper div.dataTables_length select {
    height: var(--ui-tb-h);
    min-height: var(--ui-tb-h);
    border: 1px solid var(--ui-border);
    border-radius: var(--ui-radius-md);
    background-color: var(--ui-surface);
    font-size: var(--ui-tb-fs);
    color: var(--ui-text);
    box-shadow: none;
}

div.dataTables_wrapper div.dataTables_length select {
    width: auto;
    min-width: 0;
    padding: 0 28px 0 10px;
    font-weight: 500;
    /* the same muted chevron as the button carets (the default arrow is near-black) */
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%238b95a5' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m4 6 4 4 4-4'/%3E%3C/svg%3E") !important;
    background-repeat: no-repeat;
    background-position: right 9px center;
    background-size: 12px 12px;
}

/* "display items" is a hint, not a control */
div.dataTables_wrapper div.dataTables_length label {
    font-size: var(--ui-tb-fs);
    font-weight: 400;
    color: var(--ui-muted);
}

/* Search: a magnifier in the field instead of a bare box (mid grey reads in light and dark) */
div.dataTables_wrapper div.dataTables_filter input {
    width: 240px;
    max-width: 100%;
    padding: 0 12px 0 34px;
    font-weight: 400;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%238b95a5' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='m20 20-3.5-3.5'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: 12px center;
    background-size: 15px 15px;
}

div.dataTables_wrapper div.dataTables_filter input::placeholder {
    color: var(--ui-faint);
}

div.dataTables_wrapper div.dataTables_length select:hover,
div.dataTables_wrapper div.dataTables_filter input:hover {
    border-color: var(--ui-border-strong);
}

/* Toolbar alignment: the length select and search input sit on the label's text baseline (2px low)
   while the buttons carry an mb-1 margin (pushing them up); centre everything on one line instead */
div.dataTables_wrapper div.dataTables_length label,
div.dataTables_wrapper div.dataTables_filter label {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin: 0;
}

div.dataTables_wrapper div.dataTables_length select,
div.dataTables_wrapper div.dataTables_filter input {
    margin-top: 0;
    margin-bottom: 0;
    vertical-align: middle;
}

/* style.css nudged these by hand (top: 2.5px on the search input, 2.5px padding on the length
   wrapper) to match the old button heights; with one control height they only misalign */
div.dataTables_wrapper div.dataTables_filter input {
    margin-left: 0;
    top: 0;
    right: 0;
}

.dataTables_wrapper .dataTables_length {
    padding-top: 0;
    padding-bottom: 0;
}

/* Some pages lay the toolbar out inline instead of floated; text-based alignment then drops the
   button group below the select (up to 8px). Every control is --ui-tb-h tall, so top alignment
   puts them on one line. */
.dataTables_wrapper .dt-buttons,
.dataTables_wrapper .dataTables_length,
.dataTables_wrapper .dataTables_filter {
    vertical-align: top;
}

/* When the row wraps (narrow screens, a filter sidebar), the next line keeps an 8px gap */
.dataTables_wrapper :is(.dt-buttons, .dataTables_length, .dataTables_filter) {
    margin-bottom: 8px;
}

.dt-buttons {
    align-items: center;
    gap: 8px;
}

/* Buttons came with mx-1/mb-1 margins (and some in a div.mx-1 wrapper); the 8px gap spaces them */
.dt-buttons > *,
.dt-buttons > .btn-group > .btn,
.dt-buttons .btn.mb-1,
.dt-buttons .btn-group > .btn.mb-1 {
    margin: 0 !important;
}

div.dataTables_wrapper div.dataTables_filter input:focus,
div.dataTables_wrapper div.dataTables_length select:focus {
    border-color: var(--ui-primary);
    box-shadow: var(--ui-focus-ring);
}

.dt-buttons .btn,
.dt-buttons .dt-button.btn {
    background-color: var(--ui-surface) !important;
    border: 1px solid var(--ui-border) !important;
    color: var(--ui-body) !important;
    border-radius: var(--ui-radius-md) !important;
    box-shadow: none !important;
    height: var(--ui-tb-h, 36px);
    min-height: var(--ui-tb-h, 36px);
    padding: 0 12px !important;
    font-size: var(--ui-tb-fs, 0.8125rem) !important;
    font-weight: 500 !important;
    line-height: 1;
    white-space: nowrap;
    display: inline-flex;
    align-items: center;
    gap: 7px;
    transition: background-color var(--ui-ease), border-color var(--ui-ease), color var(--ui-ease);
}

/* DataTables wraps the label in a span: keep icon + text on one centred line */
.dt-buttons .btn > span:not(.dt-down-arrow) {
    display: inline-flex;
    align-items: center;
    gap: 7px;
}

.dt-buttons .btn:hover,
.dt-buttons .dt-button.btn:hover,
.dt-buttons .btn[aria-expanded="true"] {
    background-color: var(--ui-subtle) !important;
    border-color: var(--ui-border-strong) !important;
    color: var(--ui-text) !important;
}

.dt-buttons .btn:focus-visible {
    box-shadow: var(--ui-focus-ring) !important;
}

/* toolbar button icons only: a dropdown menu nested in a toolbar button (bulk Actions) keeps its own icon spacing */
.dt-buttons .btn i:not(.dropdown-menu i),
.dt-buttons .btn .button-icon:not(.dropdown-menu .button-icon) {
    margin: 0 !important;
    padding: 0 !important;
    width: auto !important;
    font-size: 15px;
    line-height: 1;
    color: var(--ui-faint);
}

/* Carets: small and muted, so the labels carry the row */
.dt-buttons .dropdown-toggle::after,
.dt-buttons .dt-down-arrow {
    margin-left: 0 !important;
    color: var(--ui-faint);
    opacity: .8;
}

.dt-buttons .dt-down-arrow {
    padding: 0 !important;
    font-size: 9px;
}

/* Only the inner menu scrolls; the collection wrapper around it (legacy: always-on scrollbar at 40vh)
   must not scroll as well, or two scrollbars appear */
div.dt-button-collection {
    max-height: none;
    overflow: visible;
}

/* Column visibility menu ("Columns"): a checklist instead of solid blue active rows */
.dt-button-collection .dropdown-menu {
    min-width: 220px;
    max-height: 60vh;
    overflow-y: auto;
    padding: 6px;
    border: 0;
    border-radius: var(--ui-radius);
    box-shadow: var(--ui-shadow-pop);
}

.dt-button-collection .dropdown-item.buttons-columnVisibility {
    display: flex;
    align-items: center;
    gap: 10px;
    margin: 0 !important;
    padding: 7px 10px;
    border: 0 !important;
    border-radius: var(--ui-radius-sm) !important;
    background: transparent !important;
    box-shadow: none !important;
    color: var(--ui-muted) !important;
    font-size: .85rem;
    font-weight: 500;
}

.dt-button-collection .dropdown-item.buttons-columnVisibility::before {
    content: '';
    flex-shrink: 0;
    width: 16px;
    height: 16px;
    border: 1.5px solid var(--ui-border-strong);
    border-radius: 5px;
    background: var(--ui-surface) center / 10px 10px no-repeat;
    transition: background-color 120ms ease, border-color 120ms ease;
}

.dt-button-collection .dropdown-item.buttons-columnVisibility:hover {
    background: var(--ui-subtle) !important;
    color: var(--ui-text) !important;
}

.dt-button-collection .dropdown-item.buttons-columnVisibility.active {
    color: var(--ui-text) !important;
}

.dt-button-collection .dropdown-item.buttons-columnVisibility.active::before {
    background-color: var(--ui-primary);
    border-color: var(--ui-primary);
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='none' stroke='%23fff' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round' d='M3.5 8.5l3 3 6-7'/%3E%3C/svg%3E");
}

/* Other collection menus (Export, bulk actions …): icon tile + label rows */
.dt-button-collection .dropdown-menu {
    overflow-x: hidden;
}

.dt-button-collection .dropdown-menu:not(:has(.buttons-columnVisibility)) {
    min-width: 180px;
}

.dt-button-collection .dropdown-item:not(.buttons-columnVisibility) {
    display: flex;
    align-items: center;
    width: 100%;
    margin: 0 !important;
    padding: 6px 10px;
    border: 0 !important;
    border-radius: var(--ui-radius-sm) !important;
    background: transparent !important;
    box-shadow: none !important;
    color: var(--ui-text) !important;
    font-size: .85rem;
    font-weight: 600;
}

.dt-button-collection .dropdown-item:not(.buttons-columnVisibility) > span {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    min-width: 0;
}

/* Inline style="width: 20px" on these icons made the menu overflow sideways */
.dt-button-collection .dropdown-item:not(.buttons-columnVisibility) i {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 28px !important;
    height: 28px;
    margin: 0 !important;
    border-radius: var(--ui-radius-sm);
    background: var(--ui-subtle);
    color: var(--ui-muted);
    font-size: .8rem;
    transition: background-color 120ms ease, color 120ms ease;
}

.dt-button-collection .dropdown-item:not(.buttons-columnVisibility):hover {
    background: var(--ui-subtle) !important;
}

.dt-button-collection .dropdown-item:not(.buttons-columnVisibility):hover i {
    background: var(--ui-primary-tint);
    color: var(--ui-primary);
}

.dt-button-collection .dropdown-item.disabled {
    opacity: .5;
}

/* Columns whose header is markup only (e.g. a select-all checkbox) have no label to show */
.dt-button-collection .dropdown-item.buttons-columnVisibility:has(> span:empty) {
    display: none;
}

/* Every data table reads the same: sentence-case headers, no tracking. Many pages set uppercase on
   #id-scoped selectors, so this one rule wins with !important instead of editing each page. */
table.dataTable thead th,
.dataTables_scrollHead thead th,
.ui-table thead th {
    text-transform: none !important;
    letter-spacing: 0 !important;
}

/* Header cells: the quiet sentence-case style of the PIM tables (.ui-table), on data tables and plain
   Bootstrap tables alike */
.content table.dataTable thead th,
.content .dataTables_scrollHead thead th,
.content .table thead th,
.modal table.dataTable thead th,
.modal .dataTables_scrollHead thead th,
.modal .table thead th {
    font-size: var(--ui-fs-xs);
    font-weight: 600;
    letter-spacing: 0;
    text-transform: none;
    color: var(--ui-muted);
    white-space: nowrap;
    border-bottom-color: var(--ui-border) !important;
}

.content table.dataTable tbody td,
.modal table.dataTable tbody td {
    border-color: var(--ui-border);
    font-size: var(--ui-fs-sm);
    color: var(--ui-body);
}

.content table.dataTable tbody tr {
    transition: background-color 150ms ease;
}

.dataTables_wrapper.is-empty .dataTables_info,
.dataTables_wrapper.is-empty .dataTables_paginate {
    display: none !important;
}

.dataTables_info {
    font-size: .75rem;
    color: var(--ui-muted);
}

/* ---------- Pagination ---------- */
.pagination .page-link {
    border-radius: var(--ui-radius-sm) !important;
}

/* ---------- Nav pills ---------- */
.nav-pills .nav-link {
    border-radius: var(--ui-radius-md);
}

/* One placeholder grey everywhere, clearly lighter than a typed value */
.form-control::placeholder,
.form-select::placeholder {
    color: var(--ui-placeholder);
    opacity: 1;
}

/* bootstrap-tagsinput (IP whitelists, shipping-rule tags) ships a white box; match the other controls */
.bootstrap-tagsinput {
    min-height: var(--ui-control-h);
    background-color: rgb(var(--bs-input-bg-rgb, 255, 255, 255));
    border: 1px solid var(--ui-field-border);
    border-radius: var(--ui-radius-md);
    box-shadow: none;
    color: var(--ui-text);
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.25rem;
}

/* The typing field takes the remaining width, so its placeholder is never cut off ("Add IP addresses or hos") */
.bootstrap-tagsinput input {
    color: var(--ui-text);
    flex: 1 1 12rem;
    min-width: 12rem;
    width: auto !important;
}

.bootstrap-tagsinput input::placeholder {
    color: var(--ui-muted);
}

/* Phones: table cells keep their text on one line and the table scrolls inside its wrapper, instead of
   squeezing a column until words break letter by letter. Composite cells still stack their lines. */
@media (max-width: 575.98px) {
    .content table.dataTable:not(.ho-order-products-table) tbody td,
    .content .table-responsive > .table:not(.ui-pick-orders) tbody td {
        white-space: nowrap;
    }
}

/* Legacy style.css pads columns by 0.3 × gutter while the row pulls out by 0.5 × gutter, so a row's
   fields stuck out ~3px past the plain fields next to them. Inside cards and modals (forms) the
   columns get Bootstrap's own padding back, so every field lines up. */
/* Legacy style.css pads every top-level row 6px, which set grids of cards in from the page title and the plain
   cards around them (settings hub 6px, support hub). Rows line up with the page edge; their columns get
   Bootstrap's padding below, so a row's content starts exactly at the edge (it was 1px in or 5px out). */
.container-fluid > .row {
    padding-left: 0;
    padding-right: 0;
}

/* A row with an explicit gutter class (g-3, gx-2, …) declares its spacing: it gets the same treatment on the page
   too, so a grid of cards lines up with the plain cards and the title above it (support hub cards stuck out 3px). */
.card-body .row > *,
.modal-body .row > *,
.ui-card .row > *,
.rbp-card .row > *,
.container-fluid > .row > :not(.card),
.row:is(.g-0, .g-1, .g-2, .g-3, .g-4, .g-5, .gx-0, .gx-1, .gx-2, .gx-3, .gx-4, .gx-5) > :not(.card) {
    padding-left: calc(var(--bs-gutter-x) * .5);
    padding-right: calc(var(--bs-gutter-x) * .5);
}

/* A card placed straight in a row (no column around it: API keys / webhooks, order options) stood out past the page
   edges by the row's negative margin; it sits where a column's content would. */
/* (rows without the negative margin — mx-auto, mx-0, the filter + table pages — keep their cards flush) */
.row:not(.mx-auto, .mx-0, .show-on-extra-filters) > .card {
    margin-left: calc(var(--bs-gutter-x) * .5);
    margin-right: calc(var(--bs-gutter-x) * .5);
    width: calc(100% - var(--bs-gutter-x)) !important;
    max-width: calc(100% - var(--bs-gutter-x));
}

/* Responsive width utility the views use (w-100 on phones, natural width from md); Bootstrap 5 has no
   breakpoint variants for w-* */
@media (min-width: 768px) {
    .w-md-auto {
        width: auto !important;
    }
}

/* Input groups: the outer corners (icon addon, button, field) share the field's radius; inner joins stay square.
   Bootstrap gave addons 0.2rem, so a field with an icon looked rounded on one side only. */
.input-group > :first-child:not(.dropdown-menu):not(.invalid-feedback):not(.valid-feedback),
.input-group > .visually-hidden:first-child + * {
    border-top-left-radius: var(--ui-radius-md) !important;
    border-bottom-left-radius: var(--ui-radius-md) !important;
}
.input-group > :last-child:not(.dropdown-menu):not(.invalid-feedback):not(.valid-feedback):not(.cd-field-error),
.input-group > :nth-last-child(2):has(+ :is(.invalid-feedback, .valid-feedback, .cd-field-error, .dropdown-menu)) {
    border-top-right-radius: var(--ui-radius-md) !important;
    border-bottom-right-radius: var(--ui-radius-md) !important;
}
.input-group > :not(:first-child):not(.dropdown-menu) {
    border-top-left-radius: 0 !important;
    border-bottom-left-radius: 0 !important;
}
.input-group > :not(:last-child):not(:nth-last-child(2):has(+ :is(.invalid-feedback, .valid-feedback, .cd-field-error, .dropdown-menu))):not(.dropdown-menu):not(.invalid-feedback) {
    border-top-right-radius: 0 !important;
    border-bottom-right-radius: 0 !important;
}

/* Accordion headers are h2 for semantics; their label sizes like any section title */
.accordion-header {
    font-size: var(--ui-fs-lg);
}
/* List pages (filter column + table card): the table card uses the standard card padding */
.table-column.card > .card-body {
    padding: var(--ui-space-5) !important;
}
/* Extra-large card padding (p-5 = 48px) left promo/intro cards floating in white space next to 20px cards */
.card > .card-body.p-5 {
    padding: 32px !important;
}
/* Cards that hold a list table use the standard card padding on tablets and desktops (pages had 16 or 24) */
@media (min-width: 768px) {
    .card > .card-body:has(> .dataTables_wrapper, > .table-responsive > .dataTables_wrapper, > div > .dataTables_wrapper):not(.p-0):not(.px-0) {
        padding: var(--ui-space-5) !important;
    }
}

/* Page header on tablets and desktops, the same on every page: the buttons sit centred against the title +
   subtitle block (they hung from its top edge), and the content starts 24px under the subtitle (an inner 16px
   margin made it 40px) */
@media (min-width: 768px) {
    .page-header-toolbar {
        align-items: center !important;
        margin-bottom: var(--ui-space-6) !important;
    }
    .page-header-toolbar > .page-header,
    .page-header-toolbar > .main-buttons,
    .page-header-toolbar > .page-header > :last-child {
        margin-top: 0 !important;
        margin-bottom: 0 !important;
    }
    .page-header-toolbar + * {
        margin-top: 0 !important;
    }
}

/* Page filter rows (date range, seller/batch multi-selects, selects): every control the same border colour and
   the soft lift the cards on the page have; a lone input inside an input group keeps its left border */
/* one border colour for every field type (select2 came with its own lighter blue-grey) */
.select2-container--default :is(.select2-selection--single, .select2-selection--multiple) {
    border-color: var(--ui-field-border) !important;
}
/* fields that sit on the page background (filters above lists, page toolbars) get the cards' soft lift; fields
   inside cards, dialogs, tables, menus, list toolbars and the pick/pack status strip stay flat.
   Like the cards they sit between, they have no visible border: the shadow alone lifts them (the 1px stays,
   transparent, so heights don't change and the focus colour has somewhere to show). */
html body .content :is(.form-control, .form-select, .select2-container .select2-selection, .bootstrap-select > .dropdown-toggle):not(:is(.card, .ui-card, [class*="card"], .modal, .offcanvas, .dropdown-menu, .ui-sheet, table, .daterangepicker, .dataTables_length, .dataTables_filter, .cd-list-tools, .ui-pick-status, .input-group) *):not(.border-0) {
    box-shadow: var(--ui-shadow);
    border-color: transparent !important;
}
html body .content .input-group:not(:is(.card, .ui-card, [class*="card"], .modal, .offcanvas, .dropdown-menu, .ui-sheet, table, .daterangepicker, .ui-scanbox) *):not(.ui-scanbox) {
    border-radius: var(--ui-radius-md);
    box-shadow: var(--ui-shadow);
}
html body .content .input-group:not(:is(.card, .ui-card, [class*="card"], .modal, .offcanvas, .dropdown-menu, .ui-sheet, table, .daterangepicker) *):not(.ui-scanbox) > :is(.form-control, .form-select, .input-group-text) {
    border-color: transparent !important;
}
html body .content .input-group:not(:is(.card, .ui-card, [class*="card"], .modal, .offcanvas, .dropdown-menu, .ui-sheet, table, .daterangepicker) *):not(.ui-scanbox) > .input-group-text {
    background-color: var(--ui-surface) !important;
}
.content :is(.form-control, .form-select):focus,
.content .select2-container--focus .select2-selection,
html body .content :is(.form-control, .form-select):focus,
html body .content .select2-container--default.select2-container--focus .select2-selection,
html body .content .select2-container--default.select2-container--open .select2-selection,
html body .content .input-group:focus-within > :is(.form-control, .form-select, .input-group-text) {
    border-color: var(--ui-primary) !important;
    box-shadow: var(--ui-focus-ring) !important;
}
.input-group > .form-control:only-child {
    border-left-width: 1px !important;
    border-radius: var(--ui-radius-md) !important;
}

/* One field style everywhere: inputs, selects, small toolbar fields, select2 (single + multi) and bootstrap-select
   share the same corner radius, border colour and text size */
:is(.form-control, .form-select, .select2-container--default .select2-selection, .bootstrap-select > .dropdown-toggle):not(.input-group > *) {
    border-radius: var(--ui-radius-md) !important;
}
:is(.form-control, .form-select, .form-control-sm, .form-select-sm, .select2-container--default .select2-selection, .bootstrap-select > .dropdown-toggle) {
    border-color: var(--ui-field-border) !important;
}
.select2-container--default .select2-selection--multiple .select2-selection__rendered,
.select2-container--default .select2-selection--single .select2-selection__rendered {
    font-size: .85rem;
}
/* chips: room between the name and its remove icon */
.select2-container--default .select2-selection--multiple .select2-selection__choice {
    gap: 6px !important;
}
:is(.form-control, .form-select):focus,
.select2-container--focus .select2-selection,
.select2-container--open .select2-selection {
    border-color: var(--ui-primary) !important;
}
:is(.form-control, .form-select).is-invalid {
    border-color: var(--ui-danger) !important;
}
/* style.css colours page-filter select2 fields with --bs-border-color at a higher specificity */
html body .content .select2-container--default .select2-selection,
html body .select2-container--default .select2-selection {
    border-color: var(--ui-field-border) !important;
}
html body .select2-container--default.select2-container--focus .select2-selection,
html body .select2-container--default.select2-container--open .select2-selection {
    border-color: var(--ui-primary) !important;
}
/* a borderless page field still shows a red edge when it is invalid */
html body .content :is(.form-control, .form-select).is-invalid,
html body .content .is-invalid + .select2-container .select2-selection {
    border-color: var(--ui-danger) !important;
}
/* style.css gives select2 fields a faint 20px glow (with !important); on the page background they wear the same
   lift as every other field */
html body .content .select2-container:not(.select2-container--focus):not(.select2-container--open) .select2-selection:not(:is(.card, .ui-card, [class*="card"], .modal, .offcanvas, .dropdown-menu, .ui-sheet, table, .daterangepicker, .dataTables_length, .dataTables_filter, .cd-list-tools, .ui-pick-status, .input-group) *) {
    box-shadow: var(--ui-shadow) !important;
}
html body .content :is(.card, .ui-card, [class*="card"], .modal, .offcanvas, .ui-sheet) .select2-container .select2-selection {
    box-shadow: none !important;
}
/* date(-range) pickers are readonly only so the calendar drives them: they look like normal, clickable fields */
.form-control[readonly]:not(:disabled):is([id*="date" i], [id*="range" i], [name*="date" i], .cursor-pointer) {
    background-color: var(--ui-surface);
    cursor: pointer;
}

/* Readability (warehouse monitors): the page background is the token (style.css painted #f7f7f7 so cards barely
   stood off it) and filled primary buttons sit on the slightly deeper brand shade so white labels read */
body:not([data-theme=dark]) {
    background-color: var(--ui-page) !important;
}
body[data-theme=dark] {
    background-color: var(--ui-page) !important;
}
.btn-primary,
.btn-primary:disabled,
.btn-primary.disabled {
    --bs-btn-bg: var(--ui-primary-strong);
    --bs-btn-border-color: var(--ui-primary-strong);
    --bs-btn-disabled-bg: var(--ui-primary-strong);
    --bs-btn-disabled-border-color: var(--ui-primary-strong);
    background-color: var(--ui-primary-strong) !important;
    border-color: var(--ui-primary-strong) !important;
    color: #fff !important;
}
.btn-primary:hover,
.btn-primary:focus-visible,
.btn-primary:active {
    background-color: var(--ui-primary-hover-strong) !important;
    border-color: var(--ui-primary-hover-strong) !important;
    color: #fff !important;
}
.btn-outline-primary {
    color: var(--ui-link) !important;
    border-color: var(--ui-link) !important;
}
.btn-outline-primary:hover,
.btn-outline-primary:active {
    background-color: var(--ui-primary-strong) !important;
    border-color: var(--ui-primary-strong) !important;
    color: #fff !important;
}
/* Link buttons stay links on hover: Bootstrap's .btn:hover paints var(--bs-btn-hover-bg), which a theme rule set to
   the primary blue, while the text stays link blue: blue on blue ("Replace current image"). No fill, link colour. */
.btn.btn-link,
.btn.btn-link:hover,
.btn.btn-link:focus-visible,
.btn.btn-link:active {
    --bs-btn-hover-bg: transparent;
    --bs-btn-active-bg: transparent;
    background-color: transparent !important;
    border-color: transparent !important;
    box-shadow: none;
}
.btn.btn-link:hover,
.btn.btn-link:focus-visible {
    color: var(--ui-link-hover, var(--ui-link)) !important;
}
/* Dark mode: the outline-dark hover fill is light grey; white text on it was unreadable */
html body[data-theme=dark] .btn-outline-dark:hover,
html body[data-theme=dark] .btn-outline-dark:active {
    color: #111418 !important;
}
/* select2 chips: the × is the SVG ::before; style.css' text "×" ::after showed as a second cross in dark mode */
.select2-container--default .select2-selection--multiple .select2-selection__choice__remove::after {
    content: none !important;
    display: none !important;
}

/* Readability, second pass from contrast_scan.py (AA everywhere text carries information):
   placeholders, search shortcut hints, Bootstrap's .text-muted (#737d85 in style.css), labels in key/value lists,
   and status colours used as text (badges, counts, outline buttons) all read on a poor monitor */
.form-control::placeholder,
.form-select::placeholder,
input::placeholder,
textarea::placeholder,
.select2-search__field::placeholder {
    color: var(--ui-muted) !important;
    opacity: 1;
}
/* Floating fields carry their label in the box: the placeholder only shows once the field is focused,
   otherwise the label and placeholder print on top of each other */
.form-floating > :is(.form-control, .form-select):not(:focus)::placeholder,
.form-floating > .form-control.cd-ph-same::placeholder {
    color: transparent !important;
}
.spotlight-trigger-text,
.spotlight-trigger-shortcut kbd {
    color: var(--ui-muted) !important;
    opacity: 1 !important;
}
.text-muted,
.small.text-muted,
small.text-muted,
.form-text {
    color: var(--ui-muted) !important;
}
.form-label,
label.form-label {
    color: var(--ui-body);
}
.ui-kv__label,
.ui-empty-value {
    color: var(--ui-muted);
}
.badge-soft-danger,
.ui-tab__count.is-danger,
.btn-outline-danger:not(:hover):not(:active),
.text-danger {
    color: var(--ui-danger-text) !important;
}
.badge-soft-success,
.text-success {
    color: var(--ui-success-text) !important;
}
.badge-soft-warning,
.text-warning,
.feature-beta-badge {
    color: var(--ui-warning-text) !important;
}
.badge-soft-info,
.badge-soft-primary,
.text-info {
    color: var(--ui-info-text) !important;
}
.spotlight-trigger-shortcut {
    opacity: 1 !important;
}
.ui-kv__label,
.ui-empty-value {
    color: var(--ui-muted) !important;
}
/* filled brand surfaces carrying white text use the deep brand shade in every theme (dark mode lifts --primary
   for text, which left white labels at 2.8:1 on active page numbers, step numbers and the scan button) */
.page-item.active .page-link,
.ui-step__num,
.mcp-step-num,
.app-home .app-home-search__submit,
body[data-theme=dark] .app-home .app-home-search__submit,
.btn-success {
    background-color: var(--ui-primary-strong) !important;
    border-color: var(--ui-primary-strong) !important;
    color: #fff !important;
}
.btn-success,
body[data-theme=dark] .btn-success {
    background-color: #3fc77d !important; /* ChannelDock green */
    border-color: #3fc77d !important;
}
/* search popup: icon and text on one centre line (the icon's glyph sat at the top of a 40px box) */
.spotlight-input-group {
    align-items: center !important;
}
.spotlight-input-group > .spotlight-search-icon {
    display: inline-flex !important;
    align-items: center;
    justify-content: center;
    align-self: stretch;
    height: auto !important;
    line-height: 1 !important;
    margin-top: 0 !important;
    top: 0 !important;
}
.spotlight-input-group > .spotlight-input {
    align-self: stretch;
    height: auto !important;
    line-height: normal;
}
.spotlight-input-group > .spotlight-input,
.spotlight-input-group > .spotlight-input:focus {
    border: 0 !important;
    box-shadow: none !important;
    background: transparent !important;
    outline: none;
}
html body .spotlight-container .spotlight-input-group > .spotlight-input,
html body .spotlight-container .spotlight-input-group > .spotlight-input:focus,
html body[data-theme=dark] .spotlight-container .spotlight-input-group > .spotlight-input:focus {
    box-shadow: none !important;
    outline: none !important;
}
/* light mode, third pass: status text on soft badges and the red button pass AA (a few page rules beat the first pass) */
html body:not([data-theme=dark]) .badge.badge-soft-danger { color: var(--ui-danger-text) !important; }
html body:not([data-theme=dark]) .badge.badge-soft-success { color: var(--ui-success-text) !important; }
html body:not([data-theme=dark]) .badge.badge-soft-warning { color: var(--ui-warning-text) !important; }
html body:not([data-theme=dark]) .badge.badge-soft-primary,
html body:not([data-theme=dark]) .badge.badge-soft-info { color: var(--ui-info-text) !important; }
html body:not([data-theme=dark]) .badge.badge-soft-purple { color: #5b2bbf !important; }
html body:not([data-theme=dark]) .btn-danger:not(:disabled) {
    background-color: #b02a37 !important;
    border-color: #b02a37 !important;
    color: #fff !important;
}
html body:not([data-theme=dark]) .btn-link { color: var(--ui-link) !important; }

/* Light contrast pass (contrast_scan.py, 164 routes): grey text that sat at 2-4:1 on white */
.sidebar-footer-usage__copy,
.sidebar-footer-context,
.sidebar-footer-context > span:not(.sidebar-footer-context-badge),
.task-meta > span,
ol.st-wizard-steps > li:not(.is-active):not(.active),
.return-attachments-empty-hint,
.return-attachments-empty-title,
.support-phone-number__hint,
.st-phone-urgent-modal__warning-text {
    color: var(--ui-muted) !important;
}
.inv-log-qty.inv-log-qty-old {
    color: var(--ui-faint) !important;
}
.b2b-hub-step__count {
    color: var(--ui-warning-text) !important;
}

/* A spinner is round wherever it sits: the !important .input-group corner resets turned one into a rotating square.
   :not(#_) lifts the specificity above those resets */
.spinner-border:not(#_),
.spinner-grow:not(#_) {
    border-radius: 50% !important;
}
