/* Admin overrides on top of MudBlazor. Kept to the subset the CMS backend actually relies on. */

html, body {
    margin: 0;
}

/* Room for the vertical scrollbar is always kept, so its coming and going never changes the page's width: a chart's
   tooltip standing below the chart near the bottom of a page cannot make the charts redraw and flicker. */
html {
    scrollbar-gutter: stable;
}

/* MudBlazor's own error bar is replaced by an inline red band that pushes content down instead of
   covering it (CMS behaviour). */
#blazor-error-ui {
    background: rgb(244, 67, 54);
    color: #fff;
    display: none;
    padding: 0.8rem 1.25rem;
    position: relative;
    z-index: 1099;
    font-family: "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}

#blazor-error-ui .dismiss {
    cursor: pointer;
    position: absolute;
    right: 0.75rem;
    top: 0.5rem;
}

#blazor-error-ui .reload {
    color: #fff;
    text-decoration: underline;
}

/* EditForm validation output (Blazilla writes into this class). */
.validation-message {
    color: var(--mud-palette-error);
    font-size: 0.8rem;
    font-weight: 500;
}

/* Login page shell (AuthLayout). Ported from the CMS backend so staff see the same screen in both. */
.unauthenticated-layout {
    min-height: 100dvh;
    display: grid;
    place-items: center;
    padding: 24px;
}

.unauthenticated-logo {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
    margin-block-end: 8px;
    text-align: center;
    filter: drop-shadow(0 2px 6px color-mix(in srgb, white 70%, transparent));
}

.unauthenticated-logo__word {
    font-family: Rockwell, "Rockwell Nova", "Roboto Slab", "Museo Slab", Georgia, serif;
    font-size: clamp(2.2rem, 8vw, 3.4rem);
    font-weight: 800;
    line-height: 1;
    letter-spacing: -0.01em;
    color: #111;
}

.unauthenticated-logo__lead {
    color: #6b2410;
}

.unauthenticated-logo__tagline {
    font-size: clamp(0.8rem, 2.6vw, 1rem);
    font-style: italic;
    color: #222;
}

.unauthenticated-card {
    width: 100% !important;
    max-width: 560px !important;
    padding: 32px !important;
    border-radius: 8px !important;
    background: rgba(255, 255, 255, 0.92) !important;
    box-shadow: 0 3px 5px -1px rgba(0, 0, 0, 0.2), 0 5px 8px 0 rgba(0, 0, 0, 0.14), 0 1px 14px 0 rgba(0, 0, 0, 0.12) !important;
    backdrop-filter: saturate(120%) blur(6px);
}

@media (max-width: 600px) {
    .unauthenticated-layout {
        padding: 16px;
    }

    .unauthenticated-card {
        padding: 20px !important;
        max-width: 100% !important;
    }

    /* "Log ind på Maskinmarkedet" at h4 size took three lines of a phone before the first field. */
    .unauthenticated-card h1.mud-typography-h4 { font-size: 1.625rem; }
}

/* The remember-me box is a native input because MudCheckBox needs a circuit both to post a bindable value
   and to redraw its own icon. */
.auth-checkbox-label {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    cursor: pointer;
    user-select: none;
    width: fit-content;
}

.auth-checkbox {
    width: 18px;
    height: 18px;
    accent-color: var(--mud-palette-primary);
    cursor: pointer;
}

/* The login page has no circuit, so the inline script on it toggles this class on submit. Without it there
   is no sign at all that the click did anything until the response arrives. The extra right padding keeps
   the spinner off the label on a narrow button. */
button[type="submit"].auth-submitting {
    pointer-events: none;
    opacity: 0.7;
    position: relative;
    padding-right: 38px !important;
}

button[type="submit"].auth-submitting::after {
    content: "";
    position: absolute;
    top: 50%;
    right: 14px;
    width: 14px;
    height: 14px;
    margin-top: -7px;
    border: 2px solid currentColor;
    border-right-color: transparent;
    border-radius: 50%;
    animation: auth-spin 0.7s linear infinite;
}

@keyframes auth-spin {
    to { transform: rotate(360deg); }
}

/* The drawer holds six groups and seventeen pages, so its own header must not eat the room the menu needs. */
.admin-drawer-header {
    padding-block: 12px;
}

/* The icon rail: one letter where the name was, centred over the icons below it. */
.admin-drawer-mark {
    width: 100%;
    text-align: center;
    font-weight: 700;
}
.mud-drawer-mini.mud-drawer--closed .admin-drawer-header {
    padding-inline: 0;
    justify-content: center;
}

/* Seven groups fully expanded outgrow a laptop screen: the header stays put and the menu scrolls under it,
   in the rail as well as in the open drawer. */
