/* ==========================================================================
   Brandligo — Bootstrap bridge
   ==========================================================================

   Bootstrap is the grid and JS layer in this application, and a large number of
   views were authored against its class names. This file maps Bootstrap's
   component classes onto the Brandligo design tokens.

   Two reasons this is the right boundary rather than a shortcut:

     - It themes every remaining Bootstrap-authored view at once, and any future
       Bootstrap markup inherits the theme automatically instead of reintroducing
       default blue.
     - It is one place to change. Thirty rewritten files would be thirty places
       to drift.

   Loaded after both Bootstrap and brandligo.css, so specificity alone wins and
   !important is only needed where Bootstrap itself uses it (its utility classes).
   ========================================================================== */

/* --------------------------------------------------------------------------
   Pagination
   --------------------------------------------------------------------------

   Styled here, on Bootstrap's own class names, rather than under a .bl-pagination
   wrapper. Only ten of the twenty-five paginated views have that wrapper, so
   descendant-scoped rules left the other fifteen showing Bootstrap's default blue —
   which the monochrome design system does not allow. Targeting .page-link directly
   converts every one of them without touching a view. */
.pagination {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-1);
    list-style: none;
    padding: 0;
    margin: 0;
}

.page-link {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 2.25rem;
    height: 2.25rem;
    padding: 0 var(--space-2);
    border: 1px solid var(--border) !important;
    border-radius: var(--radius) !important;
    background: var(--surface);
    color: var(--text-muted);
    font-size: var(--text-sm);
    font-weight: 550;
    text-decoration: none;
    transition: background var(--duration-fast) var(--ease-out),
                color var(--duration-fast) var(--ease-out),
                border-color var(--duration-fast) var(--ease-out);
}

.page-link:hover,
.page-link:focus {
    background: var(--surface-hover);
    color: var(--text);
    border-color: var(--border-strong) !important;
    box-shadow: none;
}

.page-item.active .page-link,
.active > .page-link {
    background: var(--surface-inverse);
    border-color: var(--surface-inverse) !important;
    color: var(--text-inverse);
}

.page-item.disabled .page-link,
.disabled > .page-link {
    opacity: 0.4;
    pointer-events: none;
}

/* The paginator's own <nav> carries no class of its own to hook onto, so it is
   matched by what it contains. */
nav:has(> .pagination),
nav:has(.pagination) {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-3) var(--space-4);
    width: 100%;
}

/* The "Showing 1 to 20 of 65 results" line is a <p>, whose default bottom margin
   pushed it below the controls and off their baseline. */
nav:has(.pagination) p {
    margin-bottom: 0;
}

/* --------------------------------------------------------------------------
   Containers
   --------------------------------------------------------------------------

   Bootstrap's .container ladder tops out at 1320px, while --container is 76rem
   (1216px). Views authored against Bootstrap therefore sat ~104px wider than the
   header and footer, which read as the page hanging off the edge of the screen.
   Pinning every container variant to the token lines all 26 of those views up
   with the redesigned ones without touching their markup. */
.container,
.container-fluid,
.container-sm,
.container-md,
.container-lg,
.container-xl,
.container-xxl {
    width: 100%;
    max-width: var(--container);
    margin-inline: auto;
    padding-inline: var(--space-5);
}

/* Bootstrap's row uses negative margins to cancel column gutters. Inside a
   container whose padding is now a token, an unpadded ancestor (a .card-body,
   say) leaves those negative margins uncancelled and the row pokes out. */
.row { --bs-gutter-x: var(--space-5); }

/* A table with more columns than the viewport can hold is the other overflow
   source. Bootstrap only scrolls when the author remembered .table-responsive,
   and most of these views did not. */
.card-body:has(> .table),
.card:has(> .table),
.bl-card__body:has(> .table),
.bl-card:has(> .bl-table),
.bl-card__body:has(> .bl-table) {
    overflow-x: auto;
}

/* --------------------------------------------------------------------------
   Surfaces
   -------------------------------------------------------------------------- */

.card {
    background: var(--surface-raised);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    color: var(--text);
}

.card-header,
.card-footer {
    background: var(--surface-sunken);
    border-color: var(--border);
    color: var(--text);
}

.card-title { color: var(--text); letter-spacing: var(--tracking-tight); }
.card-text { color: var(--text-muted); }

.list-group-item {
    background: var(--surface-raised);
    border-color: var(--border);
    color: var(--text);
}

.modal-content,
.dropdown-menu,
.offcanvas,
.popover {
    background: var(--surface-raised);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    color: var(--text);
    box-shadow: var(--shadow-lg);
}

.dropdown-menu { padding: var(--space-1); }
.dropdown-item { color: var(--text); font-size: var(--text-sm); border-radius: var(--radius-sm); }
.dropdown-item:hover,
.dropdown-item:focus { background: var(--surface-hover); color: var(--text); }
.dropdown-divider { border-color: var(--border); }

