h1:focus {
    outline: none;
}

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

/* The field a failure message is about. The toast says what is wrong and this says where:
   a message in the corner of the screen is no help on a form long enough to scroll.

   .invalid is what Blazor marks an input with when validation refuses it, and .field-error is
   what this application marks one with by hand. They are given the same treatment on purpose:
   a refusal from an annotation and a refusal from the domain are the same thing to whoever is
   looking at the form, and two shades of wrong on one screen is a distinction nobody can
   learn. Blazor's own thin outline is replaced rather than added to for the same reason. */
.invalid,
.field .invalid,
.field-error,
.field .field-error {
    border-color: var(--bad) !important;
    background: var(--bad-bg);
    outline: none;
}

.invalid:focus,
.field .invalid:focus,
.field-error:focus,
.field .field-error:focus {
    border-color: var(--bad) !important;
    box-shadow: 0 0 0 3px rgba(179, 38, 30, 0.18);
}

/* On a group, the ring goes round the whole control rather than the box inside it. */
.input-group:has(.field-error),
.input-group:has(.invalid) {
    border-color: var(--bad);
    background: var(--bad-bg);
}

.validation-message {
    color: var(--bad);
}

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

/* ==========================================================================
   Merlinium brand design system
   Palette taken from the brand mark (#E7EDE8 cream, #D3A037 gold) and the hero
   plate (deep forest green). Dark-green chrome, light content, gold accents.
   ========================================================================== */

:root {
    /* Forest greens */
    --green-900: #071b15;
    --green-850: #0a231c;
    --green-800: #0d2c22;
    --green-700: #123a2c;
    --green-600: #17493a;
    --green-500: #1f5c49;

    /* Gold */
    --gold: #d3a037;

    /* The yellow of a UK rear number plate. Close to the brand gold and deliberately not
       the same value: a plate that is off-colour reads as a graphic rather than as a plate. */
    --plate-yellow: #f4d000;
    --gold-300: #e7c67e;
    --gold-600: #b8862c;

    /* Neutrals */
    --cream: #e7ede8;
    --ink: #14251e;
    --muted: #5f6f67;
    --line: #d8ddd2;
    --input-border: #7a887e;
    --bg: #f6f3eb;
    --surface: #fffdf7;
    --surface-2: #f2eee4;

    /* Pale supporting surfaces and the shared green/white section headings. These tokens
       style application sections directly, so no MudBlazor palette mirror is needed. */
    --section-header: #e9f0ec;
    --section-header-hover: #e0eae4;
    --section-heading-background: var(--green-700);
    --section-heading-foreground: #fff;
    --section-heading-hover: var(--green-800);

    /* Status */
    --ok: #1f7a4d;
    --ok-bg: #e5f4ec;
    --warn: #9a6b12;
    --warn-bg: #f8efd9;
    --bad: #b3261e;
    --bad-bg: #fbe9e7;

    --radius: 6px;
    --radius-sm: 3px;
    --shadow: 0 1px 2px rgba(7, 27, 21, 0.05);
    --shadow-lg: 0 12px 40px rgba(7, 27, 21, 0.18);
    --sidebar-w: 264px;
    --font: system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    --font-display: "Blinker", system-ui, sans-serif;
}

@font-face {
    font-family: "Blinker";
    src: url("fonts/Blinker-Regular.ttf") format("truetype");
    font-style: normal;
    font-weight: 400;
    font-display: swap;
}

@font-face {
    font-family: "Blinker";
    src: url("fonts/Blinker-SemiBold.ttf") format("truetype");
    font-style: normal;
    font-weight: 600;
    font-display: swap;
}

@font-face {
    font-family: "Blinker";
    src: url("fonts/Blinker-Bold.ttf") format("truetype");
    font-style: normal;
    font-weight: 700;
    font-display: swap;
}

*, *::before, *::after {
    box-sizing: border-box;
}

html {
    color-scheme: light;
}

body {
    margin: 0;
    font-family: var(--font);
    font-size: 16px;
    line-height: 1.55;
    color: var(--ink);
    background: var(--bg);
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
}

h1, h2, h3, h4 {
    font-family: var(--font-display);
    line-height: 1.2;
    margin: 0 0 0.5em;
    letter-spacing: -0.01em;
    color: var(--green-800);
}

h1 { font-size: 1.8rem; font-weight: 700; }
h2 { font-size: 1.3rem; font-weight: 600; }

a:where(:not([class*="mud-"])) {
    color: var(--green-600);
    text-decoration: none;
}

a:where(:not([class*="mud-"])):hover {
    text-decoration: underline;
}

code {
    font-family: ui-monospace, "Cascadia Code", "SF Mono", Menlo, Consolas, monospace;
    font-size: 0.88em;
    background: var(--surface-2);
    border: 1px solid var(--line);
    border-radius: 5px;
    padding: 0.08em 0.4em;
    color: var(--green-700);
}

/* ---- Buttons ------------------------------------------------------------ */
/*
   The :where(:not([class*="mud-"])) on every bare-element rule below is the seam that lets the
   conversion to the component library happen a page at a time. These rules style elements
   rather than classes, so without it a MudButton (which is a <button>) would come out gold
   and a MudTable (which is a <table>) would take these borders, on every page whether it
   had been converted or not.

   The :where() is not decoration and must not be unwrapped. It contributes no specificity,
   so `a:where(:not(...))` still scores as plain `a` and still loses to a class. Written as
   `a:not(...)` the rule outscores every class in this file: the sidebar links went dark
   green on a dark green sidebar, because .shell__link stopped winning.

   Every one of these is deleted once the last hand-written form and table is gone. If you
   are reading this after that has happened, the rule is dead and so is the exclusion.
*/
button:where(:not([class*="mud-"])),
.btn {
    font: inherit;
    font-weight: 600;
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.55rem 1.1rem;
    border-radius: var(--radius-sm);
    border: 1px solid transparent;
    background: var(--gold);
    color: #201400;
    cursor: pointer;
    transition: background 0.15s ease, box-shadow 0.15s ease, transform 0.05s ease;
}

button:where(:not([class*="mud-"])):hover,
.btn:hover {
    background: var(--gold-300);
}

button:where(:not([class*="mud-"])):active,
.btn:active {
    transform: translateY(1px);
}

button:where(:not([class*="mud-"])):disabled {
    opacity: 0.55;
    cursor: not-allowed;
}

button.secondary:where(:not([class*="mud-"])),
.btn.secondary {
    background: var(--surface);
    border-color: var(--line);
    color: var(--green-700);
}

button.secondary:where(:not([class*="mud-"])):hover,
.btn.secondary:hover {
    background: var(--surface-2);
    border-color: #cfd6cf;
}

button:where(:not([class*="mud-"])):focus-visible,
.btn:focus-visible,
a:where(:not([class*="mud-"])):focus-visible,
input:where(:not([class*="mud-"])):focus-visible {
    outline: 2px solid var(--gold);
    outline-offset: 2px;
}

/* ---- Cards -------------------------------------------------------------- */
.card {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    padding: 1.5rem;
}

.card + .card {
    margin-top: 1.25rem;
}

/* ---- Collapsible form section (Ui/CollapsibleSection) -------------------- */
/* The card is a MudPaper, so it brings its own surface, radius and elevation. These styles
   are the tinted header band and the body padding that replace the old "pa-4 mb-4" card. */
.collapsible-section {
    margin-bottom: 1rem;
    /* Clip the header band's top corners to the card's radius. */
    overflow: hidden;
}

.collapsible-section__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    width: 100%;
    padding: 0.75rem 1rem;
    border: 0;
    cursor: pointer;
    text-align: left;
    font-family: inherit;
    background: var(--section-heading-background);
    color: var(--section-heading-foreground);
}

.collapsible-section__header:hover {
    background: var(--section-heading-hover);
}

.collapsible-section__title {
    /* Matches MudBlazor's Typo.h6, so a converted section reads the same as before. */
    font-size: 1.25rem;
    font-weight: 500;
    line-height: 1.6;
    color: var(--section-heading-foreground);
}

.collapsible-section__body {
    padding: 1rem;
}

/* ---- Side-by-side section pairs ------------------------------------------ */
/* A page built from many CollapsibleSections (Owner/TenantEdit is the reference) reads as one
   long scroll when every card is full width, even though most of them hold two or three fields
   and a wide screen has room to spare. Wrap a short, unrelated pair in .section-row so they sit
   side by side from 900px up and stack in document order below it. A section with its own
   multi-field grid (Postal address, Sage account) is left full width instead of paired: halving
   its card would just squeeze that grid into a narrower one. */
.section-row {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    margin-bottom: 1rem;
}

.section-row > .collapsible-section {
    margin-bottom: 0;
}

@media (min-width: 900px) {
    .section-row {
        display: grid;
        grid-template-columns: 1fr 1fr;
    }
}

.page-head {
    margin-bottom: 1.5rem;
}

/* No measure cap. At 60ch the standfirst broke mid-sentence a third of the way across
   a wide page, which reads as a stray line break rather than as a column. */
.page-head p {
    color: var(--muted);
    margin: 0.25rem 0 0;
}

/* Page-level actions sit beside the heading on a wide screen and wrap under it on a narrow
   one. They are not in the flex row with the heading text, because a long tenant name would
   then squeeze the button rather than wrapping itself. */
.page-head__actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    margin-top: 1rem;
}

@media (min-width: 760px) {
    .page-head:has(.page-head__actions) {
        display: flex;
        align-items: flex-end;
        justify-content: space-between;
        gap: 1.5rem;
    }

    .page-head__actions {
        margin-top: 0;
        flex-shrink: 0;
    }
}

/* ---- Tables ------------------------------------------------------------- */
/* Scoped away from the component library's own tables. See the note above the buttons. */
table:where(:not([class*="mud-"])) {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.95rem;
}

table:where(:not([class*="mud-"])) thead th {
    text-align: left;
    font-size: 0.72rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--muted);
    font-weight: 650;
    padding: 0.6rem 0.9rem;
    border-bottom: 1px solid var(--line);
    white-space: nowrap;
}

table:where(:not([class*="mud-"])) tbody td {
    padding: 0.75rem 0.9rem;
    border-bottom: 1px solid var(--line);
    vertical-align: top;
}

table:where(:not([class*="mud-"])) tbody tr:last-child td {
    border-bottom: 0;
}

table:where(:not([class*="mud-"])) tbody tr:hover {
    background: var(--surface-2);
}

.table-wrap {
    overflow-x: auto;
}

/* ---- Status badges ------------------------------------------------------ */
.badge {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    font-size: 0.78rem;
    font-weight: 650;
    padding: 0.2rem 0.6rem;
    border-radius: 999px;
    border: 1px solid transparent;
    white-space: nowrap;
}

.badge::before {
    content: "";
    width: 0.45rem;
    height: 0.45rem;
    border-radius: 999px;
    background: currentColor;
}

.badge.state-active { color: var(--ok); background: var(--ok-bg); }
.badge.state-failed { color: var(--bad); background: var(--bad-bg); }
.badge.state-suspended,
.badge.state-pending { color: var(--warn); background: var(--warn-bg); }

.failure { color: var(--bad); }
.suspension { color: var(--warn); }

/* ---- Forms -------------------------------------------------------------- */
.field {
    margin-bottom: 1.1rem;
    max-width: 32rem;
}

.field label {
    display: block;
    font-weight: 600;
    font-size: 0.9rem;
    margin-bottom: 0.35rem;
    color: var(--green-800);
}

.field small {
    display: block;
    color: var(--muted);
    margin-top: 0.35rem;
    font-size: 0.85rem;
}

/* Required fields, marked the same way in both families of markup this application has.

   The MudBlazor fields are marked with Class="required-field" rather than with MudBlazor's own
   Required, and that is deliberate. Required feeds MudBlazor's validation as well as its label,
   so a mark meant to say "this one matters" would also change when the field turns red and what
   it says when it does, on top of the annotation already validating it. A mark should be a mark.
   The asterisk is drawn here instead, in the same place MudBlazor would have drawn it.

   The plain .field labels get a span instead, because a <label> there is ours to write and an
   ::after on every label would mark the optional ones too.

   MudBlazor's own asterisk is coloured as well, so that a field marked the other way still
   looks like the rest rather than like a black mark nobody chose. */
.required-field > .mud-input-control-input-container > .mud-input-label::after,
.mud-input-control.mud-input-required > .mud-input-control-input-container > .mud-input-label::after {
    content: "*";
    color: var(--bad);
    font-weight: 700;
    margin-inline-start: 0.15rem;
}

.required {
    color: var(--bad);
    font-weight: 700;
    margin-inline-start: 0.15rem;
}

/* One line per form saying what the asterisk means. A mark nobody has been told the meaning
   of is decoration, and this is the sentence that makes it a convention. */
.required-legend {
    margin: 0 0 1rem;
    color: var(--muted);
    font-size: 0.9rem;
}

input[type="text"],
input[type="email"],
input[type="password"],
.field input {
    width: 100%;
    font: inherit;
    padding: 0.6rem 0.75rem;
    border: 1px solid #cfd6cf;
    border-radius: var(--radius-sm);
    background: var(--surface);
    color: var(--ink);
}

/* A listbox, not a dropdown: several rows visible at once so a search can be judged
   while it is being typed. Rows are comfortable to click rather than packed. */
.field select[size] {
    padding: 0.25rem;
    font-size: 0.95rem;
}

.field select[size] option {
    padding: 0.35rem 0.5rem;
    border-radius: 4px;
}

/* Ui/SearchSelect: the second column (a postcode, a code) sits right and quieter, so the
   eye runs down the names first, as in a lookup grid. */
.search-select__row {
    display: flex;
    gap: 1rem;
    justify-content: space-between;
    width: 100%;
}

.search-select__detail {
    color: var(--mud-palette-text-secondary);
    text-align: right;
    white-space: nowrap;
}

/* Selects were left at the browser default, which sizes to its longest option, so a
   picker of Defra descriptions was several times wider than the text box above it, and
   in a fluid column that is the element that decides where the column ends. */
.field select {
    width: 100%;
    max-width: 100%;
    font: inherit;
    padding: 0.6rem 0.75rem;
    border: 1px solid #cfd6cf;
    border-radius: var(--radius-sm);
    background: var(--surface);
    color: var(--ink);
}

input:where(:not([class*="mud-"])):focus,
select:where(:not([class*="mud-"])):focus,
textarea:where(:not([class*="mud-"])):focus {
    border-color: var(--gold);
    outline: none;
    box-shadow: 0 0 0 3px rgba(211, 160, 55, 0.2);
}

.field textarea {
    width: 100%;
    font: inherit;
    padding: 0.6rem 0.75rem;
    border: 1px solid #cfd6cf;
    border-radius: var(--radius-sm);
    background: var(--surface);
    color: var(--ink);
    min-height: 6rem;
    line-height: 1.5;
    resize: vertical;
}

/* A field that runs the full width of its card rather than the ~32rem reading
   measure: used for long free text such as internal notes. */
.field--wide {
    max-width: none;
}

.field--wide textarea {
    width: 100%;
    min-height: 13rem;
}

/* Fields side by side (e.g. county + postcode).
   auto-fit rather than a fixed column count with a breakpoint: the number of columns
   then follows the space the card actually has, which is not the same thing as the
   width of the window: the same card sits in a 1560px page and in a 320px drawer. */
.field-row {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
    gap: 0 1.25rem;
    align-items: start;
}

/* A whole card's worth of fields laid out fluidly. Used on the long forms, where a
   single 32rem column wastes most of a wide screen and makes the form look longer
   than it is. Reading measure is preserved per field by the minmax floor. */
.form-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 20rem), 1fr));
    gap: 0 1.5rem;
    align-items: start;
}

/* Inside either grid the track is already the measure, so the per-field cap would
   only leave a ragged gap on the right. */
.field-row > .field,
.form-grid > .field {
    max-width: none;
}

/* One column, whatever the screen. For fields that are read as a sequence rather than
   as a set: an address is five lines of one thing, and spreading it across a row makes
   the reader assemble it. */
.form-stack {
    display: flex;
    flex-direction: column;
    max-width: 34rem;
}

.form-stack h3 {
    margin: 0.75rem 0 0.85rem;
    padding-top: 1rem;
    border-top: 1px solid var(--line);
    font-size: 0.95rem;
    letter-spacing: 0.02em;
}

.form-stack .field {
    max-width: none;
}

/* A field that should take the whole grid rather than one track, a description or
   a note, which reads badly in a narrow column beside a postcode. */
.form-grid > .field--span {
    grid-column: 1 / -1;
}

.validation-message,
.sign-in-error {
    color: var(--bad);
    font-size: 0.88rem;
    margin: 0.35rem 0 0;
}

/* ---- Definition lists (proof / result panels) --------------------------- */
dl.proof,
.result-success dl,
.result-failure dl {
    display: grid;
    grid-template-columns: minmax(12rem, auto) 1fr;
    gap: 0.5rem 1.5rem;
    margin: 0;
}

dl.proof dt,
.result-success dt,
.result-failure dt {
    color: var(--muted);
    font-size: 0.85rem;
}

dl.proof dd,
.result-success dd,
.result-failure dd {
    margin: 0;
    font-weight: 550;
}

.result-success,
.result-failure {
    margin-top: 1.5rem;
    padding: 1.25rem 1.5rem;
    border-radius: var(--radius);
    border: 1px solid var(--line);
}

.result-success { background: var(--ok-bg); border-color: #bfe2cd; }
.result-failure { background: var(--bad-bg); border-color: #f0c9c5; }

.actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    margin-bottom: 1.5rem;
}

/* ---- Brand hero band (uses hero-plate.png) ------------------------------ */
.brand-hero {
    position: relative;
    border-radius: var(--radius);
    overflow: hidden;
    background: var(--green-800) center/cover no-repeat;
    color: var(--cream);
    padding: 2rem 2rem;
    box-shadow: var(--shadow);
    margin-bottom: 1.5rem;
}

.brand-hero::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(90deg, rgba(7, 27, 21, 0.85) 0%, rgba(7, 27, 21, 0.55) 45%, rgba(7, 27, 21, 0.2) 100%);
    z-index: 0;
}

.brand-hero > * {
    position: relative;
    z-index: 1;
}

.brand-hero h1 {
    color: var(--cream);
    margin: 0;
}

.brand-hero p {
    margin: 0.4rem 0 0;
    color: rgba(231, 237, 232, 0.82);
}

.brand-hero .eyebrow {
    text-transform: uppercase;
    letter-spacing: 0.22em;
    font-size: 0.72rem;
    font-weight: 650;
    color: var(--gold-300);
}

/* ---- Stat tiles --------------------------------------------------------- */
.stat-row {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
    gap: 1rem;
    margin-bottom: 1.5rem;
}

.stat {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    padding: 1.1rem 1.25rem;
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
}

.stat__value {
    font-size: 1.9rem;
    font-weight: 700;
    line-height: 1;
    color: var(--green-800);
    font-variant-numeric: tabular-nums;
}

.stat__label {
    font-size: 0.8rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--muted);
    font-weight: 600;
}