.mud-drawer .mud-drawer-content {
    display: flex;
    flex-direction: column;
    height: 100%;
    overflow-y: auto;
    overflow-x: hidden;
    scrollbar-width: thin;
}
.mud-drawer .admin-drawer-header {
    flex: 0 0 auto;
}

/* The progress bar sits under the app bar rather than at the top of the content, so a page that is loading
   does not shift everything below it down by four pixels and back. The layout's app bar is Dense, which
   MudBlazor draws a quarter lower than --mud-appbar-height (48px of 64), so the bar is put at the dense
   height, as the sticky button bars are (DealerUpsert.razor.css) - at the variable it floated 16px below. */
.admin-progress {
    position: fixed;
    top: calc(var(--mud-appbar-height, 64px) - var(--mud-appbar-height, 64px) / 4);
    left: 0;
    right: 0;
    z-index: 1300;
}

/* ---- Snackbars ------------------------------------------------------------------------------------------
   Top right on a computer (MudBlazor's default, beside the page rather than over its buttons). Below md there
   is no "beside": a toast at the top right covered the upsert pages' sticky Gem/Slet bar, and at the bottom it
   covered whatever came next - the Status tab's "Sæt til aktiv" right after "Maskinen er oprettet". So there a
   toast is a strip laid over the app bar, the one band of the screen that holds no action of the page, and it
   is gone sooner (MpComponentBase: five seconds for a success) or at a tap.

   It stays inside that band whatever it says: at most two lines, 44px of the bar's 48, the rest cut off with
   an ellipsis. A longer toast - most errors are two or three lines at 390px - used to hang 30px down over the
   Gem/Overblik/Slet bar for ten seconds. When text is cut off, the first tap shows all of it (app.js,
   data-mp-expanded) - then, having asked, the reader gets it over the page - and the next tap closes it; the
   cross always closes. Only the newest toast shows here; a second one stacked under it would be over the bar. */
@media (max-width: 959.98px) {
    #mud-snackbar-container.mud-snackbar-location-top-right {
        top: 2px;
        right: 8px;
        bottom: auto;
        left: 8px;
        display: flex;
        flex-direction: column;
        align-items: center;
    }

    #mud-snackbar-container.mud-snackbar-location-top-right .mud-snackbar {
        width: 100%;
        min-width: 0;
        max-width: 560px;
        max-height: 44px;
        margin-top: 0;
        margin-bottom: 4px;
        padding: 2px 4px 2px 10px;
        font-size: 0.8125rem;
        line-height: 1.25;
    }

    #mud-snackbar-container.mud-snackbar-location-top-right .mud-snackbar:not(:last-child) { display: none; }

    #mud-snackbar-container.mud-snackbar-location-top-right .mud-snackbar .mud-snackbar-content-message {
        display: -webkit-box;
        -webkit-box-orient: vertical;
        -webkit-line-clamp: 2;
        line-clamp: 2;
        overflow: hidden;
        padding: 3px 0;
    }

    #mud-snackbar-container.mud-snackbar-location-top-right .mud-snackbar .mud-snackbar-icon {
        padding: 0;
        margin-inline-end: 8px;
    }

    #mud-snackbar-container.mud-snackbar-location-top-right .mud-snackbar .mud-snackbar-icon .mud-icon-root {
        width: 18px;
        height: 18px;
    }

    #mud-snackbar-container.mud-snackbar-location-top-right .mud-snackbar .mud-snackbar-content-action {
        margin-inline-end: 0;
        padding-inline-start: 4px;
    }

    #mud-snackbar-container.mud-snackbar-location-top-right .mud-snackbar .mud-snackbar-close-button {
        margin-inline-start: 0 !important;
    }

    #mud-snackbar-container.mud-snackbar-location-top-right .mud-snackbar[data-mp-expanded] { max-height: none; }

    #mud-snackbar-container.mud-snackbar-location-top-right .mud-snackbar[data-mp-expanded] .mud-snackbar-content-message {
        display: block;
        overflow: visible;
    }
}

/* ---- Keyboard focus ---------------------------------------------------------------------------------------
   MudBlazor takes the outline off every button and marks focus only with a faint tint, so a focused "Nulstil
   filter" looked like an unfocused one and a focused filled button like its neighbours. A ring, for the keyboard
   only (a click does not draw it), in the primary colour - or the bar's own text colour on the app bar. */
.mud-button-root:focus-visible,
.mud-nav-link:focus-visible,
.mud-chip.mud-clickable:focus-visible {
    outline: 2px solid var(--mud-palette-primary);
    outline-offset: 2px;
}
.mud-appbar .mud-button-root:focus-visible { outline-color: currentColor; }
.mud-drawer .mud-nav-link:focus-visible { outline-offset: -2px; }