/* --------------------------------------------------------------------------
   Buttons

   Bootstrap's semantic colours collapse onto the monochrome scale. Danger keeps
   its hue on the text and border only, so a destructive action still reads as one
   without a colour fill breaking the strict-monochrome rule.
   -------------------------------------------------------------------------- */

.btn {
    border-radius: var(--radius);
    font-size: var(--text-sm);
    font-weight: 600;
    padding: 0.5rem var(--space-4);
    transition: all var(--duration) var(--ease);
}

.btn-primary,
.btn-dark,
.btn-info,
.btn-success {
    background: var(--surface-inverse);
    border-color: var(--surface-inverse);
    color: var(--text-inverse);
}

.btn-primary:hover, .btn-primary:focus,
.btn-dark:hover, .btn-dark:focus,
.btn-info:hover, .btn-info:focus,
.btn-success:hover, .btn-success:focus {
    background: var(--ink-800);
    border-color: var(--ink-800);
    color: var(--text-inverse);
}

/* On dark, a darker hover would mean invisible — lighten instead. */
:root[data-theme="dark"] .btn-primary:hover,
:root[data-theme="dark"] .btn-dark:hover,
:root[data-theme="dark"] .btn-info:hover,
:root[data-theme="dark"] .btn-success:hover {
    background: var(--ink-200);
    border-color: var(--ink-200);
}

@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) .btn-primary:hover,
    :root:not([data-theme="light"]) .btn-dark:hover,
    :root:not([data-theme="light"]) .btn-info:hover,
    :root:not([data-theme="light"]) .btn-success:hover {
        background: var(--ink-200);
        border-color: var(--ink-200);
    }
}

.btn-secondary,
.btn-light,
.btn-outline-primary,
.btn-outline-secondary,
.btn-outline-dark,
.btn-outline-info,
.btn-outline-success {
    background: var(--surface);
    border-color: var(--border-strong);
    color: var(--text);
}

.btn-secondary:hover, .btn-light:hover,
.btn-outline-primary:hover, .btn-outline-secondary:hover, .btn-outline-dark:hover,
.btn-outline-info:hover, .btn-outline-success:hover {
    background: var(--surface-hover);
    border-color: var(--text-muted);
    color: var(--text);
}

.btn-danger {
    background: var(--surface);
    border-color: var(--border-strong);
    color: var(--danger);
}

.btn-danger:hover, .btn-danger:focus {
    background: var(--danger-bg);
    border-color: var(--danger);
    color: var(--danger);
}

.btn-outline-danger { background: transparent; border-color: var(--border-strong); color: var(--danger); }
.btn-outline-danger:hover { background: var(--danger-bg); border-color: var(--danger); color: var(--danger); }

.btn-warning { background: var(--surface); border-color: var(--border-strong); color: var(--warning); }
.btn-warning:hover { background: var(--warning-bg); border-color: var(--warning); color: var(--warning); }

.btn-link { color: var(--text); }
.btn-sm { padding: 0.375rem var(--space-3); font-size: var(--text-xs); }
.btn-lg { padding: 0.75rem var(--space-6); font-size: var(--text-md); }
.btn:focus, .btn:focus-visible { box-shadow: 0 0 0 3px var(--surface-active); }

/* --------------------------------------------------------------------------
   Forms
   -------------------------------------------------------------------------- */

.form-control,
.form-select {
    background: var(--surface);
    border: 1px solid var(--border-strong);
    border-radius: var(--radius);
    color: var(--text);
    font-size: var(--text-base);
    padding: 0.5625rem var(--space-3);
}

.form-control:focus,
.form-select:focus {
    background: var(--surface);
    border-color: var(--text);
    color: var(--text);
    box-shadow: 0 0 0 3px var(--surface-active);
}

.form-control::placeholder { color: var(--text-subtle); }
.form-control:disabled,
.form-select:disabled { background: var(--surface-sunken); color: var(--text-muted); }

.form-label { font-size: var(--text-sm); font-weight: 600; color: var(--text); margin-bottom: var(--space-2); }
.form-text { color: var(--text-muted); font-size: var(--text-sm); }

.form-check-input { border-color: var(--border-strong); background-color: var(--surface); }
.form-check-input:checked { background-color: var(--surface-inverse); border-color: var(--surface-inverse); }
.form-check-input:focus { border-color: var(--text); box-shadow: 0 0 0 3px var(--surface-active); }
.form-check-label { color: var(--text); }

.input-group-text {
    background: var(--surface-sunken);
    border-color: var(--border-strong);
    color: var(--text-muted);
}

.form-control.is-invalid,
.form-select.is-invalid { border-color: var(--danger); }
.invalid-feedback { color: var(--danger); font-size: var(--text-sm); }

/* --------------------------------------------------------------------------
   Tables
   -------------------------------------------------------------------------- */