/* ---- Migration run list ------------------------------------------------- */
.run-list {
    list-style: none;
    margin: 0.5rem 0 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}

.run-list li {
    padding: 0.5rem 0.75rem;
    border-radius: var(--radius-sm);
    background: var(--surface-2);
    border-left: 3px solid var(--muted);
    font-size: 0.92rem;
}

.run-list li.ok { border-left-color: var(--ok); }
.run-list li.failure { border-left-color: var(--bad); }

/* ---- Stat tile emphasis ------------------------------------------------- */
/* A failed provision always needs action, so its tile turns red when non-zero
   rather than reading the same as a healthy count. Outstanding bills warn in amber. */
.stat--alert {
    border-color: #f0c9c5;
    background: var(--bad-bg);
}

.stat--alert .stat__value { color: var(--bad); }

.stat--warn {
    border-color: #ecd9a8;
    background: var(--warn-bg);
}

.stat--warn .stat__value { color: var(--warn); }

/* An outstanding bill leaves the tenant Active but shows as its own status. */
.badge.state-outstanding { color: var(--warn); background: var(--warn-bg); }

/* ---- Table toolbar / search -------------------------------------------- */
/* The search grows into whatever is left over and the action stays on the right,
   until there is no room for both and the action wraps under it. */
.table-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: flex-end;
    gap: 0.75rem;
    margin-bottom: 1rem;
}

.table-toolbar .search {
    flex: 1 1 14rem;
    max-width: 28rem;
    margin-right: auto;
}

.search {
    width: min(22rem, 100%);
    font: inherit;
    padding: 0.55rem 0.75rem;
    border: 1px solid #cfd6cf;
    border-radius: var(--radius-sm);
    background: var(--surface);
    color: var(--ink);
}

.col-actions { text-align: right; white-space: nowrap; }

.table-empty {
    text-align: center;
    color: var(--muted);
    padding: 1.25rem;
}

/* ---- Link styled as a button (navigation, not submission) --------------- */
.button-link {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.4rem 0.85rem;
    border-radius: var(--radius-sm);
    background: var(--green-800);
    color: var(--cream);
    font-size: 0.9rem;
    font-weight: 600;
    text-decoration: none;
    border: 1px solid transparent;
}

.button-link:hover { text-decoration: none; filter: brightness(1.08); }

.button-link.secondary {
    background: var(--surface-2);
    color: var(--green-800);
    border-color: var(--line);
}

/* ---- Radio option rows (status picker) ---------------------------------- */
/* Radio/checkbox controls sit to the LEFT of their label text and must not inherit
   the full-width sizing that .field input applies to text inputs. */
.field input[type="radio"],
.field input[type="checkbox"] {
    width: auto;
    margin: 0;
    flex: none;
    accent-color: var(--gold-600);
}

.field .radio {
    display: flex;
    align-items: flex-start;
    gap: 0.6rem;
    padding: 0.5rem 0;
    margin: 0;
    font-weight: 400;
    color: var(--ink);
    cursor: pointer;
}

.field .radio input { margin-top: 0.25rem; }

/* ---- Payment holding page ---------------------------------------------- */
.billing-hold {
    max-width: 34rem;
    margin: 3rem auto;
    padding: 2rem;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
}

.billing-hold .eyebrow {
    text-transform: uppercase;
    letter-spacing: 0.2em;
    font-size: 0.72rem;
    font-weight: 650;
    color: var(--warn);
}

.billing-hold__contact {
    list-style: none;
    margin: 0.5rem 0 1.5rem;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}

.billing-hold__contact li {
    display: flex;
    gap: 0.75rem;
}

.billing-hold__contact span {
    color: var(--muted);
    font-weight: 600;
    min-width: 4rem;
}

/* ---- Misc --------------------------------------------------------------- */
.hint {
    color: var(--muted);
    font-size: 0.9rem;
}

section + section {
    margin-top: 1.5rem;
}

/* ==========================================================================
   Static authentication journey. AuthLayout owns the chrome; AuthFrame owns the
   shared panel. Forms stay server-rendered and retain native browser behaviour.
   ========================================================================== */