/* ---- Confirmation message box ------------------------------------------------------------------------------
   MudBlazor's message box (DialogService.ConfirmAsync) has no full-width class, so on a phone its text pushed it
   to the screen's edges, square, unlike every other dialog. The same 32px margins as the rest. */
.mud-dialog.mud-message-box { max-width: min(600px, calc(100% - 64px)); }

/* ---- Drawer: first paint ----------------------------------------------------------------------------------
   The prerender cannot know the width, so the drawer arrives open (or as the rail) and MudBlazor's own
   small-screen guard never matches a Mini drawer. On a phone that squeezed the page into 140px until the circuit
   closed the drawer and slid it away. Below md the drawer now starts where a closed overlay drawer ends - off
   the screen, the page at full width - and stays there until it really is the overlay, so nothing slides.

   Three moments, each held off the screen: the prerendered drawer (mud-drawer--initial); the circuit's first
   frames, before the layout has asked the browser for the width and closed the menu (admin-drawer--pending,
   overlay included); and the frames after that, when MudBlazor still draws a Mini drawer - a closed one is a
   rail at the left edge, narrowing from 250px - until its own width check makes it the temporary overlay
   drawer (mud-drawer-temporary). Below md a Mini drawer that is not yet temporary is only ever that moment. */
@media (max-width: 959.98px) {
    .mud-drawer.mud-drawer-mini:not(.mud-drawer-temporary),
    .mud-drawer.admin-drawer--pending {
        left: calc(-1 * var(--mud-drawer-width-left, 250px));
        box-shadow: none;
        transition: none;
    }
    .mud-layout:has(> .mud-drawer-mini:not(.mud-drawer-temporary)) > .mud-main-content,
    .mud-layout:has(> .admin-drawer--pending) > .mud-main-content { margin-left: 0; }
    .mud-layout:has(> .admin-drawer--pending) .mud-drawer-overlay,
    .mud-layout:has(> .admin-drawer--pending) .mud-overlay-drawer { display: none; }
}

/* ---- First paint: no false "empty" -------------------------------------------------------------------------
   A list page asks for its rows once the circuit runs, so its prerendered table has none and printed its
   empty-state text - "Der er ingen maskiner endnu. De kommer med den første import" - for the moment before the
   rows came, on a slow line for seconds. The layout marks the prerendered content (mp-prerendering); the text
   keeps its room but waits for the circuit, which says it only when it is true. */
.mp-prerendering .mud-table-empty-row { visibility: hidden; }

/* FocusOnNavigate gives the page heading tabindex="-1" and focuses it, so a screen reader announces where
   it landed. Chromium then draws its focus ring around the heading, which on the login page reads as an
   empty text field. The ring is removed only for that programmatic case - a heading cannot be tabbed to,
   so no real keyboard indicator is lost. */
h1[tabindex="-1"]:focus,
h1[tabindex="-1"]:focus-visible {
    outline: none;
}

/* ---- Admin side navigation ----------------------------------------------------------------------
   Compact rows, sections as small labels rather than folders, one clear marker on the current page. Staff
   see twenty pages in six sections; with the rows this tight and only the current section unfolded
   (AdminNavigation.OpenGroupsOnArrival) every section heading is above the fold of a 900px laptop screen. */
.admin-drawer-name { color: var(--mud-palette-primary); font-weight: 700; letter-spacing: -0.01em; }
/* A long dealer name in the drawer header is the one place a phone shows it, so it wraps rather than cuts. */
.admin-drawer-heading, .admin-drawer-audience { min-width: 0; overflow-wrap: anywhere; }
.admin-nav { padding: 4px 8px 16px; }
.admin-nav .mud-nav-link {
    min-height: 32px;
    padding: 3px 10px;
    margin: 1px 0;
    border-radius: 6px;
    font-size: 0.875rem;
    color: var(--mud-palette-text-primary);
}
.mud-navmenu.admin-nav .mud-nav-link:hover { background: rgba(34, 92, 111, 0.07); }
.admin-nav .mud-nav-link .mud-nav-link-icon { font-size: 1.125rem; margin-right: 10px; opacity: 0.7; }
/* Doubled selector: MudBlazor's own active rule has the same weight and would win on order alone. */
/* MudNavLink puts its Class on the wrapping .mud-nav-item, not on the link, so the "active" the side nav
   computes for a detail page (/katalog/specifikationer/{id}) is only reachable through the wrapper. */
.mud-navmenu.admin-nav .mud-nav-link.active,
.mud-navmenu.admin-nav .mud-nav-item.active > .mud-nav-link {
    background: rgba(34, 92, 111, 0.12);
    color: var(--mud-palette-primary);
    font-weight: 600;
    box-shadow: inset 3px 0 0 var(--mud-palette-primary);
}
.mud-navmenu.admin-nav .mud-nav-link.active .mud-nav-link-icon,
.mud-navmenu.admin-nav .mud-nav-item.active > .mud-nav-link .mud-nav-link-icon { color: var(--mud-palette-primary); opacity: 1; }

