html, body {
    font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
}

a, .btn-link {
    color: #006bb7;
}

.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;
}

/* C3 · Content width. Tables used to stretch to whatever monitor they
   landed on, so a wide screen turned a six-column table into six columns
   of whitespace. Capping and centring the article gives every page the
   same measure regardless of display. The asymmetric padding from
   MainLayout's scoped sheet still applies inside this box. */
.content {
    padding-top: 1.1rem;
    max-width: 1400px;
    margin-inline: auto;
    width: 100%;
}

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;
}

/* ── Tooltips ──────────────────────────────────────────────────────────

   CSS-only, driven by a data-tip attribute:

       <span class="tip" data-tip="Explanation">…</span>

   Deliberately not Bootstrap's tooltip: that needs the JS bundle, which
   this app does not ship, and every instance would have to be re-initialised
   after each Blazor Server re-render -- easy to miss, and it silently stops
   working when a row is replaced.

   Also better than the native title attribute it replaces: appears
   immediately rather than after the browser's ~1s delay, does not time out,
   can be styled to match the app, and -- because it triggers on focus as
   well as hover -- works on a tablet, where a native title never appears at
   all. Give the element tabindex="0" so it can take that focus.
*/
.tip {
    position: relative;
    cursor: help;
    /* inline-block, not inline: a bare inline anchor has no box of its own,
       so the bubble anchors to the first line box and the hit area collapses
       to the glyphs -- a "+1" ends up a ~12px target that is fiddly with a
       mouse and worse with a thumb. */
    display: inline-block;
}

.tip::after,
.tip::before {
    opacity: 0;
    visibility: hidden;
    transition: opacity 100ms ease;
    pointer-events: none;
    position: absolute;
    z-index: 1080;
}

.tip::after {
    content: attr(data-tip);
    bottom: calc(100% + 7px);
    /* Left-aligned to the anchor rather than centred on it. These sit in the
       leftmost table column, inside .table-responsive -- whose overflow-x
       clips anything crossing its edge. A centred bubble on a short anchor
       like "+1" overhangs to the left and gets cut off once the viewport is
       narrow enough (visible at tablet widths). Growing rightwards from the
       anchor keeps it inside the scroll box. */
    left: 0;
    background-color: #1f2937;
    color: #fff;
    padding: 0.3rem 0.5rem;
    border-radius: 5px;
    font-size: 0.75rem;
    font-weight: 400;
    line-height: 1.35;
    text-align: left;
    letter-spacing: normal;
    text-transform: none;
    font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
    /* Wide enough for a list of plates, capped so it never spans the table. */
    width: max-content;
    max-width: 16rem;
    white-space: normal;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.18);
}

/* Arrow, sitting over the anchor rather than the middle of the bubble. */
.tip::before {
    content: "";
    bottom: calc(100% + 2px);
    left: 50%;
    transform: translateX(-50%);
    border: 5px solid transparent;
    border-top-color: #1f2937;
}

/* Anchors close to the right edge flip the bubble the other way. */
.tip-end::after {
    left: auto;
    right: 0;
}

.tip:hover::after,
.tip:hover::before,
.tip:focus::after,
.tip:focus::before,
.tip:focus-visible::after,
.tip:focus-visible::before {
    opacity: 1;
    visibility: visible;
}

.tip:focus-visible {
    outline: 2px solid #0d6efd;
    outline-offset: 2px;
    border-radius: 3px;
}

/* Marks a count or abbreviation as having more behind it. The dotted
   underline is the affordance; the padding widens the tap target, which
   matters most on a tablet. */
.tip-more {
    text-decoration: underline dotted;
    text-underline-offset: 2px;
    padding: 0.15rem 0.2rem;
}

/* ── Page conventions (Slice UI-1) ─────────────────────────────────────

   The application-wide visual conventions. Everything here is global on
   purpose: these are the rules that make separately-built pages read as
   one product, so a page opting out is the bug, not the exception.

   Scoped component stylesheets still own anything specific to one page.
   What lives here is only what more than one module needs to agree on.
*/

/* ── C6 · Band labels ──────────────────────────────────────────────────
   Small uppercase signposts between the sections of a page. Lifted out of
   TollsHome's scoped stylesheet, where it was invented, so every page
   composes the same way. Sits below the page <h1> in weight while staying
   an <h2> in the document outline for screen readers. */
