/* /Components/Dashboard/ActionCard.razor.rz.scp.css */
/* -----------------------------------------------------------------------
   Scoped, and every selector below is on a plain element written in this
   file. The card's padding comes from Mud's own pa-3 rather than a class of
   ours, because a class handed to MudPaper never receives the scope
   attribute and the rule would match nothing.
   ----------------------------------------------------------------------- */

.acard__head[b-qyfv2z1xjk] {
    display: flex;
    align-items: center;
    gap: .4rem;
    margin-bottom: .6rem;
}

.acard__title[b-qyfv2z1xjk] {
    font-size: .95rem;
    font-weight: 600;
    color: var(--mud-palette-text-primary);
}

/* The group total sits at the end of the heading, coloured by the worst
   thing in the group rather than by its size. */
.acard__total[b-qyfv2z1xjk] {
    margin-left: auto;
    font-size: .8rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    padding: .05rem .4rem;
    border-radius: 2px;
}

.acard__total--bad[b-qyfv2z1xjk] {
    color: var(--mud-palette-error-text);
    background: var(--mud-palette-error);
}

.acard__total--warn[b-qyfv2z1xjk] {
    color: var(--mud-palette-warning-text);
    background: var(--mud-palette-warning);
}

.acard__total--queue[b-qyfv2z1xjk] {
    color: var(--mud-palette-text-secondary);
    background: var(--mud-palette-action-default-hover);
}

.acard__rows[b-qyfv2z1xjk] {
    display: flex;
    flex-direction: column;
}

.acard__row[b-qyfv2z1xjk] {
    display: flex;
    align-items: baseline;
    gap: .55rem;
    padding: .35rem .25rem;
    border-top: 1px solid var(--mud-palette-divider);
    color: inherit;
    text-decoration: none;
}

.acard__row:first-child[b-qyfv2z1xjk] {
    border-top: 0;
}

.acard__row:not(.acard__row--flat):hover[b-qyfv2z1xjk] {
    background: var(--mud-palette-action-default-hover);
}

/* A row with nowhere to go should not look clickable. */
.acard__row--flat[b-qyfv2z1xjk] {
    cursor: default;
}

.acard__count[b-qyfv2z1xjk] {
    flex: 0 0 2.2rem;
    text-align: right;
    font-weight: 700;
    font-size: .95rem;
    font-variant-numeric: tabular-nums;
}

.acard__count--bad[b-qyfv2z1xjk] {
    color: var(--mud-palette-error);
}

.acard__count--warn[b-qyfv2z1xjk] {
    color: var(--mud-palette-warning);
}

.acard__count--queue[b-qyfv2z1xjk] {
    color: var(--mud-palette-text-primary);
}