/* A section's own row is a label: small caps, no folder icon, a quiet chevron. */
.admin-nav .mud-nav-group > .mud-nav-item > .mud-nav-link,
.admin-nav .mud-nav-group > .mud-nav-link {
    margin-top: 8px;
    min-height: 28px;
    padding: 2px 10px;
    font-size: 0.6875rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--mud-palette-text-secondary);
    background: transparent;
}
.admin-nav .mud-nav-group > .mud-nav-item > .mud-nav-link:hover,
.admin-nav .mud-nav-group > .mud-nav-link:hover { background: transparent; color: var(--mud-palette-text-primary); }
.admin-nav .mud-nav-group > .mud-nav-item > .mud-nav-link .mud-nav-link-icon,
.admin-nav .mud-nav-group > .mud-nav-link .mud-nav-link-icon { display: none; }
.admin-nav .mud-nav-link-expand-icon { font-size: 1rem; opacity: 0.5; }

/* Children sit flush under their label instead of a second indent. */
.admin-nav .mud-navgroup-collapse .mud-nav-link,
.admin-nav .mud-navgroup-collapse .mud-nav-item { padding-left: 0; }
.admin-nav .mud-navgroup-collapse .mud-nav-link { padding-left: 10px; }

/* The icon rail (AdminSideNav with the drawer closed, admin-nav--rail): centred icons, each in a tooltip with
   its page's name. The name is hidden from the eye only - display: none would also take it out of the
   accessibility tree and leave twenty links called nothing. Each section opens with a marker: its icon between
   two rules, named by a tooltip, so it reads as a divider and not as a greyed-out entry. */
.admin-nav--rail { padding-inline: 6px; }
.admin-nav--rail .admin-rail-tip,
.admin-drawer-header .admin-rail-tip { display: block; width: 100%; }
.admin-nav--rail .mud-nav-link { justify-content: center; padding: 6px 0; min-height: 40px; }
.admin-nav--rail .mud-nav-link .mud-nav-link-icon { margin: 0; }
.admin-nav--rail .mud-nav-link-text {
    position: absolute !important;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}
.admin-nav--rail .mud-nav-link.active,
.admin-nav--rail .mud-nav-item.active > .mud-nav-link { box-shadow: inset 3px 0 0 var(--mud-palette-primary); }
.admin-rail-heading {
    display: flex;
    align-items: center;
    gap: 4px;
    margin: 10px 0 2px;
    color: var(--mud-palette-text-secondary);
}
.admin-rail-heading::before,
.admin-rail-heading::after { content: ""; flex: 1 1 auto; height: 1px; background: var(--mud-palette-lines-default); }
.admin-rail-heading .mud-icon-root { font-size: 0.9375rem; }

/* ---- Tabs are cards ----------------------------------------------------------------------------
   MudTabs with effects on the container raises and rounds the whole block but leaves the panels without
   a surface, so a form inside it floated on the page background and a grid inside it drew a card of its
   own. The panels are the card's body. */
.mud-tabs.mud-tabs-rounded .mud-tabs-panels,
.mud-tabs .mud-tabs-panels {
    background: var(--mud-palette-surface);
}

/* ---- Cards in a row are equally tall ----------------------------------------------------------------
   The items of a MudGrid row stretch to the tallest, but a card inside an item only grew to its own content,
   so a tile with one more line ("Slået til … 6 planlagt" on Baggrundsjob) stood taller than its neighbours
   (Danny, 15-10-2026). A card that is an item's only child now fills the item - on every page, so a new row of
   tiles cannot miss it. An item with more than one child is left alone. */
.mud-grid-item > .mud-paper:only-child,
.mud-grid-item > .mud-card:only-child {
    height: 100%;
}

/* ---- Toolbar: fields sit side by side at their own width, buttons follow them (the CMS layout) -----
   MudBlazor 9 renders MudStack as a plain "d-flex flex-row" and gives every field flex: 1 1 auto, so a
   five-field bar shared the width equally and became five islands with a sea between them. Fixed widths
   per control type; the buttons stand right after the fields, as in the CMS backend, never on the far
   side. Passive text (a hint, a count) takes the free room on the right. */
.admin-toolbar > .d-flex { gap: 8px 12px; }
.admin-toolbar > .d-flex > .mud-input-control,
.admin-toolbar > .d-flex > .mud-select { flex: 0 0 auto; width: 12.5rem; }
/* The search box always opens the bar and holds a typed name, so it gets the widest slot - and it is the
   one control that gives way when the bar is full, so the row keeps its fields together. */
