/* StableVision additions on top of Bootstrap 5.3 + stable-theme.css (the stable brand and UI guide v2).
   App-specific rules only; colours come from the theme tokens so light and dark both work. */

/* ---------------- Sidebar lock, driven from <html> (see sv-portal.js) ---------------- */
@media (min-width: 992px) {
    html.sv-sidebar-locked .bms-sidebar {
        width: 240px;
    }
    html.sv-sidebar-locked .bms-sidebar .bms-nav-link span,
    html.sv-sidebar-locked .bms-sidebar .bms-version-tag {
        flex: 1;
        width: auto;
        opacity: 1;
    }
    html.sv-sidebar-locked .bms-sidebar .bms-nav-chevron,
    html.sv-sidebar-locked .bms-sidebar .bms-sidebar-lock-toggle {
        opacity: 1;
        pointer-events: auto;
    }
    /* Menu groups (Admin) stay open on a locked rail: stable-theme.css hides submenus unless the rail is hovered,
       and this portal locks from <html>. */
    html.sv-sidebar-locked .bms-sidebar .bms-sidebar-section.open > .bms-sidebar-submenu {
        display: flex !important;
    }
    .sv-brand-wordmark {
        opacity: 0;
        transition: opacity .1s ease;
    }
    .bms-sidebar:hover .sv-brand-wordmark,
    html.sv-sidebar-locked .sv-brand-wordmark,
    html.bms-sidebar-locked-init .sv-brand-wordmark {
        opacity: 1;
    }
}
html.sv-sidebar-locked .bms-sidebar-lock-toggle {
    color: #fff;
}
html.sv-sidebar-locked .bms-sidebar-lock-toggle .bms-lock-icon-open {
    display: none;
}
html.sv-sidebar-locked .bms-sidebar-lock-toggle .bms-lock-icon-locked {
    display: inline-block;
}

/* Brand: the star mark stays visible on the collapsed 64px rail; the "stable Vision" wordmark
   fades in when the rail expands (hover) or is locked open. */
.bms-sidebar-brand {
    gap: 8px;
    padding: 11px 13px;
    overflow: hidden;
}
/* Take the padlock out of the flex row so the collapsed rail's full width goes to the star mark
   (the padlock is invisible until the rail expands anyway). */
.bms-sidebar-header {
    position: relative;
}
.bms-sidebar-header .bms-sidebar-lock-toggle {
    position: absolute;
    right: 0;
    top: 50%;
    transform: translateY(-50%);
}
.bms-sidebar-brand img.sv-brand-mark,
.bms-sidebar-brand img.sv-brand-wordmark {
    height: 36px;
    max-height: 36px;
    width: auto;
    flex: none;
}

/* Mobile off-canvas (stable-theme.css hides the rail below 992px). */
@media (max-width: 991.98px) {
    html.sv-sidebar-mobile-open .bms-sidebar {
        transform: translateX(0);
    }
    html.sv-sidebar-mobile-open .bms-sidebar-backdrop {
        display: block;
    }
}

/* ---------------- Rail: organisation above the menu, user + version in the footer (BMS 2.0, no header bar) ------- */
:root {
    --sv-header-height: 0px;      /* no header bar on desktop; sticky bars sit at the top of the page */
}
@media (max-width: 992px) {
    :root {
        --sv-header-height: 50px; /* the phone top bar (.bms-topbar) */
    }
}