.acard__body[b-qyfv2z1xjk] {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.acard__label[b-qyfv2z1xjk] {
    font-size: .8rem;
    line-height: 1.3;
    color: var(--mud-palette-text-primary);
}

/* The half that says whether it is urgent. Smaller, because it is read
   second - after the count has already caught the eye. */
.acard__detail[b-qyfv2z1xjk] {
    font-size: .7rem;
    line-height: 1.3;
    color: var(--mud-palette-text-secondary);
}

.acard__clear[b-qyfv2z1xjk] {
    display: flex;
    align-items: center;
    gap: .4rem;
    padding: .5rem .25rem 1rem;
}
/* /Components/Dashboard/ActionStrip.razor.rz.scp.css */
/* What needs a person, in one line.

   A strip rather than four cards: this is the one thing on the dashboard
   somebody can act on, and it should read in a glance rather than be worked
   through. The colour on this page belongs here - everything else is a
   measurement and nothing you can do anything about. */

.strip[b-nvj9fla8c4] {
    padding: 0.75rem 1rem;
}

.strip__head[b-nvj9fla8c4] {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
    margin-bottom: 0.625rem;
}

.strip__total[b-nvj9fla8c4] {
    font-size: 1.375rem;
    font-weight: 700;
    line-height: 1;
}

.strip__title[b-nvj9fla8c4] {
    font-size: 0.8125rem;
    color: var(--mud-palette-text-secondary);
}

.strip__spacer[b-nvj9fla8c4] {
    flex: 1 1 auto;
    min-width: 0.5rem;
}

.strip__clear[b-nvj9fla8c4] {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

/* ------------------------------------------------------------- the items
   Wrapping chips, not a list. A list implies an order to work through; these
   are alternatives, and on a wide screen they all sit on one line where the
   whole state of the operation can be taken in at once. */
.strip__items[b-nvj9fla8c4] {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.strip__item[b-nvj9fla8c4] {
    display: inline-flex;
    align-items: baseline;
    gap: 0.4rem;
    padding: 0.3rem 0.65rem;
    border-radius: 999px;
    border: 1px solid var(--mud-palette-lines-default);
    background: var(--mud-palette-background-grey);
    font-size: 0.8125rem;
    line-height: 1.3;
    color: inherit;
    text-decoration: none;
    transition: border-color 100ms ease-in-out, background-color 100ms ease-in-out;
}

a.strip__item:hover[b-nvj9fla8c4] {
    border-color: var(--mud-palette-text-secondary);
    background: var(--mud-palette-surface);
}

a.strip__item:focus-visible[b-nvj9fla8c4] {
    outline: 2px solid var(--mud-palette-secondary);
    outline-offset: 2px;
}

.strip__count[b-nvj9fla8c4] {
    font-weight: 700;
    font-size: 0.9375rem;
}

.strip__label[b-nvj9fla8c4] {
    color: var(--mud-palette-text-secondary);
}

/* The count carries the severity, not the whole chip. Eighteen coloured
   pills is a traffic accident; a coloured number beside a grey word is a
   figure you can read the urgency of without the chip shouting. */
.strip__item--bad .strip__count[b-nvj9fla8c4] { color: #A6432F; }
.strip__item--warn .strip__count[b-nvj9fla8c4] { color: #8A6410; }

/* Only the worst gets an edge as well, so the one thing that is actually
   wrong is findable in a row of twelve. */
.strip__item--bad[b-nvj9fla8c4] {
    border-color: #A6432F;
}
/* /Components/Dashboard/BookTile.razor.rz.scp.css */
/* The dashboard book tile.

   Full height so three tiles in a row line up regardless of how many alerts
   each carries, with the alerts pushed to the bottom edge - a tile whose
   sections drift is harder to compare across than one whose don't. */

/* NOTE  .btile itself - the flex column and the full height that make three
   tiles line up - is in app.css. It is the class on this component's root
   MudPaper, and scoped CSS cannot reach a child component's root element. */

.btile__head[b-7nf6mf1apc] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    margin-bottom: 0.75rem;
}

.btile__title[b-7nf6mf1apc] {
    display: flex;
    align-items: center;
    gap: 0.4375rem;
    min-width: 0;
}

.btile__title[b-7nf6mf1apc]  .btile__glyph {
    color: #2C622C;
}

.btile__head[b-7nf6mf1apc]  .btile__open {
    display: inline-flex;
    align-items: center;
    white-space: nowrap;
}

.btile__head[b-7nf6mf1apc]  .btile__open .mud-icon-root {
    font-size: 1rem;
}

/* ------------------------------------------------------------- the headline
   The count sits at display size against a small lowercase word, so the
   number is what carries from across a desk. */
.btile__headline[b-7nf6mf1apc] {
    display: flex;
    align-items: baseline;
    gap: 0.4375rem;
    margin-bottom: 0.5rem;
}

.btile__count[b-7nf6mf1apc] {
    font-size: 2.25rem;
    font-weight: 700;
    line-height: 1;
    letter-spacing: -0.02em;
    color: var(--mud-palette-text-primary);
}

.btile__unit[b-7nf6mf1apc] {
    font-size: 0.75rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--mud-palette-text-secondary);
}

/* ------------------------------------------------------------------ the bar
   One bar segmented by status, in the same colours the status chips use.
   It replaced a single green fill showing outstanding against total, which
   answered "how busy" and nothing else - two books can be equally busy and in
   completely different trouble. */
.btile__bar[b-7nf6mf1apc] {
    display: flex;
    height: 0.5rem;
    border-radius: 3px;
    overflow: hidden;
    background: var(--mud-palette-lines-default);

    /* Neutral grey, so the edge survives the night view too. */
    box-shadow: inset 0 0 0 1px rgba(127, 127, 127, 0.28);
}

/* No gap and no border between segments: a colour change is the boundary, and
   a gap at every join on a bar of six statuses is more line than bar. */
.btile__slice[b-7nf6mf1apc] {
    display: block;
    height: 100%;
    flex: 0 0 auto;
}

/* ------------------------------------------------------------------ the key
   Wraps, because the number of statuses is whatever the book is in and a tile
   is a third of a row wide. Each entry keeps its dot, label and count
   together, so a wrap never separates a colour from what it means. */
.btile__key[b-7nf6mf1apc] {
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem 0.75rem;
    margin-top: 0.5rem;
}

.btile__keyitem[b-7nf6mf1apc] {
    display: inline-flex;
    align-items: center;
    gap: 0.3125rem;
    font-size: 0.75rem;
    color: var(--mud-palette-text-secondary);
    white-space: nowrap;
}

/* A stage nothing is in. Still listed, so the key says what the whole route
   is - but set back, so the eye lands on the stages that have something in
   them first. */
.btile__keyitem--empty[b-7nf6mf1apc] {
    opacity: 0.45;
}

.btile__dot[b-7nf6mf1apc] {
    width: 0.5rem;
    height: 0.5rem;
    border-radius: 2px;
    flex: 0 0 auto;
}

.btile__keycount[b-7nf6mf1apc] {
    font-weight: 700;
    color: var(--mud-palette-text-primary);
}

/* An empty book says so rather than drawing an empty track, which reads as a
   bar that failed to load. Sized to roughly what the bar and key would take,
   so a clear book does not make its tile shorter than the two beside it. */
.btile__none[b-7nf6mf1apc] {
    display: flex;
    align-items: center;
    min-height: 2.25rem;
}

/* --------------------------------------------------------------- the alerts
   Pushed to the bottom, one row each, resting grey. Colour arrives with the
   first non-zero count and not before, which is what makes a coloured tile
   mean something across a row of three. */
.btile__alerts[b-7nf6mf1apc] {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    margin-top: auto;
    padding-top: 0.875rem;
}

.btile__alert[b-7nf6mf1apc] {
    display: flex;
    align-items: center;
    gap: 0.4375rem;
    padding: 0.3125rem 0.5rem;
    border-radius: 4px;
    background: var(--mud-palette-background-grey);
    font-size: 0.75rem;
    color: var(--mud-palette-text-disabled);
}

.btile__alert[b-7nf6mf1apc]  .mud-icon-root {
    font-size: 1rem;
}

.btile__alertcount[b-7nf6mf1apc] {
    font-weight: 700;
    min-width: 1.25rem;
}

.btile__alertlabel[b-7nf6mf1apc] {
    min-width: 0;
    /* Wraps rather than pushing the tile wider than its grid column. */
    overflow-wrap: anywhere;
}

.btile__alert[b-7nf6mf1apc]  .btile__alertlink {
    margin-left: auto;
    display: inline-flex;
    color: inherit;
}

.btile__alert[b-7nf6mf1apc]  .btile__alertlink .mud-icon-root {
    font-size: 0.9375rem;
}

/* Gold: someone should look at this today. */
.btile__alert--warn[b-7nf6mf1apc] {
    background: rgba(241, 181, 61, 0.16);
    box-shadow: inset 0 0 0 1px rgba(241, 181, 61, 0.55);
    color: var(--mud-palette-text-primary);
}

/* Brick: this is already wrong rather than about to be. */
.btile__alert--bad[b-7nf6mf1apc] {
    background: rgba(166, 67, 47, 0.14);
    box-shadow: inset 0 0 0 1px rgba(166, 67, 47, 0.5);
    color: var(--mud-palette-text-primary);
}

.btile__alert--bad[b-7nf6mf1apc]  .mud-icon-root {
    color: #A6432F;
}
/* /Components/Dashboard/CustomerHome.razor.rz.scp.css */
/* -----------------------------------------------------------------------
   Scoped, and every selector is on a plain element written in this file.
   Padding on the panels comes from Mud's own pa-3 / pa-4.
   ----------------------------------------------------------------------- */

/* The four headline tiles used to be written here, with their own type
   scale and their explanation printed underneath. They are KpiTile now - the
   same component the staff dashboard uses - so the rules that styled them
   have gone with the markup. Two dashboards in one product setting a big
   number two different ways is exactly how they drift apart. */

/* An arrival is a date and the thing arriving, in that order - the date is
   what is being scanned for down the column. */
.cdash__arrival[b-1a4xfewd96] {
    display: flex;
    gap: .9rem;
    padding: .6rem 0;
    border-top: 1px solid var(--mud-palette-divider);
}

.cdash__arrival:first-of-type[b-1a4xfewd96] {
    border-top: 0;
    padding-top: 0;
}

.cdash__when[b-1a4xfewd96] {
    flex: 0 0 6.5rem;
    display: flex;
    flex-direction: column;
}

.cdash__date[b-1a4xfewd96] {
    font-size: .85rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

.cdash__date--none[b-1a4xfewd96] {
    font-weight: 400;
    color: var(--mud-palette-text-disabled);
}

.cdash__away[b-1a4xfewd96] {
    font-size: .7rem;
    color: var(--mud-palette-text-secondary);
}

.cdash__what[b-1a4xfewd96] {
    min-width: 0;
    flex: 1 1 auto;
}

.cdash__detail[b-1a4xfewd96] {
    font-size: .72rem;
    line-height: 1.4;
    color: var(--mud-palette-text-secondary);
}

.cdash__doc[b-1a4xfewd96] {
    display: flex;
    align-items: flex-start;
    gap: .5rem;
    padding: .45rem 0;
    border-top: 1px solid var(--mud-palette-divider);
}

.cdash__doc:first-of-type[b-1a4xfewd96] {
    border-top: 0;
    padding-top: 0;
}

.cdash__docbody[b-1a4xfewd96] {
    min-width: 0;
    display: flex;
    flex-direction: column;
}
/* /Components/Dashboard/KpiTile.razor.rz.scp.css */
/* -----------------------------------------------------------------------
   Every class here sits on a plain element written in this file, so the
   scope attribute lands on it and these rules match. A class handed to a
   Mud component would not be scoped and would silently match nothing -
   which is why the tile's own padding comes from Mud's pa-3 rather than
   from a class of ours.
   ----------------------------------------------------------------------- */

.kpi[b-xp80xwjmvs] {
    display: flex;
    flex-direction: column;
    gap: .1rem;
    min-width: 0;
}

.kpi__label[b-xp80xwjmvs] {
    font-size: .7rem;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--mud-palette-text-secondary);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* The figure carries the tile. Tabular digits so a row of tiles lines up
   and a changing number does not shuffle the ones beside it. */
.kpi__value[b-xp80xwjmvs] {
    font-size: 1.7rem;
    font-weight: 700;
    line-height: 1.15;
    font-variant-numeric: tabular-nums;
    color: var(--mud-palette-text-primary);
}

.kpi__value--none[b-xp80xwjmvs] {
    color: var(--mud-palette-text-disabled);
    font-weight: 400;
}

.kpi__unit[b-xp80xwjmvs] {
    font-size: .9rem;
    font-weight: 500;
    color: var(--mud-palette-text-secondary);
}

.kpi__sample[b-xp80xwjmvs] {
    font-size: .7rem;
    color: var(--mud-palette-text-secondary);
}

/* ---------------------------------------------------------------- leading
   The handful of figures that open the page are set larger than the rest.
   Same component, same tile, more weight - rather than a second component
   that would drift from this one. */
.kpi--lead .kpi__value[b-xp80xwjmvs] {
    font-size: 2.5rem;
    line-height: 1.05;
}

.kpi--lead .kpi__label[b-xp80xwjmvs] {
    font-size: 0.75rem;
}

/* ------------------------------------------------------------- the trend
   Under the figure, in the space the sample size used to take. Green and
   brick are the portal's own good and bad; flat is grey on purpose, because
   "it has not really moved" is the most common answer and the least
   interesting. */
.kpi__trend[b-xp80xwjmvs] {
    display: flex;
    align-items: center;
    gap: 0.25rem;
    font-size: 0.75rem;
    line-height: 1.3;
    margin-top: 0.125rem;
}

.kpi__trend--good[b-xp80xwjmvs] { color: #2C622C; }
.kpi__trend--bad[b-xp80xwjmvs] { color: #A6432F; }
.kpi__trend--flat[b-xp80xwjmvs] { color: var(--mud-palette-text-secondary); }

.kpi__since[b-xp80xwjmvs] {
    color: var(--mud-palette-text-secondary);
}

/* The icon is a component root, so the scope attribute never lands on it. */
.kpi__trend[b-xp80xwjmvs]  .mud-icon-root {
    font-size: 1rem !important;
}
/* /Components/Documents/DocumentsCard.razor.rz.scp.css */
/* The documents panel.

   A row per file: type glyph, name and facts, who can see it, and the way to
   remove it. Rows rather than a table because the columns are of very
   different weights - the name is the row, everything else is a caption. */

.docs[b-nrfwagpuo7] {
    display: flex;
    flex-direction: column;
}

.docs__row[b-nrfwagpuo7] {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.5rem 0;
    border-bottom: 1px solid var(--mud-palette-lines-default);
}

.docs__row:last-child[b-nrfwagpuo7] {
    border-bottom: none;
}

.docs[b-nrfwagpuo7]  .docs__glyph {
    font-size: 1.375rem !important;
    color: var(--mud-palette-text-disabled);
    flex: 0 0 auto;
}

.docs__body[b-nrfwagpuo7] {
    display: flex;
    flex-direction: column;
    min-width: 0;
    flex: 1 1 auto;
}

.docs[b-nrfwagpuo7]  .docs__name {
    /* Long filenames are the norm here - a bill of lading arrives named after
       the vessel, the voyage and the date. Wraps rather than truncating,
       because the distinguishing part is usually at the end. */
    overflow-wrap: anywhere;
    text-align: left;
}

.docs__meta[b-nrfwagpuo7] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.25rem 0.5rem;
    font-size: 0.6875rem;
    color: var(--mud-palette-text-secondary);
}

/* A middot between the facts, drawn rather than typed, so the markup stays
   free of separator characters that would be read aloud. */
.docs__meta > * + *[b-nrfwagpuo7]::before {
    content: "·";
    margin-right: 0.5rem;
    color: var(--mud-palette-text-disabled);
}

/* What the document is - "Bill of lading", "Packing list". The one part of
   the caption worth reading first, so it carries weight and not the muted
   colour. */
.docs__cat[b-nrfwagpuo7] {
    font-weight: 700;
    color: var(--mud-palette-text-primary);
}

/* ------------------------------------------------------------- visibility
   Stated on every row, both ways round. A panel where only the internal ones
   are badged makes "no badge" mean "the customer can see this", which is the
   wrong way for a default to fail. */
.docs__vis[b-nrfwagpuo7] {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    flex: 0 0 auto;
    padding: 0.125rem 0.4375rem;
    border-radius: 3px;
    font-size: 0.6875rem;
    font-weight: 700;
    white-space: nowrap;
    background: var(--mud-palette-background-grey);
    box-shadow: inset 0 0 0 1px var(--mud-palette-lines-default);
    color: var(--mud-palette-text-secondary);
}

.docs__vis[b-nrfwagpuo7]  .mud-icon-root {
    font-size: 0.875rem;
}

/* Teal, the portal's "this is moving outward" colour. Not green: green means
   progress here, and a shared document is a fact rather than a step. */
.docs__vis--shared[b-nrfwagpuo7] {
    background: rgba(70, 120, 134, 0.14);
    box-shadow: inset 0 0 0 1px rgba(70, 120, 134, 0.5);
    color: var(--mud-palette-text-primary);
}

/* ----------------------------------------------------------- empty state */
.docs__empty[b-nrfwagpuo7] {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.375rem;
    padding: 1.5rem 1rem;
    border-radius: 6px;
    border: 1px dashed var(--mud-palette-lines-default);
    text-align: center;
}

.docs__empty[b-nrfwagpuo7]  .docs__emptyglyph {
    font-size: 1.75rem !important;
    color: var(--mud-palette-text-disabled);
}

@media (max-width: 560px) {
    .docs__row[b-nrfwagpuo7] {
        flex-wrap: wrap;
    }

    .docs__body[b-nrfwagpuo7] {
        flex-basis: 100%;
    }
}
/* /Components/Documents/SubmissionsPanel.razor.rz.scp.css */
/* One thing the customer has sent, and the two decisions about it.

   A row rather than a card: these are transient - each one is gone as soon as
   somebody decides about it - and giving them card edges would make a queue of
   three look like a permanent part of the order. */
.submission[b-2h62fk5udz] {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 0.75rem;
    padding: 0.75rem;
    border-radius: 6px;
    background: var(--mud-palette-background-grey);
}

.submission + .submission[b-2h62fk5udz] {
    margin-top: 0.5rem;
}

.submission__what[b-2h62fk5udz] {
    display: flex;
    align-items: flex-start;
    gap: 0.5rem;
    min-width: 0;
}

/* Their own words, set apart from the file name so it reads as a message
   rather than as more metadata. */
.submission__note[b-2h62fk5udz] {
    margin-top: 0.25rem;
    padding-left: 0.5rem;
    border-left: 2px solid var(--mud-palette-lines-default);
    color: var(--mud-palette-text-secondary);
}

/* Held together on a phone, where the row wraps and a stray button would
   otherwise end up under the note it belongs beside. */
.submission__act[b-2h62fk5udz] {
    display: flex;
    align-items: center;
    gap: 0.25rem;
    margin-left: auto;
}
/* /Components/Inventory/HoldStockDialog.razor.rz.scp.css */
/* The hold dialog's location options.

   Each radio carries its own figures, because the choice of shed depends on
   how much is free at each and a bare list of codes would send the reader
   back to the stock screen to find out. */

.hs__option[b-172nm4wst5] {
    display: flex;
    flex-direction: column;
    line-height: 1.35;
}

.hs__where[b-172nm4wst5] {
    display: flex;
    align-items: baseline;
    gap: 0.375rem;
    font-size: 0.875rem;
    font-weight: 700;
}

.hs__bin[b-172nm4wst5] {
    font-size: 0.6875rem;
    font-weight: 400;
    color: var(--mud-palette-text-secondary);
}

.hs__figures[b-172nm4wst5] {
    font-size: 0.75rem;
    color: var(--mud-palette-text-secondary);
}

.hs__figures .portal-num[b-172nm4wst5] {
    font-weight: 700;
    color: var(--mud-palette-text-primary);
}

.hs__muted[b-172nm4wst5] {
    margin-left: 0.25rem;
    color: var(--mud-palette-text-disabled);
}
/* /Components/Inventory/OrderLinesForPart.razor.rz.scp.css */
/* The order-lines-for-a-part panel. */

.olfp__empty[b-lkf7gnadym] {
    padding: 1.25rem 0.5rem;
    text-align: center;
}
/* /Components/Inventory/PartPicture.razor.rz.scp.css */
/* -----------------------------------------------------------------------
   A part's picture.

   Scoped, so every selector here names an element written in this
   component's own .razor file. Nothing styles a child component's root -
   Blazor stamps the scope attribute on markup, never on a component's
   rendered root, and a rule aimed at one silently does nothing. The audit in
   tools/check-scoped-css.py enforces it.

   The box is square and its size comes from the caller as an inline style,
   because one component serves a 44px thumbnail in a list and a 260px
   picture on a part's own page. Only what does not change with size is here.
   ----------------------------------------------------------------------- */

.picture[b-4kjwj3erq4] {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: none;
    overflow: hidden;
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: 4px;
    background: var(--mud-palette-background-grey);
}

/* Contained, not cropped. A photograph of a shackle cropped square may not
   show the shackle, and identification is the point of it. */
.picture__image[b-4kjwj3erq4] {
    width: 100%;
    height: 100%;
    object-fit: contain;
    display: block;
}

/* Dashed, so an empty box reads as a place a picture goes rather than as a
   picture of nothing. */
.picture--empty[b-4kjwj3erq4] {
    border-style: dashed;
}

/* The stand-in.

   The mark is painted as a mask rather than shown as an image, so its colour
   comes from a theme variable and is right in both the day and night views.
   The night view is a toggle in the application bar rather than the
   browser's preference, so prefers-color-scheme cannot see it - and the only
   supplied icon is near-black, which on the night view's dark ground would
   be invisible. The mark is monochrome, so a mask loses nothing.

   text-disabled rather than text-secondary: this is the absence of a
   picture, and it should not compete with the part number beside it. */
.picture__fallback[b-4kjwj3erq4] {
    width: 62%;
    height: 62%;
    display: block;
    background-color: var(--mud-palette-text-disabled);
    -webkit-mask-image: url("/brand/akva-icon.png");
    mask-image: url("/brand/akva-icon.png");
    -webkit-mask-size: contain;
    mask-size: contain;
    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;
    -webkit-mask-position: center;
    mask-position: center;
}

/* The enlarged picture is NOT styled here. MudTooltip renders its content
   into the popover layer at the document root, so it is not a descendant of
   anything in this component - ::deep compiles to "an element carrying this
   component's scope, then a descendant", which nothing there satisfies. Those
   rules would have been dead CSS. The two elements carry inline styles in the
   .razor instead, which is the honest answer when scoped CSS provably cannot
   reach the markup. */
/* /Components/Inventory/ScanButton.razor.rz.scp.css */
/* Scanning with the phone. */

.scan__buttons[b-xhg651uddq] {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

/* ------------------------------------------------------------ the viewfinder
   Only in the markup while the camera runs, so this is never an empty black
   rectangle. Capped in height: a full-bleed video pushes the thing being
   scanned off a phone screen, and the point is to see both. */
.scan__view[b-xhg651uddq] {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.scan__video[b-xhg651uddq] {
    width: 100%;
    max-height: 40vh;
    border-radius: 6px;
    background: #000;
    object-fit: cover;
}
/* /Components/Inventory/WarehouseFloorView.razor.rz.scp.css */
/* -----------------------------------------------------------------------
   A whole floor, down to the box.

   Scoped, so every selector here has to name an element written in this
   component's own .razor file. Nothing styles a child component's root -
   Blazor stamps the scope attribute on markup, never on a component's
   rendered root, and a rule aimed at one is a rule that silently does
   nothing. The audit in tools/check-scoped-css.py enforces it.

   The sizes are chosen so a floor fits a laptop without scrolling: three
   aisles of four bays, each bay five shelves by eight boxes, is 480 cells at
   13px plus gaps - about 1100px across and 500 down.
   ----------------------------------------------------------------------- */

.floor[b-3osbgc4eqj] {
    display: flex;
    flex-direction: column;
    gap: 1.25rem;
    overflow-x: auto;
    padding-bottom: 0.25rem;
}

/* An aisle: its number on the left, its bays across. */
.floor__aisle[b-3osbgc4eqj] {
    display: flex;
    align-items: flex-start;
    gap: 0.75rem;
    min-width: fit-content;
}

.floor__aisleLabel[b-3osbgc4eqj] {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    min-width: 2.5rem;
    padding-top: 1rem;
}

.floor__aisleNumber[b-3osbgc4eqj] {
    font-size: 1.5rem;
    font-weight: 700;
    line-height: 1;
    color: var(--mud-palette-text-primary);
}

.floor__aisleWord[b-3osbgc4eqj] {
    font-size: 0.625rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--mud-palette-text-secondary);
}

.floor__bays[b-3osbgc4eqj] {
    display: flex;
    gap: 0.75rem;
}

.floor__bay[b-3osbgc4eqj] {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
}

.floor__bayLabel[b-3osbgc4eqj] {
    display: flex;
    align-items: baseline;
    gap: 0.25rem;
    font-size: 0.6875rem;
    color: var(--mud-palette-text-secondary);
}

.floor__side[b-3osbgc4eqj] {
    font-size: 0.5625rem;
    opacity: 0.7;
}

.floor__shelves[b-3osbgc4eqj] {
    border-collapse: separate;
    border-spacing: 2px;
}

/* The shelf letter, down the left of each bay. */
.floor__shelf[b-3osbgc4eqj] {
    width: 0.875rem;
    font-size: 0.625rem;
    font-weight: 600;
    text-align: right;
    padding-right: 0.125rem;
    color: var(--mud-palette-text-secondary);
}

/* One box. A button because it is pressed, and sized to be pressable on a
   tablet in a shed rather than to be as small as it could be. */
.floor__box[b-3osbgc4eqj] {
    width: 15px;
    height: 15px;
    padding: 0;
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: 2px;
    background: var(--mud-palette-surface);
    cursor: pointer;
    display: block;
}

.floor__box:hover[b-3osbgc4eqj] {
    outline: 2px solid var(--mud-palette-primary);
    outline-offset: 1px;
}

.floor__box:focus-visible[b-3osbgc4eqj] {
    outline: 2px solid var(--mud-palette-primary);
    outline-offset: 1px;
}

/* Empty, holding something, nearly full. Three steps rather than a gradient,
   because at fifteen pixels a gradient is one indistinguishable smudge. */
.floor__box--empty[b-3osbgc4eqj] {
    background: var(--mud-palette-background-gray);
}

.floor__box--used[b-3osbgc4eqj] {
    background: #9DBE9D;
    border-color: #7FA57F;
}

.floor__box--full[b-3osbgc4eqj] {
    background: #2C622C;
    border-color: #234923;
}

/* What the current view is pointing at. Distinct hues rather than one accent,
   because the three views ask different questions and somebody switching
   between them should see that the answer changed. */
.floor__box--found[b-3osbgc4eqj] {
    background: #1976D2;
    border-color: #0D47A1;
    box-shadow: 0 0 0 2px rgba(25, 118, 210, 0.35);
}

.floor__box--stale[b-3osbgc4eqj] {
    background: #E8A33D;
    border-color: #B87A1C;
}

.floor__box--flagged[b-3osbgc4eqj] {
    background: #A6432F;
    border-color: #7E2F20;
}

/* A fault rather than a fact: more is promised out of this box than is in it.
   An outline so it reads on top of whatever the fill is saying. */
.floor__box--over[b-3osbgc4eqj] {
    outline: 2px solid #A6432F;
    outline-offset: -3px;
}

/* The box whose panel is open. */
.floor__box--open[b-3osbgc4eqj] {
    outline: 2px solid var(--mud-palette-text-primary);
    outline-offset: 1px;
}
/* /Components/Jobs/Fact.razor.rz.scp.css */
/* The label/value row.

   Was a MudBlazor flex utility stack with the label and value both at body2.
   Written out here so the label can carry a glyph and the value can carry the
   weight - a facts panel is read by finding the value, not the label. */

.fact[b-lvijsvpsyx] {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.3125rem 0;
    /* A hairline per row. On a panel of six facts this is the difference
       between a list and a paragraph. */
    border-bottom: 1px solid var(--mud-palette-lines-default);
}

.fact:last-child[b-lvijsvpsyx] {
    border-bottom: none;
}

.fact__label[b-lvijsvpsyx] {
    display: flex;
    align-items: center;
    gap: 0.4375rem;
    font-size: 0.8125rem;
    color: var(--mud-palette-text-secondary);
    white-space: nowrap;
    min-width: 0;
}

.fact__label[b-lvijsvpsyx]  .fact__icon {
    /* Quieter than the label it sits beside: it is a finding aid, not a
       second reading of the row. */
    font-size: 1rem !important;
    color: var(--mud-palette-text-disabled);
    flex: 0 0 auto;
}

.fact__value[b-lvijsvpsyx] {
    font-size: 0.8125rem;
    font-weight: 600;
    color: var(--mud-palette-text-primary);
    text-align: right;
    min-width: 0;
    /* Long values - a vessel name, an API base URL - wrap rather than push
       the row wider than its card. */
    overflow-wrap: anywhere;
}
/* /Components/Jobs/LineItemsCard.razor.rz.scp.css */
/* The order items card.

   Only the entry row needs styling of its own; the table below it is the
   portal's ordinary one. */

/* ------------------------------------------------------------ the entry row
   Set apart from the heading above and the table below, because it is neither:
   it is a control that produces the rows underneath it. A tinted band does
   that with no border to line up against the table's own. */
.lines__entry[b-1dgbc6ynml] {
    padding: 0.75rem 1rem 1rem;
    background: var(--mud-palette-background-grey);
    border-top: 1px solid var(--mud-palette-lines-default);
    border-bottom: 1px solid var(--mud-palette-lines-default);
}

/* ---------------------------------------------------------- a part in the list
   Number and description on the left, what is free on the right. The number
   and the description are both here because the search matched on either, and
   a list that hid the half that matched would look like it had misunderstood.

   Blazor stamps the scope attribute on markup written in this file, and these
   rows are written here - so no ::deep is needed. The MudText inside them is a
   component root, which is why nothing below reaches into one. */
.lines__option[b-1dgbc6ynml] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    width: 100%;
    min-width: 0;
}

/* --------------------------------------------------------------- actions
   A fixed set of positions, so the same place means the same thing on every
   row. The despatch action appears on some lines and not others; its slot is
   held open either way rather than letting the three that follow it shuffle
   left. */
.lines__do[b-1dgbc6ynml] {
    white-space: nowrap;
    text-align: right;
}

.lines__slot[b-1dgbc6ynml] {
    display: inline-block;
    width: 30px;
    vertical-align: middle;
}

/* ---------------------------------------------------------------- sources
   A line can come from stock and from two purchase orders at once, so these
   wrap rather than pushing the column wide. Tight gaps: they are chips on a
   table row, not a toolbar. */
.lines__src[b-1dgbc6ynml] {
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem;
}
/* /Components/Layout/BrandMark.razor.rz.scp.css */
/* The wordmark, and the type that stands in until the file is there. */

.brandmark[b-jkw4yat73k] {
    display: inline-flex;
    align-items: center;
    /* Fixed height so the bar does not reflow when the real mark arrives. */
    height: 1.5rem;
}

.brandmark__word[b-jkw4yat73k] {
    height: 1.375rem;
    width: auto;
    display: block;
}

.brandmark__icon[b-jkw4yat73k] {
    height: 1.5rem;
    width: auto;
    display: block;
}

/* No reversed icon was supplied, only the near-black one. Inverting it is
   exact for a monochrome mark: the supplied icon has no colour to lose, so
   this produces the off-white version rather than an approximation of it. */
.brandmark__icon--reversed[b-jkw4yat73k] {
    filter: invert(1) brightness(1.6);
}

/* --------------------------------------------------------------- fallback
   Hidden by default. The image's onerror handler adds .brandmark--missing to
   itself, which both hides the broken image and reveals this. Doing it this
   way round means the type never flashes before a present image loads. */
.brandmark__fallback[b-jkw4yat73k] {
    display: none;
    font-family: Arial, Helvetica, "Segoe UI", sans-serif;
    font-weight: 700;
    font-size: 0.9375rem;
    line-height: 1;
    letter-spacing: 0.06em;
    white-space: nowrap;
}

.brandmark__fallback-light[b-jkw4yat73k] {
    font-weight: 400;
    letter-spacing: 0.02em;
    opacity: 0.62;
    margin-left: 0.25em;
}

.brandmark--missing[b-jkw4yat73k] {
    display: none;
}

.brandmark:has(.brandmark--missing) .brandmark__fallback[b-jkw4yat73k] {
    display: inline;
}
/* /Components/Layout/GlobalSearchBox.razor.rz.scp.css */
/* The search box in the navy bar.

   MudBlazor's outlined field is drawn for a light ground, so on the bar it
   needs its own colours - the text, the placeholder, the icon and the outline
   all reverse. The field itself is a component root, so everything that
   reaches inside it goes through ::deep. */

.gsearch[b-xubcar37eb] {
    flex: 1 1 22rem;
    max-width: 30rem;
    margin-inline: 1rem;
}

/* Below the small breakpoint the bar has the mark, the menu and the account
   disc to fit; a search field as well leaves none of them room. The portal's
   own lists still have their own search, which is where somebody on a phone
   is looking anyway. */
@media (max-width: 44rem) {
    .gsearch[b-xubcar37eb] { display: none; }
}

.gsearch[b-xubcar37eb]  .mud-input-outlined-border {
    border-color: rgba(255, 255, 255, 0.28);
}

.gsearch[b-xubcar37eb]  .mud-input-outlined:hover .mud-input-outlined-border {
    border-color: rgba(255, 255, 255, 0.55);
}

.gsearch[b-xubcar37eb]  .mud-input.mud-input-outlined.mud-shrink .mud-input-outlined-border,
.gsearch[b-xubcar37eb]  .mud-input-outlined:focus-within .mud-input-outlined-border {
    border-color: var(--mud-palette-secondary);
    border-width: 1px;
}

.gsearch[b-xubcar37eb]  input,
.gsearch[b-xubcar37eb]  .mud-input-adornment .mud-icon-root {
    color: #E7EAEF;
}

.gsearch[b-xubcar37eb]  input::placeholder {
    color: rgba(231, 234, 239, 0.62);
    opacity: 1;
}

/* ------------------------------------------------------------------ a hit
   A word saying which book, then the number and what it is. Two numbers in
   two books look identical, so the word is what makes the list choosable. */

.gsearch__hit[b-xubcar37eb] {
    display: flex;
    align-items: baseline;
    gap: 0.6rem;
    width: 100%;
    min-width: 0;
    padding-block: 0.15rem;
}

.gsearch__kind[b-xubcar37eb] {
    flex: 0 0 4.5rem;
    font-size: 0.625rem;
    font-weight: 700;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    color: var(--mud-palette-text-secondary);
    padding-top: 0.15rem;
}

/* Only the two that mean money get a colour, and they are the two most
   easily confused with each other. Colouring all six would be six colours
   nobody can learn. */
.gsearch__kind--order[b-xubcar37eb] { color: var(--mud-palette-primary); }
.gsearch__kind--purchaseorder[b-xubcar37eb] { color: var(--mud-palette-info); }

.gsearch__what[b-xubcar37eb] {
    display: flex;
    flex-direction: column;
    min-width: 0;
    gap: 0.05rem;
}

.gsearch__title[b-xubcar37eb] {
    font-size: 0.875rem;
    line-height: 1.3;
}

.gsearch__sub[b-xubcar37eb] {
    font-size: 0.75rem;
    line-height: 1.35;
    color: var(--mud-palette-text-secondary);

    /* One line. A description that wraps to three turns a list of five hits
       into a list you have to scroll. */
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.gsearch__none[b-xubcar37eb] {
    padding: 0.6rem 0.25rem;
    font-size: 0.875rem;
    color: var(--mud-palette-text-secondary);
}
/* /Components/Layout/MainLayout.razor.rz.scp.css */
/* The application frame.

   Replaces the Blazor template's .page / .sidebar / .top-row rules, which
   styled a layout this app has never used - MudBlazor draws the frame. They
   were dead weight and one of them painted a purple gradient nothing showed. */

/* NOTE  The bar, the main region and the avatar are styled in app.css, not
   here. They are classes handed to MudAppBar, MudMainContent and MudAvatar,
   and Blazor's scoped CSS cannot reach a child component's root element - the
   rules compiled to `.portal-bar[b-xxxxx]` and matched nothing. The spans
   below are written in this file, so they do get the scope attribute and are
   styled here where they belong.

   ---------------------------------------------------------------------- */

.portal-bar__context[b-8wjubknn8i] {
    align-items: baseline;
    gap: 0.5rem;
    min-width: 0;
}

.portal-bar__product[b-8wjubknn8i] {
    font-size: 0.8125rem;
    /* Was .62 opacity and unreadable in the screenshot. A dim label is still
       a label - if it is not worth reading it should not be there. */
    color: rgba(249, 249, 246, 0.82);
    white-space: nowrap;
}

.portal-bar__sep[b-8wjubknn8i] {
    color: rgba(249, 249, 246, 0.45);
}

.portal-bar__section[b-8wjubknn8i] {
    font-weight: 700;
    font-size: 0.9375rem;
    color: #FFFFFF;
    white-space: nowrap;
}

/* /Components/Layout/NavMenu.razor.rz.scp.css */
/* NOTE  The navigation rail is styled in app.css, not here.

   .portal-nav is the class on this component's root MudNavMenu. Blazor's
   scoped CSS only stamps its scope attribute on HTML elements written in a
   .razor file, never on a child component's rendered root, so every rule in
   this file compiled to `.portal-nav[b-xxxxx] ...` and matched nothing. The
   drawer kept MudBlazor's own colours throughout, which is why "Customer
   Orders" and "Customers" were still nearly invisible after the first fix.

   Kept as a signpost rather than deleted, so the next person looking for the
   nav's styles finds the reason they are not here. */
/* /Components/Layout/ReconnectModal.razor.rz.scp.css */
.components-reconnect-first-attempt-visible[b-73zcx6bi4s],
.components-reconnect-repeated-attempt-visible[b-73zcx6bi4s],
.components-reconnect-failed-visible[b-73zcx6bi4s],
.components-pause-visible[b-73zcx6bi4s],
.components-resume-failed-visible[b-73zcx6bi4s],
.components-rejoining-animation[b-73zcx6bi4s] {
    display: none;
}

#components-reconnect-modal.components-reconnect-show .components-reconnect-first-attempt-visible[b-73zcx6bi4s],
#components-reconnect-modal.components-reconnect-show .components-rejoining-animation[b-73zcx6bi4s],
#components-reconnect-modal.components-reconnect-paused .components-pause-visible[b-73zcx6bi4s],
#components-reconnect-modal.components-reconnect-resume-failed .components-resume-failed-visible[b-73zcx6bi4s],
#components-reconnect-modal.components-reconnect-retrying[b-73zcx6bi4s],
#components-reconnect-modal.components-reconnect-retrying .components-reconnect-repeated-attempt-visible[b-73zcx6bi4s],
#components-reconnect-modal.components-reconnect-retrying .components-rejoining-animation[b-73zcx6bi4s],
#components-reconnect-modal.components-reconnect-failed[b-73zcx6bi4s],
#components-reconnect-modal.components-reconnect-failed .components-reconnect-failed-visible[b-73zcx6bi4s] {
    display: block;
}


#components-reconnect-modal[b-73zcx6bi4s] {
    background-color: white;
    width: 20rem;
    margin: 20vh auto;
    padding: 2rem;
    border: 0;
    border-radius: 0.5rem;
    box-shadow: 0 3px 6px 2px rgba(0, 0, 0, 0.3);
    opacity: 0;
    transition: display 0.5s allow-discrete, overlay 0.5s allow-discrete;
    animation: components-reconnect-modal-fadeOutOpacity-b-73zcx6bi4s 0.5s both;
    &[open]

{
    animation: components-reconnect-modal-slideUp-b-73zcx6bi4s 1.5s cubic-bezier(.05, .89, .25, 1.02) 0.3s, components-reconnect-modal-fadeInOpacity-b-73zcx6bi4s 0.5s ease-in-out 0.3s;
    animation-fill-mode: both;
}

}

#components-reconnect-modal[b-73zcx6bi4s]::backdrop {
    background-color: rgba(0, 0, 0, 0.4);
    animation: components-reconnect-modal-fadeInOpacity-b-73zcx6bi4s 0.5s ease-in-out;
    opacity: 1;
}

@keyframes components-reconnect-modal-slideUp-b-73zcx6bi4s {
    0% {
        transform: translateY(30px) scale(0.95);
    }

    100% {
        transform: translateY(0);
    }
}

@keyframes components-reconnect-modal-fadeInOpacity-b-73zcx6bi4s {
    0% {
        opacity: 0;
    }

    100% {
        opacity: 1;
    }
}

@keyframes components-reconnect-modal-fadeOutOpacity-b-73zcx6bi4s {
    0% {
        opacity: 1;
    }

    100% {
        opacity: 0;
    }
}

.components-reconnect-container[b-73zcx6bi4s] {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1rem;
}

#components-reconnect-modal p[b-73zcx6bi4s] {
    margin: 0;
    text-align: center;
}

#components-reconnect-modal button[b-73zcx6bi4s] {
    border: 0;
    background-color: #6b9ed2;
    color: white;
    padding: 4px 24px;
    border-radius: 4px;
}

    #components-reconnect-modal button:hover[b-73zcx6bi4s] {
        background-color: #3b6ea2;
    }

    #components-reconnect-modal button:active[b-73zcx6bi4s] {
        background-color: #6b9ed2;
    }