.admin-toolbar > .d-flex > .mud-input-control:first-child { flex: 1 1 15rem; width: auto; max-width: 20rem; }
/* On a computer the box holds its whole hint: at 20rem "Navn, webadresse, JMA-kode eller stavemåde" and "Kode,
   sammenhæng eller leveret tekst" were cut mid-word, and "Titel, varenr. eller stelnummer" once the menu was a
   rail and the row filled up. The full hint is also the box's tooltip (SearchButton). */
@media (min-width: 1280px) {
    .admin-toolbar > .d-flex > .mud-input-control:first-child { flex-basis: 18rem; max-width: 26rem; }
}
/* A MudBlazor outlined input keeps an intrinsic width (the input's own twenty-character default plus its
   adornment) that is wider than the slot, and used to run under the next field. Everything inside the
   slot shrinks to it. */
.admin-toolbar > .d-flex > .mud-input-control .mud-input-control,
.admin-toolbar > .d-flex > .mud-select .mud-input-control,
.admin-toolbar > .d-flex > .mud-picker .mud-input-control,
.admin-toolbar > .d-flex > .mud-input-control .mud-input-control-input-container,
.admin-toolbar > .d-flex > .mud-select .mud-input-control-input-container,
.admin-toolbar > .d-flex > .mud-picker .mud-input-control-input-container,
.admin-toolbar > .d-flex > .mud-input-control .mud-input,
.admin-toolbar > .d-flex > .mud-select .mud-input,
.admin-toolbar > .d-flex > .mud-picker .mud-input { min-width: 0; width: 100% !important; }
/* The typed value takes the room; the adornment (a glass, the select's arrow) keeps to its own width at
   the right edge. MudBlazor gives the select's arrow the class mud-select-input, so it must be matched by
   its adornment class, never by that one. */
.admin-toolbar > .d-flex .mud-input > .mud-input-slot { flex: 1 1 0; min-width: 0; width: auto; }
.admin-toolbar > .d-flex .mud-input > .mud-input-adornment { flex: 0 0 auto; width: auto; }
.admin-toolbar > .d-flex > .mud-picker { flex: 0 0 auto; width: 10rem; }
/* Tick boxes stand at the fields' height, centred in it. MudBlazor lays the control out as a column, so
   the centring has to be justify-content, not align-items (which only centred it sideways). */
.admin-toolbar > .d-flex > .mud-input-control-boolean-input { width: auto; padding-inline: 4px; min-height: 40px; display: flex; flex-direction: column; justify-content: center; margin: 0; }
.admin-toolbar > .d-flex > .mud-input-control-boolean-input .mud-checkbox { margin: 0; }
/* A labelled outlined field gets 8px above (room for the floating label) and 4px below from MudBlazor, so
   its visible box sat 2px lower than everything centred next to it. Symmetric margins put every visible
   centre - fields, tick boxes, buttons - on the same line. */
.admin-toolbar > .d-flex .mud-input-control.mud-input-outlined-with-label { margin-top: 8px; margin-bottom: 8px; }
.admin-toolbar > .d-flex > .flex-grow-1 { flex: 1 1 auto; }
.admin-toolbar > .d-flex > .mud-button-root,
.admin-toolbar > .d-flex > .mud-menu { flex: none; }
.admin-toolbar .mud-button-root { white-space: nowrap; }
/* Plain text in the bar (a hint, a count) sits on the fields' baseline and takes the free room. */
.admin-toolbar > .d-flex > .mud-typography { flex: 1 1 auto; margin: 0; min-width: 0; text-align: right; }
@media (max-width: 599.98px) {
    .admin-toolbar > .d-flex > .mud-input-control,
    .admin-toolbar > .d-flex > .mud-select { width: 100% !important; }
    /* The search box's 20rem cap is for a row of fields; alone on its row it takes the row. */
    .admin-toolbar > .d-flex > .mud-input-control:first-child { max-width: none; }
}

/* ---- Toolbar filter mode (Toolbar Filters="true", a list page's filter bar) -------------------------
   From md up the "Filtre" button is gone and the bar is the CMS's, so nothing moves on a desktop. Below md
   the fields fold away and is-open brings them back - on a phone one field per row, as before. What stays:
   the search box (SearchButton's admin-search), the button, anything marked admin-toolbar__keep (Genindlæs:
   an action, not a filter) and the passive text after the MudSpacer (a count, a one-line explanation), which
   moves to its own row under the controls instead of squeezing beside them (MudSpacer renders an empty
   div.flex-grow-1). The button follows the fields in the markup, so folded it sits beside the search box
   (under it on a phone) and open it closes the bar. */