.auth-page { min-height: 100vh; padding: 1.75rem 1.5rem 1rem; }
.auth-page__header { max-width: 70rem; margin: auto; display: flex; align-items: center; justify-content: space-between; gap: 1rem; }
.auth-page__brand { display: flex; align-items: center; gap: .75rem; color: var(--green-800); font: 600 1.65rem var(--font-display); }
.auth-page__brand img { background: var(--green-800); border-radius: var(--radius-sm); padding: 5px; }
.auth-page__header-note { color: var(--muted); font-size: .85rem; }
.auth-page__header form { margin: 0; }
.auth-page__header button { min-height: 44px; }
.auth-page__main { padding: 2.5rem 0 1rem; }
.auth-page__main:focus { outline: none; }
.auth-page__footer { text-align: center; padding: 1rem 0; color: var(--muted); font-size: .8rem; }
.auth { display: grid; grid-template-columns: minmax(0, .9fr) minmax(0, 1.2fr); max-width: 66rem; margin: 0 auto; background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow); overflow: hidden; }
.auth__panel { grid-column: 2; grid-row: 1; min-width: 0; padding: 2.75rem; }
.auth__heading { margin-bottom: 1.75rem; }
.auth__heading h1 { font-size: clamp(1.85rem, 3vw, 2.3rem); line-height: 1.15; margin: 0; }
.auth__eyebrow { color: var(--green-600); text-transform: uppercase; font-size: .75rem; font-weight: 700; letter-spacing: .1em; margin: 0 0 .85rem; }
.auth__description { margin: .85rem 0 0; color: var(--muted); }
.auth__brand-panel { grid-column: 1; grid-row: 1; display: grid; place-items: center; min-width: 0; padding: 3rem; background: radial-gradient(ellipse at 50% 40%, #204637, #102d22 75%); }
.auth__brand-panel img { display: block; width: clamp(6rem, 12vw, 9rem); max-width: 100%; height: auto; opacity: .8; }
.auth form { margin: 0; }
.auth .field { margin: 0 0 1.35rem; }
.auth .field label { margin-bottom: .5rem; font-size: .9rem; color: var(--ink); font-weight: 650; }
.auth .field input:not([type=checkbox]) { min-height: 48px; font-size: 1rem; width: 100%; min-width: 0; border: 1px solid var(--input-border); }
.auth__label-row { display: flex; justify-content: space-between; flex-wrap: wrap; align-items: baseline; gap: .25rem .75rem; margin-bottom: .5rem; }
.auth__label-row label { margin-bottom: 0 !important; }
.auth__label-row a { font-size: .85rem; }
.auth a { text-decoration: underline; text-underline-offset: .2em; }
.auth__field-hint { font-size: .85rem; color: var(--muted); margin: .5rem 0 0; }
.auth__password { display: flex; align-items: stretch; gap: .5rem; }
.auth__password input { flex: 1 1 0; }
.auth .password-toggle { flex: 0 0 auto; min-width: 4rem; min-height: 48px; padding: .5rem; margin: 0; font-size: .85rem; border-color: var(--input-border); }
.auth__remember { display: flex; gap: .65rem; align-items: flex-start; min-height: 44px; cursor: pointer; font-size: .9rem; margin: 0 0 1.25rem; }
.auth__remember input { width: 1.1rem; height: 1.1rem; margin: .15rem 0 0; accent-color: var(--green-600); }
.auth__remember small { display: block; font-size: .8rem; color: var(--muted); margin-top: .2rem; }
.auth .auth__submit, .auth .auth__button-link { width: 100%; min-height: 48px; display: flex; align-items: center; justify-content: space-between; gap: .75rem; padding: .75rem 1rem; font-size: 1rem; line-height: 1.4; white-space: normal; text-align: left; }
.auth .auth__button-link { background: var(--gold); color: var(--green-900); border: 1px solid var(--gold-600); border-radius: var(--radius-sm); text-decoration: none; font-weight: 600; }
.auth .auth__button-link:hover { background: var(--gold-300); }
.auth__submit span, .auth__button-link span { flex: 0 0 auto; }
.auth__note { color: var(--muted); font-size: .9rem; margin: 1.25rem 0; }
.auth__help { border-top: 1px solid var(--line); padding-top: 1.25rem; margin-top: 1.5rem; font-size: .875rem; }
.auth__help strong { color: var(--green-800); }
.auth__help p { margin: .5rem 0 0; color: var(--muted); }
.auth__help a { display: inline-block; margin-top: .5rem; padding: .5rem 0; }
.auth__back { margin: 1.5rem 0 0; font-size: .9rem; }
.auth__back a { display: inline-flex; align-items: center; min-height: 44px; }
.auth__choice { border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 1rem; margin: 0 0 1rem; }
.auth__choice h2 { font-size: 1rem; margin: 0; color: var(--green-800); }
.auth__choice h2 small { margin-left: .5rem; font-size: .75rem; font-weight: 600; color: var(--green-600); }
.auth__choice > p { font-size: .875rem; color: var(--muted); margin: .4rem 0 1rem; }
.auth__choice .field { margin-bottom: 1rem; }
.auth__resend { margin: 1rem 0 0; }
.auth__resend button { min-height: 44px; }
.auth__error, .auth__notice { padding: 1rem; margin: 0 0 1.5rem; border-left: 3px solid var(--green-500); background: var(--section-header); overflow-wrap: anywhere; }
.auth__error { color: var(--bad); border-color: var(--bad); background: var(--bad-bg); }
.auth__error p, .auth__notice p { margin: .5rem 0 0; }
.auth__error p:first-child, .auth__notice p:first-child { margin-top: 0; }
.auth__error a { color: var(--bad); display: inline-block; padding: .5rem 0; }
.auth .validation-message { margin-top: .4rem; font-size: .875rem; }
.auth :is(input, button, a, summary, [tabindex]):focus-visible { outline: 3px solid var(--green-500); outline-offset: 3px; }
.auth .otp-input.otp-input { max-width: 15rem; font-family: ui-monospace, monospace; font-size: 1.7rem; font-weight: 600; text-align: center; letter-spacing: .4em; text-indent: .4em; padding: .65rem .5rem; }
.auth__disclosure { border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); margin: 1.5rem 0 0; font-size: .875rem; }
.auth__disclosure summary { min-height: 48px; padding: .85rem 0; font-weight: 650; cursor: pointer; color: var(--green-700); }
.auth__disclosure p { margin: 0 0 1rem; color: var(--muted); }
.auth__setup-steps { list-style: none; counter-reset: auth-step; padding: 0; margin: 0 0 1.5rem; }
.auth__setup-steps > li { position: relative; padding-left: 2.5rem; margin-bottom: 1.5rem; counter-increment: auth-step; }
.auth__setup-steps > li::before { content: counter(auth-step); position: absolute; left: 0; top: 0; width: 1.75rem; height: 1.75rem; display: grid; place-items: center; background: var(--section-header); border: 1px solid var(--input-border); border-radius: 50%; font-size: .85rem; font-weight: 650; color: var(--green-700); }
.auth__setup-steps > li > strong { display: block; padding-top: .1rem; font-size: .95rem; }
.auth__setup-steps > li > p { font-size: .875rem; color: var(--muted); margin: .45rem 0 .75rem; }
.auth__setup-steps .auth__disclosure { margin-top: .75rem; }
.totp-qr { display: block; width: 12rem; max-width: 100%; height: auto; aspect-ratio: 1; background: white; padding: .5rem; border: 1px solid var(--line); border-radius: var(--radius-sm); }
.auth__setup-key { margin-bottom: .75rem; }
.auth__setup-key code { display: block; padding: .75rem; background: var(--surface-2); font-size: .85rem; overflow-wrap: anywhere; user-select: all; }
.auth__setup-key button { margin-top: .65rem; min-height: 44px; }
.auth [hidden] { display: none !important; }
.auth__organisations { list-style: none; padding: 0; margin: 0; }
.auth__organisations li { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: 1rem; padding: 1.25rem 0; border-top: 1px solid var(--line); }
.auth__organisations li > div { min-width: 0; overflow-wrap: anywhere; }
.auth__organisations li p { margin: .3rem 0 0; color: var(--muted); font-size: .85rem; }
.auth__organisations button { display: flex; gap: 1rem; align-items: center; min-height: 48px; }
@media (max-width: 1000px) {
    .auth { grid-template-columns: minmax(0, .75fr) minmax(0, 1.2fr); }
    .auth__panel { padding: 2rem; }
}
@media (max-width: 900px) {
    .auth-page { padding: 1.25rem 1rem .75rem; }
    .auth-page__main { padding-top: 1.75rem; }
    .auth { display: block; max-width: 36rem; }
    /* Decorative branding only; all instructions remain in the form panel. */
    .auth__brand-panel { display: none; }
    .auth__panel { padding: 1.75rem; }
    .auth-page__header-note { font-size: .75rem; }
}
@media (max-width: 430px) {
    .auth__panel { padding: 1.25rem; }
    .auth-page__brand { font-size: 1.4rem; gap: .5rem; }
    .auth__setup-steps > li { padding-left: 2.15rem; }
    .auth__heading h1 { font-size: 1.85rem; }
    .auth__organisations form, .auth__organisations button { width: 100%; }
}

/* ==========================================================================
   Application shell
   The sidebar-and-topbar chrome behind both signed-in areas: the platform owner
   area and a tenant's own area. Global rather than scoped to one layout,
   because two copies of one design drift apart, and the two shells differ only
   in what they put in the sidebar, never in how the sidebar looks.

   The sidebar is a fixed off-canvas drawer below 900px, toggled by a pure-CSS
   checkbox so neither shell needs interactivity of its own. That matters for the
   tenant shell in particular: it is statically rendered outside the circuit, so
   the menu keeps working while a Blazor circuit is reconnecting.
   ========================================================================== */
.shell {
    display: grid;
    grid-template-columns: var(--sidebar-w) 1fr;
    min-height: 100vh;
}

/*
   Every icon this application draws by hand is a stroked outline with no fill, so the shell
   sets that once here rather than on each of the several dozen inline paths.

   The exclusion is not optional. The shell wraps the whole page, so this reaches every SVG
   on every screen, and the component library's icons are filled glyphs. Given fill:none and
   a stroke they render as the outline of the glyph plus the outline of its bounding path,
   which is why the search icon, the sort arrow and the checkbox each came out sitting in a
   small box. :where() so the rule keeps the specificity it had.
*/
.shell svg:where(:not([class*="mud-"])) {
    width: 20px;
    height: 20px;
    flex: none;
    fill: none;
    stroke: currentColor;
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
}

/* ---- Sidebar ------------------------------------------------------------ */
.shell__sidebar {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    padding: 1.25rem 0.85rem;
    background: linear-gradient(180deg, var(--green-850), var(--green-900));
    border-right: 1px solid rgba(211, 160, 55, 0.14);
    color: var(--cream);
    position: sticky;
    top: 0;
    height: 100vh;
}

.shell__brand {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.4rem 0.6rem 1.1rem;
    margin-bottom: 0.5rem;
    border-bottom: 1px solid rgba(231, 237, 232, 0.1);
    text-decoration: none;
}

.shell__brand:hover { text-decoration: none; }

/* Says a non-production environment under the brand; see AppShell. */
.shell__environment {
    margin: -0.25rem 0.6rem 0.75rem;
    padding: 0.35rem 0.5rem;
    border-radius: 4px;
    background: var(--gold);
    color: var(--ink);
    font-size: 0.68rem;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-align: center;
    text-transform: uppercase;
}

.shell__mark {
    width: 34px;
    height: 50px;
    object-fit: contain;
    filter: drop-shadow(0 2px 6px rgba(0, 0, 0, 0.4));
}

.shell__wordmark {
    display: flex;
    flex-direction: column;
    line-height: 1.1;
    font-weight: 700;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    font-size: 0.95rem;
    color: #ffffff;
    min-width: 0;
}

.shell__wordmark small {
    font-size: 0.62rem;
    letter-spacing: 0.24em;
    font-weight: 600;
    color: var(--gold);
    margin-top: 0.2rem;
    /* A tenant's own name goes here, and organisation names are not short. */
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.shell__nav {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
}

.shell__link {
    display: flex;
    align-items: center;
    gap: 0.7rem;
    padding: 0.6rem 0.75rem;
    border-radius: var(--radius-sm);
    color: #ffffff;
    font-weight: 600;
    font-size: 0.94rem;
    border-left: 3px solid transparent;
    text-decoration: none;
    transition: background 0.15s ease, color 0.15s ease;
}

.shell__link svg { stroke: var(--gold-300); }

.shell__link:hover {
    background: rgba(255, 255, 255, 0.09);
    color: #ffffff;
    text-decoration: none;
}

.shell__link.active {
    background: rgba(211, 160, 55, 0.18);
    border-left-color: var(--gold);
    color: #ffffff;
}

.shell__link.active svg { stroke: var(--gold); }

/* ---- Collapsible nav groups --------------------------------------------- */
/* Native details/summary, because the nav renders statically and has no circuit to run a
   toggle. The chevron is the only affordance that moves; the summary row styles itself as
   an ordinary link so the grouping reads as structure rather than as a different control. */
.shell__group summary { list-style: none; cursor: pointer; }

.shell__group summary::-webkit-details-marker { display: none; }

.shell__group-summary { width: 100%; }

.shell__chevron {
    margin-left: auto;
    transition: transform 0.15s ease;
}

.shell__group[open] > summary .shell__chevron { transform: rotate(90deg); }

.shell__group-links {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
    padding-left: 0.9rem;
    margin-top: 0.2rem;
}

.shell__group-links .shell__link { font-size: 0.9rem; padding: 0.45rem 0.75rem; }

.shell__sidefoot {
    margin-top: auto;
    padding-top: 0.75rem;
    border-top: 1px solid rgba(231, 237, 232, 0.1);
}

.shell__link--muted {
    color: rgba(255, 255, 255, 0.85);
    font-size: 0.86rem;
}

/* The return to the owner console (ADR-0055) is a form post, and Message the team (ADR-0103)
   opens a dialog, so both controls are buttons that have to shed the global button look to sit
   in the sidebar as one more link. */
.shell__sidefoot-form { margin: 0; }

.shell__sidefoot-form button.shell__link,
.shell__sidefoot button.team-feedback__open {
    width: 100%;
    background: transparent;
    border-top: 0;
    border-right: 0;
    border-bottom: 0;
    box-shadow: none;
    font-family: inherit;
    text-align: left;
    cursor: pointer;
}

.shell__sidefoot-form button.shell__link:hover,
.shell__sidefoot button.team-feedback__open:hover { background: rgba(255, 255, 255, 0.09); }

/* ---- Message the team (ADR-0103) --------------------------------------- */
/* A native dialog, opened with showModal() into the browser's top layer: the one place a modal
   opened from inside the mobile drawer (a CSS transform) is not clipped to the drawer. */
.team-feedback {
    width: min(34rem, calc(100vw - 2rem));
    max-height: calc(100dvh - 2rem);
    /* The global reset zeroes every margin, and auto margins are what centre a modal dialog. */
    margin: auto;
    padding: 0;
    border: 0;
    border-radius: var(--radius);
    background: #ffffff;
    color: var(--ink, #1c2a24);
    box-shadow: var(--shadow-lg);
}

.team-feedback::backdrop { background: rgba(7, 27, 21, 0.55); }

.team-feedback__body {
    display: grid;
    gap: 1.1rem;
    padding: 1.5rem 1.6rem 1.4rem;
}

.team-feedback__title { margin: 0; font-size: 1.35rem; }
.team-feedback__lead { margin: -0.6rem 0 0; color: var(--green-700, #4a6358); }

.team-feedback__kind {
    margin: 0;
    padding: 0;
    border: 0;
}

.team-feedback__kind legend {
    padding: 0;
    margin-bottom: 0.2rem;
    font-weight: 600;
    font-size: 0.92rem;
}

.team-feedback__actions {
    display: flex;
    justify-content: flex-end;
    gap: 0.6rem;
    margin-top: 0.2rem;
}

/* The half-star rating: ten radios drawn as five stars, each half a clipped copy of one star. */
.half-stars { display: grid; gap: 0.25rem; }
.half-stars__label { font-weight: 600; font-size: 0.92rem; }
.half-stars__row { display: flex; align-items: center; gap: 0.75rem; flex-wrap: wrap; }
.half-stars__stars { display: flex; }

.half-stars__input {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    opacity: 0;
    pointer-events: none;
}

.half-stars__half {
    position: relative;
    width: 16px;
    height: 32px;
    overflow: hidden;
    cursor: pointer;
}

.half-stars__half svg {
    position: absolute;
    top: 0;
    width: 32px;
    height: 32px;
    fill: transparent;
    stroke: var(--gold);
    stroke-width: 1.4;
    stroke-linejoin: round;
    transition: fill 0.1s ease;
}

.half-stars__half--left svg { left: 0; }
.half-stars__half--right svg { left: -16px; }
.half-stars__half--filled svg { fill: var(--gold); }

/* Keyboard focus lands on the hidden radio, so the visible half beside it shows the ring. */
.half-stars__input:focus-visible + .half-stars__half { outline: 2px solid var(--green-600, #2f6b55); outline-offset: 1px; border-radius: 2px; }
.half-stars__input:disabled + .half-stars__half { cursor: default; opacity: 0.6; }

.half-stars__value { font-size: 0.9rem; color: var(--green-700, #4a6358); min-width: 6.5rem; }

.half-stars__clear {
    padding: 0.15rem 0.55rem;
    font-size: 0.82rem;
    font-weight: 600;
    background: transparent;
    color: var(--green-700, #4a6358);
    border: 1px solid rgba(7, 27, 21, 0.2);
    box-shadow: none;
}

.half-stars__clear:hover { background: rgba(7, 27, 21, 0.06); }

/* ---- Body / topbar ------------------------------------------------------ */
.shell__body {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.shell__topbar {
    position: sticky;
    top: 0;
    z-index: 20;
    display: flex;
    align-items: center;
    gap: 1rem;
    min-height: 4rem;
    padding: 0 1.5rem;
    background: rgba(255, 255, 255, 0.97);
    backdrop-filter: saturate(1.4) blur(8px);
    border-bottom: 1px solid var(--line);
}

.shell__section {
    font-weight: 650;
    color: var(--green-800);
    letter-spacing: -0.01em;
}

.shell__user {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: 1rem;
}

.shell__whoami {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    color: var(--green-700);
    font-size: 0.9rem;
    font-weight: 600;
}

.shell__whoami svg { width: 18px; height: 18px; }

/* As a link (the tenant area points it at account settings) it keeps the chip's own look;
   the underline on hover is what says it goes somewhere. */
a.shell__whoami {
    text-decoration: none;
}

a.shell__whoami:hover {
    color: var(--green-800);
    text-decoration: underline;
}

.shell__burger {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: auto;
    flex-shrink: 0;
    gap: 0.4rem;
    padding-inline: 0.5rem;
    height: 2.4rem;
    margin-left: -0.4rem;
    border-radius: var(--radius-sm);
    color: var(--green-800);
    cursor: pointer;
}

.shell__burger:hover { background: var(--surface-2); }

.shell__content {
    flex: 1;
    width: 100%;
    max-width: var(--content-max, 1120px);
    margin: 0 auto;
    /* Gutters scale with the viewport rather than stepping at a breakpoint, so the
       content keeps the same relationship to the edge at every width. */
    padding: 2rem clamp(1rem, 2.5vw, 2.5rem) 3rem;
}

/* The tenant area runs wide. Its screens are lists of operational records that an
   operator scans across (a haulier's registration number next to the town next to
   the roles), and capping those at a reading measure means horizontal scrolling on a
   monitor with room to spare. The owner area keeps the narrower default: it is prose
   and short tables, which are harder to read the wider they get. */
.shell--fluid {
    --content-max: 1560px;
}

.shell__scrim {
    display: none;
}

/* Desktop/tablet minimising releases the entire column; mobile keeps its drawer. */
@media (min-width: 901px) {
    .shell--minimised { grid-template-columns: minmax(0, 1fr); }
    .shell--minimised > .shell__sidebar { display: none; }
}

/* ---- Mobile: off-canvas drawer ------------------------------------------ */
@media (max-width: 900px) {
    .shell__menu-label { display: none; }
    .shell {
        grid-template-columns: 1fr;
    }

    .shell__burger {
        display: inline-flex;
    }

    .shell__sidebar {
        position: fixed;
        top: 0;
        left: 0;
        width: min(82vw, var(--sidebar-w));
        z-index: 60;
        transform: translateX(-100%);
        transition: transform 0.22s ease;
        box-shadow: var(--shadow-lg);
    }

    .shell__scrim {
        display: block;
        position: fixed;
        inset: 0;
        z-index: 50;
        background: rgba(7, 27, 21, 0.5);
        opacity: 0;
        pointer-events: none;
        transition: opacity 0.22s ease;
    }

    .shell__toggle:checked ~ .shell__sidebar {
        transform: translateX(0);
    }

    .shell__toggle:checked ~ .shell__scrim {
        opacity: 1;
        pointer-events: auto;
    }

    .shell__content {
        padding: 1.5rem 1rem 2.5rem;
    }
}

/* ---- Navigation feedback ------------------------------------------------ */
/* A small box, not a full-screen curtain. The old screen stays readable while the
   next one is fetched, which is the truth of what is happening; blanking the page
   would make a two-second wait feel like a reload.
   Toggled by a class rather than the hidden attribute, because display: flex here
   would override hidden and the box would never go away. */
.route-loading {
    display: none;
    position: fixed;
    inset: 0;
    z-index: 900;
    align-items: center;
    justify-content: center;
    /* Clicks pass through to the page underneath: this reports progress, it does not
       claim to have blocked anything, and pretending otherwise would be a lie the
       moment a second click got through anyway. */
    pointer-events: none;
}

.route-loading.is-visible {
    display: flex;
}

.route-loading__box {
    display: inline-flex;
    align-items: center;
    gap: 0.7rem;
    padding: 0.85rem 1.35rem;
    border-radius: var(--radius);
    background: rgba(7, 27, 21, 0.92);
    color: var(--cream);
    font-weight: 600;
    font-size: 0.95rem;
    box-shadow: var(--shadow-lg);
}

.route-loading__spinner {
    width: 1.1rem;
    height: 1.1rem;
    flex: none;
    border-radius: 50%;
    border: 2px solid rgba(231, 237, 232, 0.25);
    border-top-color: var(--gold);
    animation: route-loading-spin 0.7s linear infinite;
}

@keyframes route-loading-spin {
    to {
        transform: rotate(360deg);
    }
}

/* Motion for its own sake is the first thing to go for a reader who has asked for
   less of it. The box still appears; it just stops spinning. */
@media (prefers-reduced-motion: reduce) {
    .route-loading__spinner {
        animation: none;
    }
}

/* The error UI lives in App.razor rather than in one layout, so that a page in
   any shell can report a failed circuit. */
#blazor-error-ui {
    color-scheme: light only;
    background: #fff3cd;
    color: #332701;
    bottom: 0;
    box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
    box-sizing: border-box;
    display: none;
    left: 0;
    padding: 0.85rem 3.5rem 0.85rem 1.25rem;
    position: fixed;
    width: 100%;
    z-index: 2000;
}

    #blazor-error-ui .reload,
    #blazor-error-ui .reload:visited,
    #blazor-error-ui .reload:hover {
        color: #604600;
        font-weight: 700;
        text-decoration: underline;
        margin-left: 0.5rem;
    }

    #blazor-error-ui :focus-visible {
        outline: 2px solid #332701;
        outline-offset: 3px;
    }

    #blazor-error-ui .dismiss {
        color: #332701;
        background: transparent;
        border: 0;
        font-size: 1.5rem;
        line-height: 1;
        min-width: 2.5rem;
        min-height: 2.5rem;
        cursor: pointer;
        position: absolute;
        right: 0.5rem;
        top: 0.2rem;
    }

/* ==========================================================================
   Tenant master data
   ========================================================================== */

/* Which tenant this page belongs to, and which database it reads from, sat in
   the topbar. On screen on purpose: see TenantIdentityBanner. */
.tenant-identity {
    display: flex;
    align-items: baseline;
    gap: 0.6rem;
    min-width: 0;
    flex-wrap: wrap;
}

.tenant-identity__name {
    font-weight: 650;
    color: var(--green-800);
    letter-spacing: -0.01em;
}

/* The slug and database pills that used to sit beside the name are gone, and so are their
   rules. See TenantIdentityBanner: the comparison they supported is now made on every
   dashboard load rather than displayed as operator vocabulary on a customer's screen. */

/* An archived row. Deliberately quiet: archived records still appear when
   something references them, and they should read as context rather than
   as a problem. */
.badge.state-archived {
    color: var(--muted);
    background: var(--surface-2);
}

/* The EWC selections on a waste type. Defra accepts at most five, so this
   never has to cope with a long list. */
.chips {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin: 0.5rem 0;
}

.chip {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.25rem 0.5rem 0.25rem 0.75rem;
    border: 1px solid var(--line);
    border-radius: 999px;
    background: var(--surface-2);
    font-size: 0.9rem;
}

.chip button {
    all: unset;
    cursor: pointer;
    color: var(--muted);
    font-size: 1rem;
    line-height: 1;
    padding: 0 0.25rem;
}

.chip button:hover,
.chip button:focus-visible {
    color: var(--bad);
}

/* Two stacks side by side inside one card, collapsing to one when there is not room
   for both. Used where a card holds two things that are each read top to bottom: the
   site and its address. */
.form-columns {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 20rem), 1fr));
    gap: 0 2.5rem;
    align-items: start;
}

.form-columns > .form-stack {
    max-width: none;
}

/* A heading that opens a column is a label for it, not a divider between sections, so
   it drops the rule and the space above that .form-stack h3 carries elsewhere. Both
   columns then start on the same line. */
.form-columns > .form-stack > h3:first-child {
    margin-top: 0;
    padding-top: 0;
    border-top: 0;
}

/* ---- Bridge log ---------------------------------------------------------- */
/* A console, so it reads like one: fixed width, dark, and scrolled rather than wrapped.
   Wrapping a log line moves every line below it when one arrives, which is exactly what
   makes a moving log unreadable. */
.bridge-log {
    max-height: 60vh;
    overflow: auto;
    margin: 0;
    padding: 1rem;
    /* The two darkest brand tokens rather than a hand-mixed pair, so the console belongs to the
       same palette as everything around it and moves with the theme if one is ever added. */
    background: var(--green-900);
    color: var(--cream);
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 0.82rem;
    line-height: 1.5;
    white-space: pre;
    border-radius: var(--radius);
}

/* ---- Toast -------------------------------------------------------------- */
/* Confirmation that does not move the page. A panel above a form pushes everything
   down at the exact moment somebody has finished reading it, so what they notice is
   the movement rather than the message. */
.toast {
    position: fixed;
    right: clamp(1rem, 3vw, 2rem);
    bottom: clamp(1rem, 3vw, 2rem);
    /* Above MudBlazor's dialog layer, not merely above the page. Its dialogs sit at 1400 and
       their popovers at 1500, so a toast at 800 rendered behind any overlay: the save failed,
       the reason was written, and it was painted underneath the form that caused it. Anything
       that reports the outcome of an action has to outrank the thing the action happened in. */
    z-index: 1700;
    display: inline-flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.8rem 1.2rem;
    border-radius: var(--radius);
    background: var(--green-800);
    color: var(--cream);
    font-weight: 650;
    box-shadow: var(--shadow-lg);
    animation: toast-in 0.18s ease-out;
}

.toast svg {
    width: 18px;
    height: 18px;
    flex: none;
    fill: none;
    stroke: var(--gold);
    stroke-width: 3;
    stroke-linecap: round;
    stroke-linejoin: round;
}

/* A failure is red and carries a dismiss control, because it does not leave on its own.
   Wider than a success toast: "saved" is one word and a refusal is a sentence. */
.toast--failure {
    background: var(--bad);
    color: #fff;
    max-width: min(32rem, calc(100vw - 2rem));
    align-items: flex-start;
}

.toast--failure svg {
    stroke: #fff;
    stroke-width: 2;
    margin-top: 0.1rem;
}

.toast__action { display: block; margin-top: .5rem; color: inherit; font-weight: 600; text-decoration: underline; }
.toast__action-button { padding: 0; background: none; border: 0; font: inherit; font-weight: 600; cursor: pointer; text-align: left; }

.toast__dismiss {
    all: unset;
    cursor: pointer;
    flex: none;
    margin-left: 0.4rem;
    padding: 0 0.3rem;
    font-size: 1.2rem;
    line-height: 1;
    color: rgba(255, 255, 255, 0.85);
}

.toast__dismiss:hover,
.toast__dismiss:focus-visible {
    color: #fff;
}

@keyframes toast-in {
    from {
        opacity: 0;
        transform: translateY(0.5rem);
    }
}

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

/* ---- Number plates ------------------------------------------------------ */
/* A registration read off a plate is checked against a plate, so it is shown as one.
   The real typeface is Charles Wright, which cannot be shipped from here (nothing may
   load from another host), so this is the nearest thing a machine already has: a
   condensed grotesque, heavy, with the tight spacing plates use. */
/* Squared and upright, not condensed. The first stack tried Impact and Haettenschweiler,
   which are the wrong shape entirely: plate characters are wide and flat-sided, and a
   condensed face reads as a shouty label rather than as a plate. Verdana and DejaVu Sans
   are the closest wide grotesques a machine is likely to already have. */
.plate {
    display: inline-block;
    padding: 0.2em 0.55em;
    border: 2px solid #111;
    border-radius: 5px;
    background: var(--plate-yellow);
    color: #111;
    font-family: "UKNumberPlate", "Charles Wright", Verdana, "DejaVu Sans", Tahoma, sans-serif;
    font-size: 0.95rem;
    font-weight: 700;
    letter-spacing: 0.05em;
    line-height: 1.35;
    white-space: nowrap;
}

/* An archived vehicle's plate is dimmed rather than recoloured: it is still the same
   plate, and a grey rectangle would read as a different kind of thing. */
tr:has(.badge.state-archived) .plate {
    opacity: 0.55;
}

/* ---- Contacts ----------------------------------------------------------- */
.contact-list {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    margin-bottom: 1.25rem;
}

.contact {
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 1rem 1.1rem;
    background: var(--surface-2);
}

/* The primary contact is marked by its edge rather than by a different card, because
   promoting somebody else should visibly move a mark, not rebuild the page. */
.contact--primary {
    border-left: 3px solid var(--gold);
    background: var(--surface);
}

.contact__head {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin-bottom: 0.85rem;
}

.contact__remove {
    margin-left: auto;
}

.contact__options {
    border: 0;
    margin: 0.25rem 0 0;
    padding: 0;
}

.contact__options legend {
    padding: 0;
    font-weight: 600;
    font-size: 0.9rem;
    color: var(--green-800);
}

/* Marks an option that is stored but does nothing yet. Deliberately plain: it is a
   note to the reader, not a status the customer should act on. */
.coming-soon {
    display: inline-block;
    margin-left: 0.4rem;
    padding: 0.05rem 0.4rem;
    border: 1px dashed var(--warn);
    border-radius: 999px;
    font-size: 0.68rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--warn);
    vertical-align: 0.05em;
}

/* Declared components: what it is, how much of it, and a way to take it off again.
   A list rather than chips, because each one now carries a value to type into and a
   chip is the wrong shape for a form control. */
.component-list {
    list-style: none;
    margin: 0 0 1rem;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.component-list li {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem 0.75rem;
    padding: 0.5rem 0.75rem;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    background: var(--surface-2);
}

.component-list__name {
    flex: 3 1 18rem;
    min-width: 0;
    font-weight: 550;
}

.component-list__name input,
.component-list__name select {
    width: 100%;
    min-width: 0;
}

.component-concentration {
    display: flex;
    flex-direction: column;
    gap: .25rem;
    flex: 1 1 9rem;
    min-width: 0;
    font-size: .8rem;
}

.component-concentration input {
    width: 100%;
    min-width: 0;
}

.component-list__amount {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    flex: none;
}

.component-list__amount input {
    width: 7.5rem;
    font: inherit;
    padding: 0.35rem 0.5rem;
    border: 1px solid #cfd6cf;
    border-radius: var(--radius-sm);
    background: var(--surface);
    color: var(--ink);
    text-align: right;
}

.component-list__unit {
    color: var(--muted);
    font-size: 0.85rem;
    min-width: 3rem;
}

/* The detail that opens under a ticked declaration. Indented and ruled so it reads as
   belonging to the tick above it rather than as the next question down the form. */
.declaration {
    margin: 0.5rem 0 1.25rem 1.6rem;
    padding-left: 1.1rem;
    border-left: 2px solid var(--line);
}

.declaration .field:last-child {
    margin-bottom: 0;
}

/* Waste-type hazards: classification first, then editable component defaults. */
.waste-hazards__intro {
    color: var(--muted);
    margin: 0 0 1.25rem;
    max-width: 75ch;
}

.hazard-panel {
    container: hazards / inline-size;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    margin-top: 1rem;
    overflow: hidden;
}

.hazard-panel__toggle {
    padding: .75rem 1.25rem;
    background: var(--surface-2);
}

.hazard-panel__toggle .mud-checkbox { margin-left: -.7rem; }
.hazard-panel__toggle .mud-typography { font-weight: 600; }
.hazard-panel__toggle p { margin: 0 0 .25rem 1.9rem; color: var(--muted); font-size: .875rem; }
.hazard-panel__body { padding: 1.25rem; border-top: 1px solid var(--line); }
.hazard-classification { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 2rem; }
.hazard-classification > section + section { margin-top: 0; }
.hazard-block { min-width: 0; }
.hazard-block h3 { margin: 0; font-size: 1.05rem; color: var(--green-800); }
.hazard-help { color: var(--muted); font-size: .875rem; line-height: 1.6; margin: .4rem 0 1rem; }
.hazard-block--components { border-top: 1px solid var(--line); margin-top: 1.5rem; padding-top: 1.5rem; }
.hazard-block__heading { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem 1rem; margin-bottom: 1rem; }
.hazard-count { color: var(--muted); background: var(--surface-2); border-radius: 1rem; padding: .15rem .6rem; font-size: .75rem; }
.hazard-source { max-width: 34rem; margin-bottom: 1rem; }
.hazard-properties { margin-top: .75rem; }
.hazard-properties .chip { max-width: 100%; white-space: normal; }
.hazard-properties .chip span { min-width: 0; overflow-wrap: anywhere; }
.hazard-note { background: var(--surface-2); border-left: 3px solid var(--green-500); padding: .75rem 1rem; font-size: .875rem; }
.hazard-empty { padding: 1rem; border: 1px dashed var(--line); border-radius: var(--radius-sm); color: var(--muted); font-size: .875rem; }
.hazard-components { list-style: none; padding: 0; margin: 0 0 1rem; display: grid; gap: .75rem; }
.hazard-components li {
    display: grid;
    grid-template-columns: minmax(0, 2.5fr) minmax(0, 1fr) minmax(0, 1fr) auto;
    gap: .75rem;
    align-items: start;
    padding: 1rem;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--surface-2);
}
.hazard-components li > * { min-width: 0; }
.hazard-components .mud-input-control { margin-top: 0; }
.hazard-components .mud-input { background: var(--surface); }
.hazard-components__remove { min-height: 3.5rem; }

@container hazards (max-width: 850px) {
    .hazard-classification { grid-template-columns: 1fr; gap: 1.5rem; }
    .hazard-components li { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .hazard-components__description { grid-column: 1 / -1; }
    .hazard-components__remove { grid-column: 1 / -1; justify-self: end; min-height: 2.75rem; }
}

@container hazards (max-width: 480px) {
    .hazard-panel__body, .hazard-panel__toggle { padding: 1rem .75rem; }
    .hazard-components li { grid-template-columns: minmax(0, 1fr); padding: .75rem; }
}

/* Standing guidance, not a result of anything the user just did. */
.notice {
    border-left: 3px solid var(--gold-600);
    background: var(--surface-2);
    padding: 0.75rem 1rem;
    margin: 0 0 1rem;
}

.notice p:last-child {
    margin-bottom: 0;
}

/* An advisory validation message. Used where a value is suspect but saving it
   anyway is the lesser evil, site permit numbers, whose accepted formats
   across four regulators are long and change. */
.hint {
    display: block;
    color: var(--warn);
    margin-top: 0.25rem;
}

/* ---- Lists that stop being tables when the space runs out ---------------- */
/* A horizontally scrolling table hides its right-hand columns, and on these lists
   the right-hand column is the Edit link, so on a phone the row a user came to act
   on is the part they cannot see. Below 760px each row becomes a small card with its
   headings repeated inline, which is why every cell carries a data-label. */
@media (max-width: 760px) {
    .table-wrap {
        overflow-x: visible;
    }

    table.data thead {
        position: absolute;
        width: 1px;
        height: 1px;
        overflow: hidden;
        clip-path: inset(50%);
        white-space: nowrap;
    }

    table.data,
    table.data tbody,
    table.data tr,
    table.data td {
        display: block;
        width: 100%;
    }

    table.data tr {
        border: 1px solid var(--line);
        border-radius: var(--radius-sm);
        padding: 0.25rem 0.85rem;
        margin-bottom: 0.75rem;
        background: var(--surface);
    }

    table.data tr:hover {
        background: var(--surface);
    }

    table.data td {
        display: flex;
        align-items: baseline;
        justify-content: space-between;
        gap: 1rem;
        padding: 0.55rem 0;
        border-bottom: 1px solid var(--line);
    }

    table.data td:last-child {
        border-bottom: 0;
    }

    table.data td::before {
        content: attr(data-label);
        flex: 0 0 auto;
        font-size: 0.72rem;
        font-weight: 650;
        letter-spacing: 0.06em;
        text-transform: uppercase;
        color: var(--muted);
    }

    table.data td.col-actions {
        justify-content: flex-end;
        text-align: left;
    }

    table.data td.table-empty {
        justify-content: center;
    }

    table.data td.table-empty::before {
        content: "";
    }
}

/* ==========================================================================
   Tenant dashboard
   A holding screen: the customer's own mark, and charts drawn from fixed sample
   numbers so the shape of the page can be agreed before the real figures exist.
   Everything here is marked as sample on screen, an unlabelled placeholder chart
   is indistinguishable from a real one that is wrong.
   ========================================================================== */
.dash-hero {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 1.5rem 2rem;
}

/* A stat row is not a card, so `.card + .card` never applied to it and the tiles sat hard
   against the hero above them. Matched on the pair rather than given to .stat-row itself,
   which appears at the top of pages where a leading margin would be a gap under the heading. */
.card + .stat-row {
    margin-top: 1.25rem;
}

.dash-hero__mark {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    padding: 1rem 1.25rem;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--surface-2);
}

/* Bounded on both axes and never upscaled: a customer logo arrives as anything from
   a 200px PNG to a 4000px export, and object-fit inside a fixed box is what stops
   either extreme from deciding the height of the page. */
.dash-hero__logo {
    display: block;
    width: auto;
    height: auto;
    max-width: min(100%, 16rem);
    max-height: 5.5rem;
    object-fit: contain;
}

.dash-hero__monogram {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 5.5rem;
    height: 5.5rem;
    border-radius: var(--radius);
    background: var(--green-800);
    color: var(--gold-300);
    font-size: 2.25rem;
    font-weight: 700;
    letter-spacing: 0.02em;
}

.dash-hero__text {
    flex: 1 1 18rem;
    min-width: 0;
}

.dash-hero__text h1 {
    margin: 0;
}

.dash-hero__text p {
    margin: 0.35rem 0 0;
    color: var(--muted);
}

.dash-hero__prompt {
    margin: 0.6rem 0 0;
    font-size: 0.9rem;
}

/* A value the tenant may read but not set. Styled to sit in the same rhythm as the
   fields around it without imitating a text box, because a disabled-looking input
   invites people to try to enable it. */
.field__readonly-label {
    display: block;
    font-weight: 600;
    font-size: 0.9rem;
    margin-bottom: 0.35rem;
    color: var(--green-800);
}

.field__readonly {
    margin: 0;
    padding: 0.6rem 0.75rem;
    border-left: 3px solid var(--gold-600);
    background: var(--surface-2);
    border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
}

/* ---- Input groups ------------------------------------------------------- */
/* An icon, the box, and the action that opens what is in it, joined into one
   control. The icon says what the field is at a glance in a column of otherwise
   identical boxes, and the joined action reads as belonging to this field rather
   than as the next thing to fill in.

   Borders are collapsed by hand rather than by a border-collapse trick: each part
   drops the border it shares with its neighbour, and only the ends are rounded. */
/* One border around the whole control, drawn by the group. The box inside gives up
   its own border and radius entirely: two borders a pixel apart is what made this
   look like two controls that had been pushed together. */
.input-group {
    display: flex;
    align-items: stretch;
    width: 100%;
    min-width: 0;
    border: 1px solid #cfd6cf;
    border-radius: var(--radius-sm);
    background: var(--surface);
    overflow: hidden;
}

/* Specific enough to beat `.field input`, which sets a border and a radius on every
   text box in a form. */
.field .input-group input,
.input-group input {
    flex: 1 1 auto;
    min-width: 0;
    border: 0;
    border-radius: 0;
    background: transparent;
}

.field .input-group input:focus,
.input-group input:focus {
    box-shadow: none;
}

.input-group__addon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
    width: 2.6rem;
    border-right: 1px solid var(--line);
    background: var(--surface-2);
    color: var(--muted);
    text-decoration: none;
}

.input-group__addon svg {
    width: 18px;
    height: 18px;
    fill: none;
    stroke: currentColor;
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
}

/* Text for a screen reader and nobody else. The icon links carry their purpose here
   rather than relying on a title attribute, which is not announced reliably. */
.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

/* The icon is the action when there is something to open, so it has to look like one.
   When the box is empty it is the same square in the same place, just inert: a control
   that moves as soon as you type in it is worse than one that dims. */
a.input-group__addon {
    color: var(--green-700);
}

a.input-group__addon:hover,
a.input-group__addon:focus-visible {
    background: var(--gold);
    color: #201400;
    text-decoration: none;
}

.input-group:focus-within {
    border-color: var(--gold);
    box-shadow: 0 0 0 3px rgba(211, 160, 55, 0.2);
}

/* A text box with an action beside it, not joined to it: used where the action is a
   separate act rather than a way of reading the value, such as adding a component to
   a list. The box takes the space and the button keeps its own width. */
.input-row {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.input-row > :first-child {
    flex: 1 1 auto;
    min-width: 0;
}

.input-row .button-link {
    flex: none;
    white-space: nowrap;
}

/* The company photo where it is uploaded. Bounded the same way as on the dashboard,
   so what an operator sees here is what the dashboard will show. */
.company-photo {
    display: block;
    width: auto;
    height: auto;
    max-width: min(100%, 20rem);
    max-height: 8rem;
    object-fit: contain;
    margin-bottom: 1rem;
    padding: 0.75rem 1rem;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--surface-2);
}

/* A thumbnail of a pending identity document scan, before it has been stored anywhere. */
.identity-document-preview {
    display: block;
    width: auto;
    height: 3rem;
    object-fit: contain;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--surface-2);
}

/* Identity evidence stays summarised on the form; the shared overlay owns the detail. */
.identity-attachment-preview { min-width: 0; }
.identity-attachment-preview img { display: block; width: 100%; max-height: 60dvh; object-fit: contain; }
.identity-attachment-preview iframe { display: block; width: 100%; height: 60dvh; border: 0; }
.identity-documents { min-width: 0; scroll-margin-top: 6rem; }
.identity-documents__summary { display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 1rem; }
.identity-documents__summary p { margin: 0 0 .35rem; }
.identity-documents__hint { display: block; color: var(--muted); font-size: .875rem; margin: .35rem 0 .75rem; overflow-wrap: anywhere; }
.identity-documents__pending { font-size: .875rem; font-weight: 600; }
.identity-documents__heading { margin: 1.25rem 0 .75rem; font-size: 1.1rem; }
.identity-documents__list { list-style: none; margin: 0 0 .75rem; padding: 0; }
.identity-documents__document { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: baseline; gap: .5rem 1rem; padding: 1rem 0; border-bottom: 1px solid var(--line); }
.identity-documents__document .component-list__name { min-width: 0; overflow-wrap: anywhere; }
.identity-documents__actions { grid-column: 1 / -1; display: flex; flex-wrap: wrap; align-items: flex-start; gap: .5rem; }
.identity-documents__actions .confirm-action { flex: 1 1 16rem; }
.identity-documents__uploads { display: grid; gap: 1rem; }
.identity-documents__upload { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 1rem; padding: 1rem; border: 1px solid var(--line); border-radius: var(--radius); }
.identity-documents__upload .field { min-width: 0; margin: 0; }
.identity-documents__upload input,
.identity-documents__upload select { width: 100%; min-width: 0; min-height: 44px; }
.identity-documents__files { grid-column: 1 / -1; display: flex; align-items: center; flex-wrap: wrap; gap: .75rem; min-width: 0; }
.identity-documents__files .hint { overflow-wrap: anywhere; min-width: 0; }
.identity-documents__actions .mud-button-root,
.identity-documents__files .mud-button-root { min-height: 44px; }
.identity-documents__files .mud-icon-button { min-width: 44px; }
.identity-documents .hint { color: var(--muted); }
.identity-documents .failure { color: var(--bad); }

@media (max-width: 480px) {
    .identity-documents__summary > .mud-button-root { width: 100%; }
    .identity-documents__upload,
    .identity-documents__document { grid-template-columns: minmax(0, 1fr); }
    .identity-documents__upload { padding: .75rem; }
}

.dash-holding {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.75rem 1.25rem;
    border: 1px dashed var(--gold-600);
    background: var(--warn-bg);
    border-radius: var(--radius);
    padding: 1rem 1.25rem;
    margin-bottom: 1.25rem;
}

.dash-holding__badge {
    text-transform: uppercase;
    letter-spacing: 0.18em;
    font-size: 0.72rem;
    font-weight: 700;
    color: var(--warn);
}

.dash-holding p {
    margin: 0;
    color: var(--ink);
    flex: 1 1 20rem;
}

/* Charts size themselves to the column they land in; the columns follow the space
   available rather than a breakpoint, so this is one, two or three across without
   anything being told which. */
.chart-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 21rem), 1fr));
    gap: 1.25rem;
}