.components-rejoining-animation[b-73zcx6bi4s] {
    position: relative;
    width: 80px;
    height: 80px;
}

    .components-rejoining-animation div[b-73zcx6bi4s] {
        position: absolute;
        border: 3px solid #0087ff;
        opacity: 1;
        border-radius: 50%;
        animation: components-rejoining-animation-b-73zcx6bi4s 1.5s cubic-bezier(0, 0.2, 0.8, 1) infinite;
    }

        .components-rejoining-animation div:nth-child(2)[b-73zcx6bi4s] {
            animation-delay: -0.5s;
        }

@keyframes components-rejoining-animation-b-73zcx6bi4s {
    0% {
        top: 40px;
        left: 40px;
        width: 0;
        height: 0;
        opacity: 0;
    }

    4.9% {
        top: 40px;
        left: 40px;
        width: 0;
        height: 0;
        opacity: 0;
    }

    5% {
        top: 40px;
        left: 40px;
        width: 0;
        height: 0;
        opacity: 1;
    }

    100% {
        top: 0px;
        left: 0px;
        width: 80px;
        height: 80px;
        opacity: 0;
    }
}
/* /Components/Layout/ViewAsBanner.razor.rz.scp.css */
/* The preview banner.

   Gold on navy, full width, above everything. Gold is the portal's "a person
   needs to know this" colour and it is spent sparingly - the active nav link
   and something awaiting attention - so a whole bar of it reads as a state
   change rather than as decoration.

   Literal colours rather than palette variables: this must look identical in
   the day and the night view, because "am I in the preview" is not a question
   the answer to which should depend on a theme. */

