h1:focus {
    outline: none;
}

.valid.modified:not([type=checkbox]) {
    outline: 1px solid #26b050;
}

.invalid {
    outline: 1px solid #e50000;
}

.validation-message {
    color: #e50000;
}

.blazor-error-ui {
    color: black;
}

.blazor-error-boundary {
    background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
    padding: 1rem 1rem 1rem 3.7rem;
    color: white;
}

    .blazor-error-boundary::after {
        content: "An error has occurred."
    }

.darker-border-checkbox.form-check-input {
    border-color: #929292;
}

.form-floating > .form-control-plaintext::placeholder, .form-floating > .form-control::placeholder {
    color: var(--bs-secondary-color);
    text-align: end;
}

.form-floating > .form-control-plaintext:focus::placeholder, .form-floating > .form-control:focus::placeholder {
    text-align: start;
}

/* Cheqr list styles use MudBlazor theme variables so they adapt to dark/light modes */
.cheqr-list {
    background: var(--mud-palette-surface, #181c24);
    border-radius: 12px;
    /* subtle shadow, keeps readable in both themes */
    box-shadow: 0 2px 12px rgba(0, 0, 0, 0.06);
    padding: 0.5rem 0;
}

.cheqr-list-item {
    color: var(--mud-palette-text-primary, #fff);
    font-size: 1.1rem;
    font-weight: 500;
    border-bottom: 1px solid var(--mud-palette-divider, rgba(0,0,0,0.07));
    transition: background 0.2s, color 0.2s;
}

    .cheqr-list-item:last-child {
        border-bottom: none;
    }

    .cheqr-list-item:hover {
        /* on hover, tint background with primary colour at low opacity and make text use primary for emphasis */
        background: rgba(var(--mud-palette-primary-rgb, 0,230,118), 0.08);
        color: var(--mud-palette-primary, #00E676);
    }

/* cheqr-list meta text uses theme-aware secondary text color with reduced emphasis */
.cheqr-list-item .cheqr-list-meta {
    color: var(--mud-palette-text-secondary, rgba(255,255,255,0.65));
    font-size: 0.9rem;
    opacity: 0.9;
}

/* Action row: allows buttons to wrap and become full-width on small screens */
.cheqr-action-row {
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
    align-items: center;
}

.cheqr-action-row .cheqr-action {
    min-width: 120px;
    /* ensure consistent tap target size */
    min-height: 40px;
}

/* On small screens make actions full width for large tap targets */
@media (max-width: 720px) {
    .cheqr-action-row .cheqr-action {
        width: 100%;
        min-width: 0;
    }

    /* Stack list item content vertically on small screens */
    .cheqr-list-item > .cheqr-list-item-content,
    .cheqr-list-item > div.cheqr-list-item-content {
        display: flex;
        flex-direction: column;
        gap: 0.25rem;
        align-items: stretch;
    }

    .cheqr-list-item .cheqr-list-right {
        display: flex;
        justify-content: space-between;
        align-items: center;
    }
}

/* Default list item padding and layout */
.cheqr-list-item {
    padding: 0.75rem 1rem;
}

.cheqr-list-item-content {
    display: flex;
    justify-content: space-between;
    align-items: center;
    width: 100%;
}

.cheqr-list-left {
    display: flex;
    flex-direction: column;
    justify-self: end;
    align-self: start;
    align-items: start;
}

.cheqr-list-right {
    display: flex;
    flex-direction: column;
    justify-self: end;
    align-self: end;
    align-items: end;
}

/* Increase tap target for list items on touch devices */
@media (pointer: coarse) {
    .cheqr-list-item { min-height: 56px; }
}

.min-vh-100 {
    min-height: 100vh;
}

.h-100 {
    height: 100%;
}

.w-100 {
    width: 100%;
}

.text-center {
    text-align: center;
}

.justify-content-between {
    justify-content: space-between;
}

.autoscroll {
    overflow: auto;
}

/* ── Scroll-affordance hints (issue #65) ──
   Applies a soft fade at the right edge of horizontally-scrollable regions so
   users can tell there's more content off-screen. The gradient is a fixed-width
   mask at each edge; because it's a mask (not a background overlay) it works
   over any content/background color, including MudBlazor's light/dark themes. */
.cheqr-scroll-fade-x {
    -webkit-mask-image: linear-gradient(to right, black calc(100% - 24px), transparent 100%);
    mask-image: linear-gradient(to right, black calc(100% - 24px), transparent 100%);
}

/* Fade the edges of MudTabs' scrollable toolbar so labels that scroll out of
   view look like they're sliding under a mask rather than being abruptly
   chopped off (issue #63, issue #65). */
.mud-tabs-tabbar-wrapper {
    -webkit-mask-image: linear-gradient(to right, transparent 0, #000 24px, #000 calc(100% - 24px), transparent 100%);
    mask-image: linear-gradient(to right, transparent 0, #000 24px, #000 calc(100% - 24px), transparent 100%);
}

/* Admins & Devices table on mobile (MudTable's internal scroll container) */
.mud-table-container {
    -webkit-mask-image: linear-gradient(to right, black calc(100% - 24px), transparent 100%);
    mask-image: linear-gradient(to right, black calc(100% - 24px), transparent 100%);
}

/* Cabin Allocation board - cabin cards wrap into a grid alongside the frozen
   "Unassigned" column and the whole region scrolls vertically. */
.cheqr-cabin-grid-scroll {
    overflow-y: auto;
    overflow-x: hidden;
}

/* Give date fields a touch more room so the rendered value (e.g. "04/07/2026")
   isn't clipped by a hair at narrow widths (issue #63). */
.cheqr-date-field input {
    padding-right: 8px;
    min-width: 0;
}

@media (max-width: 599px) {
    .cheqr-date-field .mud-input-slot {
        font-size: 0.9rem;
    }
}

/* Box-plot-style rows for API Response Times: full-width readable labels (no rotation/clipping
   issues a chart axis would have) with a range bar showing min-max, ticks for median/P99, and a
   dot for the average - all relative to the slowest endpoint shown. */
.endpoint-timing-row {
    margin-bottom: 1rem;
}

.endpoint-timing-label {
    font-family: monospace;
    font-size: 0.8rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    margin-bottom: 0.25rem;
}

.endpoint-timing-track {
    position: relative;
    height: 10px;
    background: var(--mud-palette-table-lines, rgba(0, 0, 0, 0.08));
    border-radius: 5px;
}

.endpoint-timing-range {
    position: absolute;
    top: 0;
    height: 100%;
    min-width: 2px;
    background: var(--mud-palette-primary, #594AE2);
    opacity: 0.25;
    border-radius: 5px;
}

.endpoint-timing-tick {
    position: absolute;
    top: -3px;
    width: 2px;
    height: 16px;
    transform: translateX(-1px);
}

.endpoint-timing-tick-median {
    background: var(--mud-palette-primary, #594AE2);
}

.endpoint-timing-tick-p99 {
    background: var(--mud-palette-warning, #ff9800);
}

.endpoint-timing-avg-dot {
    position: absolute;
    top: 50%;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--mud-palette-primary, #594AE2);
    transform: translate(-4px, -50%);
    border: 1px solid var(--mud-palette-surface, #fff);
}

.endpoint-timing-stats {
    display: flex;
    gap: 0.75rem;
    flex-wrap: wrap;
    font-size: 0.75rem;
    color: var(--mud-palette-text-secondary, rgba(0, 0, 0, 0.6));
    margin-top: 0.25rem;
}

.endpoint-timing-samples {
    opacity: 0.7;
}

/* MudTabs' internal panel wrapper has flex: 1 1 auto but no min-height, so a flex
   item's default min-height:auto stops it shrinking below its content's natural
   size - inside a fixed-height flex column (e.g. a full-height mobile tab layout)
   this makes the wrapper grow past its container instead of clipping/scrolling.
   Its child .mud-tab-panel is a block-level element (not itself a flex item), so
   even once the wrapper is correctly sized it still needs an explicit height and
   overflow to actually clip to that size rather than rendering at its natural
   (potentially much taller) content height. */
.mud-tabs-panels {
    min-height: 0;
    overflow: hidden;
}

.mud-tab-panel {
    height: 100%;
    overflow: hidden;
}

/* Cabin Allocation's own root height only subtracts the top app bar, but on mobile
   MudMainContent also reserves pb-16 (64px) so page content clears the fixed bottom
   nav bar - that padding shrinks the visible area without the page's own height calc
   knowing about it, so content (e.g. the "N selected" bar) can sit at a Y position
   that's technically within 100vh but is actually hidden behind the bottom nav. */
.cheqr-cabin-page {
    height: calc(100vh - var(--mud-appbar-height));
}

@media (max-width: 600px) {
    .cheqr-cabin-page {
        height: calc(100vh - var(--mud-appbar-height) - 64px);
    }
}