.chart-card {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    padding: 1.25rem 1.35rem;
    min-width: 0;
}

.chart-card__head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.75rem;
    margin-bottom: 0.9rem;
}

.chart-card__head h2 {
    margin: 0;
    font-size: 1rem;
}

.chart-card__note {
    font-size: 0.78rem;
    color: var(--muted);
}

/* The SVG carries a viewBox and no width attribute, so it takes the column's width
   and keeps its own aspect ratio. Nothing here depends on a pixel size.

   Written as `.shell svg.chart` rather than `.chart`, and that is the whole point of
   the selector: the shell sizes every icon inside it with `.shell svg { width: 20px }`,
   which is more specific than a bare class and was shrinking each chart to the size of
   a menu icon. A rule that sets a size for every SVG in a subtree has to be beaten
   explicitly by anything that is not an icon. */
.shell svg.chart,
.chart {
    display: block;
    width: 100%;
    height: auto;
    overflow: visible;
}

.chart__axis {
    stroke: var(--line);
    stroke-width: 1;
}

.chart__bar {
    fill: var(--green-600);
}

.chart__bar--muted {
    fill: #b9cbc2;
}

.chart__line {
    fill: none;
    stroke: var(--gold-600);
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.chart__area {
    fill: rgba(211, 160, 55, 0.16);
}

/* Axis labels, in HTML under the chart rather than inside it. Equal columns line them
   up with the plotted points at any width, and text that stays HTML stays selectable
   and scales with the reader's font size instead of the viewBox. */
.chart__ticks {
    display: grid;
    margin-top: 0.35rem;
    font-size: 0.7rem;
    color: var(--muted);
}

.chart__ticks span {
    text-align: center;
    overflow: hidden;
}

/* A five-step categorical ramp. Ordered so that adjacent segments differ in
   lightness as well as hue, which is what keeps them apart when the page is
   printed in grey or read by somebody who cannot separate green from gold. */
.chart__seg--1 { stroke: var(--green-800); fill: var(--green-800); }
.chart__seg--2 { stroke: var(--gold); fill: var(--gold); }
.chart__seg--3 { stroke: var(--green-500); fill: var(--green-500); }
.chart__seg--4 { stroke: var(--gold-300); fill: var(--gold-300); }
.chart__seg--5 { stroke: #9fb3a9; fill: #9fb3a9; }

.chart__legend {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem 1rem;
    margin-top: 0.75rem;
    font-size: 0.82rem;
    color: var(--muted);
}

.chart__legend span {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
}

.chart__swatch {
    width: 0.7rem;
    height: 0.7rem;
    border-radius: 3px;
    flex: none;
}

.sample-flag {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    font-size: 0.72rem;
    font-weight: 650;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--warn);
    background: var(--warn-bg);
    border-radius: 999px;
    padding: 0.15rem 0.6rem;
}

/* Each term and its value are wrapped together, because a plain dt/dd sequence in a
   multi-column grid pairs the wrong term with the wrong value as soon as the column
   count is anything but two. */
.proof-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr));
    gap: 1rem 1.5rem;
    margin: 0;
}

.proof-grid > div {
    min-width: 0;
}

.proof-grid dt {
    color: var(--muted);
    font-size: 0.85rem;
    margin-bottom: 0.15rem;
}

.proof-grid dd {
    margin: 0;
    font-weight: 550;
    overflow-wrap: anywhere;
}

.isolation-breach {
    color: var(--bad);
    font-weight: 650;
}

/* Address search. The box sits above a form's own address fields and fills them in;
   everything below it is the host form's, unchanged.

   Search and suggestions live in a modal picker; only selected details stay in the form. */
.address-lookup {
    margin-bottom: 1rem;
}

.postcode-lookup-field,
.carrier-registration-field,
.sic-codes__entry {
    display: flex;
    align-items: flex-start;
    flex-wrap: wrap;
    gap: .5rem;
    min-width: 0;
}

.postcode-lookup-field > .mud-input-control {
    flex: 1 1 8rem;
    min-width: 7rem;
}

.carrier-registration-field > .mud-input-control {
    flex: 1 1 12rem;
    min-width: 0;
    max-width: 30rem;
}

.carrier-registration-field > .mud-typography { align-self: center; }

.sic-codes__entry > .mud-input-control,
.sic-codes__entry > .native-overlay-field {
    flex: 1 1 15rem;
    min-width: 0;
}

.postcode-lookup-field > .lookup-trigger,
.carrier-registration-field > .lookup-trigger,
.sic-codes__entry > .mud-button-root {
    flex: 0 0 auto;
    min-height: 44px;
    margin-top: 6px;
}

.native-overlay-field {
    display: flex;
    flex-direction: column;
    gap: .35rem;
    min-width: 0;
}

.native-overlay-field :is(input, select) {
    width: 100%;
    min-height: 48px;
    padding: .6rem;
    border: 1px solid var(--mud-palette-lines-inputs);
    border-radius: 4px;
    background: var(--mud-palette-surface);
    color: inherit;
    font: inherit;
}

.sites-summary {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 1rem;
    width: 100%;
    padding: 1rem;
    margin-block: 1rem;
    text-align: left;
    background: var(--mud-palette-surface);
    color: var(--mud-palette-text-primary);
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: 4px;
    font: inherit;
    cursor: pointer;
}

.sites-summary strong { font-size: 1.125rem; }
.lookup-dialog.lookup-dialog--wide { width: min(72rem, calc(100vw - 2rem)); }
.lookup-dialog.lookup-dialog--fullscreen { width: 100vw; max-width: 100vw; height: 100dvh; max-height: 100dvh; margin: 0; border: 0; border-radius: 0; }
.lookup-dialog--fullscreen .lookup-dialog__body { flex: 1; display: flex; min-height: 0; }
.lookup-dialog--fullscreen .identity-attachment-preview { flex: 1; display: flex; align-items: center; justify-content: center; min-width: 0; min-height: 0; }
.lookup-dialog--fullscreen .identity-attachment-preview img { width: 100%; height: 100%; max-height: calc(100dvh - 12rem); object-fit: contain; }
.lookup-dialog--fullscreen .identity-attachment-preview iframe { width: 100%; height: 100%; min-height: 0; }
.identity-scan-thumbnail { display: inline-flex; align-items: center; justify-content: center; padding: 0; border: 1px solid var(--line); background: transparent; border-radius: var(--radius-sm); cursor: zoom-in; box-shadow: none; max-width: 100%; }
.identity-scan-thumbnail:hover { background: var(--surface-2); }
.identity-scan-thumbnail > img { display: block; max-width: 100%; max-height: 150px; object-fit: contain; }
.identity-scan-thumbnail:focus-visible { outline: 3px solid var(--green-700); outline-offset: 3px; }