.viewas[b-56vbsz00di] {
    display: flex;
    align-items: center;
    gap: 0.875rem;
    padding: 0.625rem 1rem;
    background: #F1B53D;
    color: #14223A;
    border-bottom: 2px solid #14223A;
}

.viewas[b-56vbsz00di]  .viewas__glyph {
    font-size: 1.375rem !important;
    flex: 0 0 auto;
}

.viewas__text[b-56vbsz00di] {
    display: flex;
    flex-direction: column;
    min-width: 0;
    flex: 1 1 auto;
}

.viewas__lead[b-56vbsz00di] {
    font-size: 0.875rem;
    line-height: 1.3;
}

.viewas__lead strong[b-56vbsz00di] {
    font-weight: 700;
}

/* Not a caption in the usual sense - it carries the consequence, so it stays
   at readable contrast rather than fading into the gold. */
.viewas__note[b-56vbsz00di] {
    font-size: 0.75rem;
    line-height: 1.35;
    color: rgba(20, 34, 58, 0.82);
}

.viewas__form[b-56vbsz00di] {
    margin: 0;
    flex: 0 0 auto;
}

/* Navy on gold, so the way out is the highest-contrast thing in the bar. */
.viewas[b-56vbsz00di]  .viewas__exit {
    background: #14223A;
    color: #F9F9F6;
    white-space: nowrap;
}

.viewas[b-56vbsz00di]  .viewas__exit:hover {
    background: #0D1524;
}

@media (max-width: 640px) {
    .viewas[b-56vbsz00di] {
        align-items: flex-start;
        flex-wrap: wrap;
    }

    /* The note goes before the button does. Which account you are previewing
       and how to leave are the two things that must survive any width. */
    .viewas__note[b-56vbsz00di] {
        display: none;
    }
}
/* /Components/Orders/CustomerOrderSummary.razor.rz.scp.css */
/* NOTE  The customer's answer card is styled in app.css.

   Every class here - custsum, custsum__eyebrow, custsum__answer - is handed
   to a MudBlazor component (MudPaper, MudText), and scoped CSS cannot reach a
   child component's rendered root. The headline sentence was rendering at
   MudBlazor's own h5 weight rather than the 700 it was written for. */
/* /Components/Orders/DeliveryPanel.razor.rz.scp.css */
/* The delivery destination on a purchase order. */



.dp__head[b-kk2moz44w7] {

    display: flex;

    align-items: center;

    justify-content: space-between;

    gap: 0.75rem;

    margin-bottom: 0.75rem;

}



/* The resolved address, set apart from the controls that change it. A rule

   down the left rather than a box, because it is a quotation from the

   document rather than a thing of its own. */

.dp__where[b-kk2moz44w7] {

    border-left: 3px solid var(--mud-palette-primary);

    padding: 0.25rem 0 0.25rem 0.75rem;

}



/* ::deep, because the address lines are MudText and the scope attribute is

   stamped only on HTML written in this file - never on a child component's

   rendered root. A plain `.dp__line` here would match nothing at all. */

.dp__where[b-kk2moz44w7]  .mud-typography {

    line-height: 1.45;

}



/* Each choice reads as a pair: the option, and why you would pick it. The

   caption is indented to the radio's label rather than the radio itself, so

   the two lines belong to one another. */

.dp__option + .dp__option[b-kk2moz44w7] {

    margin-top: 0.4rem;

}



/* Same reason: the caption is a MudText inside .dp__option. */

.dp__option[b-kk2moz44w7]  .dp__why {

    display: block;

    margin-left: 2.1rem;

    margin-top: -0.35rem;

}



.dp__picker[b-kk2moz44w7] {

    margin-top: 1rem;

}

/* /Components/Orders/JourneySteps.razor.rz.scp.css */
/* The five-step journey shown to customers. */

.journey[b-d923pylyvr] {
    display: flex;
    align-items: flex-start;
    gap: 0;
}

.journey__step[b-d923pylyvr] {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.375rem;
    flex: 0 0 auto;
    width: 5rem;
    text-align: center;
}

.journey__dot[b-d923pylyvr] {
    width: 2rem;
    height: 2rem;
    border-radius: 50%;
    display: grid;
    place-items: center;
    flex: none;
    background: var(--mud-palette-lines-default);
    color: var(--mud-palette-text-disabled);
}

.journey__label[b-d923pylyvr] {
    font-size: 0.6875rem;
    line-height: 1.25;
    color: var(--mud-palette-text-secondary);
}

/* Passed: AKVA green, quietly. */
.journey__step--done .journey__dot[b-d923pylyvr] {
    background: #2C622C;
    color: #fff;
}

/* Here: the teal that means "moving" everywhere else in the portal, with a
   halo so the eye lands on it first. This is the only step worth reading. */
.journey__step--here .journey__dot[b-d923pylyvr] {
    background: #467886;
    color: #fff;
    box-shadow: 0 0 0 4px rgba(70, 120, 134, 0.22);
}

.journey__step--here .journey__label[b-d923pylyvr] {
    color: var(--mud-palette-text-primary);
    font-weight: 600;
}

.journey__track[b-d923pylyvr] {
    height: 2px;
    flex: 1 1 auto;
    min-width: 0.75rem;
    /* Aligned with the middle of the dots either side. */
    margin-top: 1rem;
    background: var(--mud-palette-lines-default);
}

.journey__track--done[b-d923pylyvr] {
    background: #2C622C;
}

/* On a narrow screen the labels are what has to give, not the dots - the
   sequence is the point and it must stay one row. */
@media (max-width: 30rem) {
    .journey__step[b-d923pylyvr] {
        width: 3.25rem;
    }

    .journey__label[b-d923pylyvr] {
        font-size: 0.625rem;
    }
}
/* /Components/Orders/OrderFilterBar.razor.rz.scp.css */
/* Scoped: every selector below is on a plain element written in this file.
   The panel's padding comes from Mud's own pa-3. */

.ofb__chips[b-nqbvp15a24] {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: .35rem;
    margin-top: .6rem;
}

/* Pushes the expander and Clear to the far end, so the filters somebody is
   choosing and the controls that manage them do not read as one row of
   equals. */
.ofb__spacer[b-nqbvp15a24] {
    flex: 1 1 auto;
    min-width: .5rem;
}
/* /Components/Orders/OrderList.razor.rz.scp.css */

/* The line above the table: how many matched, and the way out of the
   filters. On a plain div written in this file, so the scope attribute
   lands on it. */
.olist__applied[b-b74h6d1ior] {
    display: flex;
    align-items: center;
    gap: .5rem;
    flex-wrap: wrap;
    margin-bottom: .5rem;
    padding: 0 .25rem;
}

/* The bulk action bar: the count, then the actions pushed to the far end. */
.olist__bulk[b-b74h6d1ior] {
    display: flex;
    align-items: center;
    gap: .5rem;
    flex-wrap: wrap;
}

.olist__spacer[b-b74h6d1ior] {
    flex: 1 1 auto;
    min-width: .5rem;
}
/* /Components/Orders/OrderPipeline.razor.rz.scp.css */
/* The internal order pipeline.

   Dots on a line, then the current step named underneath. The dots are all
   the same size and the tracks take whatever is left, so the run fits any
   card width without the labels that used to collide. */

.opipe[b-eqw8gmarnq] {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.opipe__run[b-eqw8gmarnq] {
    display: flex;
    align-items: center;
    width: 100%;
}

.opipe__dot[b-eqw8gmarnq] {
    display: grid;
    place-items: center;
    flex: 0 0 auto;
    width: 1.625rem;
    height: 1.625rem;
    border-radius: 50%;
    background: var(--mud-palette-background-grey);
    box-shadow: inset 0 0 0 1.5px var(--mud-palette-lines-default);
    color: var(--mud-palette-text-disabled);
}

.opipe__dot[b-eqw8gmarnq]  .mud-icon-root {
    font-size: 0.875rem;
}

/* ---------------------------------------------------------------- reached
   Filled in AKVA green: the brand colour earns its place marking progress
   rather than decorating a heading. */
.opipe__dot--done[b-eqw8gmarnq] {
    background: #2C622C;
    box-shadow: none;
    color: #F9F9F6;
}

/* -------------------------------------------------------------------- here
   The one step worth finding: darker, and ringed in gold. Gold appears in
   two places in this portal - the active nav link and something that wants
   a person - which is what keeps it meaning anything. */
.opipe__dot--here[b-eqw8gmarnq] {
    background: #234923;
    box-shadow: 0 0 0 3px rgba(241, 181, 61, 0.9);
    color: #FFFFFF;
}

/* --------------------------------------------------------------- the track
   Takes the space the dots leave, down to nothing, so six dots always fit
   however narrow the card is. */
.opipe__track[b-eqw8gmarnq] {
    flex: 1 1 auto;
    min-width: 0.1875rem;
    height: 2px;
    background: var(--mud-palette-lines-default);
}

.opipe__track--done[b-eqw8gmarnq] {
    background: #2C622C;
}

/* ------------------------------------------------------------ where it is
   The name the dots cannot carry. Reads as one line: the state, then how far
   along that is. */
.opipe__now[b-eqw8gmarnq] {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 0.375rem;
}

.opipe__label[b-eqw8gmarnq] {
    font-size: 0.8125rem;
    font-weight: 700;
    color: var(--mud-palette-text-primary);
}

.opipe__step[b-eqw8gmarnq] {
    font-size: 0.6875rem;
    font-variant-numeric: tabular-nums;
    color: var(--mud-palette-text-secondary);
}

/* ------------------------------------------------------------- off the line */
.opipe__badge[b-eqw8gmarnq] {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    padding: 0.1875rem 0.5rem;
    border-radius: 3px;
    background: var(--mud-palette-background-grey);
    box-shadow: inset 0 0 0 1px var(--mud-palette-lines-default);
    font-size: 0.6875rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--mud-palette-text-secondary);
}