.admin-toolbar > .d-flex > .admin-toolbar__filter-toggle { flex: none; }
@media (min-width: 960px) {
    .admin-toolbar--filters .admin-toolbar__filter-toggle { display: none !important; }
}
@media (max-width: 959.98px) {
    .admin-toolbar--filters:not(.is-open) > .d-flex > :not(.admin-search):not(.admin-toolbar__filter-toggle):not(.admin-toolbar__keep):not(.flex-grow-1:empty ~ *) { display: none !important; }
    .admin-toolbar--filters > .d-flex > .flex-grow-1:empty ~ .mud-typography { order: 1; flex-basis: 100%; text-align: left; }
}

/* ---- Grid action columns (the CMS backend's): one narrow centred column per action ---------------- */
.header-centered { text-align: center !important; }
.header-centered .column-header { justify-content: center !important; }

/* ---- Grids: a wide table shows that it scrolls ----------------------------------------------------
   A table wider than its box scrolls inside it (MudBlazor's overflow-x: auto), but the scrollbar sits under
   the last row, often below the fold, so the right-hand columns looked cut off. A soft shadow now marks the
   edge that has more: the two "local" covers ride with the content and hide a shadow once its edge is
   reached, the two "scroll" shadows stay at the box's edges. Pure CSS - no script, and it follows every
   re-render. The shade is mixed from the text colour, so it is a shadow on the light theme and a glow on the
   dark one, where black on near-black showed nothing. */
.mud-table-container {
    --mp-scroll-shade: color-mix(in srgb, var(--mud-palette-text-primary) 20%, transparent);
    background:
        linear-gradient(to right, var(--mud-palette-surface) 40%, transparent) left top / 36px 100% no-repeat local,
        linear-gradient(to left, var(--mud-palette-surface) 40%, transparent) right top / 36px 100% no-repeat local,
        linear-gradient(to right, var(--mp-scroll-shade), transparent) left top / 14px 100% no-repeat scroll,
        linear-gradient(to left, var(--mp-scroll-shade), transparent) right top / 14px 100% no-repeat scroll;
    background-color: var(--mud-palette-surface);
}

/* ---- Grids on a phone: MudBlazor's stacked cards -------------------------------------------------------
   Below a grid's Breakpoint every row becomes a card of "label: value" lines (the label is the column Title).
   Three repairs, for every breakpoint a page may choose:
   - GridStyles.ActionCell's 60px (a CSS variable, see GridStyles) gives way, so an action line spans the card
     like the others instead of wrapping its label ("Kør / nu") beside a button pushed to the left;
   - the label keeps its own width and the value wraps, instead of the other way round;
   - a band of page background between the cards, so where one machine ends and the next begins is visible;
   and a cell with no Title (a tick box) loses the empty label's padding. */
@media (max-width: 600px) {
    .mud-xs-table { --mp-action-cell-width: auto; --mp-action-cell-padding: 6px 16px; }
    .mud-xs-table .mud-table-body .mud-table-cell::before { flex: 0 0 auto; max-width: 45%; }
    .mud-xs-table .mud-table-body .mud-table-cell > * { min-width: 0; overflow-wrap: anywhere; }
    .mud-xs-table .mud-table-body .mud-table-cell[data-label=""]::before,
    .mud-xs-table .mud-table-body .mud-table-cell:not([data-label])::before { display: none; }
    .mud-xs-table .mud-table-body .mud-table-row:not(:last-child) .mud-table-cell:last-child { border-bottom: 8px solid var(--mud-palette-background); }
}
@media (max-width: 960px) {
    .mud-sm-table { --mp-action-cell-width: auto; --mp-action-cell-padding: 6px 16px; }
    .mud-sm-table .mud-table-body .mud-table-cell::before { flex: 0 0 auto; max-width: 45%; }
    .mud-sm-table .mud-table-body .mud-table-cell > * { min-width: 0; overflow-wrap: anywhere; }
    .mud-sm-table .mud-table-body .mud-table-cell[data-label=""]::before,
    .mud-sm-table .mud-table-body .mud-table-cell:not([data-label])::before { display: none; }
    .mud-sm-table .mud-table-body .mud-table-row:not(:last-child) .mud-table-cell:last-child { border-bottom: 8px solid var(--mud-palette-background); }
}
@media (max-width: 1280px) {
    .mud-md-table { --mp-action-cell-width: auto; --mp-action-cell-padding: 6px 16px; }
    .mud-md-table .mud-table-body .mud-table-cell::before { flex: 0 0 auto; max-width: 45%; }
    .mud-md-table .mud-table-body .mud-table-cell > * { min-width: 0; overflow-wrap: anywhere; }
    .mud-md-table .mud-table-body .mud-table-cell[data-label=""]::before,
    .mud-md-table .mud-table-body .mud-table-cell:not([data-label])::before { display: none; }
    .mud-md-table .mud-table-body .mud-table-row:not(:last-child) .mud-table-cell:last-child { border-bottom: 8px solid var(--mud-palette-background); }
}