.address-lookup__status {
    margin: 0.35rem 0 0;
    color: var(--muted);
    font-size: 0.9rem;
}

.address-lookup__results {
    list-style: none;
    margin: 0.5rem 0 0;
    padding: 0;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    background: var(--surface);
    max-height: 17rem;
    overflow-y: auto;
}

.address-lookup__results li + li .address-lookup__result {
    border-top: 1px solid var(--line);
}

/* A button, because it is one: it is reachable by keyboard and it does something.
   Everything a button normally looks like is taken back off, so a list of addresses
   reads as a list rather than as a stack of controls. */
.address-lookup__result {
    display: block;
    width: 100%;
    padding: 0.55rem 0.75rem;
    border: 0;
    border-radius: 0;
    background: transparent;
    color: inherit;
    font: inherit;
    text-align: left;
    cursor: pointer;
}

.address-lookup__result:hover,
.address-lookup__result:focus-visible,
.address-lookup__result.is-highlighted {
    background: var(--surface-2);
    color: inherit;
}

/* Carrier registration search uses the same overlay as address lookup.

   A result is three lines rather than one. An address is identified by reading it; a
   registration is identified by comparing a company name, a town and a tier, and three of
   those on one line is a line nobody reads to the end of. */
.carrier-lookup {
    margin-bottom: 1rem;
}

.carrier-lookup--state {
    margin-top: 0.75rem;
    margin-bottom: 0;
}

.carrier-lookup__status {
    margin: 0.35rem 0 0;
    color: var(--muted);
    font-size: 0.9rem;
}

.carrier-lookup__note {
    margin: 0.35rem 0 0;
    color: var(--muted);
    font-size: 0.9rem;
}

/* Smaller and quieter than the status line. The licence has to be here, and it is not what
   anybody came to the page to read. */
.carrier-lookup__licence {
    margin: 0.4rem 0 0;
    color: var(--muted);
    font-size: 0.8rem;
}

.carrier-lookup__results {
    list-style: none;
    margin: 0.5rem 0 0;
    padding: 0;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    background: var(--surface);
    max-height: 22rem;
    overflow-y: auto;
}

.carrier-lookup__results li + li .carrier-lookup__result {
    border-top: 1px solid var(--line);
}

.carrier-lookup__result {
    display: block;
    width: 100%;
    padding: 0.55rem 0.75rem;
    border: 0;
    border-radius: 0;
    background: transparent;
    color: inherit;
    font: inherit;
    text-align: left;
    cursor: pointer;
}

.carrier-lookup__result:hover,
.carrier-lookup__result:focus-visible,
.carrier-lookup__result.is-highlighted {
    background: var(--surface-2);
    color: inherit;
}

.carrier-lookup__holder {
    display: block;
    font-weight: 550;
}

.carrier-lookup__detail {
    display: block;
    color: var(--muted);
    font-size: 0.85rem;
}

/* One scroll area keeps long result sets usable with a phone keyboard or at high zoom. */
.lookup-dialog {
    width: min(44rem, calc(100% - 2rem));
    max-width: calc(100% - 2rem);
    max-height: calc(100dvh - 2rem);
    margin: auto;
    padding: 0;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--surface);
    color: var(--ink);
    box-shadow: 0 1.5rem 5rem #071b1540;
    overflow: hidden;
}

.lookup-dialog[open] { display: flex; flex-direction: column; }
.lookup-dialog::backdrop { background: #071b1599; }
body:has(.lookup-dialog[open]) { overflow: hidden; }
.lookup-dialog__header,
.lookup-dialog__footer { display: flex; align-items: center; justify-content: space-between; gap: 1rem; padding: 1rem 1.5rem; flex-shrink: 0; }
.lookup-dialog__header { border-bottom: 1px solid var(--line); }
.lookup-dialog__header h2 { margin: 0; font-size: 1.25rem; overflow-wrap: anywhere; }
.lookup-dialog__header h2:focus { outline: none; }
.lookup-dialog__close { flex-shrink: 0; min-width: 44px; min-height: 44px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface); color: inherit; cursor: pointer; }
.lookup-dialog__body { padding: 1.25rem 1.5rem; overflow-y: auto; overscroll-behavior: contain; min-height: 0; overflow-wrap: anywhere; }
.lookup-dialog__body .mud-input-control { min-width: min(14rem, 100%); flex: 1; }
.lookup-dialog__body .mud-stack-row > .mud-button-root { min-height: 44px; }
.lookup-dialog__footer { border-top: 1px solid var(--line); background: var(--surface-2); flex-wrap: wrap; }
.lookup-dialog__footer .mud-button-root,
.lookup-trigger { min-height: 44px; }
.lookup-dialog__hint { flex: 1 1 12rem; margin: 0; font-size: .875rem; color: var(--muted); }
.lookup-dialog__results { list-style: none; margin: .5rem 0 0; padding: 0; border: 1px solid var(--line); border-radius: var(--radius-sm); }
.lookup-dialog__result { display: block; width: 100%; padding: .9rem 1rem; border: 0; border-radius: 0; color: inherit; background: transparent; text-align: left; font: inherit; cursor: pointer; }
.lookup-dialog__results li + li { border-top: 1px solid var(--line); }
.lookup-dialog__result:hover { background: var(--surface-2); }
.lookup-dialog__detail { display: block; font-size: .875rem; color: var(--muted); margin-top: .2rem; }
.lookup-dialog .address-lookup__results,
.lookup-dialog .carrier-lookup__results { max-height: none; overflow: visible; }
.lookup-dialog .address-lookup__result,
.lookup-dialog .carrier-lookup__result,
.lookup-dialog__result { min-height: 48px; padding: .85rem 1rem; overflow-wrap: anywhere; }
.lookup-dialog button:focus-visible { outline: 3px solid var(--green-600); outline-offset: -3px; }
.lookup-dialog button:disabled { opacity: .6; cursor: not-allowed; }

.account-settings { max-width: 68rem; }
.account-settings__identity { display: grid; grid-template-columns: 1fr 1fr; gap: 2rem; padding-bottom: 2rem; }
.account-settings h2 { font-size: 1.25rem; margin: 0 0 1rem; }
.account-settings h3 { font-size: 1.05rem; margin: 0 0 .5rem; }
.account-settings p { margin-top: 0; }
.account-settings__eyebrow { font-size: .75rem; font-weight: 650; text-transform: uppercase; letter-spacing: .08em; color: var(--muted); }
.account-settings__hint { font-size: .875rem; color: var(--muted); }
.account-settings__profile,
.account-settings__access { min-width: 0; }
.account-settings__details { margin: 0 0 1rem; }
.account-settings__details dt { font-size: .85rem; color: var(--muted); margin-top: 1rem; }
.account-settings__details dd { margin: .25rem 0 0; font-weight: 550; overflow-wrap: anywhere; }
.account-settings__memberships { list-style: none; margin: 0 0 1rem; padding: 0; }
.account-settings__memberships li { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: .5rem; padding: .75rem 0; border-bottom: 1px solid var(--line); overflow-wrap: anywhere; }
.account-settings__role { display: inline-block; padding: .2rem .6rem; background: var(--surface-2); border-radius: var(--radius-sm); font-size: .85rem; }
.account-settings__security { border-top: 1px solid var(--line); padding-top: 1.5rem; }
.account-settings__signature { border-top: 1px solid var(--line); padding-top: 1.5rem; margin-bottom: 2rem; }
.account-settings__signature-fields { display: grid; grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr)); gap: 1rem; margin-bottom: 1.25rem; max-width: 36rem; }
.account-settings__signature-actions { margin-top: 1rem; }
.account-settings__security-heading { margin-bottom: 1.5rem; }
.account-settings__setting { display: grid; grid-template-columns: minmax(0, 1fr) minmax(12rem, 20rem); column-gap: 2rem; padding: 1.5rem 0; border-top: 1px solid var(--line); }
.account-settings__setting > :not(.account-settings__actions) { grid-column: 1; }
.account-settings__actions { grid-column: 2; grid-row: 1 / span 4; align-self: start; }
.account-settings__warning { border-left: 3px solid var(--bad); padding: .5rem 1rem; margin: .5rem 0; }
.account-settings__warning p { margin: .3rem 0 0; }

@media (max-width: 700px) {
    .account-settings__identity,
    .account-settings__setting { grid-template-columns: minmax(0, 1fr); gap: 1rem; }
    .account-settings__actions { grid-column: 1; grid-row: auto; }
}

@media (max-width: 480px) {
    .lookup-dialog { width: calc(100% - 1rem); max-width: calc(100% - 1rem); max-height: calc(100dvh - 1rem); }
    .lookup-dialog__header,
    .lookup-dialog__body,
    .lookup-dialog__footer { padding: 1rem; }
    .lookup-dialog__footer .mud-button-root { width: 100%; }
}

/* ---- The line's net ------------------------------------------------------ */
/*
   The computed net sits in the same row as the boxes it comes from, shaped to the dense
   outlined fields beside it so the row stays one height. It carries the gold edge because
   it is the answer rather than another question; the boxes somebody types into stay plain.
   The min-height is the library's dense outlined input, measured, so the row lines up.
*/
.net-field {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    min-height: 40px;
    height: 100%;
    padding: 0 0.75rem;
    border: 1px solid rgba(211, 160, 55, 0.45);
    border-radius: var(--radius);
    background: linear-gradient(180deg, var(--surface), var(--surface-2));
}

.net-field__label {
    font-size: 0.75rem;
    color: var(--muted);
    white-space: nowrap;
}

.net-field__value {
    font-size: 1.15rem;
    font-weight: 700;
    color: var(--green-800);
    font-variant-numeric: tabular-nums;
}

/* ---- The add-a-line slot -------------------------------------------------- */
/* Drawn as the empty slot the next line will fill: full width, dashed, quiet until it is
   pointed at. A solid outlined button under a stack of cards read as one more command in a
   row of many rather than as "the list continues here". */
.add-line.mud-button-outlined {
    border-style: dashed;
    border-width: 1.5px;
    padding-top: 0.6rem;
    padding-bottom: 0.6rem;
    background: transparent;
}

.add-line.mud-button-outlined:hover {
    background: var(--surface-2);
}

/* ---- Waste line summary -------------------------------------------------- */
/*
   The title of the collapsed panel on a ticket line. It carries the physical form, the EWC
   codes and the hazard flags, so a shut panel still says what is in the load: the operator
   should have to open it to change something, never to find out what it says.
*/
.line-summary {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.5rem;
    min-width: 0;
}

.line-summary__label {
    font-weight: 650;
    color: var(--green-800);
}

.line-summary__item {
    font-size: 0.85rem;
    color: var(--muted);
}

/* A select whose empty option is genuinely empty still needs a line's height, or the list
   jumps as the blank row is passed over. */
.select-blank {
    display: inline-block;
    min-height: 1.2em;
}

/* ---- Typeable boxes read as typeable ------------------------------------ */
/*
   An outlined field from the component library is transparent, so it takes whatever is
   behind it. On a card that is white and the box reads as somewhere to type; inside a
   tinted block (a ticket line, a contact) it takes the tint and reads as a label, which
   is exactly backwards.

   Painted explicitly so a box means the same thing everywhere: white is typeable.
*/
.mud-input.mud-input-outlined {
    background: var(--surface);
}

/* The other half of the rule, and the reason it is not simply "all inputs are white": a
   field that cannot be typed into must not look as though it can. The balancing weight on
   the first ticket line is the case that matters, because it is derived and a white box
   would invite somebody to fight it. */
.mud-input.mud-input-outlined.mud-disabled,
.mud-input.mud-input-outlined input:disabled,
.mud-input.mud-input-outlined input[readonly] {
    background: var(--surface-2);
}


/* ---- Owner insights ----------------------------------------------------- */
/* The period picker: two or three controls and a button on one line, wrapping onto
   their own lines when there is not room. Given a max-width so a select does not
   stretch to the width of a wide owner page, which reads as a text field. */
.insights-range {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 0.75rem 1rem;
    margin-bottom: 0.75rem;
}

.insights-range > .mud-input-control {
    flex: 0 1 12rem;
    min-width: 9rem;
}

/* Pushed to the end of the row so the count sits away from the controls rather than
   between them, and takes the whole line once the row wraps. */
.insights-range__progress {
    margin: 0 0 0 auto;
    font-size: 0.85rem;
    color: var(--muted);
}

/* Two controls in a table's action column, kept on one line and against the right edge.
   The view-as control is a form, which is a block by default and would otherwise drop
   the Edit button onto a second row and make every row in the table taller. */
.row-actions {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 0.35rem;
}

.row-actions form {
    margin: 0;
    display: inline-flex;
}

/* The sentence that replaces a page's write controls while a member of staff is viewing
   the account. Sits where the buttons were, in an actions row or on its own, so the
   layout does not jump between a customer's view of a page and an administrator's. */
.read-only-note {
    margin: 0;
    font-size: 0.9rem;
    color: var(--muted);
    align-self: center;
}

.read-only-note strong {
    color: var(--warn);
}

/* ---- Weighbridge ticket: form and rail ---------------------------------- */
/*
   Secondary submission and pricing information goes below the form by default.
   A side rail is allowed only when the form's actual available width, after the
   app navigation, is generous enough. Landscape tablets keep the full form width.
*/
.ticket-editor { container: ticket-editor / inline-size; }
.ticket-layout {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 1.25rem;
    align-items: start;
}

.signature-pad__fieldset {
    border: 0;
    padding: 0;
    margin: 0;
    min-width: 0;
}

/*
   The signing box spans the card it sits in, because the tablet gets handed across the
   weighbridge office and signed with a finger, and a box narrower than the screen wastes
   the width somebody has to sign across.

   The 2 / 1 ratio is not decoration: strokes are stored in a fixed 1000 x 500 coordinate
   space (SignatureDrawing), which is also the viewBox the transfer note prints from. So
   the box may only ever be capped by its width. Capping its height instead would squash
   the drawing, and print a signature a different shape from the one that was signed.
*/
.signature-pad__canvas,
.signature-pad__preview {
    display: block;
    width: 100%;
    aspect-ratio: 2 / 1;
    height: auto;
    background: #fff;
    border: 1px solid #82909c;
    border-radius: .4rem;
}

/*
   A mouse signs in a small box, and at desktop width a full-width 2 / 1 pad is half a
   screen tall, so the cap comes back there. It needs both halves of the query: a tablet
   with a keyboard case attached also reports a fine pointer, and that tablet is still
   signed on with a finger.
*/
@media (pointer: fine) and (min-width: 80rem) {
    .signature-pad__canvas,
    .signature-pad__preview {
        max-width: 36rem;
    }
}

.signature-pad__canvas {
    touch-action: none;
    cursor: crosshair;
}