.opipe__badge[b-eqw8gmarnq]  .mud-icon-root {
    font-size: 0.875rem;
}
/* /Components/Orders/OrderProgressCard.razor.rz.scp.css */
/* The progress card.

   Ring on the left, figures on the right, journey underneath. Colours are the
   same three the quantity bars use, declared here from the same hex values
   rather than shared through a variable because MudBlazor's palette does not
   carry them and a second source of truth for three colours is cheaper than a
   theme extension nothing else would use. */

/* NOTE  .opc - the card's own corner radius - is in app.css, being the class
   on this component's root MudPaper, which scoped CSS cannot reach. */

.opc__top[b-zy7rlxffvx] {
    display: flex;
    align-items: center;
    gap: 1.25rem;
}

/* ---------------------------------------------------------------- the ring
   Fixed size rather than fluid: a proportion read at a glance wants a
   consistent one, and the figures beside it can take the remaining width. */
.opc__ring[b-zy7rlxffvx] {
    width: 116px;
    height: 116px;
    flex: 0 0 auto;
    /* Twelve o'clock start. Without this the first arc begins at three. */
    transform: rotate(-90deg);
}

.opc__track[b-zy7rlxffvx],
.opc__arc[b-zy7rlxffvx] {
    fill: none;
    stroke-width: 13;
}

.opc__track[b-zy7rlxffvx] {
    stroke: var(--mud-palette-lines-default);
}

.opc__arc[b-zy7rlxffvx] {
    /* Butt ends, not round: rounded caps overlap the neighbouring arc and
       make a small segment look larger than its share. */
    stroke-linecap: butt;
}

.opc__arc--shipped[b-zy7rlxffvx] {
    stroke: #467886;
}

.opc__arc--staged[b-zy7rlxffvx] {
    stroke: #4E9A4E;
}

.opc__arc--stock[b-zy7rlxffvx] {
    stroke: #2C622C;
}

.opc__arc--onorder[b-zy7rlxffvx] {
    stroke: #F1B53D;
}

.opc__arc--unsourced[b-zy7rlxffvx] {
    stroke: #A6432F;
}

/* The two text nodes sit inside the rotated SVG, so they need rotating back
   or the percentage reads sideways. */
.opc__pct[b-zy7rlxffvx],
.opc__pctlabel[b-zy7rlxffvx] {
    transform: rotate(90deg);
    transform-origin: 60px 60px;
    text-anchor: middle;
    font-family: Arial, Helvetica, "Segoe UI", sans-serif;
    fill: var(--mud-palette-text-primary);
}