/* ---- Pager (CmsPager, copied from the CMS backend): fade of the rows after a page change, and the round
   page buttons of the Skyfish-style window ---- */
.cms-fade-in {
    animation: cmsFadeIn .3s ease-out;
}

@keyframes cmsFadeIn {
    from { opacity: 0; transform: translateY(6px); }
    to { opacity: 1; transform: none; }
}

.cms-pager {
    gap: 6px;
}

.cms-pager__page {
    min-width: 34px !important;
    height: 34px;
    padding: 0 10px;
    border-radius: 999px !important;
}

.cms-pager__ellipsis {
    min-width: 20px;
    text-align: center;
    color: var(--mud-palette-text-secondary);
    user-select: none;
}

/* On a phone the numbered buttons (up to eleven of them) wrapped into a second block under a full-width page
   size box. "Side 2 af 5" already says where you are, so the phone keeps the four arrows, beside a page size
   box of its own width: one line under the count. */
/* MudBlazor gives its own pager's page-size select a -14px right margin at 360px and below, and the rule reaches
   ours too (it matches any .mud-select in a table's pagination, and MudSelect carries that class twice): the box
   stuck 28px out of the card and the whole page scrolled sideways on a 360px phone. */
.mud-table .mud-table-pagination .cms-pager-root .mud-select { margin-inline: 0; }

@media (max-width: 599.98px) {
    .cms-pager-root { padding-inline: 0 !important; row-gap: 4px !important; }
    .cms-pager-root > .d-flex { width: 100%; flex-wrap: nowrap !important; justify-content: space-between; }
    .cms-pager-root .cms-pager__page-size { flex: 0 1 8.5rem; width: auto; }
    .cms-pager-root .cms-pager { flex-wrap: nowrap !important; }
    .cms-pager-root .cms-pager__page,
    .cms-pager-root .cms-pager__ellipsis { display: none !important; }
}

/* ---- Accounts and errors ---------------------------------------------------------------------------- */

/* The error banner renders text only; the line breaks MpComponentBase puts between the sentence and the
   technical details for staff are kept. */
.error-banner-text { white-space: pre-line; overflow-wrap: anywhere; }

/* The error boundary's details for staff: the exception as it was thrown, scrollable, never wider than the page. */
.error-boundary-detail {
    max-height: 320px;
    max-width: 100%;
    overflow: auto;
    margin: 0;
    padding: 12px;
    font-size: 12px;
    white-space: pre-wrap;
    overflow-wrap: anywhere;
    background: var(--mud-palette-background-gray);
    border-radius: 4px;
}

/* A password staff read out or copy: no confusable glyphs, fixed width so each character can be counted. */
.dealer-login-password input { font-family: Consolas, "Cascadia Mono", monospace; letter-spacing: .04em; }

/* The facts on /min-konto: label column narrow and quiet. */
.account-facts th {
    width: 40%;
    font-weight: 500;
    color: var(--mud-palette-text-secondary);
    white-space: nowrap;
}
.account-facts td { overflow-wrap: anywhere; }

/* ---- App bar ---------------------------------------------------------------------------------------------
   The page title is one line at every width: a long one (a run's provider and time) ends in an ellipsis
   instead of wrapping out of the 48px bar. The dealer's name stands beside it from sm up, cut short when
   long; on a phone it is in the drawer's header, and the bar keeps its room for the title. */