.signature-pad__canvas[hidden] { display: none; }
.signature-pad__actions { display: flex; gap: .5rem; flex-wrap: wrap; align-items: center; margin-top: .65rem; }
.signature-pad__actions button { min-height: 44px; }
.signature-pad__actions .hint { margin: 0; }
.signature-card .hint, .signature-pad .hint { color: var(--muted); }
.signature-declaration { border-top: 1px solid #dbe2e8; margin-top: 1rem; padding-top: .25rem; }
.signature-declaration > summary { padding: .7rem 0; cursor: pointer; font-weight: 600; }
.ticket-submissions { min-width: 0; }
.ticket-submissions__status { font-weight: 650; font-size: 1rem; margin: .25rem 0 .75rem; }
.ticket-submissions h3 { font-size: .8rem; margin: 1rem 0 .35rem; color: #46596a; }
.ticket-submissions__list { margin: 0; padding: 0; list-style: none; }
.ticket-submissions__list > li { padding: .65rem 0; border-top: 1px solid #dbe2e8; }
.ticket-submissions__row { display: flex; flex-wrap: wrap; gap: .15rem .6rem; align-items: baseline; justify-content: space-between; font-size: .85rem; }
.ticket-submissions__row time, .ticket-submissions__method { color: #46596a; font-size: .75rem; }
.ticket-submissions summary { cursor: pointer; padding: .5rem 0; min-height: 44px; font-size: .8rem; }
.ticket-submissions__message { max-height: 12rem; overflow-y: auto; overflow-wrap: anywhere; white-space: pre-wrap; font-size: .85rem; line-height: 1.5; padding: .6rem; background: #f3f6f8; border-radius: .25rem; }

.ticket-layout__rail {
    position: static;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 22rem), 1fr));
    align-items: start;
    gap: 1rem;
    min-width: 0;
}

@container ticket-editor (min-width: 76rem) {
    .ticket-layout {
        grid-template-columns: minmax(0, 1fr) 18rem;
    }
    .ticket-layout__rail {
        position: sticky;
        top: 5rem;
        grid-template-columns: minmax(0, 1fr);
        max-height: calc(100dvh - 6rem);
        overflow-y: auto;
    }
}

/* ---- The numeric keypad for weight fields ------------------------------- */
/*
   iPadOS raises the letters keyboard for a numeric field whatever the markup asks for: type,
   inputmode and pattern were tried in all eight combinations on a real iPad and none of them
   produced a keypad. So weight-keypad.js draws this one, docked at the bottom, and the field it
   is editing is made read-only for as long as it is up so no second keyboard slides over it.

   The panel is built outside the DOM Blazor renders, which is why none of these class names
   appear in a component. It is a page-level panel: a weight field placed inside LookupDialog
   would need the keypad moved into the native top layer to stay reachable.
*/
.keypad {
    position: fixed;
    z-index: 1500;
    inset-inline: 0;
    bottom: 0;
    margin-inline: auto;
    width: min(100%, 24rem);
    display: grid;
    gap: .5rem;
    padding: .6rem .6rem calc(.6rem + env(safe-area-inset-bottom));
    background: var(--surface-2);
    border: 1px solid var(--line);
    border-bottom: 0;
    border-radius: var(--radius) var(--radius) 0 0;
    box-shadow: 0 -.5rem 1.5rem rgba(7, 27, 21, .22);
}

.keypad__head {
    display: flex;
    gap: .75rem;
    align-items: baseline;
    justify-content: space-between;
    padding: 0 .3rem;
    min-width: 0;
}

.keypad__label { font-size: .8rem; font-weight: 650; color: var(--muted); }

/* The value is repeated here because a docked panel sits over the bottom of a long form, and
   the field it is editing can be the part of the form the panel covers. */
.keypad__value {
    font-size: 1.15rem;
    font-weight: 700;
    color: var(--ink);
    font-variant-numeric: tabular-nums;
    overflow-wrap: anywhere;
}

.keypad__grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: .4rem; }
.keypad__actions { display: grid; grid-template-columns: repeat(3, 1fr); gap: .4rem; }

.keypad button {
    min-height: 3.25rem;
    font: inherit;
    font-size: 1.35rem;
    font-weight: 650;
    color: var(--ink);
    background: var(--surface);
    border: 1px solid var(--input-border);
    border-radius: var(--radius);
    cursor: pointer;
    /* A finger on a moving digit is a mis-keyed weight. */
    touch-action: manipulation;
    user-select: none;
}

.keypad__actions button { font-size: .95rem; font-weight: 650; }
.keypad button:active { background: var(--cream); }

/* Qualified by the element, because `.keypad button` above would otherwise outrank a single
   class and leave the one committing action looking like the rest of the keys. */
.keypad button.keypad__done { background: var(--green-600); border-color: var(--green-700); color: #fff; }
.keypad button.keypad__done:active { background: var(--green-700); }
.keypad button:focus-visible { outline: 3px solid var(--gold); outline-offset: 1px; }

/* So scrolling a field into view puts it above the panel rather than behind it. */
.has-keypad { scroll-padding-bottom: 22rem; }

/* Five grouped columns keep landscape tablets in a compact table, not tall stacked records. */
.ticket-results .mud-table-container { overflow-x: auto; }
.ticket-results .mud-table-cell { padding: .5rem .6rem; vertical-align: middle; }
.ticket-results__identity { width: 11rem; }
.ticket-results__identity .mud-table-sort-label { display: flex; min-height: 32px; }
.ticket-results__number { display: inline-flex; align-items: center; min-height: 44px; font-weight: 650; }
.ticket-results__date { display: block; color: var(--muted); font-size: .75rem; white-space: nowrap; }
.ticket-results__customer { display: block; margin-top: .2rem; font-size: .8rem; overflow-wrap: anywhere; }
.ticket-results__weight { width: 6rem; font-size: .85rem; }
.ticket-results__state { width: 10rem; }
.ticket-results__state .badge { display: table; font-size: .7rem; margin-block: .2rem; white-space: normal; }
.ticket-results__actions { width: 1%; text-align: right; }
/* Reserve the PDF column even when unavailable, keeping the everyday action in one place. */
.ticket-results__buttons { display: grid; grid-template-columns: 6.5rem 44px; justify-content: end; align-items: center; gap: .375rem; }
.ticket-results__primary-action { grid-column: 1; }
.ticket-results__pdf-action { grid-column: 2; }
.ticket-results__buttons .mud-button-root { min-height: 44px; white-space: nowrap; }
.ticket-results__buttons .mud-icon-button { min-width: 44px; }
.ticket-results__tracking summary { position: relative; min-height: 32px; padding-block: .35rem; cursor: pointer; font-size: .75rem; }
.ticket-results__tracking code { display: block; font-size: .75rem; overflow-wrap: anywhere; }
.ticket-results .plate { font-size: .85rem; white-space: nowrap; }
@media (min-width: 600px) {
    .ticket-results table { min-width: 40rem; }
}
@media (max-width: 599px) {
    .ticket-results .mud-table-cell { width: auto; }
    .ticket-results__buttons { justify-content: start; }
    .ticket-results__number { min-height: 32px; }
}

/* ---- Live weight indicator ---------------------------------------------- */
/*
   The one green panel on the page, and the largest number on the screen: at a
   gate it is read across the yard. The gold Capture button (the global button
   style, which is already gold) is the action the operator came to the panel for.
*/
.weighbridge-live {
    background: var(--green-800);
    color: var(--cream);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    padding: 1.1rem 1.25rem 1.25rem;
    display: flex;
    flex-direction: column;
    gap: 0.85rem;
}

.weighbridge-live__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    font-size: 0.74rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    font-weight: 650;
    color: var(--gold-300);
}

.weighbridge-live__head select {
    background: rgba(7, 27, 21, 0.35);
    color: var(--cream);
    border: 1px solid rgba(231, 237, 232, 0.28);
    border-radius: var(--radius-sm);
    padding: 0.25rem 0.5rem;
    font: inherit;
    text-transform: none;
    letter-spacing: normal;
}

.weighbridge-live__reading {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 0.35rem 0.5rem;
}

.weighbridge-live__value {
    font-size: 2.9rem;
    font-weight: 700;
    line-height: 1;
    letter-spacing: -0.01em;
    font-variant-numeric: tabular-nums;
}

.weighbridge-live__value--idle {
    color: rgba(231, 237, 232, 0.45);
}

.weighbridge-live__unit {
    font-size: 1rem;
    color: rgba(231, 237, 232, 0.75);
}

.weighbridge-live__flag {
    margin-left: auto;
    align-self: center;
    font-size: 0.68rem;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    font-weight: 650;
    padding: 0.2rem 0.6rem;
    border-radius: 999px;
}

.weighbridge-live__flag--stable {
    color: #bff0d2;
    background: rgba(31, 122, 77, 0.4);
}

.weighbridge-live__flag--motion {
    color: var(--gold-300);
    background: rgba(211, 160, 55, 0.18);
}

.weighbridge-live__actions {
    display: grid;
    gap: 0.5rem;
}

.weighbridge-live__actions button:where(:not([class*="mud-"])) {
    justify-content: center;
    width: 100%;
    padding: 0.7rem 1.1rem;
    font-weight: 650;
}

.weighbridge-live__note {
    margin: 0;
    font-size: 0.82rem;
    color: rgba(231, 237, 232, 0.82);
}

.weighbridge-live .pill {
    font-size: 0.68rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    font-weight: 650;
    padding: 0.2rem 0.55rem;
    border-radius: 999px;
    background: rgba(211, 160, 55, 0.2);
    color: var(--gold-300);
}

/* ---- Rail: weigh progress and cost -------------------------------------- */
.rail-card {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    padding: 1.1rem 1.25rem;
}

.rail-card__title {
    margin: 0 0 0.85rem;
    font-size: 0.74rem;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    font-weight: 650;
    color: var(--muted);
}

.weigh-progress {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.7rem;
}

.weigh-progress li {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.75rem;
    padding-left: 1.3rem;
    position: relative;
}

.weigh-progress li::before {
    content: "";
    position: absolute;
    left: 0;
    top: 0.3rem;
    width: 0.7rem;
    height: 0.7rem;
    border-radius: 999px;
    border: 2px solid var(--line);
    background: var(--surface);
}

.weigh-progress li.is-done::before {
    background: var(--ok);
    border-color: var(--ok);
}

.weigh-progress li.is-active::before {
    border-color: var(--gold);
}

.weigh-progress__label {
    color: var(--ink);
}

.weigh-progress__value {
    font-variant-numeric: tabular-nums;
    font-weight: 650;
    color: var(--green-800);
    white-space: nowrap;
}

.weigh-progress__value--muted {
    color: var(--muted);
    font-weight: 500;
}

.rail-costs {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.rail-costs li {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.75rem;
}

.rail-costs__label {
    color: var(--muted);
}

.rail-costs__value {
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    color: var(--ink);
}

.rail-costs li.rail-costs__total {
    border-top: 1px solid var(--line);
    padding-top: 0.65rem;
    margin-top: 0.2rem;
}

.rail-costs__total .rail-costs__label {
    color: var(--ink);
    font-weight: 650;
}

.rail-costs__total .rail-costs__value {
    font-size: 1.2rem;
    font-weight: 700;
    color: var(--green-800);
}

.rail-note {
    margin: 0.75rem 0 0;
    font-size: 0.8rem;
    color: var(--muted);
}

.rail-hint {
    margin: 0;
    font-size: 0.85rem;
    color: var(--muted);
    padding-left: 0.75rem;
    border-left: 3px solid var(--gold);
}

/* ---- Dashboard summary -------------------------------------------------- */
/* The chart and the recent tickets sit side by side on a wide screen and stack on a tablet,
   the same width the weighbridge office uses. */
.dash-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1.25rem;
    margin-top: 1.5rem;
    align-items: start;
}

@media (max-width: 900px) {
    .dash-grid {
        grid-template-columns: 1fr;
    }
}

/* The unit next to a figure on a stat tile: present but quiet, so the number stays the thing
   the eye lands on. */
.stat__unit {
    font-size: 1rem;
    font-weight: 600;
    color: var(--muted);
}

.recent-list {
    list-style: none;
    margin: 0.25rem 0 0;
    padding: 0;
    display: flex;
    flex-direction: column;
}

.recent-list li + li {
    border-top: 1px solid var(--line);
}

.recent-list__link {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    padding: 0.7rem 0.35rem;
    text-decoration: none;
    color: inherit;
    border-radius: var(--radius-sm);
}

.recent-list__link:hover {
    background: var(--surface-2);
}

.recent-list__main {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    min-width: 0;
}

.recent-list__number {
    font-weight: 650;
    color: var(--green-800);
    font-variant-numeric: tabular-nums;
}

.recent-list__meta {
    font-size: 0.82rem;
    color: var(--muted);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.recent-list__right {
    display: flex;
    align-items: center;
    gap: 0.7rem;
    white-space: nowrap;
}

.recent-list__weight {
    font-variant-numeric: tabular-nums;
    font-weight: 600;
}

/* ---- Breadcrumbs -------------------------------------------------------- */
/* Above the page heading on a page that sits under a list, so the way back up is a click
   rather than the browser's own button. Quiet by design: it is orientation, not the point of
   the page. */
.breadcrumbs {
    margin-bottom: 0.5rem;
}

.breadcrumbs ol {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.45rem;
    font-size: 0.85rem;
}

.breadcrumbs li {
    display: flex;
    align-items: center;
    gap: 0.45rem;
    color: var(--muted);
}

.breadcrumbs li:not(:last-child)::after {
    content: "/";
    color: var(--line);
}

.breadcrumbs a {
    color: var(--muted);
    text-decoration: none;
}

.breadcrumbs a:hover {
    color: var(--green-700);
    text-decoration: underline;
}

.breadcrumbs [aria-current="page"] {
    color: var(--ink);
    font-weight: 600;
}

/* ---- Long-form documentation (/owner/docs) ------------------------------ */
/* Rendered markdown, so the elements are whatever the documents use rather than classes we
   control. Everything is scoped under .prose to keep these element selectors away from the
   rest of the application. Colours are the existing tokens only: this is reading surface,
   not brand surface. */
.prose {
    max-width: 72ch;
    color: var(--ink);
    line-height: 1.65;
}

.prose h1,
.prose h2,
.prose h3,
.prose h4 {
    color: var(--ink);
    line-height: 1.25;
    margin: 1.6em 0 0.5em;
}

.prose h1 { font-size: 1.5rem; }
.prose h2 { font-size: 1.25rem; }
.prose h3 { font-size: 1.05rem; }
.prose h4 { font-size: 0.95rem; }

.prose h1:first-child,
.prose h2:first-child {
    margin-top: 0;
}

.prose p,
.prose ul,
.prose ol {
    margin: 0 0 0.9em;
}

.prose ul,
.prose ol {
    padding-left: 1.4em;
}

.prose a {
    color: var(--green-700);
}

.prose code {
    font-size: 0.88em;
    background: var(--surface-2);
    border: 1px solid var(--line);
    border-radius: 4px;
    padding: 0.08em 0.35em;
}

/* A wide code block or table scrolls inside itself; the page never scrolls sideways. */
.prose pre {
    background: var(--surface-2);
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    padding: 0.9rem 1rem;
    overflow-x: auto;
    margin: 0 0 1em;
}

.prose pre code {
    background: none;
    border: none;
    padding: 0;
}

.prose blockquote {
    margin: 0 0 1em;
    padding: 0.1rem 0 0.1rem 1rem;
    border-left: 3px solid var(--line);
    color: var(--muted);
}

.prose table {
    border-collapse: collapse;
    margin: 0 0 1em;
    display: block;
    overflow-x: auto;
    font-size: 0.92em;
}

.prose th,
.prose td {
    border: 1px solid var(--line);
    padding: 0.4rem 0.65rem;
    text-align: left;
    vertical-align: top;
}

.prose th {
    background: var(--surface-2);
}

.prose hr {
    border: none;
    border-top: 1px solid var(--line);
    margin: 1.6em 0;
}

/* The index page's per-section document lists. */
.docs-index {
    list-style: none;
    margin: 0;
    padding: 0;
    columns: 2;
    column-gap: 2rem;
}

.docs-index li {
    break-inside: avoid;
    padding: 0.15rem 0;
}

.docs-index a {
    color: var(--green-700);
    text-decoration: none;
}

.docs-index a:hover {
    text-decoration: underline;
}

@media (max-width: 720px) {
    .docs-index {
        columns: 1;
    }
}

/* ---- Operational product layer ----------------------------------------- */
/* Shared interaction rules also cover static pages and small embedded forms. */
.skip-link {
    position: fixed;
    top: 0.5rem;
    left: 0.5rem;
    z-index: 2000;
    padding: 0.75rem 1rem;
    background: var(--surface);
    border: 2px solid var(--green-700);
    transform: translateY(-200%);
}

.skip-link:focus { transform: none; }

:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
    outline: 3px solid var(--green-500);
    outline-offset: 3px;
}

.shell__sidebar :focus-visible { outline-color: var(--gold-300); }
:where(input, select, textarea, button, [tabindex]) { scroll-margin-block: 6rem; }
.shell__sidebar { overflow-y: auto; overscroll-behavior: contain; height: 100dvh; }
.shell__nav-close { display: none; }
.shell__link, .shell__group-links .shell__link { min-height: 44px; }
.shell__burger { border: 0; background: transparent; min-width: 44px; min-height: 44px; }
.shell__topbar { flex-wrap: wrap; padding-block: 0.5rem; }
.shell__user { flex-wrap: wrap; gap: 0.5rem; min-width: 0; }
.shell__whoami { overflow-wrap: anywhere; min-width: 0; }
.shell__section, .tenant-identity { overflow-wrap: anywhere; min-width: 0; }
.shell__content, .mud-grid-item, .mud-input-control, .collapsible-section, .ticket-layout > * { min-width: 0; }
.mud-button-root { min-height: 40px; }
.mud-icon-button { min-width: 40px; min-height: 40px; }
.mud-list-item-clickable { min-height: 44px; }
/* MudBlazor lays every input control's container out as a flex column, which stretches a
   checkbox's or switch's clickable label across its whole grid column: "This weight is an
   estimate" toggled from anywhere to its right. The box and its words are the target, nothing else. */
.mud-input-control-boolean-input > .mud-input-control-input-container { align-items: flex-start; }
.mud-input-outlined-border { border-color: var(--input-border); }
.mud-table-toolbar { height: auto; min-height: 64px; flex-wrap: wrap; gap: 0.75rem; padding-block: 0.75rem; }
.mud-table-toolbar > .mud-input-control { flex: 1 1 14rem; margin: 0; }
.mud-table-pagination-toolbar { flex-wrap: wrap; height: auto; gap: 0.25rem; padding-block: 0.5rem; }
.mud-table-cell { overflow-wrap: anywhere; }
.mud-table-cell .mud-button-root { margin-block: 0.125rem; }
.mud-table-cell:has(.mud-input-control) { min-width: 8rem; }
.mud-alert-message { min-width: 0; overflow-wrap: anywhere; }
.mud-dialog { max-height: calc(100dvh - 2rem); }
.mud-dialog-content { overflow-y: auto; }
.mud-dialog-actions { flex-wrap: wrap; gap: 0.5rem; }
.toast { max-width: min(32rem, calc(100vw - 2rem)); overflow-wrap: anywhere; bottom: max(1rem, env(safe-area-inset-bottom)); }
.toast__dismiss { min-width: 44px; min-height: 44px; text-align: center; margin-block: -0.5rem; }
.auth__panel code { overflow-wrap: anywhere; }
.form-actions { border-top: 1px solid var(--line); margin-top: 1rem; }
.driver-job-link { display: block; color: inherit; border: 1px solid var(--line); border-radius: var(--radius); }
.driver-job-link:hover { background: var(--surface-2); text-decoration: none; }
.driver-job-link .mud-stack { flex-wrap: wrap; }
.result-summary { margin-block: 0.75rem; color: var(--muted); font-size: 0.9rem; }
.section-nav { display: flex; flex-wrap: wrap; gap: 0.35rem; margin-bottom: 1.25rem; border-bottom: 1px solid var(--line); padding-bottom: 0.5rem; }
/* Also buttons, not only links. Owner billing's sections are separate routes, but a page whose
   one route does several jobs (ticket finance) needs the same strip over in-page state, and two
   strips that looked different would read as two different kinds of thing. */
.section-nav a, .section-nav button { padding: 0.65rem 0.8rem; min-height: 44px; border-radius: var(--radius-sm); }
.section-nav button {
    border: 0;
    background: none;
    font: inherit;
    color: inherit;
    cursor: pointer;
}
.section-nav button:hover { background: var(--surface-2); }
.section-nav a.active, .section-nav button.active { background: var(--green-700); color: white; font-weight: 650; }
.confirm-action { padding: 0.75rem; border: 1px solid var(--warn); border-radius: var(--radius); background: var(--warn-bg); max-width: 36rem; }
.confirm-action p { margin: 0 0 0.75rem; }
.form-guard { position: fixed; left: 50%; top: 1rem; transform: translateX(-50%); z-index: 1500; width: min(34rem, calc(100vw - 1.5rem)); padding: 1rem; border: 2px solid var(--warn); border-radius: var(--radius); background: var(--surface); box-shadow: var(--shadow-lg); }
/* A money, weight or count column. Written as style="text-align:right" on every single cell of
   every financial table before this existed, which is the same rule stated forty times and
   impossible to change in one place. Tabular figures so a column of amounts lines up on the
   decimal point rather than on whichever digits happen to be narrow. */
.numeric {
    text-align: right;
    font-variant-numeric: tabular-nums;
}

/* A posting row that cannot go to Sage without somebody doing something first. Tinted from the
   status tokens rather than from a hand-mixed rgba in a scoped stylesheet, so it is the same red
   as every other "this needs a person" on the site and follows the theme with them. Quiet on
   purpose: the row is still readable, and the badge in it is what names the problem. */
.sage-posting-filters { display: flex; flex-wrap: wrap; gap: .5rem; margin-bottom: 1.25rem; }
.sage-posting-filters .mud-button-root { min-height: 44px; }
.sage-posting-bulk { display: flex; flex-wrap: wrap; align-items: center; gap: .75rem; padding: .75rem 1rem; margin-bottom: .75rem; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface-2); }
.sage-posting-bulk .mud-button-filled { margin-left: auto; }
.sage-posting-ticket { display: grid; gap: .15rem; margin-block: .25rem; }
.sage-posting-ticket small { color: var(--muted); }
.sage-posting-list .mud-table-cell { overflow-wrap: anywhere; }
.sage-ticket-grid td { vertical-align: top; overflow-wrap: anywhere; }
.sage-posting-list .sage-posting-document { font-weight: 650; }
.sage-posting-list .mud-table-cell { padding-block: .85rem; }
.sage-posting-list td:last-child .mud-button-root { white-space: nowrap; min-height: 44px; }
.ticket-party-picker { display: flex; align-items: flex-start; gap: .5rem; }
.ticket-party-picker > .mud-input-control { flex: 1; min-width: 0; }
.ticket-party-picker > .mud-button-root { flex-shrink: 0; margin-top: .8rem; min-height: 36px; }
/* Suggestion rows render in a popover outside the picker, so these are not nested under it. */
.party-option { display: flex; flex-direction: column; min-width: 0; line-height: 1.25; }
.registration-choices { display: grid; grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr)); gap: .5rem; }
.registration-choice .mud-button-label { display: flex; flex-direction: column; align-items: flex-start; gap: .15rem; }
.registration-choice__when { font-size: .75rem; text-transform: none; }
.party-option__address { font-size: .8rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sage-review { min-width: 0; }
.sage-review-dialog .sage-review-content { overflow-y: auto; min-height: 0; }
.sage-review-dialog .sage-review-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 1rem; padding: 1rem 1.5rem; border-top: 1px solid var(--line); background: var(--surface-2); flex-shrink: 0; }
.sage-review__summary { display: grid; grid-template-columns: minmax(0, 1fr) minmax(200px, .45fr); gap: 2rem; padding: 1.25rem; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface-2); }
.sage-review__eyebrow { color: var(--muted); font-size: .8rem; margin: 0 0 .4rem; }
.sage-review__summary h3 { margin: 0; font-size: 1.65rem; line-height: 1.2; }
.sage-review__party { margin: .5rem 0 .75rem; }
.sage-review__amounts { margin: 0; display: grid; align-content: center; gap: .35rem; font-variant-numeric: tabular-nums; }
.sage-review__amounts > div { display: flex; justify-content: space-between; gap: 1rem; }
.sage-review__amounts dd { margin: 0; white-space: nowrap; }
.sage-review__amounts dt { color: var(--muted); }
.sage-review__amounts .sage-review__total { border-top: 1px solid var(--line); padding-top: .65rem; margin-top: .25rem; font-weight: 700; font-size: 1.15rem; }
.sage-review__total dt { color: var(--ink); }
.sage-review__facts { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1px; margin: 1rem 0; border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; background: var(--line); }
.sage-review__facts > div { min-width: 0; padding: .85rem 1rem; background: var(--surface); overflow-wrap: anywhere; }
.sage-review__facts dt { color: var(--muted); font-size: .75rem; margin-bottom: .25rem; }
.sage-review__facts dd { margin: 0; font-size: .9rem; font-weight: 600; }
.sage-review__links { display: flex; flex-wrap: wrap; gap: .5rem; }
.sage-review__issues { padding: 1rem 1.25rem; margin-bottom: 1rem; background: var(--warn-bg); border-left: 3px solid var(--warn); border-radius: var(--radius-sm); font-size: .9rem; }
.sage-review__issues ul { margin: .5rem 0 0; padding-left: 1.25rem; }
.sage-review__submit { display: flex; flex: 1 1 24rem; justify-content: flex-end; align-items: center; gap: 1rem; }
.sage-review__decision { font-size: .85rem; max-width: 46rem; overflow-wrap: anywhere; }
.sage-review__submit .mud-button-root { flex-shrink: 0; min-height: 44px; }
@media (max-width: 959.98px) {
    .sage-posting-filters button { flex: 1 1 calc(50% - .35rem); padding-inline: .5rem; }
    .sage-posting-list .mud-table-cell { display: grid; grid-template-columns: 7rem minmax(0, 1fr); gap: .25rem .5rem; text-align: left; }
    .sage-posting-list .mud-table-cell:before { grid-column: 1; grid-row: 1 / 4; white-space: normal; overflow-wrap: normal; }
    .sage-posting-list .mud-table-cell > * { grid-column: 2; min-width: 0; }
    .sage-review__summary { grid-template-columns: minmax(0, 1fr); gap: 1rem; padding: 1rem; }
    .sage-review__submit { flex-direction: column; align-items: stretch; gap: .5rem; }
    .sage-review__facts { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .sage-posting-bulk .mud-button-filled { margin-left: 0; }
}
@media (max-width: 480px) {
    .sage-review__facts { grid-template-columns: minmax(0, 1fr); }
    .sage-posting-bulk .mud-button-root { width: 100%; }
}

.sage-posting-attention > td {
    background: var(--bad-bg);
}

.responsive-records { max-width: 100%; }

@media (max-width: 900px) {
    .responsive-records thead {
        position: absolute; width: 1px; height: 1px; overflow: hidden;
        clip-path: inset(50%); white-space: nowrap;
    }
    table.responsive-records, .responsive-records table, .responsive-records tbody { display: block; width: 100%; }
    .responsive-records tbody tr { display: block; border: 1px solid var(--line); border-radius: var(--radius); margin-bottom: 0.75rem; }
    .responsive-records tbody td {
        display: block; text-align: left !important; min-width: 0; max-width: none !important;
        padding: 0.5rem 0.75rem; overflow-wrap: anywhere; border-bottom: 0;
    }
    .responsive-records tbody td[data-label]::before {
        content: attr(data-label); display: block; font-weight: 650; color: var(--muted); font-size: 0.8rem;
    }
    .responsive-records tbody td:first-child { background: var(--surface-2); font-weight: 650; }
    .responsive-records tfoot, .responsive-records tfoot tr { display: block; }
    .responsive-records tfoot td { display: inline-block; padding: 0.5rem; }
}

@media (min-width: 901px) and (min-height: 700px) {
    .form-actions { position: sticky; bottom: 0; z-index: 3; background: var(--surface); }
}

@media (max-width: 900px) {
    .shell__sidebar { visibility: hidden; }
    .shell__toggle:checked ~ .shell__sidebar { visibility: visible; }
    .shell__nav-close { display: block; align-self: flex-end; color: white; border-color: var(--gold-300); margin-bottom: 0.5rem; }
    .navigation-open { overflow: hidden; }
    .shell__topbar { padding-inline: 1rem; gap: 0.5rem; }
    .shell__user { width: 100%; padding-left: 0; }
    .shell__user > form { margin-left: auto; }
    .ticket-layout__rail { scroll-margin-top: 8rem; }
    .mud-table-toolbar > .mud-input-control { max-width: none !important; }
}

@media (max-width: 600px) {
    .shell__content { padding-inline: 0.75rem; }
    .shell__topbar { position: static; }
    .mud-paper.pa-4 { padding: 0.75rem !important; }
    .mud-button-root { min-height: 44px; }
    .mud-icon-button { min-width: 44px; min-height: 44px; }
    .mud-input input, .mud-input textarea, .field input, .field select { font-size: 16px; }
    .mud-table-cell:has(.mud-input-control) { min-width: 0; }
    .mud-dialog { margin: 0.5rem; width: calc(100% - 1rem); max-height: calc(100dvh - 1rem); }
    .ticket-action-bar { position: static; }
    .field-row, .fields-grid { grid-template-columns: minmax(0, 1fr); }
    .d-flex.gap-2, .mud-stack-row { flex-wrap: wrap; }
    .toast { right: 0.75rem; max-width: calc(100vw - 1.5rem); }
}

@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after { scroll-behavior: auto !important; animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; animation-iteration-count: 1 !important; }
}