.opc__pct[b-zy7rlxffvx] {
    font-size: 22px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

.opc__pctlabel[b-zy7rlxffvx] {
    font-size: 9px;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    fill: var(--mud-palette-text-secondary);
}

/* ------------------------------------------------------------- the figures */
.opc__figures[b-zy7rlxffvx] {
    display: flex;
    flex-direction: column;
    gap: 0.375rem;
    margin: 0;
    min-width: 0;
    flex: 1 1 auto;
}

.opc__figure[b-zy7rlxffvx] {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.75rem;
    /* A dotted leader ties the label to its number across the gap, which is
       what stops the eye losing the row on a wide card. */
    border-bottom: 1px dotted var(--mud-palette-lines-default);
    padding-bottom: 0.25rem;
}

.opc__figure:last-child[b-zy7rlxffvx] {
    border-bottom: none;
    padding-bottom: 0;
}

.opc__figure dt[b-zy7rlxffvx] {
    display: flex;
    align-items: center;
    gap: 0.4375rem;
    font-size: 0.75rem;
    color: var(--mud-palette-text-secondary);
    white-space: nowrap;
}

.opc__figure dd[b-zy7rlxffvx] {
    margin: 0;
    font-size: 0.9375rem;
    font-weight: 700;
    color: var(--mud-palette-text-primary);
    white-space: nowrap;
}

/* The total is the reference the others are read against, so it leads. */
.opc__figure:first-child dt[b-zy7rlxffvx] {
    font-weight: 700;
    color: var(--mud-palette-text-primary);
}

.opc__dot[b-zy7rlxffvx] {
    width: 9px;
    height: 9px;
    border-radius: 2px;
    flex: 0 0 auto;
}

.opc__figure--shipped .opc__dot[b-zy7rlxffvx] {
    background: #467886;
}

.opc__figure--staged .opc__dot[b-zy7rlxffvx] {
    background: #4E9A4E;
}

.opc__figure--stock .opc__dot[b-zy7rlxffvx] {
    background: #2C622C;
}

.opc__figure--onorder .opc__dot[b-zy7rlxffvx] {
    background: #F1B53D;
}

.opc__figure--unsourced .opc__dot[b-zy7rlxffvx] {
    background: #A6432F;
}

/* Not sourced is the line somebody has to act on, so it is the only figure
   that carries its colour into the text. */
.opc__figure--unsourced dd[b-zy7rlxffvx] {
    color: #A6432F;
}

/* --------------------------------------------------------------- narrow
   Under a phone width the ring and figures stack rather than squeeze; a
   116px ring next to a 90px column reads as neither. */
@media (max-width: 400px) {
    .opc__top[b-zy7rlxffvx] {
        flex-direction: column;
        align-items: stretch;
        gap: 1rem;
    }

    .opc__ring[b-zy7rlxffvx] {
        align-self: center;
    }
}
/* /Components/Orders/PurchaseApprovalPanel.razor.rz.scp.css */
/* What has happened to this purchase order, in the order it happened.

   A row each rather than a horizontal pipeline: the steps carry a name and a
   word, which do not fit under a dot, and the list is short enough that
   vertical costs nothing. */
.approval[b-abom1xyaik] {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.approval__step[b-abom1xyaik] {
    display: flex;
    align-items: flex-start;
    gap: 0.5rem;
}
/* /Components/Pages/AuditLog.razor.rz.scp.css */
/* One field that moved. Several read as a list rather than a paragraph. */
.audit__change[b-s1kdw3bici] {
    display: flex;
    align-items: center;
    gap: 6px;
    flex-wrap: wrap;
    padding-block: 1px;
    font-size: 0.8125rem;
    line-height: 1.4;
}

.audit__field[b-s1kdw3bici] {
    font-weight: 500;
    min-width: 7rem;
}

/* The old value set back and struck through, the new one plain, so the eye
   lands on what it became rather than on what it was. */
.audit__from[b-s1kdw3bici] {
    color: var(--mud-palette-text-secondary);
    text-decoration: line-through;
    text-decoration-thickness: 1px;
}

.audit__to[b-s1kdw3bici] {
    color: var(--mud-palette-text-primary);
}
/* /Components/Pages/Catalogue.razor.rz.scp.css */
/* -----------------------------------------------------------------------
   What a customer can order.

   Scoped, so every selector here names an element written in this
   component's own .razor file. Nothing styles a child component's root -
   Blazor stamps the scope attribute on markup, never on a component's
   rendered root, and a rule aimed at one silently does nothing. The audit in
   tools/check-scoped-css.py enforces it.

   Rows rather than a grid of cards. A parts catalogue is scanned by number
   and description, which read left to right; a card grid would make somebody
   hunt across a wall of near-identical pictures.
   ----------------------------------------------------------------------- */

.cat[b-pu3xfclaax] {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.cat__part[b-pu3xfclaax] {
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: 0.75rem;
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: 6px;
    background: var(--mud-palette-surface);
}

.cat__what[b-pu3xfclaax] {
    flex: 1;
    min-width: 0;
}

/* The asking controls keep their width so the rows line up down the page,
   and wrap under the part on a narrow screen rather than squeezing it. */
.cat__ask[b-pu3xfclaax] {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex: none;
}

.cat__asked[b-pu3xfclaax] {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

@media (max-width: 640px) {
    .cat__part[b-pu3xfclaax] {
        flex-wrap: wrap;
    }

    .cat__ask[b-pu3xfclaax] {
        width: 100%;
        justify-content: flex-end;
    }
}

/* ----------------------------------------------------------- how many more
   Under the list, centred, quiet. It is a fact about the list rather than
   part of it, and a reader who has found what they wanted never looks here. */
.cat__more[b-pu3xfclaax] {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.5rem;
    padding: 1.25rem 0 0.5rem;
}
/* /Components/Pages/Fulfilment.razor.rz.scp.css */
/* The fulfilment list. */

/* -------------------------------------------------------------- the actions
   Sticky, because the selection is made by scrolling and a button that
   scrolls away is one you scroll back to find. Above the list rather than at
   its foot for the same reason. */
.ful__bar[b-am52lpc9gs] {
    position: sticky;
    top: 0.5rem;
    z-index: 3;
    background: var(--mud-palette-surface);
}

/* ------------------------------------------------------------ an order head
   The order, who it is for and how long it has waited, on one line above its
   own lines. Wraps rather than truncating: a long account name matters more
   than keeping this to one row. */
.ful__head[b-am52lpc9gs] {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.5rem;
    padding: 0.5rem 0.75rem;
    border-bottom: 1px solid var(--mud-palette-lines-default);
    background: var(--mud-palette-background-grey);
}

.ful__who[b-am52lpc9gs] {
    min-width: 0;
}
/* /Components/Pages/GoodsReceipts.razor.rz.scp.css */
/* The goods receipts list.

   Same brick edge as the pick slip list and the stock screen: this row is the
   one to look at. One device, one meaning, across every screen that has rows
   worth chasing. */
.gr-row--short td:first-child[b-frdhmttfz1] {
    box-shadow: inset 3px 0 0 #A6432F;
}
/* /Components/Pages/Home.razor.rz.scp.css */
/* The dashboard's own bits.

   Only what belongs to this page. The book tiles style themselves. */

/* ---------------------------------------------------------------- all clear
   The good outcome, drawn rather than stated. A single grey sentence in a
   large white box reads the same as a list that failed to load. */
.dash-clear[b-tmxv3t76y0] {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    padding: 1rem 1.125rem;
    border-radius: 6px;
    background: rgba(35, 73, 35, 0.07);
    box-shadow: inset 0 0 0 1px rgba(35, 73, 35, 0.22);
}

.dash-clear[b-tmxv3t76y0]  .dash-clear__glyph {
    font-size: 1.5rem !important;
    color: #2C622C;
    flex: 0 0 auto;
}

/* ----------------------------------------------------------------- lateness
   The date on top, how late underneath. A date on its own has to be
   subtracted from today before it says anything; the count of days does not,
   and this list exists to be skimmed. */
.dash-late[b-tmxv3t76y0] {
    display: flex;
    flex-direction: column;
    line-height: 1.3;
}

.dash-late__by[b-tmxv3t76y0] {
    font-size: 0.6875rem;
    font-weight: 700;
    letter-spacing: 0.02em;
    color: #A6432F;
    white-space: nowrap;
}
/* /Components/Pages/Inventory.razor.rz.scp.css */
/* The inventory page.

   Only the one thing that is this page's rather than a component's. */

/* A brick edge on a row promising more than the last count found. The Free
   column already shows a negative, but on a list of two hundred rows the
   edge is what makes them findable without reading any of them - the same
   device the shipments panel uses for a reported problem. */
.inv-row--over td:first-child[b-pwiyu13o38] {
    box-shadow: inset 3px 0 0 #A6432F;
}
/* /Components/Pages/Items.razor.rz.scp.css */
/* The item report.

   One big figure and two tables. The figure is the point - everything else on
   the page is the working that produced it - so it gets display size and the
   only red on the screen. */

.items__position[b-zwxoo2jtk2] {
    display: flex;
    align-items: baseline;
    gap: 0.4375rem;
    margin-bottom: 0.25rem;
}

.items__figure[b-zwxoo2jtk2] {
    font-size: 2.5rem;
    font-weight: 700;
    line-height: 1;
    letter-spacing: -0.02em;
    color: #2C622C;
}

.items__label[b-zwxoo2jtk2] {
    font-size: 0.75rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--mud-palette-text-secondary);
}

/* Short is the one thing worth alarming about, so it is the one thing in
   brick. A spare position stays green rather than turning grey: having enough
   is good news and should read as such. */
.items__position--short .items__figure[b-zwxoo2jtk2] {
    color: #A6432F;
}

/* A brick edge, as on the stock screen and the pick slip list. Same device,
   same meaning: this row is the one to look at. */
.items__row--over td:first-child[b-zwxoo2jtk2] {
    box-shadow: inset 3px 0 0 #A6432F;
}

.items__empty[b-zwxoo2jtk2] {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.375rem;
    padding: 1.5rem 1rem;
    border-radius: 6px;
    border: 1px dashed var(--mud-palette-lines-default);
    text-align: center;
}

.items[b-zwxoo2jtk2]  .items__emptyglyph,
.items__empty[b-zwxoo2jtk2]  .items__emptyglyph {
    font-size: 1.75rem !important;
    color: var(--mud-palette-text-disabled);
}

/* -------------------------------------------------------- the part picture
   The whole box is the click target, not a button beside it. On a part with
   no picture the dashed box is the only affordance there is, so it has to be
   the thing you press - a separate button would leave the box looking inert.

   The cursor and the lift are all this adds; the box itself is PartPicture's,
   and a rule here could not reach inside it anyway. Blazor stamps the scope
   attribute on markup, never on a child component's rendered root. */
.items__picture[b-zwxoo2jtk2] {
    cursor: pointer;
    border-radius: 4px;
    transition: opacity 120ms ease-in-out;
}

.items__picture:hover[b-zwxoo2jtk2] {
    opacity: 0.75;
}


/* ----------------------------------------------------------- the batch bar
   Above the table, never over it. The same shape the order list uses for the
   same job, because they are the same gesture: tick some rows, then act. */
.items__bulk[b-zwxoo2jtk2] {
    display: flex;
    align-items: center;
    gap: .5rem;
    flex-wrap: wrap;
}

.items__spacer[b-zwxoo2jtk2] {
    flex: 1 1 auto;
    min-width: .5rem;
}

/* ----------------------------------------------------------------- the pager
   Under the table, with the count on the left and the controls on the right.
   The count is of what the filters matched, not of what is on screen - which
   is the distinction this whole screen was rebuilt around. */
.items__pager[b-zwxoo2jtk2] {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.75rem;
    padding: 0.75rem 0.25rem 0.25rem;
}
/* /Components/Pages/OrderDetail.razor.rz.scp.css */
/* The order detail page's own arrangement.

   Only the parts that are this page's rather than a component's: the shipment
   rows and the two empty states. Everything else is styled where it lives. */

/* ------------------------------------------------------------ shipment rows
   A card each rather than a divider between rows. A consolidated shipment
   carries other people's goods too, and giving each one its own edge stops
   two shipments reading as one longer entry. */
.order-ships[b-hewruy9j9m] {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.order-ships__row[b-hewruy9j9m] {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    padding: 0.75rem;
    border-radius: 6px;
    border: 1px solid var(--mud-palette-lines-default);
    background: var(--mud-palette-background-grey);
}

/* A reported problem gets a brick edge down the left. The warning flag inside
   the status already says so; this is what makes it findable in a list of
   eight without reading any of them. */
.order-ships__row--attention[b-hewruy9j9m] {
    border-left: 3px solid #A6432F;
    padding-left: calc(0.75rem - 2px);
}

.order-ships__head[b-hewruy9j9m] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.order-ships__row[b-hewruy9j9m]  .order-ships__route {
    /* Indented under the reference it belongs to, which is what makes the
       shipment number read as the heading of the row rather than as another
       item in it. */
    padding: 0 0.25rem;
}

/* ----------------------------------------------------------- empty states
   A glyph and two lines, centred, in the space the content would fill. The
   previous version was a single grey sentence at the top left of a large
   white box, which read as though something had failed to load. */
.order-empty[b-hewruy9j9m] {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.25rem;
    padding: 1.75rem 1rem;
    border-radius: 6px;
    border: 1px dashed var(--mud-palette-lines-default);
    text-align: center;
}

.order-empty[b-hewruy9j9m]  .order-empty__glyph {
    font-size: 2rem !important;
    color: var(--mud-palette-text-disabled);
    margin-bottom: 0.25rem;
}

/* --------------------------------------------------- the supply link's date
   The "supplier goods expected" cell. A date reads as a fact and the missing
   case reads as a gap, so the two are given different shapes rather than
   different shades of grey. */
.order-supply__when[b-hewruy9j9m] {
    display: inline-flex;
    align-items: center;
    gap: 0.3125rem;
    white-space: nowrap;
    font-size: 0.8125rem;
}

.order-supply__when[b-hewruy9j9m]  .mud-icon-root {
    font-size: 0.9375rem;
    color: var(--mud-palette-text-disabled);
}

/* Gold, and boxed. Nothing has been booked, which is the only actionable
   thing this panel ever says. */
.order-supply__when--none[b-hewruy9j9m] {
    padding: 0.125rem 0.4375rem;
    border-radius: 3px;
    background: rgba(241, 181, 61, 0.18);
    box-shadow: inset 0 0 0 1px rgba(241, 181, 61, 0.6);
    font-size: 0.75rem;
    font-weight: 700;
    color: var(--mud-palette-text-primary);
}

.order-supply__when--none[b-hewruy9j9m]  .mud-icon-root {
    color: #B4831F;
}
/* /Components/Pages/OrderImport.razor.rz.scp.css */
/* Upload orders. */

/* ------------------------------------------------------------- the choice
   Two cards, clickable as a whole. A card that only responds on its little
   button is a card people click three times before noticing. */
.oi__pick[b-xuclfnj38e] {
    cursor: pointer;
    height: 100%;
    text-align: center;
    transition: border-color .12s ease, background-color .12s ease;
}

/* The card inside is a component root, so it is reached with ::deep. */
.oi__pick[b-xuclfnj38e]  .oi__card {
    height: 100%;
    transition: border-color .12s ease, background-color .12s ease;
}

.oi__pick:hover[b-xuclfnj38e]  .oi__card {
    border-color: var(--mud-palette-primary);
    background: var(--mud-palette-action-default-hover);
}

/* --------------------------------------------------------- an order's lines
   Inset and tinted, so an expanded order reads as belonging to the row above
   it rather than as more rows of the same list. */
.oi__lines[b-xuclfnj38e] {
    padding: 0.5rem 0.5rem 0.5rem 2.25rem;
    background: var(--mud-palette-background-grey);
    border-left: 3px solid var(--mud-palette-primary);
}
/* /Components/Pages/PartsImport.razor.rz.scp.css */
/* The parts import page. */

/* The numbered step markers. Numbered because this genuinely is a sequence -
   you cannot preview before choosing a file, or apply before previewing - so
   the numbering encodes something true rather than decorating three cards. */
.pi__step[b-despqzdxr4] {
    display: grid;
    place-items: center;
    width: 1.5rem;
    height: 1.5rem;
    flex: 0 0 auto;
    border-radius: 50%;
    background: #2C622C;
    color: #F9F9F6;
    font-size: 0.8125rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

.pi__problems[b-despqzdxr4] {
    margin: 0;
    padding-left: 1.125rem;
    font-size: 0.75rem;
    line-height: 1.5;
    color: var(--mud-palette-text-secondary);
}

.pi__problems li + li[b-despqzdxr4] {
    margin-top: 0.1875rem;
}
/* /Components/Pages/PickBoard.razor.rz.scp.css */
/* -----------------------------------------------------------------------
   What needs picking, on a phone.

   Scoped, so every selector here names an element written in this
   component's own .razor file. Nothing styles a child component's root -
   Blazor stamps the scope attribute on markup, never on a component's
   rendered root, and a rule aimed at one silently does nothing. The audit in
   tools/check-scoped-css.py enforces it.

   Cards rather than a table, because the whole row is the tap target. A
   table on a phone makes somebody aim at a link inside a cell.
   ----------------------------------------------------------------------- */

.board[b-rjsy0nxm0v] {
    display: flex;
    flex-direction: column;
    padding-bottom: 2rem;
}

.board__bar[b-rjsy0nxm0v] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    padding: 0.75rem 0.75rem 0.5rem;
}

.board__list[b-rjsy0nxm0v] {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    padding: 0 0.75rem;
}

/* ------------------------------------------------------------------ a slip */
.board__slip[b-rjsy0nxm0v] {
    border: 1px solid var(--mud-palette-lines-default);
    background: var(--mud-palette-surface);
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    padding: 0.85rem;
    border-radius: 6px;
    cursor: pointer;
}

.board__slip:active[b-rjsy0nxm0v] {
    background: var(--mud-palette-action-default-hover);
}

.board__slip-head[b-rjsy0nxm0v] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
}

/* Three figures across, because they are read together: how much work, how
   much stock, how long it has been waiting. */
.board__figures[b-rjsy0nxm0v] {
    display: flex;
    gap: 1.5rem;
    padding-top: 0.35rem;
}

.board__figure[b-rjsy0nxm0v] {
    display: flex;
    flex-direction: column;
    line-height: 1.15;
}

/* ------------------------------------------------------- held with no slip
   A row rather than a card: this is a prompt with one action, and giving it
   the same weight as a job to walk would bury the jobs. */
.board__pickable[b-rjsy0nxm0v] {
    border: 1px solid var(--mud-palette-lines-default);
    background: var(--mud-palette-surface);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    padding: 0.75rem 0.85rem;
    border-radius: 6px;
}

.board__pickable > :first-child[b-rjsy0nxm0v] {
    min-width: 0;
}

/* On a desktop this gets a comfortable measure rather than stretching across
   a monitor. The phone layout is the default and this is the exception, which
   is the right way round for a screen whose purpose is the phone. */
@media (min-width: 900px) {
    .board__bar[b-rjsy0nxm0v],
    .board__list[b-rjsy0nxm0v] {
        max-width: 46rem;
        margin-inline: auto;
        width: 100%;
    }
}

/* A second list under the open slips: picked, but nobody has said what it
   went into yet. Set apart with a heading rather than mixed in, because it is
   a different job from walking a slip. */
.board__section[b-rjsy0nxm0v] {
    margin-top: 20px;
}

.board__section-head[b-rjsy0nxm0v] {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 0 12px 8px;
    color: var(--mud-palette-text-secondary);
}
/* /Components/Pages/PickPack.razor.rz.scp.css */
/* Phone first, like the walk it follows. One column, generous targets, and
   nothing that needs a mouse. */
.pack[b-pou9dhkraq] {
    display: flex;
    flex-direction: column;
    gap: 12px;
    padding-bottom: 32px;
}

.pack__bar[b-pou9dhkraq] {
    display: flex;
    align-items: center;
    gap: 4px;
    padding: 8px 4px;
    border-bottom: 1px solid var(--mud-palette-lines-default);
}

.pack__bar-text[b-pou9dhkraq] {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.pack__block[b-pou9dhkraq] {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 12px;
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: var(--mud-default-borderradius);
    background: var(--mud-palette-surface);
}

.pack__head[b-pou9dhkraq] {
    display: flex;
    align-items: center;
    gap: 8px;
}

.pack__hint[b-pou9dhkraq] {
    line-height: 1.4;
}

/* One recorded thing. The identifying half on top and the detail under it,
   because on a phone they will not sit side by side. */
.pack__row[b-pou9dhkraq] {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 10px;
    border-radius: var(--mud-default-borderradius);
    background: var(--mud-palette-background-grey);
}

.pack__row-main[b-pou9dhkraq] {
    display: flex;
    align-items: baseline;
    gap: 8px;
    flex-wrap: wrap;
    flex: 1 1 auto;
    min-width: 0;
    font-size: 0.9375rem;
}

.pack__row-sub[b-pou9dhkraq] {
    flex-basis: 100%;
    font-size: 0.8125rem;
    color: var(--mud-palette-text-secondary);
}

.pack__kind[b-pou9dhkraq] {
    font-weight: 600;
}

.pack__ref[b-pou9dhkraq],
.pack__qty[b-pou9dhkraq] {
    color: var(--mud-palette-text-secondary);
}

.pack__form[b-pou9dhkraq] {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding-top: 4px;
}

.pack__pair[b-pou9dhkraq] {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 8px;
}

.pack__triple[b-pou9dhkraq] {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 8px;
}

/* Held apart from the lists above so it is not pressed by accident while
   somebody is still adding rows. */
.pack__done[b-pou9dhkraq] {
    margin-top: 8px;
    padding: 12px;
    border-top: 1px solid var(--mud-palette-lines-default);
}
/* /Components/Pages/PickSlips.razor.rz.scp.css */
/* The pick slips list. */

/* A brick edge on a slip that came up short. The Picked column shows it, but
   on a list of runs the edge is what makes those rows findable without
   reading any of them - the same device the stock screen uses for a holding
   promised beyond its count. */
.ps-row--short td:first-child[b-9nh9zjn8do] {
    box-shadow: inset 3px 0 0 #A6432F;
}
/* /Components/Pages/PickWalk.razor.rz.scp.css */
/* -----------------------------------------------------------------------
   Walking a slip on a phone.

   Scoped, so every selector here names an element written in this
   component's own .razor file. Nothing styles a child component's root -
   Blazor stamps the scope attribute on markup, never on a component's
   rendered root, and a rule aimed at one silently does nothing. The audit in
   tools/check-scoped-css.py enforces it.

   Sized for a thumb rather than a cursor. The controls that record a pick
   are 48px or taller, which is the smallest a target can be and still be hit
   reliably by somebody holding a part in their other hand.
   ----------------------------------------------------------------------- */

.walk[b-jf53svudse] {
    display: flex;
    flex-direction: column;
    gap: 0;

    /* Room under the sticky submit bar, so the last line is reachable rather
       than permanently behind it. */
    padding-bottom: 7rem;
}

/* ---------------------------------------------------------------- the header
   Sticky and thin. A picker scrolls constantly, and losing which slip they
   are on is worse than losing four millimetres of list. */
.walk__bar[b-jf53svudse] {
    position: sticky;
    top: 0;
    z-index: 3;
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.25rem 0.5rem;
    background: var(--mud-palette-surface);
    border-bottom: 1px solid var(--mud-palette-lines-default);
}

.walk__bar-text[b-jf53svudse] {
    flex: 1;
    min-width: 0;
}

.walk__progress[b-jf53svudse] {
    position: sticky;
    top: 3.1rem;
    z-index: 3;
    height: 3px;
}

/* ------------------------------------------------------------- the scan box
   Sticky with the header, because a scan is the one action available from
   anywhere in the list. */
.walk__scan[b-jf53svudse] {
    position: sticky;
    top: 3.35rem;
    z-index: 2;
    padding: 0.5rem;
    background: var(--mud-palette-surface);
    border-bottom: 1px solid var(--mud-palette-lines-default);
}

/* ------------------------------------------------------------------ a line */
.walk__lines[b-jf53svudse] {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    padding: 0.5rem;
}

.walk__line[b-jf53svudse] {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    padding: 0.75rem;
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: 6px;
    background: var(--mud-palette-surface);
}

/* Done lines stay in the list rather than disappearing: a picker wants to see
   what they have already done, and a list that shortens under them loses the
   sense of where they are. Faded, so what is left stands out. */
.walk__line--done[b-jf53svudse] {
    opacity: 0.55;
}

/* What a scan just landed on. A left rail rather than a fill, so it reads at
   a glance without competing with the shortfall colours. */
.walk__line--focus[b-jf53svudse] {
    border-left: 4px solid var(--mud-palette-primary);
    opacity: 1;
}

/* ---------------------------------------------------------------- the where
   The address first and biggest. It is what a picker reads before anything
   else, because they have to walk somewhere before they can pick. */
.walk__where[b-jf53svudse] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
}

/* The address, and the biggest thing on the line. A picker reads it before
   anything else, because they have to walk somewhere before they can pick. */
.walk__bin[b-jf53svudse] {
    font-size: 1.25rem;
    font-weight: 600;
    letter-spacing: 0.02em;
    color: var(--mud-palette-text-primary);
}

/* ----------------------------------------------------------------- the what */
.walk__what[b-jf53svudse] {
    display: flex;
    align-items: flex-start;
    gap: 0.75rem;
}

.walk__part[b-jf53svudse] {
    min-width: 0;
    flex: 1;
}

/* ---------------------------------------------------------------- the count */
.walk__count[b-jf53svudse] {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.walk__wanted[b-jf53svudse] {
    font-size: 1.5rem;
    font-weight: 500;
    line-height: 1.1;
    color: var(--mud-palette-text-primary);
}

.walk__unit[b-jf53svudse] {
    font-size: 0.5em;
    margin-left: 0.35em;
    color: var(--mud-palette-text-secondary);
}

.walk__actions[b-jf53svudse] {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}

/* The number and its button on one row, because entering a partial count is
   two gestures and they belong together. */
.walk__some[b-jf53svudse] {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.walk__some > :first-child[b-jf53svudse] {
    flex: 1;
}

.walk__settled[b-jf53svudse] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
}

/* --------------------------------------------------------------- the submit
   Fixed to the bottom, because it is the one thing that must be reachable
   without scrolling to the end of a forty-line slip. */
.walk__submit[b-jf53svudse] {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 4;
    padding: 0.6rem 0.75rem calc(0.6rem + env(safe-area-inset-bottom));
    background: var(--mud-palette-surface);
    border-top: 1px solid var(--mud-palette-lines-default);
}

/* On a desktop the list is read rather than walked, so it gets a comfortable
   measure instead of stretching across a monitor. The phone layout is the
   default and this is the exception, which is the right way round for a screen
   whose whole purpose is the phone. */
@media (min-width: 900px) {
    .walk__lines[b-jf53svudse],
    .walk__scan[b-jf53svudse],
    .walk__bar[b-jf53svudse] {
        max-width: 46rem;
        margin-inline: auto;
        width: 100%;
    }

    .walk__submit[b-jf53svudse] {
        padding-inline: max(0.75rem, calc((100% - 46rem) / 2));
    }
}
/* /Components/Pages/ReadyToShip.razor.rz.scp.css */
/* Ready to ship.

   A brick edge on anything that has sat in the despatch area more than a
   week. Same device as the stock screen and the pick slip list: this row is
   the one to look at. Goods picked and then forgotten are the failure this
   screen exists to prevent, so they are the thing it marks. */
.rts-row--stale td:first-child[b-aubzyxsz40] {
    box-shadow: inset 3px 0 0 #A6432F;
}
/* /Components/Pages/ReceiveBoard.razor.rz.scp.css */
/* -----------------------------------------------------------------------
   What needs booking in, on a phone.

   Scoped, so every selector here names an element written in this
   component's own .razor file. Nothing styles a child component's root -
   Blazor stamps the scope attribute on markup, never on a component's
   rendered root, and a rule aimed at one silently does nothing. The audit in
   tools/check-scoped-css.py enforces it.

   Cards rather than a table, because the whole row is the tap target. A
   table on a phone makes somebody aim at a link inside a cell.
   ----------------------------------------------------------------------- */

.board[b-2wz1n48tlt] {
    display: flex;
    flex-direction: column;
    padding-bottom: 2rem;
}

.board__bar[b-2wz1n48tlt] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    padding: 0.75rem 0.75rem 0.5rem;
}

.board__list[b-2wz1n48tlt] {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    padding: 0 0.75rem;
}

/* --------------------------------------------------------------- a receipt */
.board__slip[b-2wz1n48tlt] {
    border: 1px solid var(--mud-palette-lines-default);
    background: var(--mud-palette-surface);
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    padding: 0.85rem;
    border-radius: 6px;
    cursor: pointer;
}

.board__slip:active[b-2wz1n48tlt] {
    background: var(--mud-palette-action-default-hover);
}

.board__slip-head[b-2wz1n48tlt] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
}

/* Three figures across, because they are read together: how much work, how
   much stock, how long it has been waiting. */
.board__figures[b-2wz1n48tlt] {
    display: flex;
    gap: 1.5rem;
    padding-top: 0.35rem;
}

.board__figure[b-2wz1n48tlt] {
    display: flex;
    flex-direction: column;
    line-height: 1.15;
}

/* -------------------------------------------------- arrived, no receipt
   A row rather than a card: this is a prompt with one action, and giving it
   the same weight as a job to do would bury the jobs. */
.board__pickable[b-2wz1n48tlt] {
    border: 1px solid var(--mud-palette-lines-default);
    background: var(--mud-palette-surface);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    padding: 0.75rem 0.85rem;
    border-radius: 6px;
}

.board__pickable > :first-child[b-2wz1n48tlt] {
    min-width: 0;
}

/* On a desktop this gets a comfortable measure rather than stretching across
   a monitor. The phone layout is the default and this is the exception, which
   is the right way round for a screen whose purpose is the phone. */
@media (min-width: 900px) {
    .board__bar[b-2wz1n48tlt],
    .board__list[b-2wz1n48tlt] {
        max-width: 46rem;
        margin-inline: auto;
        width: 100%;
    }
}

/* Which store this phone is at. A receipt has to be told where the goods are
   going, unlike a slip, which already knows where its stock is. */
.board__store[b-2wz1n48tlt] {
    padding: 0 0.75rem 0.5rem;
}

@media (min-width: 900px) {
    .board__store[b-2wz1n48tlt] {
        max-width: 46rem;
        margin-inline: auto;
        width: 100%;
    }
}
/* /Components/Pages/ReceiveWalk.razor.rz.scp.css */
/* -----------------------------------------------------------------------
   Booking a container in, on a phone.

   Scoped, so every selector here names an element written in this
   component's own .razor file. Nothing styles a child component's root -
   Blazor stamps the scope attribute on markup, never on a component's
   rendered root, and a rule aimed at one silently does nothing. The audit in
   tools/check-scoped-css.py enforces it.

   Sized for a thumb rather than a cursor. The controls that record a pick
   are 48px or taller, which is the smallest a target can be and still be hit
   reliably by somebody holding a part in their other hand.
   ----------------------------------------------------------------------- */

.walk[b-xl19d44trz] {
    display: flex;
    flex-direction: column;
    gap: 0;

    /* Room under the sticky submit bar, so the last line is reachable rather
       than permanently behind it. */
    padding-bottom: 7rem;
}

/* ---------------------------------------------------------------- the header
   Sticky and thin. A picker scrolls constantly, and losing which slip they
   are on is worse than losing four millimetres of list. */
.walk__bar[b-xl19d44trz] {
    position: sticky;
    top: 0;
    z-index: 3;
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.25rem 0.5rem;
    background: var(--mud-palette-surface);
    border-bottom: 1px solid var(--mud-palette-lines-default);
}

.walk__bar-text[b-xl19d44trz] {
    flex: 1;
    min-width: 0;
}

.walk__progress[b-xl19d44trz] {
    position: sticky;
    top: 3.1rem;
    z-index: 3;
    height: 3px;
}

/* ------------------------------------------------------------- the scan box
   Sticky with the header, because a scan is the one action available from
   anywhere in the list. */
.walk__scan[b-xl19d44trz] {
    position: sticky;
    top: 3.35rem;
    z-index: 2;
    padding: 0.5rem;
    background: var(--mud-palette-surface);
    border-bottom: 1px solid var(--mud-palette-lines-default);
}

/* ------------------------------------------------------------------ a line */
.walk__lines[b-xl19d44trz] {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    padding: 0.5rem;
}

.walk__line[b-xl19d44trz] {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    padding: 0.75rem;
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: 6px;
    background: var(--mud-palette-surface);
}

/* Done lines stay in the list rather than disappearing: a picker wants to see
   what they have already done, and a list that shortens under them loses the
   sense of where they are. Faded, so what is left stands out. */
.walk__line--done[b-xl19d44trz] {
    opacity: 0.55;
}

/* What a scan just landed on. A left rail rather than a fill, so it reads at
   a glance without competing with the shortfall colours. */
.walk__line--focus[b-xl19d44trz] {
    border-left: 4px solid var(--mud-palette-primary);
    opacity: 1;
}

/* ---------------------------------------------------------------- the where
   The address first and biggest. It is what a picker reads before anything
   else, because they have to walk somewhere before they can pick. */
.walk__where[b-xl19d44trz] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
}

/* The address, and the biggest thing on the line. A picker reads it before
   anything else, because they have to walk somewhere before they can pick. */
.walk__bin[b-xl19d44trz] {
    font-size: 1.25rem;
    font-weight: 600;
    letter-spacing: 0.02em;
    color: var(--mud-palette-text-primary);
}

/* ----------------------------------------------------------------- the what */
.walk__what[b-xl19d44trz] {
    display: flex;
    align-items: flex-start;
    gap: 0.75rem;
}

.walk__part[b-xl19d44trz] {
    min-width: 0;
    flex: 1;
}

/* ---------------------------------------------------------------- the count */
.walk__count[b-xl19d44trz] {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.walk__wanted[b-xl19d44trz] {
    font-size: 1.5rem;
    font-weight: 500;
    line-height: 1.1;
    color: var(--mud-palette-text-primary);
}

.walk__unit[b-xl19d44trz] {
    font-size: 0.5em;
    margin-left: 0.35em;
    color: var(--mud-palette-text-secondary);
}

.walk__actions[b-xl19d44trz] {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}

/* The number and its button on one row, because entering a partial count is
   two gestures and they belong together. */
.walk__some[b-xl19d44trz] {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.walk__some > :first-child[b-xl19d44trz] {
    flex: 1;
}

.walk__settled[b-xl19d44trz] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
}

/* --------------------------------------------------------------- the submit
   Fixed to the bottom, because it is the one thing that must be reachable
   without scrolling to the end of a forty-line slip. */
.walk__submit[b-xl19d44trz] {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 4;
    padding: 0.6rem 0.75rem calc(0.6rem + env(safe-area-inset-bottom));
    background: var(--mud-palette-surface);
    border-top: 1px solid var(--mud-palette-lines-default);
}

/* On a desktop the list is read rather than walked, so it gets a comfortable
   measure instead of stretching across a monitor. The phone layout is the
   default and this is the exception, which is the right way round for a screen
   whose whole purpose is the phone. */
@media (min-width: 900px) {
    .walk__lines[b-xl19d44trz],
    .walk__scan[b-xl19d44trz],
    .walk__bar[b-xl19d44trz] {
        max-width: 46rem;
        margin-inline: auto;
        width: 100%;
    }

    .walk__submit[b-xl19d44trz] {
        padding-inline: max(0.75rem, calc((100% - 46rem) / 2));
    }
}

/* Where goods are going, under the scan box.

   The one piece of state that makes this screen faster than the desktop one: a
   pallet goes to one bay, so it is said once by scanning that bay rather than
   chosen per line. */
.walk__into[b-xl19d44trz] {
    padding: 0.4rem 0.15rem 0;
    min-height: 1.75rem;
}
/* /Components/Pages/Warehouse.razor.rz.scp.css */
/* -----------------------------------------------------------------------
   The warehouse screen's own styling.

   Scoped, so every selector here names an element written in this
   component's own .razor file. Nothing styles a child component's root -
   Blazor stamps the scope attribute on markup, never on a component's
   rendered root, and a rule aimed at one silently does nothing. The audit in
   tools/check-scoped-css.py enforces it, which is why the contents table is
   reached through a wrapping div and ::deep rather than by naming
   MudSimpleTable.
   ----------------------------------------------------------------------- */

/* ------------------------------------------------------- what is in a box
   Three figures a part rather than one, so the number columns have to stay
   narrow enough that the part and its description keep the width. */
.box__contents[b-dc21x0xow5]  th,
.box__contents[b-dc21x0xow5]  td {
    padding-inline: 0.35rem;
}

.box__contents[b-dc21x0xow5]  th:first-child,
.box__contents[b-dc21x0xow5]  td:first-child {
    padding-inline-start: 0;
}

/* Tabular figures, because these are read down a column: proportional digits
   make 13 and 8 fail to line up and the eye has to do the work. */
.box__contents[b-dc21x0xow5]  td.portal-num {
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.box__contents[b-dc21x0xow5]  th {
    font-weight: 500;
    white-space: nowrap;
    color: var(--mud-palette-text-secondary);
}

/* The unit sits with its figure and should not compete with it. */
.box__unit[b-dc21x0xow5] {
    font-size: 0.75em;
    color: var(--mud-palette-text-secondary);
}
/* /Components/Shared/EmptyState.razor.rz.scp.css */
/* Nothing here yet.

   A dashed edge rather than a solid one: a solid border says "this is a
   thing", and the point of this box is that there is no thing. Taken from the
   item report, which had the only version of this worth keeping. */

.empty[b-rp6vyatocq] {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.375rem;
    padding: 2rem 1rem;
    border-radius: 6px;
    border: 1px dashed var(--mud-palette-lines-default);
    text-align: center;
}

/* Large enough to register, faint enough not to be the thing you read
   first - the sentence is. Reached through ::deep because MudIcon renders
   its own root and Blazor stamps the scope attribute on markup, never on a
   child component. */
.empty[b-rp6vyatocq]  .empty__glyph {
    font-size: 1.75rem !important;
    color: var(--mud-palette-text-disabled);
}

.empty__detail[b-rp6vyatocq] {
    max-width: 34rem;
    line-height: 1.5;
}

.empty__do[b-rp6vyatocq] {
    margin-top: 0.625rem;
}
/* /Components/Shared/HistoryPanel.razor.rz.scp.css */
/* One field that moved, on its own line so several read as a list rather
   than as a paragraph. */
.hist__change[b-m0j2ghxcon] {
    display: flex;
    align-items: center;
    gap: 6px;
    flex-wrap: wrap;
    padding-block: 1px;
    font-size: 0.8125rem;
    line-height: 1.4;
}

.hist__field[b-m0j2ghxcon] {
    font-weight: 500;
    min-width: 8rem;
}

/* The old value set back and the new one plain, so the eye lands on what it
   became rather than on what it was. */
.hist__from[b-m0j2ghxcon] {
    color: var(--mud-palette-text-secondary);
    text-decoration: line-through;
    text-decoration-thickness: 1px;
}

.hist__to[b-m0j2ghxcon] {
    color: var(--mud-palette-text-primary);
}
/* /Components/Shared/PageHeader.razor.rz.scp.css */
/* The page header block. */

.pagehead[b-zngf5o5lz6] {
    display: flex;
    flex-direction: column;
    gap: 0.375rem;
    margin-bottom: 1.5rem;
}

.pagehead__crumbs[b-zngf5o5lz6] {
    display: flex;
    align-items: center;
    gap: 0.25rem;
    min-height: 1.25rem;
    flex-wrap: wrap;
}

.pagehead__crumbs[b-zngf5o5lz6]  .pagehead__chev {
    color: var(--mud-palette-text-disabled);
    font-size: 0.875rem !important;
}

.pagehead__row[b-zngf5o5lz6] {
    display: flex;
    align-items: flex-start;
    gap: 1rem;
    flex-wrap: wrap;
}

.pagehead__titles[b-zngf5o5lz6] {
    display: flex;
    flex-direction: column;
    gap: 0.1875rem;
    min-width: 0;
    flex: 1 1 20rem;
}

.pagehead__title[b-zngf5o5lz6] {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
    min-width: 0;
}

/* The section glyph sits quieter than the words beside it - it is a
   confirmation of where you are, not the headline. */
.pagehead__title[b-zngf5o5lz6]  .pagehead__icon {
    color: var(--mud-palette-text-secondary);
    flex: none;
}

.pagehead__title[b-zngf5o5lz6]  .pagehead__h {
    min-width: 0;
    overflow-wrap: anywhere;
}

.pagehead__badges[b-zngf5o5lz6] {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    flex-wrap: wrap;
}

.pagehead__titles[b-zngf5o5lz6]  .pagehead__sub {
    max-width: 68ch;
}

.pagehead__actions[b-zngf5o5lz6] {
    display: flex;
    align-items: center;
    gap: 0.375rem;
    flex-wrap: wrap;
    /* Pushed right on a wide screen, wrapping under the title on a narrow one
       rather than squeezing the heading. */
    margin-left: auto;
}
/* /Components/Shared/QuantityBar.razor.rz.scp.css */
/* The three-part quantity bar.

   Colours are literal rather than palette variables because they must mean the
   same thing in day and night view: teal is always "moving", green is always
   "here and ours", gold is always "coming", hatching is always "nobody has
   acted". A segment that changed hue with the theme would break the legend's
   promise. All are legible on the light and dark surfaces the bar sits on. */

.qbar-wrap[b-onwp21pqmb] {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    min-width: 0;
}

.qbar[b-onwp21pqmb] {
    display: flex;
    /* Was 0.5rem. At eight pixels a three-part bar was a smudge - the
       segments were there but not countable, which is most of what "not
       much is clearly visible" meant. Twelve gives each colour room to be
       recognised without the bar becoming a chart. */
    height: 0.75rem;
    min-width: 6rem;
    border-radius: 3px;
    overflow: hidden;
    /* The track shows through wherever a segment is absent. */
    background: var(--mud-palette-lines-default);
    /* An inset edge so a pale segment still has a boundary. Neutral grey
       rather than near-black: the same rgba has to read as an edge on a white
       card and on a near-black one, and ink on ink is nothing. */
    box-shadow: inset 0 0 0 1px rgba(127, 127, 127, 0.3);
}

.qbar__seg[b-onwp21pqmb] {
    display: block;
    height: 100%;
    /* Hairlines between segments so two adjacent colours stay countable.
       Strengthened when stock joined as a fourth segment: teal and green are
       the closest pair on the bar, and at 0.35 alpha the join between them was
       the one boundary you had to look for rather than see. */
    box-shadow: inset -1.5px 0 0 rgba(255, 255, 255, 0.6);
}

.qbar__seg:last-child[b-onwp21pqmb] {
    box-shadow: none;
}

.qbar__seg--shipped[b-onwp21pqmb] {
    background: #467886;
}

/* Picked: the brighter green. Between the teal of "moving" and the deep green
   of "on a shelf", which is exactly where it sits in the process - off the
   shelf, not yet away. */
.qbar__seg--staged[b-onwp21pqmb] {
    background: #4E9A4E;
}

/* AKVA green: on a shelf, already ours. It sits next to the teal on purpose -
   both are good news, and the pair reads as "covered" without either being
   mistaken for the other. */
.qbar__seg--stock[b-onwp21pqmb] {
    background: #2C622C;
}

.qbar__seg--onorder[b-onwp21pqmb] {
    background: #F1B53D;
}

/* Hatched, not just grey. It reads as "open" rather than as a fourth colour,
   and survives being printed in black and white. */
.qbar__seg--unsourced[b-onwp21pqmb] {
    background: repeating-linear-gradient(
        135deg,
        rgba(166, 67, 47, 0.55) 0 3px,
        rgba(166, 67, 47, 0.22) 3px 6px
    );
}

.qbar__seg--empty[b-onwp21pqmb] {
    display: block;
    width: 100%;
    height: 100%;
}

/* ------------------------------------------------------------------ legend */
.qbar__legend[b-onwp21pqmb] {
    display: flex;
    flex-wrap: wrap;
    gap: 0.375rem 0.875rem;
    /* Was 0.6875rem - eleven pixels of Arial at secondary contrast, which is
       below what a legend can be read at. This is the smallest size in the
       portal and it now sits at the floor rather than under it. */
    font-size: 0.75rem;
    line-height: 1.35;
    color: var(--mud-palette-text-secondary);
}

.qbar__key[b-onwp21pqmb] {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
    letter-spacing: 0.01em;
}

/* The one figure worth chasing carries the page's text colour rather than the
   muted secondary, so it holds the eye a fraction longer than the rest. */
.qbar__key--attention[b-onwp21pqmb] {
    color: var(--mud-palette-text-primary);
    font-weight: 700;
}

.qbar__swatch[b-onwp21pqmb] {
    display: block;
    width: 0.625rem;
    height: 0.625rem;
    border-radius: 2px;
    flex: none;
}

.qbar__swatch--shipped[b-onwp21pqmb] {
    background: #467886;
}

.qbar__swatch--staged[b-onwp21pqmb] {
    background: #4E9A4E;
}

.qbar__swatch--stock[b-onwp21pqmb] {
    background: #2C622C;
}

.qbar__swatch--onorder[b-onwp21pqmb] {
    background: #F1B53D;
}

.qbar__swatch--unsourced[b-onwp21pqmb] {
    background: repeating-linear-gradient(
        135deg,
        rgba(166, 67, 47, 0.55) 0 2px,
        rgba(166, 67, 47, 0.22) 2px 4px
    );
}
/* /Components/Shared/SearchPicker.razor.rz.scp.css */
/* One row of the dropdown: what it is on the left, how much of it on the
   right. The two lines are stacked so a long customer name wraps under the
   reference rather than pushing the count off the row. */
.picker__row[b-isyvlc16te] {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.75rem;
    width: 100%;
    min-width: 0;
}

.picker__what[b-isyvlc16te] {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

/* Figures line up down the column, which is what makes a list of counts
   scannable rather than ten separate readings. */
.picker__badge[b-isyvlc16te] {
    flex: none;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}
/* /Components/Shared/SortHead.razor.rz.scp.css */
/* A sortable table heading.

   The th keeps its own padding from MudBlazor; everything here is about the
   button inside it looking like a heading rather than like a button. */

.sorthead[b-k2autxdwgj] {
    /* Nothing else in a header row is clickable, so the pointer is the only
       hint before the arrow is noticed. */
    cursor: pointer;
    white-space: nowrap;
    user-select: none;
}

/* The button is the control - it has to be a button for the keyboard - but it
   must not look like one. Stripped back to the heading it replaces, and
   inheriting the font so it matches the headings beside it that do not sort. */
.sorthead__hit[b-k2autxdwgj] {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    width: 100%;

    /* The browser's own stylesheet centres a button's contents, which centred
       every sortable heading while the plain ones beside them stayed left.
       Nothing in the reset below covers it, because it is justify-content
       rather than text-align. */
    justify-content: flex-start;
    padding: 0;
    border: none;
    background: none;
    font: inherit;
    color: inherit;
    text-align: inherit;
    cursor: pointer;
}

/* Keyboard focus has to be visible, and a heading is too tight for an outline
   that sits outside it. */
.sorthead__hit:focus-visible[b-k2autxdwgj] {
    outline: 2px solid var(--mud-palette-primary);
    outline-offset: 2px;
    border-radius: 2px;
}

.sorthead--on .sorthead__text[b-k2autxdwgj] {
    font-weight: 700;
}

/* Faint until this is the column in use. Always present, though: a control
   that appears on hover does not exist on a touch screen, and these lists are
   read on phones. Reached with ::deep because MudIcon renders its own root and
   Blazor never stamps the scope attribute on a child component. */
.sorthead[b-k2autxdwgj]  .sorthead__arrow {
    font-size: 0.9rem !important;
    opacity: 0.3;
    flex: 0 0 auto;
}

.sorthead:hover[b-k2autxdwgj]  .sorthead__arrow {
    opacity: 0.6;
}

.sorthead[b-k2autxdwgj]  .sorthead__arrow--on {
    opacity: 1;
    color: var(--mud-palette-primary);
}

/* A heading that carries text-align:right inline wants its arrow on the same
   side as the figures it names. */
.sorthead[style*="right"] .sorthead__hit[b-k2autxdwgj] {
    justify-content: flex-end;
}
/* /Components/Shipments/RouteStrip.razor.rz.scp.css */
/* The route strip.

   Three columns: origin, leg, destination. The ends size to their content and
   the leg takes the rest, so two short port names give a long line and two
   long ones give a short line - either way the ends stay readable, which
   matters more than a constant leg length. */

.route[b-84nnr0t6ue] {
    display: grid;
    grid-template-columns: auto minmax(2.5rem, 1fr) auto;
    align-items: start;
    gap: 0.625rem;
    min-width: 0;
}

/* ----------------------------------------------------------------- the ends */
.route__end[b-84nnr0t6ue] {
    display: grid;
    grid-template-columns: auto auto;
    grid-template-areas:
        "pin place"
        ".   when";
    align-items: center;
    gap: 0 0.375rem;
    min-width: 0;
}

.route__end--to[b-84nnr0t6ue] {
    /* The far end reads right-aligned, so the pin sits outside the text and
       the whole thing anchors to the destination rather than to the line. */
    grid-template-columns: auto auto;
    grid-template-areas:
        "place pin"
        "when  .";
    justify-items: end;
}

.route__end[b-84nnr0t6ue]  .route__pin {
    grid-area: pin;
    font-size: 0.625rem !important;
    color: var(--mud-palette-text-secondary);
}

.route__end--to[b-84nnr0t6ue]  .route__pin {
    font-size: 0.875rem !important;
}

.route__place[b-84nnr0t6ue] {
    grid-area: place;
    font-size: 0.8125rem;
    font-weight: 600;
    color: var(--mud-palette-text-primary);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 10rem;
}

.route__when[b-84nnr0t6ue] {
    grid-area: when;
    font-size: 0.6875rem;
    font-variant-numeric: tabular-nums;
    color: var(--mud-palette-text-secondary);
    white-space: nowrap;
}

/* A date that has not happened yet is bracketed, so a schedule is never
   mistaken for a record of events. */
.route__when--planned[b-84nnr0t6ue]::before {
    content: "due ";
    color: var(--mud-palette-text-disabled);
}

/* ------------------------------------------------------------------ the leg */
.route__leg[b-84nnr0t6ue] {
    position: relative;
    height: 1.5rem;
    min-width: 0;
}

.route__track[b-84nnr0t6ue] {
    position: absolute;
    top: 0.5rem;
    left: 0;
    width: 100%;
    height: 3px;
    border-radius: 2px;
    /* Dashed for the part not yet travelled: it reads as an intention rather
       than as a thinner version of the same thing. */
    background: repeating-linear-gradient(
        to right,
        var(--mud-palette-lines-default) 0 4px,
        transparent 4px 8px
    );
}

.route__track--done[b-84nnr0t6ue] {
    background: #467886;
}

.route__vehicle[b-84nnr0t6ue] {
    position: absolute;
    top: 0;
    /* left is set inline as a percentage of the leg, inset from both ends by
       the component; the translate pulls the glyph back onto its own centre. */
    transform: translateX(-50%);
    display: grid;
    place-items: center;
    width: 1.375rem;
    height: 1.375rem;
    border-radius: 50%;
    background: var(--mud-palette-surface);
    box-shadow: 0 0 0 2px #467886;
    color: #467886;
}

.route__vehicle[b-84nnr0t6ue]  .mud-icon-root {
    font-size: 0.8125rem;
}

.route__detail[b-84nnr0t6ue] {
    position: absolute;
    top: 1.0625rem;
    left: 50%;
    transform: translateX(-50%);
    max-width: 100%;
    font-size: 0.625rem;
    color: var(--mud-palette-text-secondary);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Narrow screens keep the horizontal arrangement and give up the dates
   instead. Turning the leg vertical was the other option, but the fill's
   length is set inline as a width - on a vertical track that percentage
   would mean nothing and the strip would have to claim a position it does
   not know. Losing the dates costs less than drawing a wrong one. */
@media (max-width: 520px) {
    .route[b-84nnr0t6ue] {
        gap: 0.375rem;
    }

    .route__place[b-84nnr0t6ue] {
        max-width: 6.5rem;
    }

    .route__when[b-84nnr0t6ue],
    .route__detail[b-84nnr0t6ue] {
        display: none;
    }
}
