/* ==========================================================================
   Intuceo UI - the application's design system
   --------------------------------------------------------------------------
   A restyle of the whole application, built as a layer over the existing
   markup rather than a rewrite of it.

   That is a deliberate choice. There are 77 templates and about 20,000 lines
   of Blade here, most of it carrying its own inline styles and its own jQuery.
   Rewriting that markup would mean re-testing every form in the application to
   find out what broke. Restyling the components the markup already uses gets
   the same result on screen and cannot break a form's name attributes, its
   validation, or the handlers bound to it.

   Load order: brand.css (tokens and typefaces) -> ui.css (this file).
   Bootstrap 3 is old and leans on !important in places; where a rule below
   carries one, it is because the rule it settles does too.

   Sections
     1  shell            the app bar, canvas and page frame
     2  typography       headings, text, links
     3  buttons
     4  forms            inputs, selects, checkboxes, radios, select2
     5  tables
     6  surfaces         cards, panels, wells
     7  overlays         modals, dropdowns, tooltips
     8  feedback         alerts, badges, progress
     9  navigation       breadcrumbs, list groups, tabs, pagination
    10  loading          the top bar, button spinners, skeletons
    11  motion & utility
    12  responsive
    13  print
   ========================================================================== */

:root {
    /* Elevation, as a small ladder rather than ad-hoc shadows. */
    --ui-e1: 0 1px 2px rgba(14, 24, 70, .06);
    --ui-e2: 0 1px 3px rgba(14, 24, 70, .08), 0 6px 16px -6px rgba(14, 24, 70, .12);
    --ui-e3: 0 2px 6px rgba(14, 24, 70, .08), 0 16px 32px -12px rgba(14, 24, 70, .18);
    --ui-e4: 0 8px 24px rgba(14, 24, 70, .14), 0 32px 64px -24px rgba(14, 24, 70, .28);

    --ui-ring: 0 0 0 3px rgba(18, 118, 225, .18);
    --ui-ring-danger: 0 0 0 3px rgba(198, 40, 40, .16);

    --ui-r-sm: 6px;
    --ui-r: 10px;
    --ui-r-lg: 14px;
    --ui-r-pill: 999px;

    /* One easing for everything, so the interface moves as one thing. */
    --ui-ease: cubic-bezier(.16, .84, .44, 1);
    --ui-fast: 140ms var(--ui-ease);
    --ui-mid: 220ms var(--ui-ease);

    --ui-bar-h: 68px;
}

/* ============================================================ 1. shell ==== */

body {
    background:
        radial-gradient(1200px 600px at 78% -8%, rgba(18, 118, 225, .07), transparent 60%),
        radial-gradient(900px 500px at -6% 4%, rgba(254, 125, 52, .05), transparent 55%),
        var(--brand-canvas);
    background-attachment: fixed;
    padding-top: var(--ui-bar-h) !important;
    font-feature-settings: "cv05" 1, "ss01" 1;
}

/* The app bar. Dark, so the interface has a clear top edge and the brand sits
   on the ground it was designed for. */
