html, body {
    font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
}

/* Dark mode piggybacks on Bootstrap 5.3's built-in [data-bs-theme=dark] CSS-variable theming
   (see App.razor, which sets this on <html> from the account's persisted preference, and
   NavMenu.razor's toggle, which flips it instantly client-side) - most components (.card, .table,
   .alert, .btn, .form-control, .badge, borders, ...) already adapt for free. Only the handful of
   colors this app hardcodes outside that variable system need an explicit override here. These two
   custom properties are read by MainLayout.razor.css's .top-row rule - defining them at :root (here,
   unscoped) rather than inside that component-scoped stylesheet is what lets a dark override reach
   it at all, since Blazor's CSS isolation would otherwise block a `[data-bs-theme=dark] .top-row`
   selector from ever matching (the attribute lives on <html>, outside that component's own markup). */
:root {
    --bop-top-row-bg: #f7f7f7;
    --bop-top-row-border-color: #d6d5d5;
}

[data-bs-theme="dark"] {
    --bop-top-row-bg: var(--bs-tertiary-bg);
    --bop-top-row-border-color: var(--bs-border-color);
}

a, .btn-link {
    color: #006bb7;
}

[data-bs-theme="dark"] a, [data-bs-theme="dark"] .btn-link {
    color: #6ea8fe;
}

.btn-primary {
    color: #fff;
    background-color: #1b6ec2;
    border-color: #1861ac;
}

.btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus {
  box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem #258cfb;
}

.content {
    padding-top: 1.1rem;
}

.login-box {
    margin-top: 2rem;
}

/* Severity badges for BCLog record severities (used by the Search page's result list). Built on
   Bootstrap 5.3's per-color subtle/emphasis variables, which flip automatically under
   [data-bs-theme=dark], so no explicit dark override is needed here. */
.severity-badge-debug {
    background-color: var(--bs-secondary-bg-subtle);
    color: var(--bs-secondary-text-emphasis);
    border: 1px solid var(--bs-secondary-border-subtle);
}

.severity-badge-information {
    background-color: var(--bs-info-bg-subtle);
    color: var(--bs-info-text-emphasis);
    border: 1px solid var(--bs-info-border-subtle);
}

.severity-badge-warning {
    background-color: var(--bs-warning-bg-subtle);
    color: var(--bs-warning-text-emphasis);
    border: 1px solid var(--bs-warning-border-subtle);
}

.severity-badge-error {
    background-color: var(--bs-danger-bg-subtle);
    color: var(--bs-danger-text-emphasis);
    border: 1px solid var(--bs-danger-border-subtle);
}

/* Critical: same danger palette but visually escalated - darker border, bolder text. */
.severity-badge-critical {
    background-color: var(--bs-danger-bg-subtle);
    color: var(--bs-danger-text-emphasis);
    border: 2px solid var(--bs-danger-text-emphasis);
    font-weight: 700;
}

h1:focus {
    outline: none;
}

.valid.modified:not([type=checkbox]) {
    outline: 1px solid #26b050;
}

.invalid {
    outline: 1px solid #e50000;
}

.validation-message {
    color: #e50000;
}

.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;
}

/* The audit log browser marks whether the hash of a record adds up. */
.audit-hash-ok {
    background-color: var(--bs-success-bg-subtle);
    color: var(--bs-success-text-emphasis);
    border: 1px solid var(--bs-success-border-subtle);
}

.audit-hash-broken {
    background-color: var(--bs-danger-bg-subtle);
    color: var(--bs-danger-text-emphasis);
    border: 1px solid var(--bs-danger-border-subtle);
}


/* ---------------------------------------------------------------- filter fly-in

   Used identically by the Search, Debug log and Audit log pages: everything that narrows a
   result set lives in one panel, so the page itself stays a search box plus a list. It slides
   in from the RIGHT edge of the screen (the sidebar and its own flyout own the left) and is
   fixed, so a long result list never scrolls it out of reach. Global rather than per-page
   scoped CSS because all three pages use it the same way, and it uses Bootstrap's theme
   variables so it follows dark mode without an override. */