@media (forced-colors: active) {
    .badge, .plate, .mud-button-root { border: 1px solid ButtonText; }
}

/*
   The application is read at a gate, in an office and on a driver's phone. These rules make
   the shared primitives read as one calm paper-based operational product rather than a set of
   floating component cards. Keep product-specific exceptions local to their screen.
*/
.mud-typography.mud-typography-h1,
.mud-typography.mud-typography-h2,
.mud-typography.mud-typography-h3,
.mud-typography.mud-typography-h4,
.mud-typography.mud-typography-h5,
.mud-typography.mud-typography-h6,
.mud-button,
.button-link,
.shell__wordmark,
.shell__section {
    font-family: var(--font-display);
}

.card,
.collapsible-section,
.ticket-section,
.rail-card,
.chart-card {
    border-radius: var(--radius);
    box-shadow: var(--shadow);
}

.collapsible-section {
    border-color: var(--line);
    box-shadow: none;
}

.collapsible-section__header {
    min-height: 3.25rem;
    padding: 0.9rem 1rem 0.75rem;
    background: var(--section-heading-background);
    border-bottom: 1px solid var(--line);
    cursor: default;
}

button.collapsible-section__header {
    cursor: pointer;
}

.collapsible-section__header:hover {
    background: var(--section-heading-background);
}

button.collapsible-section__header:hover {
    background: var(--section-heading-hover);
}

.collapsible-section__title {
    margin: 0;
    font-family: var(--font-display);
    font-size: 1.15rem;
    font-weight: 600;
    line-height: 1.2;
}

.collapsible-section__body {
    padding: 1.25rem 1rem;
}

.ticket-section {
    position: relative;
    border: 1px solid var(--line);
    box-shadow: none;
}

.ticket-section > .mud-typography-h6 {
    font-family: var(--font-display);
    font-size: 1.2rem;
    font-weight: 600;
}

/* The internal notes banner at the top of a ticket is the way back to the notes box at the foot
   of the form, so it has to read as a control rather than as a static alert. */
.ticket-notes-banner { cursor: pointer; }

.ticket-notes-banner:focus-visible {
    outline: 2px solid var(--mud-palette-primary);
    outline-offset: 2px;
}

.ticket-notes-banner__text {
    white-space: pre-line;
    overflow-wrap: anywhere;
}

/* A required box the Defra submission found empty, lit while the rest of the page dims for a
   moment (merliniumSpotlightField). A giant box-shadow rather than a backdrop element, because
   .ticket-editor is a size container: its layout containment makes it a stacking context and the
   containing block for anything fixed inside it, so a backdrop on the body would cover this box too
   and one inside the editor would not reach the edges of the screen. */
.field-spotlight {
    position: relative;
    z-index: 20;
    border-radius: 4px;
    background: var(--mud-palette-surface);
    box-shadow: 0 0 0 8px var(--mud-palette-surface), 0 0 0 100vmax rgba(7, 27, 21, 0.6);
    animation: field-spotlight-in .25s ease-out;
}

@keyframes field-spotlight-in {
    from { box-shadow: 0 0 0 8px var(--mud-palette-surface), 0 0 0 100vmax rgba(7, 27, 21, 0); }
}

.field-flash .mud-input-outlined-border {
    animation: field-flash .5s ease-in-out 3;
}

@keyframes field-flash {
    50% {
        border-color: var(--mud-palette-error);
        border-width: 2px;
        box-shadow: 0 0 0 4px rgba(179, 38, 30, 0.35);
    }
}

.ticket-finance-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: flex-end;
    gap: .5rem;
    margin-inline-start: auto;
    max-width: 100%;
}

.ticket-finance-document {
    display: inline-flex;
    flex-wrap: nowrap;
    align-items: center;
    justify-content: flex-end;
    gap: .5rem;
    max-width: 100%;
}

.ticket-finance-document > .mud-button-root { min-width: 0; }
.ticket-finance-document > .mud-chip-container {
    display: flex;
    align-items: center;
    align-self: center;
    flex-shrink: 0;
}
.ticket-finance-document .mud-chip { margin: 0; }

.ticket-action-bar {
    position: sticky;
    bottom: 0.75rem;
    z-index: 3;
    border: 1px solid rgba(18, 58, 44, 0.25);
    border-radius: var(--radius);
    background: color-mix(in srgb, var(--surface) 94%, var(--gold-300));
    box-shadow: var(--shadow-lg);
}

.mud-button {
    border-radius: var(--radius-sm);
    font-weight: 600;
    letter-spacing: 0.015em;
    text-transform: none;
}

.mud-input-control .mud-input-label,
.mud-table-head .mud-table-cell {
    font-weight: 650;
}

.mud-table-container {
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--surface);
}

.mud-table-cell {
    padding-block: 0.7rem;
}

.badge {
    border-radius: var(--radius-sm);
    font-family: var(--font-display);
    font-weight: 600;
}

@media (max-width: 720px) {
    .ticket-action-bar {
        bottom: 0;
        margin-inline: -0.25rem;
    }

    .collapsible-section__body {
        padding: 1rem;
    }
}

/* Keyed on touch rather than width: a landscape tablet is as wide as a small desktop, but
   there the on-screen keyboard already takes half the height and a bar pinned above it
   covers the field being typed into. A desktop with a mouse keeps the bar in reach. */
@media (hover: none) and (pointer: coarse) {
    .ticket-action-bar { position: static; }
}

/* Final overrides also cover the operational ticket layer above. */
.load-state-retry { display: block; padding-block: .65rem; }
@media (max-width: 600px) {
    .ticket-action-bar { position: static; }
    .mud-input-control { min-width: 0 !important; max-width: 100%; }
    .mud-table-pagination-information { margin-inline: 8px; }
}

main code, main small { overflow-wrap: anywhere; }
.chart-data { margin-top: .75rem; }
.chart-data summary { cursor: pointer; padding-block: .65rem; }
.chart-data ol { padding-left: 1.5rem; }
@media (max-width: 600px) {
    .d-flex.ga-2 { flex-wrap: wrap; }
    .proof-grid > div { min-width: 0; }
}

.row-actions { text-align: left; max-width: 24rem; }
.row-actions summary { cursor: pointer; min-height: 44px; padding: .65rem; font-weight: 600; }
.row-actions[open] { min-width: min(100%, 16rem); }
.row-actions > .mud-stack { padding: .5rem; }

/* Keep the title and its description together beside the page action. */
.page-head__copy { min-width: 0; flex: 1; }
.page-head__copy p { max-width: 85ch; }
.result-summary { color: var(--muted); margin-block: .65rem; font-size: .9rem; }
@media (max-width: 900px) {
    .mud-simple-table.responsive-records .mud-table-container table tbody { display: block; width: 100%; }
    .mud-simple-table.responsive-records .mud-table-container table tbody tr {
        display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
    }
    .mud-simple-table.responsive-records .mud-table-container table tbody td {
        display: block; width: auto !important; max-width: none !important;
        text-align: left !important; border-bottom: 0; padding: .6rem .9rem;
    }
    .mud-simple-table.responsive-records .mud-table-container table tbody td:first-child { grid-column: 1 / -1; }
}
@media (max-width: 600px) {
    .mud-simple-table.responsive-records .mud-table-container table tbody tr { grid-template-columns: minmax(0, 1fr); }
}

.chip > button { min-width: 32px; min-height: 32px; }

.button-link { min-height: 44px; }