.navbar.navbar-fixed-top {
    min-height: var(--ui-bar-h);
    background: linear-gradient(100deg, #0B1338 0%, var(--brand-navy) 46%, #16265C 100%);
    border: 0;
    border-bottom: 1px solid rgba(255, 255, 255, .07);
    box-shadow: 0 1px 0 rgba(14, 24, 70, .04), 0 6px 24px -12px rgba(14, 24, 70, .5);
}

/* A thin accent along the bottom edge. */
.navbar.navbar-fixed-top::after {
    content: "";
    position: absolute;
    left: 0; right: 0; bottom: -1px;
    height: 2px;
    background: linear-gradient(90deg,
        var(--brand-blue) 0%, #37A0F5 28%, var(--brand-accent) 62%, transparent 100%);
    opacity: .85;
}

.navbar-nav > .wrapper {
    align-items: center;
}

.navbar-nav .nav-group-1,
.navbar-nav .nav-item {
    height: var(--ui-bar-h);
}

.navbar-nav .brand-logo {
    width: 128px;
    filter: drop-shadow(0 1px 6px rgba(0, 0, 0, .35));
    transition: transform var(--ui-mid);
}

.navbar-nav .nav-group-1:hover .brand-logo {
    transform: translateY(-1px);
}

.navbar-nav .logo-text {
    color: rgba(255, 255, 255, .92);
    border-left-color: rgba(255, 255, 255, .18);
    letter-spacing: .01em;
}

/* Bar links: quiet until wanted, with the active one marked by the accent. */
.navbar-nav .nav-item,
.navbar-nav > .wrapper a {
    color: rgba(255, 255, 255, .76) !important;
    font-weight: 500;
    letter-spacing: .02em;
    position: relative;
    transition: color var(--ui-fast);
}

.navbar-nav .nav-item:hover,
.navbar-nav .nav-item:focus,
.navbar-nav > .wrapper a:hover {
    color: #fff !important;
}

.navbar-nav .nav-item::after {
    content: "";
    position: absolute;
    left: 15px; right: 15px; bottom: 16px;
    height: 2px;
    border-radius: 2px;
    background: linear-gradient(90deg, var(--brand-blue), #4FB0FF);
    transform: scaleX(0);
    transform-origin: left;
    transition: transform var(--ui-mid);
}

.navbar-nav .nav-item:hover::after,
.navbar-nav .nav-item.active::after,
.navbar-nav .nav-item.selected::after {
    transform: scaleX(1);
}

.navbar-nav .nav-group-1::after { display: none; }

/* The bar's own dropdown sits on a dark ground, so it gets its own surface. */
.navbar-nav .dropdown-menu {
    background: #fff;
    border: 1px solid var(--brand-border);
    border-radius: var(--ui-r);
    box-shadow: var(--ui-e3);
    padding: 6px;
    margin-top: 6px;
}

.navbar-nav .dropdown-menu li a {
    color: var(--brand-text) !important;
    border-radius: var(--ui-r-sm);
    padding: 9px 12px;
    font-weight: 500;
}

.navbar-nav .dropdown-menu li a:hover {
    background: var(--brand-blue-faint) !important;
    color: var(--brand-blue-dark) !important;
}

/* Page frame: give the content room and a consistent rhythm. */
.content,
.container,
.container-fluid {
    position: relative;
}

/* ======================================================= 2. typography ==== */

h1, .h1 { font-size: 30px; line-height: 1.2; }
h2, .h2 { font-size: 24px; }
h3, .h3 { font-size: 20px; }
h4, .h4 { font-size: 17px; font-weight: 600; }
h5, .h5 { font-size: 15px; font-weight: 600; }

h1, h2, h3, h4, h5, h6 {
    letter-spacing: -.015em;
}

.text-muted,
small {
    color: var(--brand-text-muted) !important;
}

code, kbd, pre, samp {
    font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;
    font-size: .92em;
}

code {
    background: var(--brand-blue-faint);
    color: var(--brand-blue-darker);
    border: 1px solid #DCE9F8;
    border-radius: var(--ui-r-sm);
    padding: 2px 6px;
}

hr {
    border-top-color: var(--brand-border);
    opacity: .9;
}

/* ========================================================== 3. buttons ==== */

.btn {
    border-radius: var(--ui-r) !important;
    font-weight: 600 !important;
    letter-spacing: .01em;
    padding: 9px 18px;
    border-width: 1px;
    box-shadow: var(--ui-e1);
    transition: background-color var(--ui-fast), border-color var(--ui-fast),
                box-shadow var(--ui-mid), transform var(--ui-fast), color var(--ui-fast);
    will-change: transform;
}

.btn:hover { transform: translateY(-1px); box-shadow: var(--ui-e2); }
.btn:active { transform: translateY(0); box-shadow: var(--ui-e1); }

.btn:focus-visible {
    outline: none !important;
    box-shadow: var(--ui-ring), var(--ui-e2) !important;
}

.btn-primary,
.btn-save {
    background-image: linear-gradient(180deg, #2C86EA 0%, var(--brand-blue) 100%);
    border-color: var(--brand-blue-dark) !important;
}

.btn-primary:hover,
.btn-save:hover {
    background-image: linear-gradient(180deg, var(--brand-blue) 0%, var(--brand-blue-dark) 100%);
    box-shadow: 0 6px 18px -6px rgba(18, 118, 225, .55) !important;
}

.btn-success {
    background-image: linear-gradient(180deg, #2C86EA 0%, var(--brand-blue) 100%);
}

.btn-danger {
    background-image: linear-gradient(180deg, #D94141 0%, var(--brand-danger) 100%);
    border-color: #A81F1F !important;
}

.btn-danger:hover {
    box-shadow: 0 6px 18px -6px rgba(198, 40, 40, .5) !important;
}

.btn-warning {
    background-image: linear-gradient(180deg, #FF9455 0%, var(--brand-accent) 100%);
    border-color: var(--brand-accent-dark) !important;
    color: #fff !important;
}

.btn-default,
.btn-secondary {
    background: #fff !important;
    background-image: none !important;
    border-color: var(--brand-border-strong) !important;
    color: var(--brand-text) !important;
}

.btn-default:hover,
.btn-secondary:hover {
    background: var(--brand-blue-faint) !important;
    border-color: var(--brand-blue) !important;
    color: var(--brand-blue-dark) !important;
}

.btn-link {
    box-shadow: none;
    color: var(--brand-blue);
}

.btn-link:hover { box-shadow: none; transform: none; text-decoration: underline; }

.btn-lg { padding: 12px 24px; font-size: 16px; border-radius: var(--ui-r-lg) !important; }
.btn-sm { padding: 6px 12px; font-size: 12.5px; }
.btn-xs { padding: 3px 9px; font-size: 11.5px; border-radius: var(--ui-r-sm) !important; }

.btn[disabled],
.btn.disabled {
    opacity: .55;
    transform: none !important;
    box-shadow: none !important;
    cursor: not-allowed;
}

/* ============================================================ 4. forms ==== */

label,
.control-label {
    font-weight: 600;
    font-size: 13px;
    color: var(--brand-navy);
    letter-spacing: .01em;
    margin-bottom: 6px;
}

.form-control {
    height: auto;
    min-height: 40px;
    padding: 9px 12px;
    border: 1px solid var(--brand-border-strong) !important;
    border-radius: var(--ui-r) !important;
    background-color: #fff;
    color: var(--brand-ink);
    box-shadow: inset 0 1px 2px rgba(14, 24, 70, .04) !important;
    transition: border-color var(--ui-fast), box-shadow var(--ui-mid), background-color var(--ui-fast);
}

.form-control:hover:not(:disabled):not([readonly]) {
    border-color: var(--brand-border-strong);
    background-color: #FCFDFF;
}

.form-control:focus {
    border-color: var(--brand-blue) !important;
    box-shadow: var(--ui-ring), inset 0 1px 2px rgba(14, 24, 70, .03) !important;
    background-color: #fff;
    outline: none;
}

.form-control::placeholder { color: #97A2B4; }

.form-control[disabled],
.form-control[readonly],
fieldset[disabled] .form-control {
    background-color: #F4F6FA;
    color: var(--brand-text-muted);
    cursor: not-allowed;
    box-shadow: none !important;
}

textarea.form-control { min-height: 96px; line-height: 1.6; }

select.form-control {
    appearance: none;
    -webkit-appearance: none;
    background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%235A6577' stroke-width='1.6' stroke-linecap='round'%3E%3Cpath d='M4 6.5 8 10.5l4-4'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 12px center;
    background-size: 15px;
    padding-right: 36px;
}

.has-error .form-control {
    border-color: var(--brand-danger) !important;
}

.has-error .form-control:focus {
    box-shadow: var(--ui-ring-danger) !important;
}

.has-error .control-label,
.help-block.text-danger,
.invalid-feedback {
    color: var(--brand-danger);
}

.has-success .form-control { border-color: var(--brand-success) !important; }

.help-block {
    font-size: 12.5px;
    color: var(--brand-text-muted);
    margin-top: 6px;
}

.form-group { margin-bottom: 18px; }

/* Checkboxes and radios, drawn rather than left to the platform. */
.checkbox input[type="checkbox"],
.radio input[type="radio"],
input[type="checkbox"],
input[type="radio"] {
    accent-color: var(--brand-blue);
    width: 16px;
    height: 16px;
    cursor: pointer;
}

.checkbox label,
.radio label {
    font-weight: 500;
    color: var(--brand-text);
    cursor: pointer;
}

.input-group-addon {
    background: var(--brand-canvas);
    border-color: var(--brand-border-strong);
    border-radius: var(--ui-r);
    color: var(--brand-text-muted);
}

/* select2, which 18 templates use, brought onto the same shape as the inputs. */
.select2-container--default .select2-selection--single,
.select2-container--default .select2-selection--multiple {
    min-height: 40px;
    border: 1px solid var(--brand-border-strong) !important;
    border-radius: var(--ui-r) !important;
    box-shadow: inset 0 1px 2px rgba(14, 24, 70, .04);
    transition: border-color var(--ui-fast), box-shadow var(--ui-mid);
}

.select2-container--default .select2-selection--single .select2-selection__rendered {
    line-height: 38px;
    color: var(--brand-ink);
    padding-left: 12px;
}

.select2-container--default .select2-selection--single .select2-selection__arrow {
    height: 38px;
    right: 8px;
}

.select2-container--default.select2-container--focus .select2-selection--single,
.select2-container--default.select2-container--focus .select2-selection--multiple,
.select2-container--default.select2-container--open .select2-selection--single {
    border-color: var(--brand-blue) !important;
    box-shadow: var(--ui-ring);
}

.select2-dropdown {
    border: 1px solid var(--brand-border) !important;
    border-radius: var(--ui-r) !important;
    box-shadow: var(--ui-e3);
    overflow: hidden;
}

.select2-container--default .select2-results__option--highlighted[aria-selected] {
    background: var(--brand-blue) !important;
}

.select2-container--default .select2-results__option[aria-selected="true"] {
    background: var(--brand-blue-faint) !important;
    color: var(--brand-blue-dark) !important;
}

.select2-container--default .select2-search--dropdown .select2-search__field {
    border: 1px solid var(--brand-border-strong) !important;
    border-radius: var(--ui-r-sm) !important;
    padding: 7px 10px;
}

.select2-container--default .select2-selection--multiple .select2-selection__choice {
    background: var(--brand-surface) !important;
    border: 1px solid #BBD9F7 !important;
    border-radius: var(--ui-r-pill) !important;
    color: var(--brand-navy);
    padding: 2px 10px;
}

/* =========================================================== 5. tables ==== */

.table {
    background: #fff;
    border-radius: var(--ui-r);
    overflow: hidden;
    border-collapse: separate;
    border-spacing: 0;
}

.table > thead > tr > th {
    background: linear-gradient(180deg, #FBFCFE 0%, #F4F7FB 100%) !important;
    border-bottom: 1px solid var(--brand-border) !important;
    color: var(--brand-navy);
    font-size: 11.5px;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    padding: 12px 14px;
    white-space: nowrap;
    position: sticky;
    top: var(--ui-bar-h);
    z-index: 2;
}

.table > tbody > tr > td {
    padding: 12px 14px;
    border-top: 1px solid #EEF2F7 !important;
    vertical-align: middle;
    color: var(--brand-text);
}

.table > tbody > tr {
    transition: background-color var(--ui-fast), box-shadow var(--ui-fast);
}

.table-hover > tbody > tr:hover,
.table > tbody > tr:hover {
    background: var(--brand-blue-faint) !important;
    box-shadow: inset 3px 0 0 var(--brand-blue);
}

.table-striped > tbody > tr:nth-of-type(odd) {
    background: #FBFCFE;
}

.table-responsive {
    border: 1px solid var(--brand-border);
    border-radius: var(--ui-r);
    box-shadow: var(--ui-e1);
    background: #fff;
}

/* ========================================================= 6. surfaces ==== */

.brand-card,
.panel,
.well {
    background: #fff;
    border: 1px solid var(--brand-border) !important;
    border-radius: var(--ui-r-lg) !important;
    box-shadow: var(--ui-e2) !important;
    transition: box-shadow var(--ui-mid), transform var(--ui-mid), border-color var(--ui-mid);
}

.brand-card:hover,
.panel:hover {
    box-shadow: var(--ui-e3) !important;
}

.panel-heading,
.brand-card-header {
    background: linear-gradient(180deg, #FFFFFF 0%, #FAFCFE 100%) !important;
    border-bottom: 1px solid var(--brand-border) !important;
    border-radius: var(--ui-r-lg) var(--ui-r-lg) 0 0 !important;
    padding: 16px 20px;
    font-size: 15px;
}

.panel-primary,
.panel-default { border-color: var(--brand-border) !important; }

.panel-primary > .panel-heading {
    background: linear-gradient(100deg, var(--brand-navy), #1B2A5E) !important;
    color: #fff;
    border-color: transparent !important;
}

.panel-body { padding: 20px; }

.well {
    padding: 18px 20px;
    background: #fff;
}

/* ========================================================= 7. overlays ==== */

.modal-backdrop.in {
    opacity: .45;
    background: #0A1330;
    backdrop-filter: blur(3px);
    -webkit-backdrop-filter: blur(3px);
}

.modal-content {
    border: 0;
    border-radius: var(--ui-r-lg);
    box-shadow: var(--ui-e4);
    overflow: hidden;
}

.modal-header {
    background: linear-gradient(180deg, #FFFFFF 0%, #F9FBFE 100%);
    border-bottom: 1px solid var(--brand-border);
    padding: 18px 22px;
}

.modal-title {
    font-family: var(--brand-font-head);
    color: var(--brand-navy);
    font-weight: 600;
}

.modal-body { padding: 22px; }

.modal-footer {
    background: #FBFCFE;
    border-top: 1px solid var(--brand-border);
    padding: 16px 22px;
}

.modal.fade .modal-dialog {
    transform: translateY(16px) scale(.98);
    transition: transform var(--ui-mid), opacity var(--ui-mid);
    opacity: 0;
}

.modal.in .modal-dialog {
    transform: translateY(0) scale(1);
    opacity: 1;
}

.modal-header .close {
    opacity: .5;
    font-size: 26px;
    text-shadow: none;
    transition: opacity var(--ui-fast), transform var(--ui-fast);
}

.modal-header .close:hover { opacity: 1; transform: rotate(90deg); }

.dropdown-menu {
    border: 1px solid var(--brand-border);
    border-radius: var(--ui-r);
    box-shadow: var(--ui-e3);
    padding: 6px;
    animation: uiPop var(--ui-mid) both;
}

.dropdown-menu > li > a {
    border-radius: var(--ui-r-sm);
    padding: 9px 12px;
    color: var(--brand-text);
    font-weight: 500;
    transition: background-color var(--ui-fast), color var(--ui-fast);
}

.dropdown-menu > li > a:hover {
    background: var(--brand-blue-faint);
    color: var(--brand-blue-dark);
}

.tooltip-inner {
    background: var(--brand-navy);
    border-radius: var(--ui-r-sm);
    padding: 7px 11px;
    font-size: 12.5px;
    box-shadow: var(--ui-e3);
}

.tooltip.top .tooltip-arrow { border-top-color: var(--brand-navy); }
.tooltip.bottom .tooltip-arrow { border-bottom-color: var(--brand-navy); }

/* ========================================================= 8. feedback ==== */

.alert {
    border-radius: var(--ui-r) !important;
    border: 1px solid transparent;
    border-left-width: 4px;
    padding: 14px 18px;
    box-shadow: var(--ui-e1);
    font-size: 14px;
}

.alert-info    { border-left-color: var(--brand-blue); }
.alert-success { border-left-color: var(--brand-success); }
.alert-warning { border-left-color: var(--brand-accent); }
.alert-danger  { border-left-color: var(--brand-danger); }

.badge,
.label {
    border-radius: var(--ui-r-pill);
    font-weight: 600;
    font-size: 11.5px;
    letter-spacing: .02em;
    padding: 4px 10px;
}

.label-success { background: var(--brand-success); }
.label-danger  { background: var(--brand-danger); }
.label-warning { background: var(--brand-accent); }
.label-info    { background: var(--brand-blue); }

.progress {
    height: 8px;
    border-radius: var(--ui-r-pill);
    background: #E9EEF6;
    box-shadow: none;
    overflow: hidden;
}

.progress-bar {
    background-image: linear-gradient(90deg, var(--brand-blue), #4FB0FF);
    box-shadow: none;
    transition: width var(--ui-mid);
}

/* ======================================================= 9. navigation ==== */

.breadcrumb {
    background: transparent;
    padding: 0 0 14px;
    margin-bottom: 18px;
    font-size: 13px;
    border-bottom: 1px solid var(--brand-border);
    border-radius: 0;
}

.breadcrumb > li + li::before {
    content: "›";
    color: var(--brand-border-strong);
    padding: 0 8px;
    font-size: 15px;
}

.breadcrumb a { color: var(--brand-text-muted); font-weight: 500; }
.breadcrumb a:hover { color: var(--brand-blue); }
.breadcrumb > .active { color: var(--brand-navy); font-weight: 600; }

.list-group-item {
    border-color: #EEF2F7;
    transition: background-color var(--ui-fast), box-shadow var(--ui-fast), padding-left var(--ui-fast);
}

.list-group-item:first-child { border-radius: var(--ui-r) var(--ui-r) 0 0; }
.list-group-item:last-child  { border-radius: 0 0 var(--ui-r) var(--ui-r); }

.list-group-item:hover {
    background: var(--brand-blue-faint);
}

.list-group-item.active,
.list-group-item.active:hover {
    background: var(--brand-blue) !important;
    border-color: var(--brand-blue) !important;
    box-shadow: inset 3px 0 0 var(--brand-navy);
}

.nav-tabs {
    border-bottom: 1px solid var(--brand-border);
}

.nav-tabs > li > a {
    border: 0;
    border-bottom: 2px solid transparent;
    border-radius: 0;
    color: var(--brand-text-muted);
    font-weight: 600;
    transition: color var(--ui-fast), border-color var(--ui-fast), background-color var(--ui-fast);
}

.nav-tabs > li > a:hover {
    background: var(--brand-blue-faint);
    border-bottom-color: var(--brand-border-strong);
}

.nav-tabs > li.active > a,
.nav-tabs > li.active > a:hover,
.nav-tabs > li.active > a:focus {
    border: 0;
    border-bottom: 2px solid var(--brand-blue);
    color: var(--brand-blue);
    background: transparent;
}

.pagination > li > a,
.pagination > li > span {
    border-color: var(--brand-border);
    color: var(--brand-blue);
    margin: 0 2px;
    border-radius: var(--ui-r-sm) !important;
    transition: background-color var(--ui-fast), color var(--ui-fast), transform var(--ui-fast);
}

.pagination > li > a:hover { background: var(--brand-blue-faint); transform: translateY(-1px); }

.pagination > .active > a,
.pagination > .active > span {
    background: var(--brand-blue) !important;
    border-color: var(--brand-blue) !important;
    box-shadow: 0 4px 12px -4px rgba(18, 118, 225, .6);
}

/* ========================================================== 10. loading ==== */

/* Top progress bar. Shown on navigation and on any AJAX that takes long
   enough to be worth mentioning - see ui.js. */
#ui-progress {
    position: fixed;
    top: 0; left: 0;
    height: 3px;
    width: 0;
    z-index: 2000;
    background: linear-gradient(90deg, var(--brand-blue), #4FB0FF 55%, var(--brand-accent));
    box-shadow: 0 0 12px rgba(18, 118, 225, .7);
    opacity: 0;
    transition: width 200ms ease-out, opacity 220ms ease-out;
    pointer-events: none;
}

#ui-progress.is-active { opacity: 1; }

/* The first-paint overlay. Removed as soon as the page is interactive, and
   also on a timer, so a slow script can never leave a reader looking at it. */
#ui-boot {
    position: fixed;
    inset: 0;
    z-index: 2100;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-direction: column;
    gap: 22px;
    background: linear-gradient(160deg, #0B1338, var(--brand-navy) 55%, #16265C);
    transition: opacity 420ms var(--ui-ease), visibility 420ms;
}

#ui-boot.is-done {
    opacity: 0;
    visibility: hidden;
}

#ui-boot .ui-boot-mark {
    width: 168px;
    animation: uiFloat 2.6s var(--ui-ease) infinite;
}

#ui-boot .ui-boot-track {
    width: 190px;
    height: 3px;
    border-radius: var(--ui-r-pill);
    background: rgba(255, 255, 255, .16);
    overflow: hidden;
}

#ui-boot .ui-boot-fill {
    display: block;
    height: 100%;
    width: 40%;
    border-radius: inherit;
    background: linear-gradient(90deg, transparent, #4FB0FF, var(--brand-accent), transparent);
    animation: uiSlide 1.15s ease-in-out infinite;
}

/* A button that is working says so, and stops taking clicks. */
.btn.is-loading {
    position: relative;
    color: transparent !important;
    pointer-events: none;
}

.btn.is-loading::after {
    content: "";
    position: absolute;
    top: 50%; left: 50%;
    width: 15px; height: 15px;
    margin: -8px 0 0 -8px;
    border: 2px solid rgba(255, 255, 255, .45);
    border-top-color: #fff;
    border-radius: 50%;
    animation: uiSpin .6s linear infinite;
}

.btn-default.is-loading::after,
.btn-secondary.is-loading::after {
    border-color: rgba(18, 118, 225, .3);
    border-top-color: var(--brand-blue);
}

/* Skeletons, for content that arrives after the page. */
.ui-skeleton {
    background: linear-gradient(90deg, #EDF1F7 25%, #F6F9FC 37%, #EDF1F7 63%);
    background-size: 400% 100%;
    animation: uiShimmer 1.3s ease-in-out infinite;
    border-radius: var(--ui-r-sm);
    min-height: 14px;
}

/* ================================================= 11. motion & utility ==== */

@keyframes uiSpin { to { transform: rotate(360deg); } }
@keyframes uiShimmer { 0% { background-position: 100% 50%; } 100% { background-position: 0 50%; } }
@keyframes uiSlide { 0% { transform: translateX(-120%); } 100% { transform: translateX(320%); } }
@keyframes uiFloat { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-7px); } }
@keyframes uiPop {
    from { opacity: 0; transform: translateY(-6px) scale(.985); }
    to   { opacity: 1; transform: translateY(0) scale(1); }
}
@keyframes uiRise {
    from { opacity: 0; transform: translateY(10px); }
    to   { opacity: 1; transform: translateY(0); }
}

/* Content settles in on load. Applied by ui.js to the main region only, so it
   never fights a view's own animation. */
.ui-rise { animation: uiRise 380ms var(--ui-ease) both; }

::-webkit-scrollbar { width: 11px; height: 11px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
    background: #C6D0DE;
    border-radius: var(--ui-r-pill);
    border: 3px solid var(--brand-canvas);
}
::-webkit-scrollbar-thumb:hover { background: #A9B7CA; }

/* ======================================================= 12. responsive ==== */

@media (max-width: 991px) {
    :root { --ui-bar-h: 60px; }
    .navbar-nav .brand-logo { width: 108px; }
    .table > thead > tr > th { position: static; }
}

@media (max-width: 767px) {
    .btn { padding: 9px 14px; }
    .panel-body, .modal-body { padding: 16px; }
    .table > tbody > tr > td,
    .table > thead > tr > th { padding: 10px; }
}

/* Anyone who asks for less movement gets none of it. */
@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: .001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .001ms !important;
    }
    .btn:hover { transform: none; }
}

/* ============================================================ 13. print ==== */

@media print {
    .navbar, #ui-progress, #ui-boot, .copilot-launcher, .copilot-panel,
    .nav-mobile-toggle, footer .tutorial {
        display: none !important;
    }
    body { padding-top: 0 !important; background: #fff !important; }
    .panel, .brand-card, .table-responsive { box-shadow: none !important; border-color: #ccc !important; }
}

/* ==========================================================================
   14. dashboard
   --------------------------------------------------------------------------
   The landing panel. It replaces a page that showed a logo and nothing else,
   so the priority is that every number is legible at a glance and that every
   one of them goes somewhere.
   ========================================================================== */

.dash {
    padding: 26px 30px 40px;
    max-width: 1180px;
    animation: uiRise 420ms var(--ui-ease) both;
}

.dash-hero {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 24px;
    flex-wrap: wrap;
    padding-bottom: 22px;
    margin-bottom: 24px;
    border-bottom: 1px solid var(--brand-border);
}

.dash-hello {
    margin: 0 0 2px;
    font-size: 13px;
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--brand-blue);
}

.dash-title {
    margin: 0;
    font-family: var(--brand-font-head);
    font-size: 34px;
    font-weight: 300;
    color: var(--brand-navy);
    letter-spacing: -.02em;
}

.dash-sub {
    margin: 6px 0 0;
    color: var(--brand-text-muted);
    font-size: 14px;
}

.dash-hero-actions { display: flex; gap: 10px; flex-shrink: 0; }

/* --- the four figures --- */

.dash-stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(212px, 1fr));
    gap: 16px;
    margin-bottom: 24px;
}

.dash-stat {
    position: relative;
    display: block;
    padding: 18px 20px 22px;
    background: #fff;
    border: 1px solid var(--brand-border);
    border-radius: var(--ui-r-lg);
    box-shadow: var(--ui-e1);
    text-decoration: none !important;
    overflow: hidden;
    transition: transform var(--ui-mid), box-shadow var(--ui-mid), border-color var(--ui-mid);
}

.dash-stat:hover {
    transform: translateY(-3px);
    box-shadow: var(--ui-e3);
    border-color: #C9DCF2;
}

.dash-stat-label {
    display: block;
    font-size: 11.5px;
    font-weight: 700;
    letter-spacing: .07em;
    text-transform: uppercase;
    color: var(--brand-text-muted);
}

.dash-stat-value {
    display: block;
    margin: 8px 0 4px;
    font-size: 40px;
    line-height: 1;
    font-weight: 600;
    color: var(--brand-navy);
    letter-spacing: -.03em;
    font-variant-numeric: tabular-nums;
}

.dash-stat-note {
    display: block;
    font-size: 12.5px;
    color: var(--brand-text-muted);
    line-height: 1.45;
}

.dash-stat-note .is-flagged {
    font-style: normal;
    font-weight: 600;
    color: var(--brand-accent-dark);
}

/* A quiet proportion bar along the bottom edge, rather than a chart nobody
   asked for. --fill is set per tile in the template. */
.dash-stat-bar {
    position: absolute;
    left: 0; right: 0; bottom: 0;
    height: 3px;
    background: #EEF2F7;
}

.dash-stat-bar::after {
    content: "";
    display: block;
    height: 100%;
    width: var(--fill, 0%);
    background: linear-gradient(90deg, var(--brand-blue), #4FB0FF);
    transition: width 700ms var(--ui-ease);
}

.dash-stat.is-attention .dash-stat-value { color: var(--brand-accent-dark); }
.dash-stat.is-attention .dash-stat-bar::after {
    background: linear-gradient(90deg, var(--brand-accent), #FFB27A);
}

/* --- the two lists --- */

.dash-columns {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
    gap: 16px;
    margin-bottom: 24px;
}

.dash-card {
    background: #fff;
    border: 1px solid var(--brand-border);
    border-radius: var(--ui-r-lg);
    box-shadow: var(--ui-e1);
    overflow: hidden;
}

.dash-card-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    padding: 16px 20px;
    border-bottom: 1px solid var(--brand-border);
    background: linear-gradient(180deg, #FFFFFF, #FAFCFE);
}

.dash-card-head h2 {
    margin: 0;
    font-family: var(--brand-font-head);
    font-size: 16px;
    font-weight: 600;
    color: var(--brand-navy);
}

.dash-card-note {
    font-size: 11.5px;
    color: var(--brand-text-muted);
    text-transform: uppercase;
    letter-spacing: .05em;
    font-weight: 600;
}

.dash-list { list-style: none; margin: 0; padding: 6px; }

.dash-list li {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 9px 12px;
    border-radius: var(--ui-r-sm);
    transition: background-color var(--ui-fast);
}

.dash-list li:hover { background: var(--brand-blue-faint); }

.dash-list li > a {
    flex: 1;
    min-width: 0;
    text-decoration: none !important;
}

.dash-list-main {
    display: block;
    font-weight: 600;
    font-size: 13.5px;
    color: var(--brand-navy);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.dash-list-sub {
    display: block;
    font-size: 12px;
    color: var(--brand-text-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.dash-list li > span.dash-list-main { flex: 1; min-width: 0; }

.dash-tag {
    flex-shrink: 0;
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: .05em;
    text-transform: uppercase;
    padding: 3px 9px;
    border-radius: var(--ui-r-pill);
}

.dash-tag.is-gxp  { background: #EFE8FC; color: #4B2E9E; }
.dash-tag.is-out  { background: #FFF1E6; color: #9A4E12; }
.dash-tag.is-back { background: #E7F5EE; color: #146340; }

.dash-more {
    display: block;
    padding: 11px 18px;
    border-top: 1px solid var(--brand-border);
    font-size: 12.5px;
    font-weight: 600;
    color: var(--brand-blue);
    text-decoration: none !important;
    transition: background-color var(--ui-fast);
}

.dash-more:hover { background: var(--brand-blue-faint); }

.dash-none {
    padding: 26px 20px;
    text-align: center;
    color: var(--brand-text-muted);
    font-size: 13.5px;
}

.dash-none .glyphicon {
    display: block;
    font-size: 22px;
    margin-bottom: 8px;
    color: var(--brand-success);
    opacity: .8;
}

/* --- what to do next --- */

.dash-actions {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
    gap: 12px;
}

.dash-action {
    display: flex;
    align-items: flex-start;
    gap: 13px;
    padding: 16px 18px;
    background: #fff;
    border: 1px solid var(--brand-border);
    border-radius: var(--ui-r-lg);
    text-decoration: none !important;
    transition: transform var(--ui-mid), box-shadow var(--ui-mid), border-color var(--ui-mid);
}

.dash-action:hover {
    transform: translateY(-2px);
    box-shadow: var(--ui-e2);
    border-color: #C9DCF2;
}

.dash-action-icon {
    flex-shrink: 0;
    width: 36px; height: 36px;
    display: flex; align-items: center; justify-content: center;
    border-radius: var(--ui-r);
    background: var(--brand-surface);
    color: var(--brand-blue);
    font-size: 15px;
}

.dash-action-text { font-size: 12.5px; color: var(--brand-text-muted); line-height: 1.45; }
.dash-action-text strong {
    display: block;
    font-size: 14px;
    color: var(--brand-navy);
    margin-bottom: 2px;
}

/* --- a reader who belongs to no lab --- */

.dash-empty {
    text-align: center;
    padding: 54px 30px;
    background: #fff;
    border: 1px solid var(--brand-border);
    border-radius: var(--ui-r-lg);
    box-shadow: var(--ui-e1);
}

.dash-empty-mark {
    width: 56px; height: 56px;
    margin: 0 auto 18px;
    display: flex; align-items: center; justify-content: center;
    border-radius: 50%;
    background: var(--brand-surface);
    color: var(--brand-blue);
    font-size: 22px;
}

.dash-empty h2 {
    margin: 0 0 10px;
    font-family: var(--brand-font-head);
    font-size: 21px;
    color: var(--brand-navy);
}

.dash-empty p { max-width: 460px; margin: 0 auto 10px; color: var(--brand-text-muted); }
.dash-empty-who { font-size: 13px; }
.dash-empty .btn { margin-top: 14px; }

@media (max-width: 767px) {
    .dash { padding: 18px 16px 30px; }
    .dash-title { font-size: 26px; }
    .dash-stat-value { font-size: 32px; }
    .dash-hero { align-items: flex-start; }
}

/* ==========================================================================
   15. command palette
   --------------------------------------------------------------------------
   Ctrl+K. The fastest route to an item, a lab or a page, so nobody has to
   learn where things live in the menus.
   ========================================================================== */

.cmdk {
    position: fixed;
    inset: 0;
    z-index: 1900;
    display: flex;
    align-items: flex-start;
    justify-content: center;
    padding: 12vh 16px 16px;
    background: rgba(10, 19, 48, .46);
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
    animation: uiFade 160ms var(--ui-ease) both;
}

.cmdk[hidden] { display: none; }

@keyframes uiFade { from { opacity: 0; } to { opacity: 1; } }

.cmdk-panel {
    width: 100%;
    max-width: 620px;
    background: #fff;
    border-radius: var(--ui-r-lg);
    box-shadow: var(--ui-e4);
    overflow: hidden;
    display: flex;
    flex-direction: column;
    max-height: 72vh;
    animation: uiPop 200ms var(--ui-ease) both;
}

.cmdk-head {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 14px 16px;
    border-bottom: 1px solid var(--brand-border);
}

.cmdk-input {
    flex: 1;
    border: 0;
    outline: none;
    font: inherit;
    font-size: 16px;
    color: var(--brand-ink);
    background: transparent;
}

.cmdk-input::placeholder { color: #97A2B4; }

.cmdk-esc {
    flex-shrink: 0;
    font-size: 11px;
    font-family: inherit;
    font-weight: 600;
    color: var(--brand-text-muted);
    background: var(--brand-canvas);
    border: 1px solid var(--brand-border);
    border-radius: var(--ui-r-sm);
    padding: 3px 7px;
    box-shadow: none;
}

.cmdk-list { overflow-y: auto; padding: 6px; }

.cmdk-group {
    padding: 10px 12px 5px;
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--brand-text-muted);
}

.cmdk-row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 14px;
    padding: 10px 12px;
    border-radius: var(--ui-r-sm);
    text-decoration: none !important;
    color: inherit;
    cursor: pointer;
}

.cmdk-row.is-active { background: var(--brand-blue); }
.cmdk-row.is-active .cmdk-row-label,
.cmdk-row.is-active .cmdk-row-hint { color: #fff; }

.cmdk-row-label {
    font-weight: 600;
    font-size: 14px;
    color: var(--brand-navy);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.cmdk-row-hint {
    flex-shrink: 0;
    font-size: 12px;
    color: var(--brand-text-muted);
    max-width: 48%;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.cmdk-empty,
.cmdk-pending {
    margin: 0;
    padding: 22px 16px;
    text-align: center;
    color: var(--brand-text-muted);
    font-size: 13.5px;
}

.cmdk-pending { padding: 12px; font-size: 12.5px; }

.cmdk-foot {
    padding: 10px 16px;
    border-top: 1px solid var(--brand-border);
    background: #FBFCFE;
    font-size: 11.5px;
    color: var(--brand-text-muted);
}

/* The trigger in the app bar. It is drawn as a search box - wide, with a
   prompt saying what it finds - and sits straight after the logo where people
   look for one; the page links keep to the right. A small "Search" pill among
   the links read as a button and was mistaken for a second, different search. */
.navbar-nav .nav-group-2 {
    flex: 1 1 auto;
    justify-content: flex-end;
    min-width: 0;
}

.cmdk-trigger {
    display: flex;
    align-items: center;
    gap: 10px;
    width: clamp(300px, 34vw, 520px);
    min-width: 0;
    margin: 0 auto 0 28px;
    padding: 9px 9px 9px 15px;
    border-radius: var(--ui-r-pill);
    border: 1px solid rgba(255, 255, 255, .18);
    background: rgba(255, 255, 255, .08);
    color: rgba(255, 255, 255, .72) !important;
    font-size: 13.5px;
    cursor: text;
    transition: background-color var(--ui-fast), border-color var(--ui-fast), color var(--ui-fast);
    align-self: center;
}

.cmdk-trigger:hover,
.cmdk-trigger:focus-visible {
    background: rgba(255, 255, 255, .15);
    border-color: rgba(255, 255, 255, .34);
    color: #fff !important;
}

.cmdk-trigger-text {
    flex: 1 1 auto;
    min-width: 0;
    text-align: left;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.cmdk-trigger kbd {
    flex: none;
    font-family: inherit;
    font-size: 10.5px;
    font-weight: 700;
    background: rgba(255, 255, 255, .16);
    border: 0;
    border-radius: 999px;
    padding: 3px 8px;
    color: inherit;
    box-shadow: none;
}

.cmdk-trigger::after { display: none !important; }

/* The box takes whatever room is spare; when there is none, this keeps it
   from running into the first link. */
.cmdk-trigger + * { margin-left: 20px; }

@media (max-width: 1199px) {
    .cmdk-trigger { width: clamp(220px, 26vw, 300px); margin-left: 18px; }
    .cmdk-trigger-more { display: none; }
}

@media (max-width: 991px) {
    .cmdk-trigger-text, .cmdk-trigger kbd { display: none; }
    .cmdk-trigger { width: auto; padding: 8px 10px; margin-left: 12px; cursor: pointer; }
}

/* In the folded-out mobile menu the box takes the full row again. */
@media (max-width: 768px) {
    .cmdk-trigger { width: auto; margin: 10px 12px; padding: 10px 14px; }
    .cmdk-trigger-text { display: block; }
    .cmdk-trigger-more { display: inline; }
    .cmdk-trigger + * { margin-left: 0; }
}

@media (max-width: 575px) {
    .cmdk { padding: 8vh 10px 10px; }
    .cmdk-row-hint { display: none; }
}

/* ==========================================================================
   16. empty states
   --------------------------------------------------------------------------
   A panel with nothing in it yet should say what it is for and offer the next
   step, rather than leaving somebody to work out what to click.
   ========================================================================== */

.panel-hint {
    padding: 30px 22px;
    text-align: center;
}

.panel-hint-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px; height: 44px;
    margin-bottom: 14px;
    border-radius: 50%;
    background: var(--brand-surface);
    color: var(--brand-blue);
    font-size: 17px;
}

.panel-hint-lead {
    margin: 0 0 6px;
    font-family: var(--brand-font-head);
    font-size: 15px;
    font-weight: 600;
    color: var(--brand-navy);
}

.panel-hint-body {
    margin: 0 auto 16px;
    max-width: 260px;
    font-size: 13px;
    line-height: 1.55;
    color: var(--brand-text-muted);
}

/* ==========================================================================
   17. icons
   --------------------------------------------------------------------------
   Bootstrap 3 glyphicons are a 2013 icon font and they are the single thing
   that most dates this interface. Replacing them in 40-odd templates would
   mean editing every one, so instead each glyph is swapped for a modern
   stroked icon here: the class keeps its name, the font is dropped, and the
   shape is painted as a mask in the current text colour.

   Masked rather than a background image, so an icon inherits colour from its
   button or link exactly as the font did, and stays crisp at any size.
   ========================================================================== */

.glyphicon {
    font-family: inherit !important;
    position: relative;
    top: 0;
    display: inline-block;
    width: 1em;
    height: 1em;
    vertical-align: -0.145em;
}

.glyphicon::before {
    content: "" !important;
    display: block;
    width: 100%;
    height: 100%;
    background-color: currentColor;
    -webkit-mask: var(--icon) center / contain no-repeat;
    mask: var(--icon) center / contain no-repeat;
}

/* Anything without a mapping below keeps a neutral dot rather than a box of
   tofu, so an unmapped glyph degrades quietly. */
.glyphicon { --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='12' cy='12' r='2.5'/%3E%3C/svg%3E"); }

.glyphicon-search    { --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='M20.5 20.5 16.7 16.7'/%3E%3C/svg%3E"); }
.glyphicon-plus      { --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='M12 5v14M5 12h14'/%3E%3C/svg%3E"); }
.glyphicon-minus     { --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='M5 12h14'/%3E%3C/svg%3E"); }
.glyphicon-remove    { --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='M6 6l12 12M18 6L6 18'/%3E%3C/svg%3E"); }
.glyphicon-ok,
.glyphicon-check     { --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E"); }
.glyphicon-ok-circle { --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='9'/%3E%3Cpath d='M8.5 12.3l2.4 2.4 4.6-4.9'/%3E%3C/svg%3E"); }
.glyphicon-trash     { --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 7h16M10 7V5h4v2M9 11v6M15 11v6M6 7l1 13h10l1-13'/%3E%3C/svg%3E"); }
.glyphicon-pencil,
.glyphicon-edit      { --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 20h4L20.5 7.5a2.1 2.1 0 0 0-3-3L5 17v3z'/%3E%3C/svg%3E"); }
.glyphicon-user      { --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='8' r='3.6'/%3E%3Cpath d='M4.5 20c.9-3.6 3.9-5.4 7.5-5.4s6.6 1.8 7.5 5.4'/%3E%3C/svg%3E"); }
.glyphicon-transfer  { --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 8h13M14 5l3 3-3 3M20 16H7M10 13l-3 3 3 3'/%3E%3C/svg%3E"); }
.glyphicon-map-marker{ --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 21s6.5-5.9 6.5-11.2A6.5 6.5 0 0 0 5.5 9.8C5.5 15.1 12 21 12 21z'/%3E%3Ccircle cx='12' cy='9.8' r='2.3'/%3E%3C/svg%3E"); }
.glyphicon-log-in    { --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M14 4h4a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2h-4M10 16l4-4-4-4M14 12H4'/%3E%3C/svg%3E"); }
.glyphicon-log-out,
.glyphicon-off       { --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M10 4H6a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h4M17 16l4-4-4-4M21 12H10'/%3E%3C/svg%3E"); }
.glyphicon-chevron-right { --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9.5 5.5 16 12l-6.5 6.5'/%3E%3C/svg%3E"); }
.glyphicon-chevron-down  { --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5.5 9.5 12 16l6.5-6.5'/%3E%3C/svg%3E"); }
.glyphicon-chevron-left  { --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M14.5 5.5 8 12l6.5 6.5'/%3E%3C/svg%3E"); }
.glyphicon-chevron-up    { --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5.5 14.5 12 8l6.5 6.5'/%3E%3C/svg%3E"); }
.glyphicon-warning-sign  { --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 4 2.8 20h18.4L12 4z'/%3E%3Cpath d='M12 10v4'/%3E%3Ccircle cx='12' cy='17' r='.6' fill='%23000'/%3E%3C/svg%3E"); }
.glyphicon-info-sign     { --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='9'/%3E%3Cpath d='M12 11v5'/%3E%3Ccircle cx='12' cy='8' r='.7' fill='%23000'/%3E%3C/svg%3E"); }
.glyphicon-th-list,
.glyphicon-list          { --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='M9 6h11M9 12h11M9 18h11'/%3E%3Ccircle cx='4.5' cy='6' r='1.3' fill='%23000'/%3E%3Ccircle cx='4.5' cy='12' r='1.3' fill='%23000'/%3E%3Ccircle cx='4.5' cy='18' r='1.3' fill='%23000'/%3E%3C/svg%3E"); }
.glyphicon-stats         { --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='M5 19V11M12 19V5M19 19v-6'/%3E%3C/svg%3E"); }
.glyphicon-star          { --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.9' stroke-linejoin='round'%3E%3Cpath d='M12 3.5l2.7 5.6 6.1.8-4.4 4.3 1.1 6.1L12 17.4 6.5 20.3l1.1-6.1L3.2 9.9l6.1-.8L12 3.5z'/%3E%3C/svg%3E"); }
.glyphicon-refresh       { --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 12a8 8 0 1 1-2.6-5.9'/%3E%3Cpath d='M20 4v4.5h-4.5'/%3E%3C/svg%3E"); }
.glyphicon-print         { --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M7 9V4h10v5M7 18H5a2 2 0 0 1-2-2v-4a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v4a2 2 0 0 1-2 2h-2'/%3E%3Cpath d='M7 15h10v5H7z'/%3E%3C/svg%3E"); }
.glyphicon-lock          { --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='4.5' y='10.5' width='15' height='9.5' rx='2'/%3E%3Cpath d='M8 10.5V8a4 4 0 0 1 8 0v2.5'/%3E%3C/svg%3E"); }
.glyphicon-inbox         { --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3.5 13.5 6 5h12l2.5 8.5v5a1.5 1.5 0 0 1-1.5 1.5H5a1.5 1.5 0 0 1-1.5-1.5v-5z'/%3E%3Cpath d='M3.5 13.5H9l1 2.5h4l1-2.5h5.5'/%3E%3C/svg%3E"); }
.glyphicon-download-alt,
.glyphicon-export,
.glyphicon-save          { --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 4v10M8 10.5l4 3.5 4-3.5M4 18.5h16'/%3E%3C/svg%3E"); }
.glyphicon-calendar      { --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3.5' y='5.5' width='17' height='15' rx='2'/%3E%3Cpath d='M3.5 10h17M8 3.5v4M16 3.5v4'/%3E%3C/svg%3E"); }
.glyphicon-home          { --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 11l8-6.5 8 6.5M6.5 9.8V20h11V9.8'/%3E%3C/svg%3E"); }
.glyphicon-cog,
.glyphicon-wrench        { --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='3'/%3E%3Cpath d='M12 3v2.2M12 18.8V21M21 12h-2.2M5.2 12H3M18.4 5.6l-1.6 1.6M7.2 16.8l-1.6 1.6M18.4 18.4l-1.6-1.6M7.2 7.2 5.6 5.6'/%3E%3C/svg%3E"); }
.glyphicon-question-sign { --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='9'/%3E%3Cpath d='M9.6 9.3a2.5 2.5 0 1 1 3.3 2.4c-.6.2-.9.8-.9 1.4v.4'/%3E%3Ccircle cx='12' cy='16.6' r='.7' fill='%23000'/%3E%3C/svg%3E"); }

/* ==========================================================================
   18. the record form
   --------------------------------------------------------------------------
   .show-form carried "max-width: 600px; float: right", which stranded a
   38-field form in the right third of a 1555px panel and left the rest of the
   screen blank. It now fills the column and lays its fields out in as many
   readable columns as the width allows.
   ========================================================================== */

.show-form {
    float: none !important;
    max-width: none !important;
    width: 100%;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
    gap: 2px 26px;
    align-items: start;
    padding: 4px 26px 26px;
}

/* Each field is a grid cell, so the Bootstrap columns inside it - which put
   the label in a third of the width and wrapped "Serial Number" onto two
   lines - are flattened. The cell already provides the column. */
.show-form .form-group > .col-sm-4,
.show-form .form-group > .col-sm-6,
.show-form .form-group > .col-sm-12,
.show-form .form-group > .control-label {
    width: 100% !important;
    float: none !important;
    padding-left: 0 !important;
    padding-right: 0 !important;
    text-align: left !important;
}

.show-form .form-group label,
.show-form .form-group .control-label label {
    display: block;
    margin-bottom: 5px;
    font-size: 12.5px;
    font-weight: 600;
    line-height: 1.35;
    color: var(--brand-navy);
    white-space: normal;
}

/* A checkbox reads as one line, not a label stacked over a box. */
.show-form .form-group .checkbox label,
.show-form .form-group label.checkbox-inline {
    display: flex;
    align-items: center;
    gap: 8px;
    font-weight: 500;
    color: var(--brand-text);
    margin-bottom: 0;
}

/* Headings, rules and anything wide take the full row. */
.show-form > h4,
.show-form > h3,
.show-form > hr,
.show-form > .alert,
.show-form > .form-actions,
.show-form > .full-width {
    grid-column: 1 / -1;
}

.show-form > h4 {
    margin: 26px 0 6px;
    padding-bottom: 10px;
    border-bottom: 1px solid var(--brand-border);
    font-family: var(--brand-font-head);
    font-size: 15px;
    font-weight: 600;
    color: var(--brand-navy);
    letter-spacing: .01em;
}

.show-form > h4:first-of-type { margin-top: 8px; }

/* A long free-text field is easier to read across the whole row. */
.show-form .form-group:has(textarea) { grid-column: 1 / -1; }

.show-form .form-group { margin-bottom: 14px; }

.show-form .form-group > label,
.show-form > label {
    display: block;
    margin-bottom: 5px;
    font-size: 12.5px;
    font-weight: 600;
    color: var(--brand-navy);
}

/* The grid supplies the columns, so Bootstrap's own column widths inside the
   form would fight it. */
.show-form > .col-sm-4,
.show-form > .col-sm-6,
.show-form > .col-sm-12,
.show-form .form-group[class*="col-sm-"] {
    width: auto;
    float: none;
    padding-left: 0;
    padding-right: 0;
}

/* The panel this sits in should breathe. */
#equipment_info_inner { padding-bottom: 20px; }


/* ==========================================================================
   19. the account menu
   --------------------------------------------------------------------------
   This was a plain white box of underlined capitals. It is now a proper menu:
   sentence case, an icon per row, the destructive item set apart at the foot.
   Icons are attached by href, so no template changes were needed.
   ========================================================================== */

.navbar-nav .dropdown-toggle {
    display: flex;
    align-items: center;
    gap: 8px;
}

.navbar-nav .dropdown-toggle .caret {
    border-top-color: currentColor;
    opacity: .65;
    margin-left: 2px;
    transition: transform var(--ui-fast);
}

.navbar-nav .open > .dropdown-toggle .caret { transform: rotate(180deg); }

.navbar-nav .open > .dropdown-toggle {
    background: rgba(255, 255, 255, .1) !important;
    color: #fff !important;
}

.navbar-nav .dropdown-menu {
    min-width: 262px;
    padding: 7px;
    border: 1px solid var(--brand-border);
    border-radius: var(--ui-r-lg);
    box-shadow: var(--ui-e4);
    margin-top: 10px;
    /* This is the last thing in the bar, so it hangs from the right edge;
       left-aligned it ran off the side of the window. */
    left: auto;
    right: 0;
}

/* Bootstrap 3 draws a rule between items; a modern menu uses spacing. */
.navbar-nav .dropdown-menu > li { border: 0 !important; }
.navbar-nav .dropdown-menu > li + li > a { border-top: 0 !important; }

.navbar-nav .dropdown-menu li a {
    display: flex !important;
    align-items: center;
    gap: 11px;
    padding: 10px 12px !important;
    border: 0 !important;
    border-radius: var(--ui-r) !important;
    font-size: 13.5px;
    font-weight: 500;
    text-transform: none !important;
    letter-spacing: 0 !important;
    text-align: left;
    color: var(--brand-text) !important;
    white-space: nowrap;
}

.navbar-nav .dropdown-menu li a::before {
    content: "";
    flex-shrink: 0;
    width: 17px;
    height: 17px;
    background-color: var(--brand-text-muted);
    -webkit-mask: var(--icon, none) center / contain no-repeat;
    mask: var(--icon, none) center / contain no-repeat;
    transition: background-color var(--ui-fast);
}

.navbar-nav .dropdown-menu li a:hover {
    background: var(--brand-blue-faint) !important;
    color: var(--brand-blue-dark) !important;
}

.navbar-nav .dropdown-menu li a:hover::before { background-color: var(--brand-blue); }

/* One icon per destination. */
.navbar-nav .dropdown-menu a[href$="/profile"]      { --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='8' r='3.6'/%3E%3Cpath d='M4.5 20c.9-3.6 3.9-5.4 7.5-5.4s6.6 1.8 7.5 5.4'/%3E%3C/svg%3E"); }
.navbar-nav .dropdown-menu a[href$="/admin/app"]    { --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='3'/%3E%3Cpath d='M12 3v2.2M12 18.8V21M21 12h-2.2M5.2 12H3M18.4 5.6l-1.6 1.6M7.2 16.8l-1.6 1.6M18.4 18.4l-1.6-1.6M7.2 7.2 5.6 5.6'/%3E%3C/svg%3E"); }
.navbar-nav .dropdown-menu a[href$="/admin/lab"]    { --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 11l8-6.5 8 6.5M6.5 9.8V20h11V9.8'/%3E%3C/svg%3E"); }
.navbar-nav .dropdown-menu a[href$="/admin/lend"]   { --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 8h13M14 5l3 3-3 3M20 16H7M10 13l-3 3 3 3'/%3E%3C/svg%3E"); }
.navbar-nav .dropdown-menu a[href$="/reviewtotal"]  { --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='M5 19V11M12 19V5M19 19v-6'/%3E%3C/svg%3E"); }

/* Signing out is the one thing here you cannot undo with a click, so it is
   separated and coloured as the exit. */
.navbar-nav .dropdown-menu a[href$="/auth/logout"],
.navbar-nav .dropdown-menu a[href$="/logout"] {
    --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M10 4H6a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h4M17 16l4-4-4-4M21 12H10'/%3E%3C/svg%3E");
    margin-top: 6px;
    padding-top: 13px !important;
    border-top: 1px solid var(--brand-border) !important;
    border-radius: 0 0 var(--ui-r) var(--ui-r) !important;
    color: var(--brand-danger) !important;
}

.navbar-nav .dropdown-menu a[href$="/auth/logout"]:hover,
.navbar-nav .dropdown-menu a[href$="/logout"]:hover {
    background: #FDECEC !important;
    color: #8E1F1F !important;
}

.navbar-nav .dropdown-menu a[href$="/auth/logout"]::before,
.navbar-nav .dropdown-menu a[href$="/logout"]::before { background-color: var(--brand-danger); }

/* The signed-in person, as initials on a disc. */
.navbar-nav .user-avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
    width: 30px;
    height: 30px;
    margin-right: 8px;
    border-radius: 50%;
    background: linear-gradient(135deg, var(--brand-blue) 0%, #37A0F5 100%);
    box-shadow: 0 0 0 2px rgba(255, 255, 255, .22);
    color: #fff;
    font-size: 11.5px;
    font-weight: 700;
    letter-spacing: .04em;
    line-height: 1;
    vertical-align: middle;
}


/* ==========================================================================
   20. the lab tree
   --------------------------------------------------------------------------
   Three levels of building, floor and lab in one column. The level somebody
   is on should be obvious without reading it.
   ========================================================================== */

.sidebar .first-part,
.sidebar .last-part {
    background: #fff;
}

.first-panel-header,
.second-panel-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 15px 16px !important;
    background: linear-gradient(180deg, #FFFFFF, #FAFCFE) !important;
    border-bottom: 1px solid var(--brand-border) !important;
}

.first-panel-header h4,
.second-panel-header h4 {
    margin: 0 !important;
    font-family: var(--brand-font-head);
    font-size: 14px !important;
    font-weight: 600 !important;
    color: var(--brand-navy) !important;
    letter-spacing: .01em;
}

.sidebar .list-group-item {
    border: 0 !important;
    border-bottom: 1px solid #F1F5F9 !important;
    padding: 10px 16px !important;
    font-size: 13.5px;
    color: var(--brand-text) !important;
    background: transparent !important;
    transition: background-color var(--ui-fast), color var(--ui-fast),
                box-shadow var(--ui-fast);
}

.sidebar .list-group-item:hover {
    background: var(--brand-blue-faint) !important;
    color: var(--brand-blue-dark) !important;
}

/* The chosen lab, and the chosen item, marked with a rail rather than a
   full-width block of colour. */
.sidebar .list-group-item.active,
.sidebar .list-group-item.active:hover,
.sidebar .item.active,
.sidebar .lab_number.active {
    background: var(--brand-surface) !important;
    color: var(--brand-navy) !important;
    font-weight: 600;
    box-shadow: inset 3px 0 0 var(--brand-blue);
    border-radius: 0 !important;
}

.sidebar .list-group-item.disabled,
.sidebar .list-group-item.disabled:hover {
    color: #A6B0BF !important;
    background: transparent !important;
    box-shadow: none;
}

/* The expand arrow rotates instead of swapping glyph. */
.sidebar .list-group-item .glyphicon-chevron-right,
.sidebar .list-group-item .glyphicon-chevron-down {
    margin-right: 8px;
    font-size: 11px;
    color: var(--brand-text-muted);
    transition: transform var(--ui-mid);
}

/* No rotation here: ajax.js swaps the class to chevron-down on click and
   that glyph already points down. Rotating it as well is what made an
   expanded section show a left-pointing arrow. */

/* Depth, shown by indent rather than left to chance. */
.sidebar .list-group .list-group .list-group-item { padding-left: 30px !important; }
.sidebar .list-group .list-group .list-group .list-group-item { padding-left: 44px !important; }

/* ==========================================================================
   21. the lab navigator
   --------------------------------------------------------------------------
   Replaces a Bootstrap 3 list-group accordion of plain rows. The tree is the
   right shape for the estate; what it lacked was a way to find a lab without
   already knowing which building and floor it is on, and any sense of where
   the equipment actually is.
   ========================================================================== */

.navtree {
    display: flex;
    flex-direction: column;
    height: 100%;
    min-height: 0;
    background: #fff;
}

/* --- filter --- */

.navtree-filter {
    position: relative;
    display: flex;
    align-items: center;
    padding: 10px 12px;
    border-bottom: 1px solid var(--brand-border);
    background: #fff;
    flex-shrink: 0;
}

.navtree-filter-icon {
    position: absolute;
    left: 23px;
    /* Without this the icon sits at the top of the padded container, above
       the input, instead of inside it. */
    top: 50%;
    transform: translateY(-50%);
    font-size: 13px;
    line-height: 1;
    color: var(--brand-text-muted);
    pointer-events: none;
    z-index: 1;
}

.navtree-filter-input {
    width: 100%;
    padding: 8px 30px 8px 32px;
    font-size: 13px;
    color: var(--brand-ink);
    background: var(--brand-canvas);
    border: 1px solid transparent;
    border-radius: var(--ui-r-pill);
    outline: none;
    transition: background-color var(--ui-fast), border-color var(--ui-fast), box-shadow var(--ui-mid);
}

.navtree-filter-input:focus {
    background: #fff;
    border-color: var(--brand-blue);
    box-shadow: var(--ui-ring);
}

.navtree-filter-input::placeholder { color: #9AA5B5; }

.navtree-filter-clear {
    position: absolute;
    right: 20px;
    width: 20px; height: 20px;
    display: flex; align-items: center; justify-content: center;
    border: 0;
    border-radius: 50%;
    background: var(--brand-border);
    color: var(--brand-text);
    font-size: 15px;
    line-height: 1;
    cursor: pointer;
    padding: 0;
}

.navtree-filter-clear:hover { background: var(--brand-border-strong); }

.navtree-scroll {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    margin: 0 !important;
    padding: 6px !important;
    background: transparent !important;
    border: 0 !important;
    box-shadow: none !important;
}

/* --- rows --- */

.navtree .list-group-item {
    display: flex !important;
    align-items: center;
    gap: 9px;
    border: 0 !important;
    border-radius: var(--ui-r-sm) !important;
    padding: 8px 10px !important;
    margin: 1px 0;
    background: transparent !important;
    color: var(--brand-text) !important;
    font-size: 13.5px;
    line-height: 1.35;
    transition: background-color var(--ui-fast), color var(--ui-fast);
}

.navtree .list-group-item:hover { background: var(--brand-blue-faint) !important; }

.navtree-label {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Building and floor read as structure, not as destinations. */
.navtree-building {
    font-weight: 600;
    color: var(--brand-navy) !important;
    font-size: 13px !important;
    letter-spacing: .01em;
}

.navtree-floor {
    font-size: 12.5px !important;
    color: var(--brand-text-muted) !important;
    font-weight: 500;
}

.navtree-caret {
    flex-shrink: 0;
    width: 12px; height: 12px;
    font-size: 12px;
    color: var(--brand-border-strong);
    transition: transform var(--ui-mid);
}

/* is-open is set from the panel's own state by the tree's script; Bootstrap's
   .collapsed class lies here because the remembered lab is opened by adding
   .in directly to the panel, which never updates the trigger. */
.navtree-building.is-open > .glyphicon-chevron-right,
.navtree-floor.is-open > .glyphicon-chevron-right { transform: rotate(90deg); }

/* And never rotate the down glyph, whichever route opened the section. */
.navtree-caret.glyphicon-chevron-down { transform: none !important; }

/* The lab itself: room number, then name, then how much is in it. */
.navtree-lab { padding-left: 30px !important; }

.navtree-room {
    flex-shrink: 0;
    font-variant-numeric: tabular-nums;
    font-size: 11.5px;
    font-weight: 600;
    color: var(--brand-text-muted);
    background: var(--brand-canvas);
    border-radius: 4px;
    padding: 2px 6px;
}

.navtree-count {
    flex-shrink: 0;
    min-width: 24px;
    text-align: center;
    font-size: 11px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    color: var(--brand-text-muted);
    background: var(--brand-canvas);
    border-radius: var(--ui-r-pill);
    padding: 2px 7px;
}

.navtree-count.is-empty { opacity: .55; }

.navtree-badge {
    flex-shrink: 0;
    font-size: 9.5px;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--brand-blue-dark);
    background: var(--brand-surface);
    border-radius: var(--ui-r-pill);
    padding: 2px 7px;
}

/* The lab being looked at. A rail and a tint, not a slab of blue. */
.navtree .list-group-item.active,
.navtree .list-group-item.active:hover {
    background: var(--brand-surface) !important;
    color: var(--brand-navy) !important;
    font-weight: 600;
    box-shadow: inset 3px 0 0 var(--brand-blue);
}

.navtree .list-group-item.active .navtree-count,
.navtree .list-group-item.active .navtree-room {
    background: #fff;
    color: var(--brand-blue-dark);
}

/* An empty lab is shown, not hidden: knowing a lab has nothing in it is
   information. It simply cannot be opened. */
.navtree .list-group-item.disabled,
.navtree .list-group-item.disabled:hover {
    color: #A6B0BF !important;
    background: transparent !important;
    cursor: not-allowed;
    box-shadow: none;
}

.navtree .list-group-item.disabled .navtree-room { opacity: .6; }

.navtree-lab.is-offsite {
    padding-left: 10px !important;
    margin-top: 6px;
    border-top: 1px solid var(--brand-border) !important;
    border-radius: 0 !important;
    padding-top: 12px !important;
    color: var(--brand-text-muted) !important;
}

/* While filtering, matching labs are revealed wherever they sit. */
.navtree-scroll .list-group.collapse.is-forced {
    display: block !important;
    height: auto !important;
}

.navtree-none {
    margin: 0;
    padding: 20px 16px;
    text-align: center;
    font-size: 13px;
    color: var(--brand-text-muted);
}

/* The panel header above the tree. */
.first-panel-header,
.second-panel-header {
    border-radius: 0 !important;
}

/* [hidden] must win over any display we set above. */
[hidden] { display: none !important; }

/* ==========================================================================
   22. sign in
   --------------------------------------------------------------------------
   A screen of its own rather than a panel inside the application chrome.
   ========================================================================== */

.signin {
    position: fixed;
    inset: 0;
    z-index: 1200;
    display: grid;
    grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
    background: #fff;
}

/* The bar and the page footer are not part of signing in. */
body:has(.signin) .navbar,
body:has(.signin) footer,
body:has(.signin) .copilot-launcher { display: none !important; }

body:has(.signin) { padding-top: 0 !important; overflow: hidden; }

/* --- brand side --- */

.signin-brand {
    position: relative;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    padding: 56px 56px 32px;
    overflow: hidden;
    background:
        radial-gradient(760px 420px at 18% 12%, rgba(18, 118, 225, .35), transparent 62%),
        radial-gradient(640px 420px at 88% 88%, rgba(254, 125, 52, .22), transparent 60%),
        linear-gradient(150deg, #0A1230 0%, var(--brand-navy) 52%, #172A63 100%);
    color: #fff;
}

/* A faint grid, so the panel reads as a surface rather than a gradient. */
.signin-brand::before {
    content: "";
    position: absolute;
    inset: 0;
    background-image:
        linear-gradient(rgba(255, 255, 255, .05) 1px, transparent 1px),
        linear-gradient(90deg, rgba(255, 255, 255, .05) 1px, transparent 1px);
    background-size: 46px 46px;
    mask-image: radial-gradient(circle at 30% 30%, #000, transparent 78%);
    -webkit-mask-image: radial-gradient(circle at 30% 30%, #000, transparent 78%);
    pointer-events: none;
}

.signin-brand-inner { position: relative; max-width: 460px; }

.signin-logo { width: 186px; margin-bottom: 44px; }

.signin-headline {
    margin: 0 0 14px;
    font-family: var(--brand-font-head);
    font-size: 40px;
    line-height: 1.12;
    font-weight: 300;
    letter-spacing: -.02em;
    color: #fff;
}

.signin-blurb {
    margin: 0 0 34px;
    font-size: 15.5px;
    line-height: 1.65;
    color: rgba(255, 255, 255, .72);
}

.signin-points { list-style: none; margin: 0; padding: 0; }

.signin-points li {
    display: flex;
    align-items: center;
    gap: 13px;
    padding: 9px 0;
    font-size: 14px;
    color: rgba(255, 255, 255, .88);
}

.signin-point-icon {
    flex-shrink: 0;
    width: 32px; height: 32px;
    display: flex; align-items: center; justify-content: center;
    border-radius: var(--ui-r-sm);
    background: rgba(255, 255, 255, .11);
    border: 1px solid rgba(255, 255, 255, .13);
    font-size: 14px;
}

.signin-foot {
    position: relative;
    margin: 0;
    font-size: 12px;
    color: rgba(255, 255, 255, .45);
    letter-spacing: .03em;
}

/* --- form side --- */

.signin-panel {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 40px 32px;
    overflow-y: auto;
    background: var(--brand-canvas);
}

.signin-form { width: 100%; max-width: 384px; }

.signin-head { margin-bottom: 26px; }

.signin-head h2 {
    margin: 0 0 6px;
    font-family: var(--brand-font-head);
    font-size: 27px;
    font-weight: 600;
    color: var(--brand-navy);
}

.signin-head p { margin: 0; color: var(--brand-text-muted); font-size: 14px; }

.signin-field { margin-bottom: 18px; }

.signin-field label {
    display: block;
    margin-bottom: 6px;
    font-size: 12.5px;
    font-weight: 600;
    color: var(--brand-navy);
}

.signin-field .form-control {
    height: 46px;
    font-size: 15px;
    background: #fff;
}

.signin-password { position: relative; }

.signin-reveal {
    position: absolute;
    right: 6px; top: 50%;
    transform: translateY(-50%);
    border: 0;
    background: transparent;
    color: var(--brand-blue);
    font-size: 12.5px;
    font-weight: 600;
    padding: 6px 10px;
    border-radius: var(--ui-r-sm);
    cursor: pointer;
}

.signin-reveal:hover { background: var(--brand-blue-faint); }

.signin-error {
    display: block;
    margin-top: 6px;
    font-size: 12.5px;
    color: var(--brand-danger);
    font-weight: 500;
}

.signin-remember {
    display: flex;
    align-items: center;
    gap: 9px;
    margin: 0 0 22px;
    font-size: 13.5px;
    font-weight: 500;
    color: var(--brand-text);
    cursor: pointer;
}

.signin-submit { width: 100%; }

.signin-alt {
    margin: 22px 0 0;
    text-align: center;
    font-size: 13.5px;
    color: var(--brand-text-muted);
}

.signin .alert { margin-bottom: 18px; }

@media (max-width: 900px) {
    .signin { grid-template-columns: 1fr; }
    /* On a phone the brand panel becomes a header rather than half the screen. */
    .signin-brand {
        padding: 26px 24px;
        min-height: auto;
    }
    .signin-headline { font-size: 26px; }
    .signin-blurb, .signin-points, .signin-foot { display: none; }
    .signin-logo { width: 140px; margin-bottom: 18px; }
    .signin-panel { align-items: flex-start; padding-top: 34px; }
}

/* Single sign-on, offered above the credential form. */
.signin-sso {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 11px;
    width: 100%;
    padding: 12px 16px;
    margin-bottom: 20px;
    background: #fff;
    border: 1px solid var(--brand-border-strong);
    border-radius: var(--ui-r);
    font-size: 14.5px;
    font-weight: 600;
    color: var(--brand-navy) !important;
    text-decoration: none !important;
    box-shadow: var(--ui-e1);
    transition: border-color var(--ui-fast), box-shadow var(--ui-mid), transform var(--ui-fast);
}

.signin-sso:hover {
    border-color: var(--brand-blue);
    box-shadow: var(--ui-e2);
    transform: translateY(-1px);
}

.signin-sso-mark { width: 18px; height: 18px; flex-shrink: 0; }

.signin-or {
    position: relative;
    text-align: center;
    margin: 0 0 20px;
}

.signin-or::before {
    content: "";
    position: absolute;
    top: 50%; left: 0; right: 0;
    border-top: 1px solid var(--brand-border);
}

.signin-or span {
    position: relative;
    padding: 0 12px;
    background: var(--brand-canvas);
    font-size: 12px;
    color: var(--brand-text-muted);
}

/* --------------------------------------------------------------------------
   The content column must be allowed to shrink.

   .content carries a large margin-left so it clears the two side panels. A
   flex or grid child will not shrink below its content by default, so on a
   1366px screen the dashboard was pushing the page 126px wider than the window
   and everything sat half off the right edge. min-width: 0 lets it give way,
   and the panel is capped to what is actually available rather than to a fixed
   ideal width.
   -------------------------------------------------------------------------- */

.content,
#equipment_info,
#equipment_info_inner,
.dash,
.dash-hero > div {
    min-width: 0;
}

.dash {
    width: auto;
    max-width: min(1180px, 100%);
    box-sizing: border-box;
}

.dash-hero > div { flex: 1 1 260px; }
/* Written against the rule above rather than beside it: `.dash-hero > div`
   outranks a bare class, which stretched this box across half the hero and
   left its button floating in the middle. */
.dash-hero > .dash-hero-actions { flex: 0 0 auto; justify-content: flex-end; }

/* Nothing in the application should make the page itself scroll sideways. */
html, body { max-width: 100%; overflow-x: hidden; }

/* The footer tutorial link is an <a class="pull-right"> inside a <button>.
   The float fights the flex centring around it and pushed the link past the
   right edge of the window. */
footer .tutorial-section .pull-right { float: none !important; }
footer .tutorial-section { flex-wrap: wrap; }

/* The hero row computed to zero width in the browser, which threw its two
   children out past the right edge of the window. Stating the width settles it
   regardless of how the surrounding boxes resolve. */
.dash-hero,
.dash-stats,
.dash-columns,
.dash-actions { width: 100%; box-sizing: border-box; }

/* --------------------------------------------------------------------------
   main.css centres every h1 in the application with a bare `h1 { text-align:
   center }`. That is why a page title sat offset from the text beneath it,
   which reads as broken alignment rather than as a choice. Headings follow
   their container like any other text; the one place that genuinely wants
   centring asks for it.
   -------------------------------------------------------------------------- */
h1, h2, h3, h4, h5, h6 { text-align: inherit; }
.welcome-logo-content h1,
.text-center h1,
.text-center { text-align: center; }

/* --------------------------------------------------------------------------
   The footer is a full-width .container in normal flow, while .sidebar is
   fixed at left: 0. Its rule therefore drew straight across the lab tree as
   the page scrolled. Lifting the panels above it, on an opaque ground, keeps
   the line where it belongs.
   -------------------------------------------------------------------------- */
.sidebar {
    z-index: 3;
    background: #fff;
}

footer.container { position: relative; z-index: 0; }

/* --------------------------------------------------------------------------
   Loading a panel
   --------------------------------------------------------------------------
   Clicking a lab used to leave the previous panel - or the "no lab chosen"
   message - on screen until the fetch returned, which read as the click having
   done nothing, or worse, as an empty lab. These stand in while it loads.
   -------------------------------------------------------------------------- */
.panel-loading { padding: 14px 12px; }

.panel-loading-row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 9px 8px;
}

.panel-loading-row span {
    display: block;
    height: 11px;
    border-radius: 4px;
    background: linear-gradient(90deg, #EDF1F7 25%, #F6F9FC 37%, #EDF1F7 63%);
    background-size: 400% 100%;
    animation: uiShimmer 1.2s ease-in-out infinite;
}

.panel-loading-row .is-tag  { width: 38px; flex-shrink: 0; }
.panel-loading-row .is-name { flex: 1; }

/* Each row starts a little later than the one above it. */
.panel-loading-row:nth-child(2) span { animation-delay: .08s; }
.panel-loading-row:nth-child(3) span { animation-delay: .16s; }
.panel-loading-row:nth-child(4) span { animation-delay: .24s; }
.panel-loading-row:nth-child(5) span { animation-delay: .32s; }
.panel-loading-row:nth-child(6) span { animation-delay: .40s; }

.panel-loading-note {
    margin: 10px 0 0;
    text-align: center;
    font-size: 12px;
    color: var(--brand-text-muted);
}

/* ==========================================================================
   23. record form alignment
   --------------------------------------------------------------------------
   Three things were out of line on the equipment record.

   A cell holding only a checkbox is much shorter than one holding a label and
   an input, so with the grid aligning to the top the checkboxes floated above
   the fields beside them. A checkbox now sits where its neighbouring input
   sits, on the same line.

   The class form is wrapped in a <fieldset>, which is a single grid item, so
   all of its fields stacked into one narrow column and left the rest of the
   width empty. The fieldset now spans the row and lays its own fields out on
   the same grid.

   The action buttons are a .form-group, so they were being placed as an
   ordinary field - which is why Delete/Clone/Save/Cancel appeared beside the
   first input instead of under the form.
   ========================================================================== */

/* --- every cell is as tall as a label-and-input cell --- */

.show-form .form-group,
.show-form > fieldset .form-group {
    display: flex;
    flex-direction: column;
    justify-content: flex-start;
    min-height: 72px;
    margin-bottom: 14px;
}

/* --- a checkbox lines up with the inputs on its row --- */

.show-form .form-group > .checkbox-group,
.show-form > fieldset .form-group > .checkbox-group {
    /* Drop past where the label would be, so the control starts level with a
       neighbouring input rather than level with its caption. */
    margin-top: 24px;
    min-height: 40px;
    align-items: center;
    gap: 10px;
}

.show-form .checkbox-group label,
.show-form > fieldset .checkbox-group label {
    margin-bottom: 0;
    line-height: 1.3;
}

.show-form .checkbox-group .custom-checkbox { display: flex; align-items: center; }

/* A group that is only a checkbox needs no reserved caption line of its own. */
.show-form .form-group.custom-flex-column > .checkbox-group:only-child { margin-top: 24px; }

/* --- the class form uses the full width --- */

.show-form > fieldset {
    grid-column: 1 / -1;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
    gap: 2px 26px;
    align-items: start;
    border: 0;
    margin: 0;
    padding: 0;
    min-width: 0;
}

.show-form > fieldset > h4,
.show-form > fieldset > hr,
.show-form > fieldset > .full-width { grid-column: 1 / -1; }

/* Free text and multi-select chips read better across the row. */
.show-form > fieldset .form-group:has(textarea),
.show-form > fieldset .form-group:has(.select2-container) { grid-column: 1 / -1; }

/* A disabled fieldset should look read-only, not broken. */
.show-form > fieldset[disabled] .form-control,
.show-form > fieldset[disabled] textarea {
    background: #F4F6FA;
    color: var(--brand-text-muted);
    cursor: default;
}

/* --- the action bar sits under the form, not inside it --- */

.show-form > .row.form-group,
.show-form > fieldset > .row.form-group,
.show-form .form-group.row:has(.btn-primary[type="submit"]) {
    grid-column: 1 / -1;
    flex-direction: row !important;
    flex-wrap: wrap;
    align-items: center;
    justify-content: flex-end !important;
    gap: 10px;
    min-height: 0;
    margin: 22px 0 0 !important;
    padding-top: 18px;
    border-top: 1px solid var(--brand-border);
}

/* Delete is the one that cannot be undone, so it is kept away from Save. */
.show-form .row.form-group .btn-delete { margin-right: auto; }

/* --------------------------------------------------------------------------
   Record form, second pass - measured, not eyeballed.

   Bootstrap's `.form-horizontal .form-group` carries margin: 0 -15px. Inside
   the grid that made every cell 30px wider than its track, swallowing the 26px
   column gap: adjacent inputs overlapped by 4px, so their borders touched, and
   a checkbox in the next column sat jammed against the input beside it. The
   grid supplies the spacing; the negative margins go.
   -------------------------------------------------------------------------- */
.form-horizontal.show-form .form-group,
.form-horizontal.show-form > fieldset .form-group,
.show-form .form-group,
.show-form > fieldset .form-group {
    margin-left: 0 !important;
    margin-right: 0 !important;
}

/* Inputs fill their own cell, never more. */
.show-form .form-control,
.show-form .select2-container {
    width: 100% !important;
    max-width: 100%;
    box-sizing: border-box;
}

/* --------------------------------------------------------------------------
   The action bar. main.css gives `.row.form-group .btn` flex: 1, which
   stretched four buttons into four equal 272px slabs across the page. They
   size to their labels, Save leads, and Delete - the one that cannot be
   undone - stands apart on the left.
   -------------------------------------------------------------------------- */
.show-form .row.form-group .btn {
    flex: 0 0 auto !important;
    min-width: 112px;
    margin: 0 !important;
    padding: 10px 22px;
}

.show-form .row.form-group .btn-delete { margin-right: auto !important; }

.show-form .row.form-group {
    /* Clear of the Copilot launcher that floats bottom-right. */
    padding-right: 72px;
}