.filter-flyin {
    position: fixed;
    top: 0;
    bottom: 0;
    right: 0;
    width: min(24rem, 94vw);
    z-index: 1030;
    padding: 1rem;
    overflow-y: auto;
    background-color: var(--bs-body-bg);
    color: var(--bs-body-color);
    border-left: 1px solid var(--bs-border-color);
    box-shadow: -0.5rem 0 1.5rem rgba(0, 0, 0, 0.25);

    /* Closed: parked outside the viewport, so it neither shows nor takes clicks. */
    transform: translateX(105%);
    transition: transform 0.15s ease-out;
    visibility: hidden;
}

.filter-flyin-open {
    transform: translateX(0);
    visibility: visible;
}

.filter-flyin .form-label {
    font-weight: 600;
}

/* A row which arrived during the last live refresh: it comes up on a grey ground and fades out of
   it on its own, so "what just came in" is visible for a moment without turning the list into a
   light show. Grey rather than a colour on purpose - a log row's colours mean severity, and a new
   row is not a more severe row. The rows around it stay exactly as they are.

   It uses the theme's own greys (both are defined in light and dark mode), so the highlight is
   visible in either theme without a second rule. */
.live-entry-new > td {
    animation: live-entry-arrival 1.6s ease-out 1;
}

@keyframes live-entry-arrival {
    from { background-color: var(--bs-secondary-bg); }
    60%  { background-color: var(--bs-secondary-bg-subtle); }
    to   { background-color: transparent; }
}

/* The event source cell of the four log tables. It shows the service name and nothing else - the
   version, the machine, the instance and the file it was read from are its tooltip - so a long
   service name is clipped instead of being allowed to widen the table and push the message out. */
.businesslogentry-source,
.debuglogentry-source,
.auditentry-source {
    max-width: 15rem;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* ------------------------------------------------------------------ one row is one line

   A log table is READ BY SCANNING DOWN it. A cell which wraps breaks that rhythm and makes the
   list jump around as content arrives, so every log table is fixed-layout and every cell is one
   line: what does not fit is clipped with an ellipsis, and the whole value is one click away in
   the detail panel. This is a hard rule of these four tables - not a styling preference. */
.logline-table {
    table-layout: fixed;
    width: 100%;
}

.logline-table > thead > tr > th,
.logline-table > tbody > tr > td {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Inside a one-line cell nothing may open its own line box either. Only block children can do
   that - badges and other inline-block children keep their own display, or they would lose their
   padding. */
.logline-table > tbody > tr > td > div,
.logline-table > thead > tr > th > div {
    display: inline;
}

/* ------------------------------------------------------------------ the detail screen

   Everything a log entry carries, for the one entry a reader picked - including what had to be
   read back out of the stored (compressed, packaged) file to know it. It is a fly-in like the
   filter, and wider: this is a reading surface, not a form. */
.detail-flyin {
    position: fixed;
    top: 0;
    bottom: 0;
    right: 0;
    width: min(42rem, 96vw);
    z-index: 1035;
    padding: 1rem 1.25rem;
    overflow-y: auto;
    background-color: var(--bs-body-bg);
    color: var(--bs-body-color);
    border-left: 1px solid var(--bs-border-color);
    box-shadow: -0.5rem 0 1.5rem rgba(0, 0, 0, 0.25);

    transform: translateX(105%);
    transition: transform 0.15s ease-out;
    visibility: hidden;
}

.detail-flyin-open {
    transform: translateX(0);
    visibility: visible;
}

.detail-flyin h3 {
    font-size: 0.95rem;
    font-weight: 700;
    margin: 1rem 0 0.35rem;
    padding-bottom: 0.2rem;
    border-bottom: 1px solid var(--bs-border-color);
}

.detail-flyin dl {
    margin-bottom: 0;
}

.detail-flyin dt {
    font-weight: 600;
    font-size: 0.85rem;
}

/* A value may be anything from a guid to a stack trace, so it wraps and breaks - the one-line
   rule belongs to the grid, and this is where the whole value is supposed to be readable. */
.detail-flyin dd {
    font-size: 0.85rem;
    margin-bottom: 0.4rem;
    overflow-wrap: anywhere;
}

.detail-flyin pre {
    font-size: 0.8rem;
    white-space: pre-wrap;
    overflow-wrap: anywhere;
    margin-bottom: 0;
}