/* Operational home. Scoped to the dashboard so forms and other statistics keep their layout. */
.dashboard { --dashboard-pad: 1.35rem; max-width: 1500px; margin-inline: auto; color: var(--ink); }
.dashboard h1 { font-size: clamp(1.8rem, 3vw, 2.4rem); letter-spacing: -.035em; line-height: 1.15; margin: .2rem 0 .45rem; }
.dashboard h2 { font-size: 1.15rem; letter-spacing: -.015em; line-height: 1.35; margin: 0; }
.dashboard h3 { font-size: 1rem; margin: .6rem 0 .3rem; }
.dashboard__header { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 1rem; padding-block: .35rem 1.5rem; }
.dashboard__identity { display: flex; flex-wrap: wrap; align-items: center; gap: 1.5rem; min-width: 0; max-width: 100%; }
.dashboard__logo { width: 340px; height: 200px; max-width: 100%; object-fit: contain; object-position: left center; flex-shrink: 0; }
.dashboard__eyebrow { color: var(--muted); font-size: .75rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; margin: 0 0 .35rem; overflow-wrap: anywhere; }
.dashboard__header-actions { display: flex; gap: .6rem; flex-shrink: 0; }
.dashboard__header-actions .mud-button-root { min-height: 44px; }
.dashboard__updated { margin: 0 0 1.25rem; font-size: .8rem; color: var(--muted); }
.dashboard__updated strong { color: #864910; }
.dashboard__metrics { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); border: 1px solid var(--line); border-radius: 12px; background: var(--surface); margin-bottom: 1.4rem; overflow: hidden; }
.dashboard__metric, button.dashboard__metric { display: flex; flex-direction: column; align-items: flex-start; justify-content: space-between; gap: .4rem; padding: 1.1rem var(--dashboard-pad); margin: 0; border: 0; border-right: 1px solid var(--line); border-radius: 0; color: var(--ink); background: transparent; text-align: left; box-shadow: none; font-weight: 400; min-width: 0; }
.dashboard__metric:last-child { border-right: 0; }
.dashboard__metric > span { font-size: .85rem; font-weight: 600; }
.dashboard__metric > strong { font-size: clamp(1.6rem, 2.8vw, 2.2rem); line-height: 1.25; letter-spacing: -.035em; font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.dashboard__metric em { font-size: 1rem; font-style: normal; font-weight: 400; }
.dashboard__metric small { color: var(--muted); font-size: .75rem; line-height: 1.5; }
.dashboard__metric small span { margin-left: .4rem; }
button.dashboard__metric:hover, button.dashboard__metric[aria-pressed="true"] { background: #edf3ef; color: var(--ink); }
button.dashboard__metric--attention { background: #fff5e5; }
button.dashboard__metric--attention > strong { color: #864910; }
button.dashboard__metric--attention:hover, button.dashboard__metric--attention[aria-pressed="true"] { background: #fcebd0; }
.dashboard__workspace { display: grid; grid-template-columns: minmax(0, 1fr) minmax(280px, .46fr); gap: 1.4rem; align-items: start; }
.dashboard__main, .dashboard__aside { display: grid; gap: 1.4rem; min-width: 0; }
.dashboard__panel { border: 1px solid var(--line); border-radius: 12px; background: var(--surface); min-width: 0; margin: 0; }
.dashboard__panel-head { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: .75rem; padding: var(--dashboard-pad); }
.dashboard__panel a { color: #245842; }
.dashboard__panel-head > a, .dashboard__panel-foot a { font-size: .85rem; font-weight: 600; }
.dashboard__panel-head > a { flex-shrink: 0; }
.dashboard__filters { display: flex; gap: .35rem; flex-wrap: wrap; margin-inline: var(--dashboard-pad); padding: .25rem; background: #edf1ec; border-radius: 8px; }
.dashboard__filters button { min-height: 44px; border: 1px solid transparent; padding: .45rem .7rem; background: transparent; color: #3e5147; border-radius: 6px; font-size: .85rem; font-weight: 600; flex: 1; box-shadow: none; white-space: nowrap; }
.dashboard__filters button:hover { background: #e1e9e1; }
.dashboard__filters button[aria-pressed="true"] { background: var(--surface); border-color: var(--line); color: #194e34; box-shadow: 0 1px 3px #14251e0a; }
.dashboard__filters button span { display: inline-block; padding: 0 .35rem; margin-left: .2rem; border-radius: 4px; background: #e8ede7; font-variant-numeric: tabular-nums; }
.dashboard__queue-note { padding: .8rem var(--dashboard-pad); margin: 0; color: var(--muted); font-size: .78rem; line-height: 1.55; }
.dashboard__tickets, .dashboard__jobs { list-style: none; padding: 0; margin: 0; }
.dashboard__tickets li, .dashboard__jobs li { border-top: 1px solid var(--line); }
.dashboard__ticket { display: grid; grid-template-columns: minmax(0, 1fr) auto 16px; align-items: center; gap: .75rem; padding: .6rem var(--dashboard-pad); text-decoration: none; }
.dashboard__ticket:hover, .dashboard__jobs a:hover { background: #f0f4ed; text-decoration: none; }
.dashboard__ticket-main { display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: baseline; gap: .15rem .65rem; min-width: 0; }
.dashboard__ticket-main > strong { color: var(--ink); font-size: .9rem; font-variant-numeric: tabular-nums; }
.dashboard__customer { color: #3e5147; font-size: .9rem; overflow-wrap: anywhere; }
.dashboard__ticket-meta { grid-column: 1 / -1; color: var(--muted); font-size: .78rem; overflow-wrap: anywhere; }
.dashboard__ticket-side { display: grid; grid-template-columns: auto auto; align-items: center; justify-items: end; gap: .15rem .5rem; font-size: .78rem; color: #3e5147; }
.dashboard__ticket-side time { grid-column: 1 / -1; font-size: .72rem; color: var(--muted); }
.dashboard__status { background: #e8ede7; color: #345343; padding: .15rem .45rem; border-radius: 4px; font-size: .7rem; font-weight: 700; }
.dashboard__status--attention { background: #fff0d5; color: #794411; }
.dashboard__row-arrow { color: #58745f; }
.dashboard__panel-foot { border-top: 1px solid var(--line); padding: .75rem var(--dashboard-pad); }
.dashboard__panel-foot a, .dashboard__panel-head > a, .dashboard__welcome > a, .dashboard__invoices > a, .dashboard__empty > a { display: inline-flex; align-items: center; min-height: 44px; gap: .45rem; }
.dashboard__empty { text-align: center; padding: 2rem var(--dashboard-pad); color: var(--muted); }
.dashboard__empty h3 { color: var(--ink); }
.dashboard__empty p { font-size: .9rem; margin: .25rem auto .5rem; max-width: 30rem; }
.dashboard__empty > .mud-icon-root { width: 2rem; height: 2rem; }
.dashboard__empty--compact { padding-block: 1rem; }
.dashboard__planning-summary { display: flex; flex-wrap: wrap; gap: .75rem 1.25rem; padding: 0 var(--dashboard-pad) 1rem; font-size: .8rem; color: var(--muted); }
.dashboard__planning-summary strong { color: var(--ink); }
.dashboard__jobs a { display: grid; grid-template-columns: 3rem minmax(0, 1fr) auto; gap: .75rem; padding: 1rem var(--dashboard-pad); align-items: center; text-decoration: none; font-size: .85rem; }
.dashboard__jobs a > span:nth-child(2) { display: grid; gap: .2rem; overflow-wrap: anywhere; }
.dashboard__jobs strong { font-size: .8rem; color: var(--ink); }
.dashboard__jobs time { font-weight: 700; font-variant-numeric: tabular-nums; }
.dashboard__job-status { font-size: .75rem; color: #6c4c24; }
.dashboard__shortcuts { padding: var(--dashboard-pad); }
.dashboard__shortcuts h2 { margin-bottom: .5rem; }
.dashboard__shortcuts nav a { display: flex; align-items: center; gap: .75rem; padding-block: .85rem; min-height: 60px; text-decoration: none; }
.dashboard__shortcuts nav a + a { border-top: 1px solid var(--line); }
.dashboard__shortcuts nav a > span:first-of-type { flex: 1; font-weight: 600; font-size: .85rem; }
.dashboard__shortcuts .mud-icon-root { width: 21px; height: 21px; color: #58745f; }
.dashboard__shortcuts small { display: block; color: var(--muted); font-size: .75rem; font-weight: 400; margin-top: .2rem; }
.dashboard__shortcuts a:hover > span:first-of-type { text-decoration: underline; }
.dashboard__invoices { padding: var(--dashboard-pad); }
.dashboard__invoices .dashboard__panel-head { padding: 0; }
.dashboard__invoices dl { margin: .6rem 0; }
.dashboard__invoices dl > div { display: flex; justify-content: space-between; gap: 1rem; padding: .65rem 0; border-bottom: 1px solid var(--line); font-size: .85rem; }
.dashboard__invoices dd { margin: 0; font-weight: 700; }
.dashboard__invoices > p { font-size: .78rem; color: var(--muted); margin: .8rem 0 .25rem; }
.dashboard__invoices > a { font-size: .85rem; font-weight: 600; }
.dashboard__invoices > .dashboard__balance { display: grid; gap: .25rem; margin-block: 1rem; }
.dashboard__balance strong { font-size: 1.8rem; line-height: 1.2; color: var(--ink); font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.dashboard__finance-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); margin: 0; padding: 0 var(--dashboard-pad); gap: 1rem; }
.dashboard__finance-grid > div { border-top: 1px solid var(--line); padding-top: .9rem; }
.dashboard__finance-grid dt { font-size: .8rem; color: var(--muted); }
.dashboard__finance-grid dd { margin: .35rem 0 0; font-size: 1.8rem; font-weight: 700; color: var(--ink); }
.dashboard__finance-foot { display: flex; flex-wrap: wrap; gap: .5rem 1.25rem; color: var(--muted); font-size: .8rem; }
@media (max-width: 600px) {
    .dashboard__finance-grid { grid-template-columns: minmax(0, 1fr); gap: .5rem; }
    .dashboard__finance-grid > div { display: flex; align-items: center; justify-content: space-between; gap: 1rem; }
    .dashboard__finance-grid dd { margin: 0; }
}
.dashboard__throughput { padding: var(--dashboard-pad); }
.dashboard__throughput .dashboard__filters { margin: 1rem 0; }
.dashboard__throughput-total { margin: 0 0 .5rem; font-size: .8rem; color: var(--muted); }
.dashboard__throughput-total strong { font-size: 1.75rem; color: var(--ink); letter-spacing: -.025em; }
.dashboard__throughput .chart__ticks { font-size: .65rem; }
.dashboard__throughput .chart__ticks span { white-space: nowrap; overflow: visible; min-width: 0; }
.dashboard__throughput .chart__ticks span:last-child { text-align: right; }
.dashboard__throughput .chart__ticks span:not(:first-child):not(:last-child) { visibility: hidden; overflow: hidden; }
.dashboard__throughput .chart-data summary { min-height: 44px; display: flex; align-items: center; text-decoration: underline; font-size: .8rem; cursor: pointer; }
.dashboard__throughput .chart-data ol { font-size: .8rem; padding-left: 1.5rem; }
.dashboard__chart-note, .dashboard__throughput > p:not([class]) { color: var(--muted); font-size: .75rem; line-height: 1.6; margin: .6rem 0 0; }
.dashboard__welcome { padding: 2rem; }
.dashboard__welcome > p:not(.dashboard__eyebrow) { color: var(--muted); max-width: 35rem; }
.dashboard :is(a, button, summary):focus-visible { outline: 3px solid #245842; outline-offset: 3px; }
.dashboard button.dashboard__metric:focus-visible { outline-offset: -4px; }
@media (max-width: 1100px) {
    .dashboard__workspace { grid-template-columns: minmax(0, 1fr); }
    .dashboard__aside { grid-template-columns: repeat(auto-fit, minmax(min(100%, 18rem), 1fr)); align-items: start; }
}
@media (max-width: 850px) {
    .dashboard__metrics { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .dashboard__metric:nth-child(2) { border-right: 0; }
    .dashboard__metric:nth-child(-n+2) { border-bottom: 1px solid var(--line); }
    .dashboard__header { align-items: flex-start; flex-wrap: wrap; }
}
@media (max-width: 600px) {
    .dashboard { --dashboard-pad: 1rem; }
    .dashboard__identity { flex-direction: column; align-items: flex-start; gap: .75rem; width: 100%; }
    .dashboard__logo { width: 280px; height: 164px; }
    .dashboard__aside { grid-template-columns: minmax(0, 1fr); }
    .dashboard__header-actions { width: 100%; }
    .dashboard__header-actions .mud-button-root { flex: 1; }
    .dashboard__panel-head { align-items: flex-start; flex-wrap: wrap; gap: .25rem .75rem; }
    .dashboard__metric, button.dashboard__metric { padding: .9rem; }
    .dashboard__ticket { grid-template-columns: minmax(0, 1fr) 16px; gap: .3rem .6rem; }
    .dashboard__ticket-side { display: flex; grid-column: 1; grid-row: 2; flex-direction: row; flex-wrap: wrap; align-items: center; gap: .25rem .65rem; }
    .dashboard__row-arrow { grid-column: 2; grid-row: 1 / 3; }
    .dashboard__jobs a { grid-template-columns: 3rem minmax(0, 1fr); }
    .dashboard__job-status { grid-column: 2; }
    .dashboard__filters button { white-space: normal; }
    .dashboard__welcome { padding: var(--dashboard-pad); }
}
/* PDF choices use the browser's top layer, including inside lookup/edit overlays. */
dialog.document-actions { width: min(900px, calc(100vw - 2rem)); max-height: calc(100dvh - 2rem); margin: auto; padding: 1.25rem; border: 0; border-radius: 12px; background: var(--mud-palette-surface, white); color: var(--mud-palette-text-primary, #222); box-shadow: 0 16px 64px #0005; }
dialog.document-actions::backdrop { background: #0009; }
.document-actions__heading { display: flex; align-items: center; justify-content: space-between; gap: 1rem; }
.document-actions__heading h2 { margin: 0; font-size: 1.25rem; }
.document-actions__heading button { font-size: 1.5rem; width: 2.5rem; height: 2.5rem; padding: 0; background: transparent; color: inherit; border-radius: 50%; }
.document-actions__heading button:hover { background: #8882; }
.document-actions__buttons { display: flex; gap: .75rem; margin: 1rem 0; }
.document-actions iframe { width: 100%; height: 60dvh; border: 1px solid #ddd; border-radius: 6px; background: #f5f5f5; }

/* Compact account entry inside the weighbridge dialog. */
.identity-documents__staged { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 150px), 1fr)); gap: 10px; margin-top: 10px; }
.identity-documents__thumbnail { margin: 0; padding: 8px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); min-width: 0; }
.identity-documents__thumbnail img { display: block; width: 100%; height: 150px; object-fit: contain; }
.identity-documents__thumbnail figcaption { margin-top: 6px; color: var(--ink); font-size: .8rem; overflow-wrap: anywhere; }
.identity-documents__thumbnail figcaption span { display: block; color: var(--muted); font-size: .75rem; }
.quick-party { display: grid; gap: 12px; }
.quick-party__columns { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; align-items: stretch; }
.quick-party__columns--single { grid-template-columns: minmax(0, 1fr); }
.quick-party .quick-party__section { margin: 0; min-width: 0; border: 1px solid var(--line); overflow: hidden; }
.quick-party .collapsible-section__header { min-height: 36px; padding: 9px 12px; }
.quick-party .collapsible-section__title { font-size: 1rem; }
.quick-party .collapsible-section__body { padding: 10px 12px 12px; }
.quick-party__hint { display: block; color: var(--muted); margin-top: 8px; }
.quick-party__haulier .quick-party__hint { margin: 0 0 8px; }
.quick-party__bank-identity .identity-documents__summary { flex-direction: column; align-items: flex-start; gap: 12px; }
.quick-party__bank-identity .identity-documents__summary > .mud-button-root { width: 100%; }
.quick-party__bank-identity .identity-documents__summary > div { width: 100%; }
@media (max-width: 699px) {
    .quick-party__columns { grid-template-columns: minmax(0, 1fr); }
}

/* Shared section bands for cards that predate CollapsibleSection. */
.mud-paper.pa-4 > .mud-typography-h6:first-child,
.rail-card > .rail-card__title:first-child,
.chart-card > .chart-card__head:first-child,
.dashboard__panel > .dashboard__panel-head:first-child {
    background: var(--section-heading-background);
    color: var(--section-heading-foreground);
    border-radius: var(--radius) var(--radius) 0 0;
}

.mud-paper.pa-4 > .mud-typography-h6:first-child {
    margin-top: -16px;
    margin-left: -16px;
    margin-right: -16px;
    padding: 12px 16px;
    font-family: var(--font-display);
    font-size: 1.15rem;
    font-weight: 600;
}

.rail-card > .rail-card__title:first-child {
    margin: -1.1rem -1.25rem .85rem;
    padding: .85rem 1.25rem;
    font-family: var(--font-display);
    font-size: 1rem;
    letter-spacing: normal;
    text-transform: none;
}

.chart-card > .chart-card__head:first-child {
    margin: -1.25rem -1.35rem .9rem;
    padding: .85rem 1.35rem;
}

.chart-card__head h2,
.chart-card__head .chart-card__note,
.dashboard .dashboard__panel-head h2,
.dashboard .dashboard__panel-head > a {
    color: inherit;
}

.dashboard .dashboard__panel-head > a { text-decoration: underline; }

.dashboard .dashboard__panel-head .dashboard__eyebrow { color: var(--section-heading-foreground); opacity: .8; }
.dashboard__panel > .dashboard__panel-head:first-child { border-radius: 11px 11px 0 0; }
.dashboard__invoices > .dashboard__panel-head:first-child {
    margin: calc(-1 * var(--dashboard-pad)) calc(-1 * var(--dashboard-pad)) 1rem;
    padding: var(--dashboard-pad);
}
.dashboard .dashboard__shortcuts > h2:first-child {
    margin: calc(-1 * var(--dashboard-pad)) calc(-1 * var(--dashboard-pad)) .5rem;
    padding: var(--dashboard-pad);
    border-radius: 11px 11px 0 0;
    background: var(--section-heading-background);
    color: var(--section-heading-foreground);
}

.customer-tickets-dialog .mud-dialog-title {
    background: var(--section-heading-background);
    color: var(--section-heading-foreground);
}

.customer-tickets-dialog .mud-dialog-title .mud-button-root { color: inherit; }
.customer-tickets-dialog .mud-table-container { max-height: 360px; }

.organisation-columns {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    column-gap: 1rem;
}

.organisation-columns > div { min-width: 0; }
.organisation-registrations > .collapsible-section:only-child { grid-column: 1 / -1; }
.organisation-locations .sites-summary { margin-block: 0; }

.organisation-actions {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: .75rem;
}

.organisation-actions > .mud-stack { margin-left: auto; }

@media (min-width: 1100px) {
    .organisation-columns { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .organisation-profile > div > .collapsible-section { height: calc(100% - 1rem); }
}

/* Product prices share column widths so rates can be compared down the list. */
.update-prices .price-list__selectors {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 12rem), 1fr));
    gap: 1rem;
    width: 100%;
    margin: 0;
}
.update-prices .price-list__selectors > .mud-grid-item { width: auto; max-width: none; padding: 0; }
.price-editor__toolbar,
.price-editor__actions {
    display: flex;
    justify-content: space-between;
    align-items: center;
    flex-wrap: wrap;
    gap: 1rem;
}

.price-editor__toolbar > .mud-input-control,
.price-editor__toolbar > .search-field { flex: 1 1 18rem; max-width: 32rem; }
.price-editor__scope { color: var(--muted); font-size: .875rem; }
.price-editor__help { margin: .75rem 0 1rem; font-size: .875rem; color: var(--muted); }
.price-editor__help summary { cursor: pointer; width: fit-content; }
.price-editor__help p { margin: .5rem 0 0; }
.price-editor__actions { padding: .85rem 0 0; }
.price-editor__actions small { display: block; color: var(--muted); margin-top: .2rem; }
.update-prices .price-editor { overflow: visible; }
.price-editor > .collapsible-section__header { border-radius: 6px 6px 0 0; }

.pricing-list--grid {
    --price-columns: minmax(10rem, 2fr) minmax(5rem, 1fr) minmax(6.5rem, 1fr) repeat(2, minmax(5rem, 1fr)) minmax(4.5rem, .8fr) minmax(7rem, 1.3fr);
}

.pricing-list--grid .pricing-list__table {
    border: 1px solid var(--line);
    border-radius: var(--radius);
}

.pricing-list--grid .pricing-list__columns {
    display: grid;
    grid-template-columns: var(--price-columns);
    gap: .65rem;
    padding: .85rem .75rem;
    background: var(--section-heading-background);
    color: var(--section-heading-foreground);
    font-size: .8rem;
    font-weight: 600;
    border-radius: 5px 5px 0 0;
}

.pricing-list--grid .pricing-list__row { padding: .6rem .75rem; border-bottom: 1px solid var(--line); }
.pricing-list--grid .pricing-list__row:last-child { border-bottom: 0; }
.pricing-list--grid .pricing-list__row:nth-child(odd) { background: var(--surface-2); }
.pricing-list--grid .pricing-list__row:focus-within { box-shadow: inset 3px 0 var(--gold); }
.pricing-list--grid .pricing-list__row > .mud-grid {
    display: grid;
    grid-template-columns: var(--price-columns);
    align-items: center;
    gap: .65rem;
    width: 100%;
    margin: 0 !important;
}

.pricing-list--grid .pricing-list__row > .mud-grid > .mud-grid-item { width: auto; max-width: none; padding: 0; }
.pricing-list--grid .pricing-list__product { display: flex; flex-direction: column; gap: .15rem; overflow-wrap: anywhere; }
.pricing-list--grid .pricing-list__product > span { font-size: .75rem; color: var(--muted); }
.pricing-list--grid .pricing-list__product > strong { font-size: .9rem; font-weight: 600; }
.pricing-list--grid .pricing-list__inherited { color: var(--muted); margin-top: .35rem; }
.pricing-list--grid .pricing-list__inherited > .mud-typography { margin-bottom: 0 !important; font-size: .72rem; }
.pricing-list--grid .mud-input-control { margin-top: 0; }
.pricing-list--grid input { font-variant-numeric: tabular-nums; }

@media (min-width: 1100px) {
    .pricing-list--grid .pricing-list__table { overflow: visible; }
    .pricing-list--grid .pricing-list__columns { position: sticky; top: 4rem; z-index: 2; }
    .pricing-list--grid .mud-input-label {
        position: absolute;
        width: 1px;
        height: 1px;
        padding: 0;
        margin: -1px;
        overflow: hidden;
        clip-path: inset(50%);
        white-space: nowrap;
    }
    .pricing-list--grid .mud-input-outlined-border legend { display: none; }
}

@media (max-width: 1099px) {
    .pricing-list--grid .pricing-list__columns {
        position: absolute;
        width: 1px;
        height: 1px;
        overflow: hidden;
        clip-path: inset(50%);
    }
    .pricing-list--grid .pricing-list__row > .mud-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .75rem; }
    .pricing-list--grid .pricing-list__row > .mud-grid > .mud-grid-item:first-child,
    .pricing-list--grid .pricing-list__row > .mud-grid > .mud-grid-item:last-child { grid-column: 1 / -1; }
    .pricing-list--grid .pricing-list__row { padding: 1rem; }
    .pricing-list--grid .pricing-list__product { margin-bottom: .25rem; }
    .price-editor__actions > .mud-stack { width: 100%; justify-content: flex-end; }
}

/* Touch devices (tablets on the weighbridge) keep only the menu button in the topbar: the
   organisation, site and account chips cost a row of a screen that is mostly form, and the
   menu holds Sign out instead. Keyed on touch rather than width for the reason the ticket
   action bar is. */
.shell__touch-signout { display: none; margin-top: auto; }
.shell__sidefoot + .shell__touch-signout { margin-top: 0; }

@media (hover: none) and (pointer: coarse) {
    .shell__topbar .tenant-identity,
    .shell__topbar .shell__user { display: none; }
    .shell__touch-signout { display: block; }
}

.shell__touch-only { display: none; }
@media (hover: none) and (pointer: coarse) {
    .shell__link.shell__touch-only { display: flex; }
}