.table {
    --bs-table-bg: transparent;
    --bs-table-color: var(--text);
    --bs-table-border-color: var(--border);
    --bs-table-striped-bg: var(--surface-sunken);
    --bs-table-striped-color: var(--text);
    --bs-table-hover-bg: var(--surface-hover);
    --bs-table-hover-color: var(--text);
    color: var(--text);
    font-size: var(--text-sm);
}

.table > thead { background: var(--surface-sunken); }

.table > thead th {
    font-size: var(--text-xs);
    font-weight: 650;
    letter-spacing: var(--tracking-wide);
    text-transform: uppercase;
    color: var(--text-muted);
    border-bottom-color: var(--border);
}

.table-light,
.table-light > th,
.table-light > td {
    --bs-table-bg: var(--surface-sunken);
    --bs-table-color: var(--text-muted);
}

.table-responsive { border-radius: var(--radius-lg); }

/* --------------------------------------------------------------------------
   Badges, alerts, navigation
   -------------------------------------------------------------------------- */

.badge {
    border-radius: var(--radius-sm);
    font-size: var(--text-xs);
    font-weight: 600;
    letter-spacing: var(--tracking-wide);
    padding: 0.25rem var(--space-2);
}

/* Bootstrap sets these with !important on its own utilities, so matching it is
   the only way to win. All contextual badges resolve to the three permitted
   colours or to ink. */
.badge.bg-primary,
.badge.bg-dark,
.badge.bg-secondary,
.badge.bg-info { background-color: var(--surface-inverse) !important; color: var(--text-inverse); }

.badge.bg-success { background-color: var(--success-bg) !important; color: var(--success); }
.badge.bg-warning { background-color: var(--warning-bg) !important; color: var(--warning); }
.badge.bg-danger { background-color: var(--danger-bg) !important; color: var(--danger); }
.badge.bg-light { background-color: var(--surface-sunken) !important; color: var(--text-muted); }

.alert {
    border: 1px solid var(--border);
    border-left-width: 3px;
    border-radius: var(--radius);
    background: var(--surface-sunken);
    color: var(--text);
    font-size: var(--text-base);
}

.alert-success { background: var(--success-bg); border-left-color: var(--success); color: var(--success); }
.alert-warning { background: var(--warning-bg); border-left-color: var(--warning); color: var(--warning); }
.alert-danger { background: var(--danger-bg); border-left-color: var(--danger); color: var(--danger); }
.alert-info,
.alert-primary,
.alert-secondary { background: var(--surface-sunken); border-left-color: var(--text); color: var(--text); }
.alert-link { color: inherit; text-decoration: underline; }

.nav-tabs { border-bottom-color: var(--border); }

.nav-tabs .nav-link {
    color: var(--text-muted);
    border: 0;
    border-bottom: 2px solid transparent;
    font-size: var(--text-sm);
    font-weight: 600;
}

.nav-tabs .nav-link:hover { border-bottom-color: var(--border-strong); color: var(--text); background: transparent; }
.nav-tabs .nav-link.active { color: var(--text); background: transparent; border-bottom-color: var(--text); }

.nav-link { color: var(--text-muted); }
.nav-link:hover { color: var(--text); }

.progress { background: var(--surface-active); border-radius: var(--radius-full); height: 0.5rem; }
.progress-bar { background: var(--surface-inverse); }

.breadcrumb { font-size: var(--text-sm); }
.breadcrumb-item,
.breadcrumb-item a { color: var(--text-muted); }
.breadcrumb-item.active { color: var(--text); }
.breadcrumb-item + .breadcrumb-item::before { color: var(--text-subtle); }

/* --------------------------------------------------------------------------
   Utility remaps

   Bootstrap ships these with !important. Remapping them is what stops any view
   reintroducing default blue simply by writing .text-primary or .bg-primary.
   -------------------------------------------------------------------------- */

.text-primary,
.text-info,
.text-dark { color: var(--text) !important; }
.text-secondary,
.text-muted { color: var(--text-muted) !important; }
.text-success { color: var(--success) !important; }
.text-warning { color: var(--warning) !important; }
.text-danger { color: var(--danger) !important; }
.text-white { color: var(--text-inverse) !important; }

.bg-white,
.bg-body { background-color: var(--surface) !important; }
.bg-light { background-color: var(--surface-sunken) !important; }
.bg-dark,
.bg-primary,
.bg-info,
.bg-secondary { background-color: var(--surface-inverse) !important; color: var(--text-inverse); }

.border,
.border-top,
.border-bottom,
.border-start,
.border-end { border-color: var(--border) !important; }

.shadow,
.shadow-sm,
.shadow-lg { box-shadow: var(--shadow-sm) !important; }

.link-primary { color: var(--text) !important; }

.spinner-border,
.spinner-grow { color: var(--text); }

/* Bootstrap's close button is a black SVG data-URI; it disappears on dark ink. */
:root[data-theme="dark"] .btn-close { filter: invert(1) grayscale(100%) brightness(200%); }

@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) .btn-close { filter: invert(1) grayscale(100%) brightness(200%); }
}