.sv-sidebar-context {
    display: flex;
    align-items: center;
    gap: 10px;
    margin: 6px 10px 4px;
    padding: 6px 10px;
    min-height: 40px;
    border-radius: 6px;
    background: rgba(255, 255, 255, .06);
    color: #fff;
    font-weight: 600;
    font-size: 13.5px;
    flex-shrink: 0;
    overflow: hidden;
}
.sv-sidebar-context .bms-icon {
    flex: none;
    color: rgba(255, 255, 255, .78);
}
.sv-sidebar-context-label {
    flex: 1;
    min-width: 0;
    margin: 0;
}
.sv-sidebar-context-name {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.sv-sidebar-context .form-select {
    background-color: rgba(0, 0, 0, .2);
    color: #fff;
    border-color: rgba(255, 255, 255, .2);
    font-weight: 600;
    --bs-form-select-bg-img: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23ffffff' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");
}
.sv-sidebar-context .form-select option {
    background: #343a40;
    color: #fff;
}
@media (min-width: 992px) {
    /* Collapsed rail: just the icon; the name / picker shows when the rail expands or is locked open. */
    .sv-sidebar-context-label {
        flex: none;
        width: 0;
        opacity: 0;
        overflow: hidden;
        transition: opacity .1s ease;
    }
    .bms-sidebar:hover .sv-sidebar-context-label,
    html.sv-sidebar-locked .bms-sidebar .sv-sidebar-context-label,
    html.bms-sidebar-locked-init .bms-sidebar .sv-sidebar-context-label {
        flex: 1;
        width: auto;
        opacity: 1;
    }
    html.sv-sidebar-locked .bms-sidebar .bms-user-btn .bms-user-name {
        flex: 1;
        width: auto;
        opacity: 1;
    }
}
.bms-user-btn .bms-nav-chevron {
    font-size: 12px;
}
.sv-user-menu-header {
    padding: 10px 14px;
    border-bottom: 1px solid var(--bs-border-color, #e3e7ef);
    color: var(--bs-body-color, #1c2536);
}
.bms-user-menu form button.text-danger {
    color: var(--bs-danger, #d63939) !important;
}
[data-bs-theme=dark] .bms-topbar {
    background: #343a40;
}

/* ---------------- Login ---------------- */
.sv-login-panel {
    /* Warehouse photo (Brad, 2026-10-15) under a dark navy wash so the white logo and tagline stay readable. */
    background:
        linear-gradient(rgba(15, 30, 63, .55), rgba(15, 30, 63, .55)),
        url("../images/login-warehouse.jpg") center / cover no-repeat,
        #0f1e3f;
    min-height: 460px;
}
.sv-login-overlay {
    color: #fff;
    font-weight: 700;
    font-size: 3rem;
    line-height: 1.1;
    text-shadow: 0 3px 6px rgba(0, 0, 0, .45);
}
/* Login page headline over the warehouse photo (Brad, 2026-10-15): no logo, large white text. */
.sv-login-headline {
    font-size: 3.4rem;
    font-weight: 700;
    line-height: 1.1;
}
.sv-login-overlay:has(.sv-login-headline) {
    width: 85%;
}
.sv-account-bg {
    background: var(--bms-bg-surface-secondary, #f5f6f8);
}
/* The form side shows the light-background logo in light mode and the white-text logo in dark mode. */
.sv-account-logo {
    max-width: 240px;
    width: 100%;
}
.sv-account-logo-dark { display: none !important; }
[data-bs-theme=dark] .sv-account-logo-light { display: none !important; }
[data-bs-theme=dark] .sv-account-logo-dark { display: block !important; }

/* ---------------- Grids & forms ---------------- */
.sv-clickable-row {
    cursor: pointer;
}
.sv-colour-swatch {
    display: inline-block;
    width: 14px;
    height: 14px;
    border-radius: 3px;
    vertical-align: -2px;
    border: 1px solid rgba(0, 0, 0, .15);
}
.sv-classes-table .form-control-color {
    width: 44px;
    padding: 4px;
}
.sv-classes-table td {
    vertical-align: middle;
}

/* ---------------- Image grid ---------------- */
.sv-image-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
    gap: 14px;
}
.sv-image-tile {
    position: relative;
    border: 1px solid var(--bs-border-color, #e6e7e9);
    border-radius: 8px;
    overflow: hidden;
    background: var(--bms-bg-surface, #fff);
    display: block;
    color: inherit;
}
.sv-image-tile:hover {
    border-color: #00A1D6;
    text-decoration: none;
    box-shadow: 0 2px 8px rgba(15, 30, 63, .12);
}
.sv-image-tile img {
    display: block;
    width: 100%;
    aspect-ratio: 4 / 3;
    object-fit: cover;
    background: #0f1e3f;
    image-orientation: none;
}
.sv-image-tile-meta {
    padding: 6px 8px;
    font-size: 12px;
    display: flex;
    align-items: center;
    gap: 6px;
}
.sv-image-tile-meta .sv-file-name {
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.sv-image-tile-status {
    position: absolute;
    top: 6px;
    right: 6px;
}
.sv-drop-zone {
    border: 2px dashed var(--bs-border-color, #cfd4dc);
    border-radius: 8px;
    padding: 18px;
    text-align: center;
    color: var(--bms-secondary, #6b7280);
    position: relative;
}
.sv-drop-zone input[type=file] {
    position: absolute;
    inset: 0;
    opacity: 0;
    cursor: pointer;
}
.sv-drop-zone:hover {
    border-color: #00A1D6;
    color: var(--bs-body-color, #1c2536);
}

/* ---------------- Annotator ---------------- */
.sv-annotator-layout {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 260px;
    gap: 16px;
    align-items: start;
}
@media (max-width: 991.98px) {
    .sv-annotator-layout {
        grid-template-columns: 1fr;
    }
}
.sv-annotator-stage {
    background: #0b1428;
    border-radius: 8px;
    padding: 10px;
    display: flex;
    justify-content: center;
    align-items: center;
    min-height: 300px;
}
.sv-annotator-canvas {
    position: relative;
    display: inline-block;
    line-height: 0;
    user-select: none;
    -webkit-user-select: none;
    touch-action: none;
}
.sv-annotator-canvas img {
    display: block;
    max-width: 100%;
    max-height: calc(100vh - 230px);
    image-orientation: none;
    pointer-events: none;
}
.sv-annotator-overlay {
    position: absolute;
    inset: 0;
    cursor: crosshair;
}
.sv-guide-x,
.sv-guide-y {
    position: absolute;
    pointer-events: none;
    background: rgba(255, 255, 255, .55);
}
.sv-guide-x {
    left: 0;
    right: 0;
    height: 1px;
}
.sv-guide-y {
    top: 0;
    bottom: 0;
    width: 1px;
}
.sv-box {
    position: absolute;
    border: 2px solid var(--sv-box-colour, #206BC4);
    background: color-mix(in srgb, var(--sv-box-colour, #206BC4) 12%, transparent);
    cursor: move;
    box-sizing: border-box;
}
.sv-box.selected {
    border-width: 3px;
    box-shadow: 0 0 0 1px #fff;
    background: color-mix(in srgb, var(--sv-box-colour, #206BC4) 22%, transparent);
}
/* A box suggested by Detect, not yet checked: dashed, lighter. */
.sv-box.suggested {
    border-style: dashed;
    background: color-mix(in srgb, var(--sv-box-colour, #206BC4) 6%, transparent);
}
.sv-box.suggested .sv-box-label {
    opacity: .85;
}
.sv-box.drawing {
    border-style: dashed;
    cursor: crosshair;
}
.sv-box-label {
    position: absolute;
    left: -2px;
    bottom: 100%;
    background: var(--sv-box-colour, #206BC4);
    color: #fff;
    font: 600 11px/1.6 system-ui, sans-serif;
    padding: 0 5px;
    border-radius: 3px 3px 0 0;
    white-space: nowrap;
    pointer-events: none;
}
.sv-box.label-inside .sv-box-label {
    bottom: auto;
    top: 0;
    left: 0;
    border-radius: 0 0 3px 0;
}
.sv-handle {
    position: absolute;
    width: 10px;
    height: 10px;
    background: #fff;
    border: 2px solid var(--sv-box-colour, #206BC4);
    border-radius: 2px;
    display: none;
}
.sv-box.selected .sv-handle {
    display: block;
}
.sv-handle.nw { left: -6px; top: -6px; cursor: nwse-resize; }
.sv-handle.ne { right: -6px; top: -6px; cursor: nesw-resize; }
.sv-handle.sw { left: -6px; bottom: -6px; cursor: nesw-resize; }
.sv-handle.se { right: -6px; bottom: -6px; cursor: nwse-resize; }

.sv-class-palette .list-group-item {
    display: flex;
    align-items: center;
    gap: 8px;
    cursor: pointer;
}
.sv-class-palette .list-group-item.active {
    background: color-mix(in srgb, var(--sv-box-colour, #206BC4) 14%, var(--bms-bg-surface, #fff));
    color: var(--bs-body-color, #1c2536);
    border-color: var(--bs-border-color, #e6e7e9);
    box-shadow: inset 3px 0 0 var(--sv-box-colour, #206BC4);
}
.sv-kbd-hint {
    font-size: 11px;
    color: var(--bms-secondary, #6b7280);
}

/* ---------------- Blazor error / reconnect UI ---------------- */
#blazor-error-ui {
    display: none;
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    z-index: 2000;
    padding: .6rem 1.25rem .7rem;
    background: #fff3cd;
    color: #664d03;
    box-shadow: 0 -1px 4px rgba(0, 0, 0, .15);
    font-size: 14px;
}
#blazor-error-ui .reload {
    margin-left: .5rem;
}
#blazor-error-ui .dismiss {
    cursor: pointer;
    position: absolute;
    right: .75rem;
    top: .5rem;
}

/* Crop mode: boxes stay visible but dimmed and untouchable; crop regions are dashed, coloured by the
   size the new image will be (green good / amber small / red too small - see sv-annotator.js). */
.sv-box.inactive {
    opacity: .4;
    pointer-events: none;
}
.sv-box.crop {
    border-style: dashed;
    background: color-mix(in srgb, var(--sv-box-colour, #fff) 10%, transparent);
    box-shadow: 0 0 0 1px rgba(0, 0, 0, .55);
}
.sv-box.crop .sv-box-label {
    color: #0f1e3f;
}
.sv-box.crop.crop-good .sv-box-label,
.sv-box.crop.crop-too-small .sv-box-label {
    color: #fff;
}
.sv-crop-legend {
    display: inline-block;
    width: .85rem;
    height: .85rem;
    border: 2px dashed currentColor;
    border-radius: 2px;
    vertical-align: -.1rem;
    margin-right: .35rem;
}
.sv-annotator-canvas.crop-mode .sv-annotator-overlay {
    cursor: cell;
}

.sv-scroll-sentinel {
    min-height: 1px;
}

/* ---------------- Image grid selection ---------------- */
.sv-tile-check {
    position: absolute;
    top: 6px;
    left: 6px;
    width: 28px;
    height: 28px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: none;
    border-radius: 6px;
    background: rgba(255, 255, 255, .9);
    color: #0f1e3f;
    font-size: 16px;
    opacity: 0;
    transition: opacity .1s ease;
    box-shadow: 0 1px 3px rgba(0, 0, 0, .25);
}
.sv-image-tile:hover .sv-tile-check,
.sv-image-tile.selecting .sv-tile-check,
.sv-image-tile.selected .sv-tile-check,
.sv-tile-check:focus-visible {
    opacity: 1;
}
.sv-image-tile.selected {
    border-color: #00A1D6;
    box-shadow: 0 0 0 2px #00A1D6;
}
.sv-image-tile.selected .sv-tile-check {
    color: #00A1D6;
}
.sv-image-tile.selected img {
    opacity: .85;
}
.sv-selection-bar {
    position: sticky;
    top: var(--sv-header-height, 56px);
    z-index: 5;
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 16px;
    background: color-mix(in srgb, #00A1D6 12%, var(--bms-bg-surface, #fff));
    border-bottom: 1px solid var(--bs-border-color, #e6e7e9);
}

/* ---------------- Image quality ---------------- */
.sv-quality-badge {
    flex: none;
    font-size: 10px;
}
.sv-quality-guide .card-header {
    cursor: pointer;
    user-select: none;
}
.sv-quality-guide li {
    margin-bottom: .25rem;
}

/* ---------------- Page spinner (same look as BMS 2.0's #bmsLoadingOverlay) ---------------- */
#svBusyOverlay {
    display: none;
    position: fixed;
    inset: 0;
    z-index: 2100;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 14px;
    background: transparent; /* the page stays visible; the layer just blocks clicks */
    cursor: progress;
}
#svBusyOverlay.sv-busy-visible {
    display: flex;
}
#svBusyOverlay img {
    width: 72px;
    height: 72px;
    animation: sv-busy-spin 1.1s linear infinite;
}
#svBusyOverlay .sv-busy-message {
    background: rgba(15, 30, 63, .88);
    color: #fff;
    font-size: 13px;
    font-weight: 600;
    padding: 6px 14px;
    border-radius: 999px;
    box-shadow: 0 2px 8px rgba(0, 0, 0, .2);
}
@keyframes sv-busy-spin {
    from { transform: rotate(0deg); }
    to { transform: rotate(360deg); }
}
@media (prefers-reduced-motion: reduce) {
    #svBusyOverlay img {
        animation-duration: 3s;
    }
}

/* ---------------- Reserve the scrollbar space so the page doesn't jump when a scrollbar appears ---------------- */
html {
    scrollbar-gutter: stable;
}

/* ---------------- Test results (training report) ---------------- */
.sv-test-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: .75rem;
}
.sv-test-image {
    position: relative;
    background: var(--bms-bg-surface-secondary, #f6f8fb);
    border-radius: var(--bs-border-radius, 4px) var(--bs-border-radius, 4px) 0 0;
    overflow: hidden;
}
.sv-test-image img {
    display: block;
    width: 100%;
    height: auto;
}
.sv-test-image-missing {
    aspect-ratio: 4 / 3;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--bms-secondary, #667382);
    font-size: .85rem;
}
.sv-test-box {
    position: absolute;
    box-sizing: border-box;
    pointer-events: auto;
}
.sv-test-box.expected {
    border: 2px solid var(--sv-test-colour);
}
.sv-test-box.detected {
    border: 2px dashed var(--sv-test-colour);
    box-shadow: 0 0 0 1px rgba(0, 0, 0, .45);
}
.sv-test-box-label {
    position: absolute;
    left: -2px;
    bottom: 100%;
    background: var(--sv-test-colour);
    color: #fff;
    font: 600 10px/1.5 system-ui, sans-serif;
    padding: 0 4px;
    border-radius: 3px 3px 0 0;
    white-space: nowrap;
    pointer-events: none;
}
.sv-test-legend {
    display: inline-block;
    width: .9rem;
    height: .7rem;
    margin-right: .3rem;
    vertical-align: -.05rem;
    border: 2px solid currentColor;
}
.sv-test-legend.detected {
    border-style: dashed;
}
.sv-test-dot {
    display: inline-block;
    width: .6rem;
    height: .6rem;
    border-radius: 50%;
    margin-right: .25rem;
}

/* ---------------- Servers ---------------- */
.sv-status-dot {
    display: inline-block;
    width: .5rem;
    height: .5rem;
    border-radius: 50%;
    vertical-align: .05rem;
}

/* Server health charts. Series colours: validated categorical palette (CVD-safe), stepped for dark mode. */
:root, [data-bs-theme=light] {
    --sv-series-1: #2a78d6;
    --sv-series-2: #eb6834;
    --sv-series-3: #1baf7a;
    --sv-series-4: #4a3aa7;
}
[data-bs-theme=dark] {
    --sv-series-1: #3987e5;
    --sv-series-2: #d95926;
    --sv-series-3: #199e70;
    --sv-series-4: #9085e9;
}
.sv-health-legend {
    display: flex;
    gap: 1rem;
    font-size: .8rem;
    color: var(--bms-secondary, #667382);
    margin-bottom: .25rem;
}
.sv-health-swatch {
    display: inline-block;
    width: .9rem;
    height: 3px;
    border-radius: 2px;
    vertical-align: middle;
    margin-right: .35rem;
}
.sv-health-grid {
    stroke: var(--bs-border-color, #e6e7e9);
    stroke-width: 1;
}
.sv-health-axis {
    font: 11px system-ui, sans-serif;
    fill: var(--bms-secondary, #667382);
}
.sv-health-offline {
    fill: var(--bms-secondary, #667382);
    opacity: .12;
}
.sv-health-hit {
    fill: transparent;
}
.sv-health-hit:hover {
    fill: var(--bms-secondary, #667382);
    opacity: .08;
}

/* ---- Server → Cameras: picture tiles ---- */
.sv-camera-tile {
    display: flex;
    flex-direction: column;
    height: 100%;
    background: var(--bms-bg-surface-secondary, #f1f1f1);
    border: 1px solid var(--bs-border-color, #e6e7e9);
    border-radius: 6px;
    overflow: hidden;
}

.sv-camera-when {
    padding: .5rem .75rem .35rem;
    text-align: right;
    font-size: .8125rem;
    font-variant-numeric: tabular-nums;
    color: var(--bs-body-color, #1c2536);
    min-height: 1.9rem;
}

.sv-camera-thumb {
    position: relative;
    display: block;
    width: calc(100% - 1.5rem);
    margin: 0 .75rem;
    padding: 0;
    border: 0;
    border-radius: 4px;
    overflow: hidden;
    aspect-ratio: 16 / 9;
    background: #1f2328;
    cursor: zoom-in;
}

.sv-camera-status-tag {
    position: absolute;
    top: 6px;
    right: 6px;
    z-index: 1;
}

.sv-camera-thumb:disabled {
    cursor: default;
}

.sv-camera-thumb img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.sv-camera-tile.is-paused .sv-camera-thumb img {
    filter: grayscale(1);
    opacity: .6;
}

.sv-camera-thumb-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: .35rem;
    height: 100%;
    padding: 1rem;
    color: #aab0b8;
    font-size: .8125rem;
}

.sv-camera-thumb-empty .bi {
    font-size: 1.75rem;
}

.sv-camera-info {
    padding: .6rem .75rem .75rem;
    flex: 1 1 auto;
    min-width: 0;
}

.sv-camera-name {
    font-size: 1.05rem;
    font-weight: 500;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.sv-camera-actions {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .25rem;
    padding: .25rem .5rem;
    background: color-mix(in srgb, var(--bs-body-color, #1c2536) 6%, var(--bms-bg-surface-secondary, #f1f1f1));
    border-top: 1px solid var(--bs-border-color, #e6e7e9);
}

.sv-camera-actions .bi {
    font-size: 1.2rem;
}

.sv-spin {
    display: inline-block;
    animation: sv-busy-spin 1s linear infinite;
}

@media (prefers-reduced-motion: reduce) {
    .sv-spin {
        animation: none;
    }
}

/* Server → Health: hardware model beside the tile heading, e.g. "CPU · Intel Core i7-12700" */
.sv-health-tile-head {
    display: flex;
    gap: .35rem;
    white-space: nowrap;
    overflow: hidden;
}

.sv-health-tile-detail {
    text-transform: none;
    letter-spacing: normal;
    font-weight: 500;
    overflow: hidden;
    text-overflow: ellipsis;
    min-width: 0;
}

/* Camera → Rules: region editor (sv-regions.js) */
.sv-regions-host {
    user-select: none;
}

.sv-regions-canvas {
    position: relative;
    width: 100%;
    background: #1f2328;
    border-radius: 4px;
    overflow: hidden;
    touch-action: none;
}

.sv-regions-canvas img {
    display: block;
    width: 100%;
    height: auto;
    pointer-events: none;
}

.sv-regions-canvas.no-picture {
    aspect-ratio: 960 / 544;
}

.sv-regions-canvas.is-drawing {
    cursor: crosshair;
}

.sv-regions-empty {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: .35rem;
    color: #aab0b8;
    font-size: .8125rem;
    pointer-events: none;
}

.sv-regions-empty .bi {
    font-size: 1.75rem;
}

.sv-regions-svg,
.sv-regions-labels,
.sv-regions-handles {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
}

.sv-regions-labels {
    pointer-events: none;
}

.sv-regions-handles {
    pointer-events: none;
}

.sv-region-poly {
    fill: color-mix(in srgb, var(--sv-region-colour) 22%, transparent);
    stroke: var(--sv-region-colour);
    stroke-width: 2;
    vector-effect: non-scaling-stroke;
    cursor: move;
}

.sv-region-poly.is-selected {
    fill: color-mix(in srgb, var(--sv-region-colour) 35%, transparent);
    stroke-width: 3;
}

.sv-regions-canvas.is-drawing .sv-region-poly {
    pointer-events: none;
}

.sv-region-drawing {
    fill: rgba(255, 255, 255, .12);
    stroke: #fff;
    stroke-width: 2;
    stroke-dasharray: 6 4;
    vector-effect: non-scaling-stroke;
    pointer-events: none;
}

.sv-region-label {
    position: absolute;
    transform: translate(-50%, -50%);
    padding: 1px 6px;
    border-radius: 3px;
    background: var(--sv-region-colour);
    color: #fff;
    font-size: .75rem;
    font-weight: 600;
    white-space: nowrap;
    box-shadow: 0 1px 3px rgba(0, 0, 0, .35);
}

.sv-region-corner,
.sv-region-mid {
    position: absolute;
    transform: translate(-50%, -50%);
    border-radius: 50%;
    pointer-events: auto;
}

.sv-region-corner {
    width: 12px;
    height: 12px;
    background: #fff;
    border: 2px solid #1f2328;
    cursor: grab;
}

.sv-region-corner.is-first {
    width: 16px;
    height: 16px;
    background: #2fb344;
    cursor: pointer;
}

.sv-region-draw-corner {
    pointer-events: none;
}

.sv-region-draw-corner.is-first {
    pointer-events: auto;
}

.sv-region-mid {
    width: 14px;
    height: 14px;
    background: rgba(255, 255, 255, .75);
    border: 1px solid #1f2328;
    cursor: copy;
}

.sv-region-mid::after {
    content: "+";
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 11px;
    line-height: 1;
    color: #1f2328;
    font-weight: 700;
}

.sv-region-item {
    padding: .6rem;
    border: 1px solid var(--bs-border-color, #e6e7e9);
    border-radius: 6px;
    cursor: pointer;
}

.sv-region-item.is-selected {
    border-color: var(--bs-primary, #206bc4);
    background: color-mix(in srgb, var(--bs-primary, #206bc4) 6%, var(--bms-bg-surface, #fff));
}

.sv-region-swatch {
    width: 14px;
    height: 14px;
    flex: 0 0 14px;
    border-radius: 3px;
    background: var(--sv-region-colour);
}

/* Hidden via the eye toggle: still in the list, greyed out, not drawn on the picture (view-only, nothing is saved). */
.sv-region-item.is-hidden {
    opacity: .55;
}

/* Rules → Cameras: where a rule is used */
.sv-rule-usage {
    display: block;
    height: 100%;
    border: 1px solid var(--bs-border-color, #e6e7e9);
    border-radius: 6px;
    overflow: hidden;
    color: inherit;
    text-decoration: none;
    background: var(--bms-bg-surface, #fff);
}

.sv-rule-usage:hover {
    border-color: var(--bs-primary, #206bc4);
    color: inherit;
}

.sv-rule-usage-pic {
    position: relative;
    aspect-ratio: 960 / 544;
    background: #1f2328;
}

.sv-rule-usage-pic img,
.sv-rule-usage-pic svg {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: fill;
}

.sv-region-shape {
    fill: rgba(42, 120, 214, .25);
    stroke: #2a78d6;
    stroke-width: 2;
    vector-effect: non-scaling-stroke;
}

/* Camera → Calibration (sv-calibration.js) */
.sv-calib-canvas {
    position: relative;
    width: 100%;
    background: #1f2328;
    border-radius: 4px;
    overflow: hidden;
    touch-action: none;
    user-select: none;
}

.sv-calib-canvas img {
    display: block;
    width: 100%;
    height: auto;
    pointer-events: none;
}

.sv-calib-canvas.no-picture {
    aspect-ratio: 960 / 544;
}

.sv-calib-canvas.is-placing {
    cursor: crosshair;
}

.sv-calib-svg {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    pointer-events: none;
}

.sv-calib-grid {
    fill: none;
    stroke: rgba(255, 255, 255, .55);
    stroke-width: 1;
    vector-effect: non-scaling-stroke;
}

.sv-calib-rect {
    fill: rgba(47, 179, 68, .18);
    stroke: #2fb344;
    stroke-width: 2.5;
    vector-effect: non-scaling-stroke;
}

.sv-calib-rect.is-invalid {
    fill: rgba(214, 57, 57, .18);
    stroke: #d63939;
}

.sv-calib-check {
    stroke: #f59f00;
    stroke-width: 2.5;
    vector-effect: non-scaling-stroke;
}

.sv-calib-measure {
    stroke: #fff;
    stroke-width: 2.5;
    stroke-dasharray: 6 4;
    vector-effect: non-scaling-stroke;
}

.sv-calib-corner {
    position: absolute;
    transform: translate(-50%, -50%);
    width: 22px;
    height: 22px;
    border-radius: 50%;
    background: #2fb344;
    border: 2px solid #fff;
    color: #fff;
    font-size: 11px;
    font-weight: 700;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: grab;
    box-shadow: 0 1px 3px rgba(0, 0, 0, .4);
}

.sv-calib-end {
    position: absolute;
    transform: translate(-50%, -50%);
    width: 12px;
    height: 12px;
    border-radius: 50%;
    background: #f59f00;
    border: 2px solid #fff;
    cursor: grab;
}

.sv-calib-end.is-measure {
    background: #fff;
    border-color: #1f2328;
}

.sv-calib-label {
    position: absolute;
    transform: translate(-50%, -50%);
    padding: 1px 6px;
    border-radius: 3px;
    color: #fff;
    font-size: .75rem;
    font-weight: 600;
    white-space: nowrap;
    box-shadow: 0 1px 3px rgba(0, 0, 0, .35);
}

.sv-calib-edge-label {
    background: #2fb344;
}

.sv-calib-check-label {
    background: #f59f00;
}

.sv-calib-measure-label {
    background: #1f2328;
}

.sv-calib-check-row {
    padding: .5rem;
    border: 1px solid var(--bs-border-color, #e6e7e9);
    border-radius: 6px;
    margin-bottom: .5rem;
}

.sv-calib-check-label,
.sv-calib-measure-label {
    transform: translate(-50%, calc(-100% - 8px));
}

/* Email template editor (TinyMCE, sv-tinymce.js): red border like any other field when the message is missing or wrong. */
.sv-tinymce-host { min-height: 460px; }
.sv-tinymce-host.is-invalid .tox-tinymce { border-color: var(--bs-danger, #d63939); box-shadow: 0 0 0 .25rem rgba(214, 57, 57, .25); }
.sv-email-preview { height: 540px; }

/* Images page (rule breaches): picture with the objects' boxes drawn over it, and the crop box. */
.sv-incident-picture { position: relative; background: #1d273b; aspect-ratio: 16 / 9; overflow: hidden; }
.sv-incident-picture img { width: 100%; height: 100%; object-fit: fill; display: block; }
.sv-incident-picture svg { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
.sv-incident-picture .sv-box { fill: none; stroke: #d63939; stroke-width: 2; vector-effect: non-scaling-stroke; }
/* Proximity rules with "Show the measured distance": a dotted hi-vis yellow line between the two measured points. */
.sv-incident-picture .sv-distance-line { stroke: #ffd400; stroke-width: 2; stroke-dasharray: 6 5; vector-effect: non-scaling-stroke; }
/* Same label as the mark-up page (.sv-box-label): 11px, however large the picture is shown. */
.sv-pic-label { position: absolute; transform: translateY(-100%); background: #d63939; color: #fff; font: 600 11px/1.6 system-ui, sans-serif; padding: 0 4px; border-radius: 3px 3px 0 0; white-space: nowrap; pointer-events: none; }
.sv-pic-label.inside { transform: none; border-radius: 0 0 3px 0; }
/* The small pictures on the Images page: a thinner box and smaller label (the viewer keeps the full size). */
.sv-incident-picture.sv-pic-small .sv-box { stroke-width: 1; }
.sv-incident-picture.sv-pic-small .sv-distance-line { stroke-width: 1; stroke-dasharray: 4 3; }
.sv-incident-picture.sv-pic-small .sv-pic-label { font-size: 9px; padding: 0 3px; }
.sv-images-filters { position: sticky; top: 1rem; }
.sv-incident-card.is-selected { box-shadow: 0 0 0 2px var(--bs-primary, #206bc4); }
.sv-incident-card .card-footer .btn-icon { --bs-btn-padding-x: .45rem; --bs-btn-padding-y: .3rem; }
.sv-incident-card .card-footer .btn-icon .bi { font-size: 1.3rem; line-height: 1; }
.sv-incident-card .card-footer .badge { font-size: .85rem; }
.sv-crop-host { position: relative; cursor: crosshair; user-select: none; touch-action: none; }
.sv-crop-host img { width: 100%; display: block; pointer-events: none; }
.sv-crop-box { position: absolute; border: 2px dashed #fff; box-shadow: 0 0 0 9999px rgba(0, 0, 0, .45); pointer-events: none; }
.sv-heat-host { position: relative; background: #1d273b; aspect-ratio: 16 / 9; overflow: hidden; border-radius: 4px; }
.sv-heat-host img, .sv-heat-blank { width: 100%; height: 100%; object-fit: fill; display: block; }
.sv-heat-host svg { position: absolute; inset: 0; width: 100%; height: 100%; }
.sv-heat-host svg rect { shape-rendering: crispEdges; }
.sv-heat-scale { display: inline-block; width: 120px; height: 10px; border-radius: 5px; background: linear-gradient(90deg, rgba(32,108,196,.5), rgba(247,200,30,.7), rgba(214,57,57,.85)); }
/* Server plan (Plan tab) */
.sv-plan-host { position: relative; height: 70vh; min-height: 420px; background: #fbfbfc; border: 1px solid var(--bs-border-color); border-radius: 4px; overflow: hidden; }
.sv-plan-svg { width: 100%; height: 100%; display: block; outline: none; cursor: default; touch-action: none; }
.sv-plan-host.tool-line .sv-plan-svg, .sv-plan-host.tool-place .sv-plan-svg { cursor: crosshair; }
.sv-plan-grid .minor { stroke: #e6e8ec; stroke-width: 1; }
.sv-plan-grid .major { stroke: #cfd3da; stroke-width: 1; }
.sv-plan-line { stroke-linecap: round; }
.sv-plan-line.selected { filter: drop-shadow(0 0 2px #206bc4); }
.sv-plan-line.drawing { stroke: #206bc4; stroke-width: 2; stroke-dasharray: 6 4; }
.sv-plan-handle { fill: #fff; stroke: #206bc4; stroke-width: 2; cursor: move; }
.sv-plan-handle.rotate { stroke: #f59f00; cursor: grab; }
.sv-plan-rotline { stroke: #f59f00; stroke-width: 1; stroke-dasharray: 4 3; }
.sv-plan-wedge { fill: var(--sv-cam); fill-opacity: .13; stroke: var(--sv-cam); stroke-width: 1; stroke-opacity: .7; }
.sv-plan-wedge.guessed { stroke-dasharray: 5 4; fill-opacity: .08; }
.sv-plan-wedge.selected { fill-opacity: .22; stroke-width: 2; }
.sv-plan-camdot { fill: var(--sv-cam, #206bc4); stroke: #fff; stroke-width: 2; }
.sv-plan-camdot.placing { fill: #206bc4; }
.sv-plan-camdir { stroke: var(--sv-cam, #206bc4); stroke-width: 3; stroke-linecap: round; }
.sv-plan-camdir.placing { stroke: #206bc4; stroke-dasharray: 6 4; }
.sv-plan-calrect { fill: none; stroke: var(--sv-cam, #206bc4); stroke-width: 1.5; stroke-dasharray: 4 3; }
.sv-plan-calrect.placing { stroke: #206bc4; }
.sv-plan-camera.selected .sv-plan-calrect { stroke-width: 2.5; stroke-dasharray: none; }
.sv-plan-camlabel { font-size: 12px; font-weight: 600; fill: #1d273b; paint-order: stroke; stroke: #fff; stroke-width: 3px; pointer-events: none; }
.sv-plan-length { font-size: 13px; font-weight: 600; fill: #206bc4; paint-order: stroke; stroke: #fff; stroke-width: 3px; pointer-events: none; }
.sv-plan-incident { fill: #d63939; fill-opacity: .8; stroke: #fff; stroke-width: 1; vector-effect: non-scaling-stroke; }
.sv-plan-camera-item { display: flex; align-items: center; gap: .5rem; padding: .4rem .5rem; border-radius: 4px; cursor: pointer; }
.sv-plan-camera-item:hover { background: var(--bms-bg-surface-secondary); }
.sv-plan-camera-item.is-selected { background: rgba(32, 107, 196, .1); }
.sv-plan-swatch { width: 10px; height: 10px; border-radius: 50%; flex: 0 0 auto; }
.sv-plan-shape { stroke-linejoin: round; }
.sv-plan-shape.selected { filter: drop-shadow(0 0 2px #206bc4); }
.sv-plan-shape.drawing { fill: #206bc4; fill-opacity: .15; stroke: #206bc4; stroke-width: 2; stroke-dasharray: 6 4; }
.sv-plan-objlabel { font-size: 12px; font-weight: 600; fill: #1d273b; paint-order: stroke; stroke: #fff; stroke-width: 3px; pointer-events: none; }
.sv-plan-swatches { display: flex; flex-wrap: wrap; gap: 4px; }
.sv-plan-swatches button { width: 22px; height: 22px; border-radius: 4px; border: 2px solid transparent; padding: 0; cursor: pointer; }
.sv-plan-swatches button.is-selected { border-color: #1d273b; }
.sv-plan-swatches button.none { background: #fff; border: 1px dashed #999; }
/* Pages reached from an email link (no login) */
.sv-public-bg { background: #f5f8fb; }

/* ---------------- Dashboard tabs (BMS 2.0 underline style) ---------------- */
.sv-dash-tabs {
    display: flex;
    justify-content: center;
    flex-wrap: wrap;
    gap: 4px;
    padding-top: 8px;
    border-bottom: 1px solid var(--bs-border-color, #dee2e6);
}
/* BMS 2.0 dashboard tabs (Brad, 2026-10-15): larger muted labels, the active one in full ink with a 3px blue bar
   that runs a little wider than its word. */
.sv-dash-tab {
    position: relative;
    padding: 10px 18px 16px;
    font-size: 18px;
    font-weight: 500;
    line-height: 1.2;
    color: var(--bs-secondary-color, #6c757d);
    text-decoration: none;
    white-space: nowrap;
    transition: color .15s ease;
}
.sv-dash-tab::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: -1px;
    height: 3px;
    border-radius: 2px 2px 0 0;
    background: transparent;
}
/* In the page title row: no rule underneath and short enough to keep the row one control (40px) high. */
.sv-dash-tabs-inline { padding-top: 0; border-bottom: 0; margin: 0; }
.sv-dash-tabs-inline .sv-dash-tab { padding: 6px 16px 9px; font-size: 16px; }
.sv-dash-tab:hover { color: var(--bs-emphasis-color, #000); text-decoration: none; }
.sv-dash-tab.active { color: var(--bs-emphasis-color, #000); font-weight: 600; }
.sv-dash-tab.active::after { background: var(--bs-primary, #0d6efd); }

/* Dashboard tiles: a solid colour with white words, like the BMS dashboards. */
.sv-tile { color: #fff; border-radius: var(--bs-border-radius, 4px); padding: 14px 16px; position: relative; min-height: 88px; }
.sv-tile .sv-tile-value { font-size: 28px; font-weight: 700; line-height: 1.1; }
.sv-tile .sv-tile-label { font-size: 13px; opacity: .92; margin-top: 4px; }
.sv-tile .sv-tile-icon { position: absolute; right: 14px; top: 12px; font-size: 26px; opacity: .55; }
.sv-tile .sv-tile-share { position: absolute; right: 0; bottom: 0; left: 0; text-align: center; font-size: 12px; padding: 3px 0; background: rgba(0, 0, 0, .18); border-radius: 0 0 var(--bs-border-radius, 4px) var(--bs-border-radius, 4px); }
.sv-tile.bg-yellow, .sv-tile.bg-warning, .sv-tile.bg-orange { color: #000; }
.sv-tile.bg-yellow .sv-tile-share, .sv-tile.bg-warning .sv-tile-share, .sv-tile.bg-orange .sv-tile-share { background: rgba(0, 0, 0, .07); }

/* Dashboard tiles that filter the incident list when clicked (Total incidents, each distance band). */
.sv-tile-clickable {
    cursor: pointer;
    transition: transform .1s ease, box-shadow .1s ease;
}
.sv-tile-clickable:hover {
    box-shadow: inset 0 0 0 999px rgba(255, 255, 255, .08);
}
.sv-tile-clickable:focus-visible {
    outline: 2px solid var(--bs-body-color, #000);
    outline-offset: 2px;
}
.sv-tile-clickable.is-selected {
    box-shadow: inset 0 0 0 3px rgba(255, 255, 255, .85);
}

/* Blazor's FocusOnNavigate moves keyboard focus to the page heading after each navigation (so screen readers
   announce the new page); headings aren't controls, so don't draw a focus box around them. */
h1:focus, h1:focus-visible,
h2:focus, h2:focus-visible {
    outline: none;
    box-shadow: none;
}

/* Dashboards: the incidents-per-hour chart (Chart.js) fills this box at its real size, so nothing is stretched. */
.sv-hour-chart-box { position: relative; height: 260px; width: 100%; }

/* Date fields (DateField + flatpickr, branding guide): the "x" clear button on the right, and the calendar in the theme. */
.sv-date-field .sv-date-clear { pointer-events: auto; cursor: pointer; color: var(--bs-secondary-color); text-decoration: none; }
.sv-date-field .sv-date-clear:hover { color: var(--bs-danger); }
.input-group > .sv-date-field { position: relative; flex: 1 1 auto; width: 1%; min-width: 0; }
.input-group > .sv-date-field .form-control { border-radius: 0; }

/* Training runs grid: columns only as wide as their values (counts up to 9999). */
th.sv-col-status, td.sv-col-status { width: 104px !important; min-width: 0; white-space: nowrap; padding-left: .5rem; padding-right: .5rem; }
th.sv-col-inuse, td.sv-col-inuse { width: 72px !important; min-width: 0; white-space: nowrap; padding-left: .5rem; padding-right: .5rem; }
th.sv-col-images, td.sv-col-images { width: 96px !important; min-width: 0; white-space: nowrap; padding-left: .5rem; padding-right: .5rem; }
th.sv-col-boxes, td.sv-col-boxes { width: 72px !important; min-width: 0; white-space: nowrap; padding-left: .5rem; padding-right: .5rem; }
th.sv-col-time, td.sv-col-time { width: 60px !important; min-width: 0; white-space: nowrap; padding-left: .375rem; padding-right: .375rem; }
@media (max-width: 767.98px) {
    table.bms-rt :is(.sv-col-status, .sv-col-inuse, .sv-col-images, .sv-col-boxes, .sv-col-time) { width: auto !important; }
}
/* Server Health charts: Chart.js canvas at its real size (same chart library as the dashboard). */
.sv-health-chart-box { position: relative; width: 100%; }
/* Icon-only action buttons (Training runs grid): 24 x 24 icons. */
.sv-icon-btn { line-height: 1; }
.sv-icon-btn > .bi { display: block; width: 24px; height: 24px; font-size: 24px; line-height: 24px; }
/* Training report (test results + training check): the grey explanatory text 5% darker, light mode only. */
:root:not([data-bs-theme=dark]) .sv-training-report .text-secondary { color: color-mix(in srgb, var(--bms-secondary) 95%, #000) !important; }