.band-heading {
    font-size: 0.72rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--bs-secondary-color);
    margin-bottom: 0.6rem;
}

/* Every band after the first gets air above it, so the groups read as
   groups without needing rules between them. */
.band-heading ~ .band-heading,
.row + .band-heading,
.card + .band-heading,
.table-responsive + .band-heading {
    margin-top: 1.75rem;
}

/* ── C6 · Content cards ────────────────────────────────────────────────
   Section blocks. Quieter than Bootstrap's default card — a page made of
   eight of these should read as a page with structure, not as eight
   boxes shouting at each other. */
.content-card {
    margin-bottom: 1.25rem;
}

/* A card that is entirely one table: no body padding, and the table's own
   bottom margin removed so the last row sits on the border rather than
   above a strip of empty card. The corner rounding has to be clipped or
   the table's square corners poke through the card's round ones. */
.content-card-flush > .card-body {
    padding: 0;
}

.content-card-flush > .card-body > .table-responsive {
    border-radius: inherit;
}

.content-card-flush > .card-body > .table-responsive > .table {
    margin-bottom: 0;
}

/* The header strip carries controls, so it needs to lay them out. */
.content-card > .card-header {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem 1rem;
    font-size: 0.875rem;
}

/* ── Filter boxes ──────────────────────────────────────────────────────
   Every list in the app narrows through the same 18rem search input, and
   until now it was a white box on a white page — present, findable only
   if you already knew it was there. A tinted fill gives it an edge
   without making it shout, which is right for a control that refines
   what you are already looking at rather than starting the task.

   Focus returns it to white: the box you are typing in should be the
   brightest thing in the row. */
.filter-input {
    background-color: var(--bs-tertiary-bg);
}

.filter-input:focus {
    background-color: var(--bs-body-bg);
}

.filter-input::placeholder {
    color: var(--bs-secondary-color);
}

/* ── C5 · Data freshness ───────────────────────────────────────────────
   Floated right so it sits on the same line as whatever the page opens
   with — the breadcrumb or the h1 — instead of pushing the title down a
   row. Floating rather than flexing keeps it out of every page's markup:
   the layout drops it in and the page is unchanged.

   The three colours are the banner's, unchanged, and still driven by the
   configured thresholds. Only the size and position moved. */
.data-freshness {
    float: right;
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
    margin-left: 1rem;
    /* Aligns the pills with the cap-height of the title beside them. */
    margin-top: 0.15rem;
    max-width: 100%;
}

.freshness-pill {
    display: inline-block;
    font-size: 0.72rem;
    line-height: 1.25;
    padding: 0.2rem 0.5rem;
    border-radius: 999px;
    border: 1px solid transparent;
    text-decoration: none;
    white-space: nowrap;
}

.freshness-pill strong {
    font-weight: 600;
}

/* Same three states the alert box had, at pill scale. Colours are drawn
   from Bootstrap's alert palette so fresh/amber/red read identically to
   the banner they replaced and to the one still on Home. */
.freshness-fresh {
    background-color: var(--bs-tertiary-bg);
    border-color: var(--bs-border-color);
    color: var(--bs-secondary-color);
}

.freshness-yellow {
    background-color: var(--bs-warning-bg-subtle);
    border-color: var(--bs-warning-border-subtle);
    color: var(--bs-warning-text-emphasis);
}

.freshness-red {
    background-color: var(--bs-danger-bg-subtle);
    border-color: var(--bs-danger-border-subtle);
    color: var(--bs-danger-text-emphasis);
}

.freshness-pill:hover,
.freshness-pill:focus-visible {
    filter: brightness(0.95);
    text-decoration: underline;
}

.freshness-pill:focus-visible {
    outline: 2px solid currentColor;
    outline-offset: 2px;
}

/* The float must not escape the page it belongs to and land on the next
   section's heading. */
.content > .page-header,
.content > .lotops-breadcrumb {
    clear: none;
}