.admin-appbar-title {
    flex: 0 1 auto;
    min-width: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.admin-appbar-dealer {
    display: none;
    align-items: center;
    gap: 4px;
    flex: 0 1 auto;
    min-width: 0;
    max-width: 30ch;
    margin-left: 12px;
}
.admin-appbar-dealer__name {
    font-size: 0.875rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
@media (min-width: 600px) {
    .admin-appbar-dealer { display: inline-flex; }
}
@media (max-width: 599.98px) {
    .admin-appbar-title { font-size: 1.0625rem; }
}
/* The avatar menu's activator is MudMenu's own div (role=button, tabindex=0). MudBlazor lays it out as
   display: contents, which a browser will not focus - it counted on a button inside - so it is a box again
   here, and gets a round focus ring around the picture, shown to the keyboard only. */
.admin-user-menu-wrap,
.admin-user-menu__face { display: inline-flex; }
.mud-menu.admin-user-menu > .mud-menu-activator { display: inline-flex; border-radius: 50%; cursor: pointer; }
.mud-menu.admin-user-menu > .mud-menu-activator:focus-visible { outline: 2px solid currentColor; outline-offset: 2px; }

/* ---- "Log ind som forhandler" ---------------------------------------------------------------------------
   An administrator acting as a dealer sees the admin as the dealer does, and must never mistake it for their own:
   the app bar turns amber, and a strip over every page says whose admin it is, the name everything is logged in
   and when it ends. The colour pair is its own and the same in both themes - amber with near-black text, about
   9:1 on the bar and 13:1 on the strip - not the palette's Warning: the light palette has no WarningContrastText,
   and the white text MudBlazor would put on amber is unreadable. Everything inside takes the dark text (the
   bar's buttons are Color.Inherit). */
.mud-appbar.admin-appbar--acting {
    background-color: #ffb300;
    color: rgba(0, 0, 0, 0.87);
}

.acting-banner {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: -4px 0 12px;
    padding: 4px 6px 4px 12px;
    border-left: 4px solid #ffb300;
    border-radius: 4px;
    background-color: #ffe08a;
    color: rgba(0, 0, 0, 0.87);
    font-size: 0.875rem;
    line-height: 1.4;
}
.acting-banner__icon { flex: none; }
.acting-banner__text { flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; }
.acting-banner__short { display: none; }

/* The way back is a form of its own; it sits in a row like the button it holds. */
.acting-return { display: inline-flex; margin: 0; }
.acting-return__short { display: none; }

/* A phone: the strip is one line ("Som <dealer> · slutter kl. 15:42" and "Tilbage"), a long name ending in an
   ellipsis - the whole sentence is in its title - and the bar's button says "Tilbage". The long words are hidden
   from the eye only, the way .mp-visually-hidden does it, so a screen reader still hears the whole sentence (the
   short "Som " is aria-hidden); display: none would take them from it too. */
@media (max-width: 599.98px) {
    .acting-banner { padding-left: 8px; }
    .acting-banner__text { position: relative; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; overflow-wrap: normal; }
    .acting-banner__long,
    .acting-banner__audit {
        position: absolute;
        width: 1px;
        height: 1px;
        margin: -1px;
        padding: 0;
        overflow: hidden;
        clip-path: inset(50%);
        white-space: nowrap;
        border: 0;
    }
    .acting-banner__short { display: inline; }
    .acting-return__long { display: none; }
    .acting-return__short { display: inline; }
}

/* The one-line help under the app bar (Title's Help): what the page is for, before anything else. */
.admin-page-help { margin: -4px 0 12px; }

/* ---- Login: the server's messages are the errors ---------------------------------------------------------
   The form is novalidate and static, so no MudBlazor field is ever told it is invalid; a field whose Danish
   message is showing is outlined and labelled in the error colour here instead, and the message sits under it
   where MudBlazor puts its own. */
/* Only a message that is there: .NET renders an empty, hidden placeholder for every field's message on every
   load (for client-side validation), and matching the class alone painted both fields red on a fresh form - and
   the e-mail field red after a wrong password, as if the address were the problem. */
.auth-field:has(.auth-field__error:not([hidden]):not(:empty)) .mud-input-outlined-border { border-color: var(--mud-palette-error) !important; }
.auth-field:has(.auth-field__error:not([hidden]):not(:empty)) .mud-input-label { color: var(--mud-palette-error) !important; }
.auth-field__error { margin: 4px 14px 0; font-size: 0.8125rem; }

/* ---- Utilities -------------------------------------------------------------------------------------------- */

/* A long unbroken value (a URL, a file name, an e-mail, a JMA code) wraps inside its box instead of pushing the
   page sideways on a phone. min-width: 0 lets it do so inside a flex row as well. */
.mp-wrap-anywhere { overflow-wrap: anywhere; word-break: normal; min-width: 0; }

/* Words that wrap between themselves (and at a <wbr>), cut only when one alone is wider than its box. Unlike
   mp-wrap-anywhere it keeps a table column as wide as its longest word, so a grid with many columns does not squeeze
   a name into one letter per line. */
.mp-wrap-word { overflow-wrap: break-word; min-width: 0; }

/* A shortened column title (AbbrHeader): dotted like an abbreviation, with the full words in its tooltip. */
.mp-abbr { text-decoration: underline dotted; text-underline-offset: 3px; cursor: help; }

/* ResetFilterButton: the badge sits on the button's corner without pushing the next field away. */
.mp-reset-filter { display: inline-flex; }

/* Hidden from the eye, read by a screen reader: a label an icon already says for the sighted. */
.mp-visually-hidden {
    position: absolute !important;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

/* A tooltip is text, never a target. Its popover can open over the button next to the one hovered (a row of
   grid actions, the pager's arrows), and it used to swallow the click meant for that button. */
.mud-tooltip { pointer-events: none; }