/* ── C4 · Breadcrumbs ──────────────────────────────────────────────────
   The trail orients, and the ancestors in it are the way back up — so
   they have to read as links.

   The first version styled them grey with no underline "to stay quiet",
   which rendered them identically to the current-item text beside them:
   nothing on the row said which parts were clickable, and the whole trail
   scanned as a caption. Quiet is the wrong goal for a control.

   The fix is to stop overriding. Ancestors now inherit the application's
   own anchor treatment — the same blue as every other link in the app,
   with Bootstrap's underline left on — so the trail is consistent with
   links everywhere else by construction rather than by a matching hex
   value that could drift. Only three things are added on top: a little
   more weight, a bigger underline gap so the small type stays legible,
   and a thicker underline on hover.

   The current item keeps the muted, unlinked treatment. That contrast is
   now the point: coloured and underlined means you can go there, grey and
   plain means you are there. */
.lotops-breadcrumb .breadcrumb {
    --bs-breadcrumb-divider: "/";
    /* Muted divider so the slashes recede and the links carry the row. */
    --bs-breadcrumb-divider-color: var(--bs-secondary-color);
    font-size: 0.8125rem;
    align-items: center;
}

.lotops-breadcrumb .breadcrumb-item a {
    font-weight: 500;
    text-underline-offset: 0.18em;
}

.lotops-breadcrumb .breadcrumb-item a:hover {
    text-decoration-thickness: 2px;
}

.lotops-breadcrumb .breadcrumb-item a:focus-visible {
    outline: 2px solid currentColor;
    outline-offset: 2px;
    border-radius: 2px;
}

/* The page you are on — plainly not a link. */
.lotops-breadcrumb .breadcrumb-item.active {
    color: var(--bs-secondary-color);
    font-weight: 400;
}

/* ── C7 · Identifiers ──────────────────────────────────────────────────
   Plates, transponder IDs, citation numbers. One rendering everywhere:
   plain monospace, inheriting the surrounding colour.

   Replaces the <code> treatment, which Bootstrap paints red — a colour
   this app uses for money that is wrong and runs that failed. A plate is
   neither. Closes P2-HOME-4 / LE-13, where the same data rendered red on
   the citation pages and plain monospace on Customer Detail. */
.identifier {
    font-family: var(--bs-font-monospace);
    font-size: 0.9em;
    color: inherit;
    white-space: nowrap;
}

/* ── C3 · Column discipline ────────────────────────────────────────────
   Opt-in, via .table-cols on the <table>. Under it every cell refuses to
   wrap, so money, dates, counts and identifiers keep one row each however
   narrow the window gets — .table-responsive scrolls instead, which is
   the behaviour that was already there for wide tables.

   Exactly one column per table carries .col-flex: it absorbs the leftover
   width and truncates with an ellipsis. The width:100% / max-width:0 pair
   is the standard trick for making a table cell truncate at all — without
   max-width:0 the cell sizes to its content and never clips.

   Truncated cells carry a native title attribute rather than the .tip
   bubble above: .tip positions its bubble absolutely, and the clipping
   that makes truncation work would cut the bubble off. */
.table-cols th,
.table-cols td {
    white-space: nowrap;
}

.table-cols .col-flex {
    width: 100%;
    max-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* A flex cell holding stacked lines (a name over a muted sub-line) needs
   the truncation on the lines, not the cell. */
.table-cols .col-flex > .truncate {
    display: block;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Tabular figures on the whole table, not just the cells tagged .col-num.
   Money and dates line up down a column only if every digit is the same
   width, and tagging each <td> individually would mean the header and its
   body cells could drift apart the first time someone adds a column.
   Proportional text is unaffected by this. */
.table-cols {
    font-variant-numeric: tabular-nums;
}

/* Marks a column as numeric: right-aligned, so the units line up at the
   decimal point rather than at the left edge. */
.table-cols .col-num,
.table-cols th.col-num {
    text-align: right;
}

/* ── C2 · Striping ─────────────────────────────────────────────────────
   Flat tables take Bootstrap's .table-striped directly; there is nothing
   to add here.

   Master-detail tables — the ones whose rows expand — stay unstriped, and
   that is deliberate rather than an omission. Bootstrap stripes on
   :nth-child, so an expanded detail row both takes a stripe of its own and
   flips the parity of every row beneath it: opening one row visibly
   re-paints half the table. The expand affordance and the hover highlight
   already carry the row rhythm on those tables.

   .row-actions marks a table whose rows are clickable or carry controls,
   so the pointer matches the affordance in one place instead of an inline
   style per <tr>. */
.table.row-actions > tbody > tr {
    cursor: pointer;
}

.table.row-actions > tbody > tr.no-action {
    cursor: default;
}
