@import '_content/AdvDeli.Catalog.UI/AdvDeli.Catalog.UI.kpaxqrypx1.bundle.scp.css';

/* _content/AdvDeli.WebOffice/Components/Layout/MainLayout.razor.rz.scp.css */
#blazor-error-ui[b-si2sjwyi2k] {
    background: lightyellow;
    bottom: 0;
    box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
    display: none;
    left: 0;
    padding: 0.6rem 1.25rem 0.7rem 1.25rem;
    position: fixed;
    width: 100%;
    z-index: 1000;
}

    #blazor-error-ui .dismiss[b-si2sjwyi2k] {
        cursor: pointer;
        position: absolute;
        right: 0.75rem;
        top: 0.5rem;
    }
/* _content/AdvDeli.WebOffice/Components/Pages/GlobalChanges.razor.rz.scp.css */
/* Global Changes.

   Wider than the .rf-page maximum the single-record forms use: this screen is two working panes
   side by side, and squeezing them into 1100px turns the item grid into a column of ellipses. */

.gc-page[b-4aedh4vxbb] { max-width: 1560px; margin: 0 auto; padding: 8px 4px; }

/* The split. Item selection is the half that gets scanned, so it takes the larger share; the
   change pane is a column of controls and does not benefit from the extra width. */
.gc-split[b-4aedh4vxbb] {
    display: grid;
    grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
    gap: 18px;
    align-items: start;
}

/* Below this the two panes stop being readable side by side and stack instead. */
@media (max-width: 1180px) {
    .gc-split[b-4aedh4vxbb] { grid-template-columns: minmax(0, 1fr); }
}

.gc-pane[b-4aedh4vxbb] {
    background: #fff;
    border: 1px solid var(--line, #e3e8ef);
    border-radius: 14px;
    padding: 14px 16px 16px;
    min-width: 0;
}

.gc-pane-head[b-4aedh4vxbb] {
    display: flex; align-items: baseline; justify-content: space-between;
    gap: 12px; margin-bottom: 12px;
}
.gc-pane-head h2[b-4aedh4vxbb] { font-size: 1.05rem; margin: 0; color: #1f2733; }
.gc-count[b-4aedh4vxbb] { font-size: .84rem; color: #5c6674; font-variant-numeric: tabular-nums; }

/* ---- filters ---- */

.gc-filters[b-4aedh4vxbb] { display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: 10px; }
.gc-f[b-4aedh4vxbb] { display: flex; flex-direction: column; gap: 5px; min-width: 140px; }
.gc-f.grow[b-4aedh4vxbb] { flex: 1 1 180px; }
.gc-f > label[b-4aedh4vxbb] { font-size: .74rem; font-weight: 700; color: #6b7482; text-transform: uppercase; letter-spacing: .03em; }
.gc-f .rf-in[b-4aedh4vxbb] { padding: 7px 10px; font-size: .88rem; }

.gc-seltools[b-4aedh4vxbb] { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 10px; }

/* ---- the item grid ---- */

/* Capped and scrolled rather than left to run down the page: the change pane has to stay in view
   while the selection is being made, and a thousand-row table would push it out of reach. */
.gc-grid-wrap[b-4aedh4vxbb] { max-height: 62vh; }

/* On a phone the cap stops earning its keep. 62vh of a 717px screen is a scroll box roughly three
   CARDS tall — a window onto 143 items, inside a page that also scrolls, so the operator is
   working two nested scrollbars with a thumb. The cap exists to stop the list running down the
   page on a desktop where the change panel sits beside it; here that panel is BELOW the list
   anyway, so letting the list have its own length costs nothing and removes the inner scroll.
   dvh, not vh, so the mobile URL bar does not eat the bottom of it. */
@media (max-width: 560px) {
    .gc-grid-wrap[b-4aedh4vxbb] { max-height: none; }
}

.gc-grid[b-4aedh4vxbb] { width: 100%; font-size: .87rem; }
.gc-grid th[b-4aedh4vxbb] { position: sticky; top: 0; z-index: 1; background: #f7f9fc; }
.gc-grid td[b-4aedh4vxbb], .gc-grid th[b-4aedh4vxbb] { padding: 7px 10px; }
.gc-grid th.chk[b-4aedh4vxbb], .gc-grid td.chk[b-4aedh4vxbb] { width: 34px; padding-right: 0; }
.gc-grid td.num[b-4aedh4vxbb], .gc-grid th.num[b-4aedh4vxbb] { text-align: right; font-variant-numeric: tabular-nums; }
.gc-grid tr.gc-sel[b-4aedh4vxbb] { background: #eef1fd; }

.gc-code[b-4aedh4vxbb] { font-family: ui-monospace, "Cascadia Mono", Consolas, monospace; font-size: .82rem; color: #47505e; }
.gc-sub[b-4aedh4vxbb] { display: block; font-size: .76rem; color: #8a93a1; }
.gc-muted[b-4aedh4vxbb] { color: #9aa3b1; }

.gc-tag[b-4aedh4vxbb] {
    display: inline-block; padding: 1px 7px; border-radius: 999px;
    font-size: .74rem; font-weight: 600; border: 1px solid transparent;
}
.gc-tag.ok[b-4aedh4vxbb]   { background: #e6f4ec; color: #1e6f45; border-color: #c3e4d2; }
.gc-tag.off[b-4aedh4vxbb]  { background: #f1f3f6; color: #6b7482; border-color: #dde2ea; }
.gc-tag.warn[b-4aedh4vxbb] { background: #fdf3e3; color: #8a5a12; border-color: #e8d3a8; }

/* ---- the change cards ---- */

.gc-cards[b-4aedh4vxbb] { display: flex; flex-direction: column; gap: 10px; }

.gc-card[b-4aedh4vxbb] {
    border: 1px solid #e3e8ef; border-radius: 12px;
    background: #fbfcfe; transition: border-color .12s, background .12s;
}
/* A chosen card is visibly chosen. Six collapsed cards look identical otherwise, and "why did it
   only change the tax?" is the question that follows. */
.gc-card.on[b-4aedh4vxbb] { border-color: #b9c0f0; background: #fff; }

.gc-card-head[b-4aedh4vxbb] {
    display: flex; align-items: center; gap: 10px;
    padding: 11px 13px; cursor: pointer; user-select: none;
}
.gc-card-t[b-4aedh4vxbb] { font-weight: 650; font-size: .93rem; color: #1f2733; }

.gc-card-body[b-4aedh4vxbb] {
    display: flex; flex-direction: column; gap: 10px;
    padding: 2px 13px 13px; border-top: 1px solid #eef1f6;
    padding-top: 11px;
}
.gc-card-body .rf-in[b-4aedh4vxbb] { font-size: .88rem; padding: 7px 10px; }

/* Label above control, for the "leave as is / on / off" dropdowns. */
.gc-tri[b-4aedh4vxbb] { display: flex; flex-direction: column; gap: 5px; }
.gc-tri > label[b-4aedh4vxbb] { font-size: .74rem; font-weight: 700; color: #6b7482; text-transform: uppercase; letter-spacing: .03em; }

.gc-qty[b-4aedh4vxbb] { display: grid; grid-template-columns: 1.4fr 1fr; gap: 8px; }

/* THE STOCK QUANTITY ROW IS HOW ITEMS GO OFF SALE, so it gets stacked rather than squeezed.
   Availability across the kiosks and tills is driven from here — mark the item as counted, enter
   what is physically left, and it sells out on its own once that many have gone. That makes this
   the most consequential pair of fields on the screen, and the two are not equal: picking
   Replace when you meant Add books a stock correction rather than a delivery.

   Side by side at 320px the mode select gets about 148px and shows "Replace — coun…", which is
   exactly where that mistake gets made. One per row, full width, both legible. */
@media (max-width: 560px) {
    .gc-qty[b-4aedh4vxbb] { grid-template-columns: 1fr; gap: 10px; }
}

.gc-note[b-4aedh4vxbb] { margin: 0; font-size: .8rem; color: #5c6674; line-height: 1.45; }
.gc-note.warn[b-4aedh4vxbb] {
    background: #fdf3e3; border: 1px solid #e8d3a8; color: #8a5a12;
    padding: 7px 10px; border-radius: 8px;
}

/* ---- apply ---- */

.gc-apply[b-4aedh4vxbb] {
    display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
    margin-top: 14px; padding-top: 13px; border-top: 1px solid #eef1f6;
}
.gc-hint[b-4aedh4vxbb] { font-size: .82rem; color: #8a93a1; }

/* ---- the preview dialog ---- */

.gc-plan-lead[b-4aedh4vxbb] { margin: 0 0 10px; font-size: .9rem; color: #3d4756; line-height: 1.5; }

.gc-plan[b-4aedh4vxbb] { width: 100%; border-collapse: collapse; font-size: .88rem; }
.gc-plan td[b-4aedh4vxbb] { padding: 8px 10px; border-bottom: 1px solid #eef1f6; vertical-align: top; }
.gc-plan tr:last-child td[b-4aedh4vxbb] { border-bottom: 0; }
.gc-plan-w[b-4aedh4vxbb] { font-weight: 650; color: #1f2733; white-space: nowrap; width: 1%; }
.gc-plan-d[b-4aedh4vxbb] { color: #3d4756; }
.gc-plan-n[b-4aedh4vxbb] { text-align: right; white-space: nowrap; color: #5c6674; font-variant-numeric: tabular-nums; }

.gc-blockers[b-4aedh4vxbb] {
    background: #fdeceb; border: 1px solid #f2c4c0; border-radius: 10px;
    padding: 11px 13px; margin-bottom: 14px; color: #8c2f28;
}
.gc-blocker[b-4aedh4vxbb] { margin-top: 9px; }
.gc-blocker:first-of-type[b-4aedh4vxbb] { margin-top: 7px; }
.gc-blocker-r[b-4aedh4vxbb] { font-weight: 600; font-size: .88rem; }
.gc-blocker-n[b-4aedh4vxbb] { font-weight: 400; opacity: .8; }
.gc-blocker-a[b-4aedh4vxbb] { font-size: .83rem; opacity: .9; margin-top: 2px; line-height: 1.45; }

/* ---- the confirmation that it landed ---- */

.gc-done[b-4aedh4vxbb] {
    display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
    position: fixed; left: 50%; bottom: 22px; transform: translateX(-50%);
    z-index: 60; background: #e6f4ec; border: 1px solid #c3e4d2; color: #1e6f45;
    padding: 11px 16px; border-radius: 12px; font-size: .9rem;
    box-shadow: 0 6px 22px rgba(20, 40, 30, .16);
}
/* _content/AdvDeli.WebOffice/Components/Pages/Home.razor.rz.scp.css */
/* =============================================================================================
   Back Office dashboard.

   WAS AN INLINE <style> BLOCK IN Home.razor. That is worth knowing about rather than just
   fixing: a <style> element inside a component is emitted into the document verbatim. It is not
   scoped, so every rule in it is global and leaks to every other page; and it was written before
   the design system arrived, so it carried its own hex literals and never picked up a token
   change. The same trap took out the ModifierPicker dialog on the till, which stayed dark for a
   week after everything around it went light. Scoped stylesheet, shared tokens.

   MOUSE, NOT TOUCH — this is a browser application. The Cashier's 44px floor does not apply.
   ============================================================================================= */

.dash-home[b-shs2q56y8r] {
    max-width: 1100px;
    margin: 0 auto;
    padding: 8px 4px;
    color: var(--c-text);
}

.dash-head[b-shs2q56y8r] { padding: 12px 6px 24px; }
.dash-head h1[b-shs2q56y8r] {
    font-size: 1.8rem;
    font-weight: 800;
    letter-spacing: -.018em;
    margin: 0 0 .35rem;
    color: var(--c-text);
}
.dash-lead[b-shs2q56y8r] { color: var(--c-text-dim); font-size: 1.02rem; margin: 0; }

.dash-cards[b-shs2q56y8r] {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: 18px;
}

/* Glass, no backdrop-filter: these sit over the mesh that .bo::before paints, and blurring a
   smooth gradient returns the same gradient. The fill and the edge highlight do the work. */
.dash-card[b-shs2q56y8r] {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 22px;
    background: var(--glass-fill);
    border: 1px solid var(--glass-line);
    border-radius: var(--r-lg);
    box-shadow: var(--glass-edge);
    text-decoration: none;
    color: inherit;
    transition: transform .1s ease, box-shadow .15s ease, border-color .15s ease;
}
a.dash-card:hover[b-shs2q56y8r] {
    transform: translateY(-2px);
    border-color: var(--glass-line-hi);
    box-shadow: 0 10px 28px rgba(20, 30, 50, .12), var(--glass-edge);
}

/* Not a link — the screen does not exist yet. It keeps its shape so the grid stays even, but
   loses the hover and the arrow so it never looks clickable. */
.dash-card.soon[b-shs2q56y8r] { opacity: .66; }

.dash-ic[b-shs2q56y8r] {
    width: 46px;
    height: 46px;
    border-radius: var(--r-sm);
    display: grid;
    place-items: center;
    flex: 0 0 auto;
}
.dash-ic svg[b-shs2q56y8r] { width: 22px; height: 22px; }

/* Tinted glass rather than flat pastel fills, so the chips sit in the same material as the card.
   One hue per destination — the only place on this screen colour carries any meaning. */
.dash-ic.cat[b-shs2q56y8r]   { background: var(--c-accent-wash);                              color: var(--c-accent-text); }
.dash-ic.menu[b-shs2q56y8r]  { background: color-mix(in srgb, var(--c-go) 15%, transparent);  color: var(--c-go-text); }
.dash-ic.sys[b-shs2q56y8r]   { background: color-mix(in srgb, #2B62C9 14%, transparent);      color: #1E4C9E; }
.dash-ic.store[b-shs2q56y8r] { background: color-mix(in srgb, #7C5CD6 15%, transparent);      color: #5B3FB0; }

.dash-ct[b-shs2q56y8r] {
    font-size: 1.12rem;
    font-weight: 800;
    letter-spacing: var(--track-tight);
    margin-top: 6px;
    color: var(--c-text);
}
.dash-cd[b-shs2q56y8r] { color: var(--c-text-dim); font-size: .9rem; line-height: 1.55; }

.dash-go[b-shs2q56y8r] {
    color: var(--c-accent-text);
    font-weight: 700;
    font-size: .9rem;
    margin-top: auto;
    padding-top: 8px;
}
.dash-soon[b-shs2q56y8r] {
    color: var(--c-text-faint);
    font-weight: 700;
    font-size: .76rem;
    text-transform: uppercase;
    letter-spacing: var(--track-label);
    margin-top: auto;
    padding-top: 8px;
}

/* =============================================================================================
   Your shortcuts — the customisable half of the dashboard.
   ============================================================================================= */

.dash-sechead[b-shs2q56y8r] {
    display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
    margin: 34px 6px 14px;
}
.dash-sechead h2[b-shs2q56y8r] {
    font-size: .78rem; font-weight: 800;
    text-transform: uppercase; letter-spacing: var(--track-label);
    color: var(--c-text-faint);
}
.dash-edit[b-shs2q56y8r] {
    border: 1px solid var(--glass-line-hi);
    background: var(--c-s2);
    color: var(--c-text);
    border-radius: var(--r-sm);
    padding: 6px 14px;
    font-family: var(--font); font-size: .82rem; font-weight: 700;
    cursor: pointer;
}
.dash-edit:hover[b-shs2q56y8r] { background: var(--c-s4); }

.dash-ic.pin[b-shs2q56y8r] { background: var(--well-fill-strong); color: var(--c-text-dim); }

/* A pinned card is a link wrapping the whole tile, plus a tool row that only exists in edit mode.
   The <a> is a grid child rather than the card itself so the tools are not inside the link — a
   Remove button inside an anchor navigates as well as removing. */
.dash-card.sc[b-shs2q56y8r] { padding: 0; }
.sc-hit[b-shs2q56y8r] {
    display: flex; flex-direction: column; gap: 8px;
    padding: 22px;
    text-decoration: none; color: inherit;
    border-radius: var(--r-lg);
    height: 100%;
}
.dash-card.sc.editing .sc-hit[b-shs2q56y8r] { cursor: default; }

.sc-tools[b-shs2q56y8r] {
    display: flex; align-items: center; gap: 8px;
    padding: 0 16px 16px;
}
.sc-tool[b-shs2q56y8r] {
    border: 1px solid var(--glass-line-hi);
    background: var(--c-s2);
    color: var(--c-text);
    border-radius: var(--r-sm);
    min-height: 32px; padding: 0 11px;
    font-family: var(--font); font-size: .8rem; font-weight: 700;
    cursor: pointer;
}
.sc-tool:hover:not(:disabled)[b-shs2q56y8r] { background: var(--c-s4); }
.sc-tool:disabled[b-shs2q56y8r] { opacity: .4; cursor: default; }
.sc-tool.danger[b-shs2q56y8r] {
    margin-left: auto;
    color: var(--c-stop-text);
    border-color: color-mix(in srgb, var(--c-stop) 40%, transparent);
    background: color-mix(in srgb, var(--c-stop) 9%, var(--c-s2));
}
.sc-tool.danger:hover[b-shs2q56y8r] { background: color-mix(in srgb, var(--c-stop) 16%, var(--c-s2)); }

/* The add tile. Dashed and unfilled so it reads as a slot rather than as a card with content —
   the one place on the screen where "this is empty on purpose" has to be obvious. */
.dash-card.add[b-shs2q56y8r] {
    display: flex; flex-direction: column; align-items: flex-start; gap: 6px;
    padding: 22px;
    background: transparent;
    border: 1px dashed var(--c-line-strong);
    box-shadow: none;
    cursor: pointer;
    text-align: left;
    font-family: var(--font);
    min-height: 168px;
    justify-content: center;
    transition: border-color .15s ease, background-color .15s ease;
}
.dash-card.add:hover[b-shs2q56y8r] {
    border-color: var(--c-accent);
    background: var(--c-accent-wash);
    transform: none;
}
.add-plus[b-shs2q56y8r] {
    font-size: 1.5rem; font-weight: 800; line-height: 1;
    color: var(--c-accent-text);
}
.add-lbl[b-shs2q56y8r] { font-size: 1.02rem; font-weight: 800; color: var(--c-text); }
.add-hint[b-shs2q56y8r] { font-size: .86rem; color: var(--c-text-faint); }

/* ---------------------------------------------------------------------------------------------
   Picker dialog.
   --------------------------------------------------------------------------------------------- */
.pk-ov[b-shs2q56y8r] {
    position: fixed; inset: 0; z-index: 200;
    background: var(--scrim);
    -webkit-backdrop-filter: var(--scrim-blur);
    backdrop-filter: var(--scrim-blur);
    display: grid; place-items: center; padding: 20px;
}
.pk[b-shs2q56y8r] {
    width: min(520px, 100%); max-height: 82vh;
    display: flex; flex-direction: column;
    background: var(--modal-fill);
    border: 1px solid var(--glass-line-hi);
    border-radius: var(--r-lg);
    -webkit-backdrop-filter: var(--modal-blur);
    backdrop-filter: var(--modal-blur);
    box-shadow: var(--shadow-modal), var(--glass-edge);
    color: var(--c-text);
}
.pk-head[b-shs2q56y8r] {
    display: flex; align-items: center; justify-content: space-between; gap: 12px;
    padding: 18px 20px 14px;
    border-bottom: 1px solid var(--glass-line);
}
.pk-head h3[b-shs2q56y8r] { font-size: 1.05rem; font-weight: 800; letter-spacing: var(--track-tight); }
.pk-x[b-shs2q56y8r] {
    width: 34px; height: 34px; flex: 0 0 auto;
    border: 1px solid var(--glass-line-hi);
    background: var(--glass-fill-hi);
    color: var(--c-text-dim);
    border-radius: var(--r-sm);
    cursor: pointer;
}
.pk-x:hover[b-shs2q56y8r] { background: var(--glass-fill-hover); color: var(--c-text); }

.pk-search[b-shs2q56y8r] { padding: 14px 20px 8px; }
.pk-search input[b-shs2q56y8r] {
    width: 100%; min-height: 42px;
    border: 1px solid var(--glass-line-hi);
    border-radius: var(--r-sm);
    background: var(--c-s2);
    color: var(--c-text);
    padding: 0 14px;
    font-family: var(--font); font-size: .94rem;
    outline: none;
}
.pk-search input:focus[b-shs2q56y8r] { border-color: var(--c-accent); box-shadow: 0 0 0 3px var(--c-accent-wash); }

.pk-body[b-shs2q56y8r] { overflow-y: auto; padding: 6px 12px 16px; }
.pk-group[b-shs2q56y8r] { margin-bottom: 10px; }
.pk-group-ttl[b-shs2q56y8r] {
    font-size: .7rem; font-weight: 800;
    text-transform: uppercase; letter-spacing: var(--track-label);
    color: var(--c-text-faint);
    padding: 10px 8px 6px;
}
.pk-opt[b-shs2q56y8r] {
    width: 100%;
    display: flex; align-items: center; justify-content: space-between; gap: 12px;
    min-height: 40px; padding: 0 8px;
    border: 0; background: transparent;
    border-radius: var(--r-sm);
    font-family: var(--font); font-size: .92rem;
    color: var(--c-text);
    cursor: pointer; text-align: left;
}
.pk-opt:hover[b-shs2q56y8r] { background: var(--glass-fill-hi); }
.pk-opt-add[b-shs2q56y8r] {
    opacity: 0;
    font-size: .78rem; font-weight: 700;
    color: var(--c-accent-text);
}
/* Revealed on hover AND on focus — keyboard users never trigger :hover, and a control that only
   appears under a pointer is invisible to them. */
.pk-opt:hover .pk-opt-add[b-shs2q56y8r], .pk-opt:focus-visible .pk-opt-add[b-shs2q56y8r] { opacity: 1; }

.pk-empty[b-shs2q56y8r] { color: var(--c-text-faint); font-size: .9rem; padding: 18px 10px; margin: 0; }
/* _content/AdvDeli.WebOffice/Components/Pages/Items.razor.rz.scp.css */
/* =============================================================================================
   Item Manager — the Web Office's phone layout for a screen it does not own.

   ItemManagerView lives in AdvDeli.Catalog.UI and is reused verbatim by the Cashier, with eleven
   other projects referencing that library. Its shell — `.im { position: fixed; inset: 0;
   overflow: hidden }` with a single scrolling grid at `flex: 1` — is right for a till or a kiosk:
   fixed-size touch screens that want their chrome pinned and their data scrolling underneath it.

   It is wrong on a phone, and measurably so. The masthead, filter row and toolbar wrap until they
   take 645px of a 956px viewport, so the grid inherits the 105px left over — and because the shell
   is fixed with hidden overflow, the page cannot scroll to reach the rest either. The item list
   was not merely cramped, it was unreachable: the screen read as a toolbar with nothing under it.

   So the fix belongs HERE, with the one consumer that needs it, rather than in the shared file.

   WHY EVERY RULE GOES THROUGH ::deep, AND WHY THAT IS ALSO WHAT MAKES THEM WIN.
   .im and its children are rendered by the library component, so they carry ITS scope attribute,
   not this page's — a plain `.wo-im .im` here would compile to `.wo-im .im[b-thispage]` and match
   nothing. ::deep stops the scope attribute at .wo-im, giving `.wo-im[b-thispage] .im`.
   That is also the specificity answer: the library's own rule is `.im[b-itemmanager]` at (0,2,0),
   and this is (0,3,0) — one class, one attribute, one class. It wins on merit rather than on
   !important or source order.
   ============================================================================================= */

@media (max-width: 700px) {

    /* Out of the fixed shell and into ordinary document flow: the chrome stacks, the page scrolls,
       and the list runs on below the filters for as long as it needs to. */
    .wo-im[b-nn7omfcaki]  .im {
        position: static;
        height: auto;
        min-height: 100dvh;
        overflow: visible;
        /* Room for the pinned action bar is set once, further down, next to the rules that decide
           how tall that bar actually is — keeping the number and its cause in the same place. */
    }

    /* flex:none, or the wrap still tries to divide a container whose height is now its own
       content — the same squeeze in a new place. With height driven by content, the PAGE does the
       vertical scrolling.

       Its `overflow: auto` is left alone deliberately: the table is nine columns wide and still
       needs to scroll HORIZONTALLY. overflow-x:auto with overflow-y:visible is not a valid pair —
       one axis being non-visible forces the other to auto — so auto on both is the honest way to
       say it, and vertically it never engages because the box is exactly as tall as its rows. */
    .wo-im[b-nn7omfcaki]  .im-grid-wrap {
        flex: none;
        margin: 4px 10px;
    }

    /* MONEY MUST NOT WRAP. Squeezed into a narrow column, "€4.50" broke after the decimal point
       and rendered as "€4.5" above "0" — which does not read as a price at all, and beside a stock
       column reads as a different number entirely. tabular-nums is already set on these cells for
       alignment; keeping each figure on one line is the other half of that. */
    .wo-im[b-nn7omfcaki]  .im-tbl .c-num { white-space: nowrap; }

    /* THE ACTION BAR STAYS PINNED — the half of the shell worth keeping.

       In the fixed layout .im-foot sat at the bottom of the viewport, so Edit, Clone and Delete
       were reachable whatever the grid was scrolled to. Flattening the page sent it below the
       list: with 143 items that is about ten thousand pixels down, so selecting a row and then
       editing it meant scrolling the whole catalogue to reach the button and scrolling back to
       pick the next one. The chrome goes into the flow; the actions do not. */
    .wo-im[b-nn7omfcaki]  .im-foot {
        position: fixed;
        left: 0; right: 0; bottom: 0;
        z-index: 30;
        flex-wrap: wrap;
        gap: 8px;
        padding: 10px 12px;
        /* It overlays content now, so there is page behind it rather than the shell's own ground.
           Opaque, or rows scroll visibly through the buttons. */
        background: var(--c-surface, #fff);
        box-shadow: 0 -6px 20px rgba(0, 0, 0, .14);
        /* Clear of the home indicator on a phone with no hardware button. */
        padding-bottom: max(10px, env(safe-area-inset-bottom));
    }

    /* COMPACT, because this bar is permanently on screen.

       The first version let each button grow (`flex: 1 1 auto`), which sounds thumb-friendly and
       is not: five actions each claimed a full row, the bar measured 239px — a third of a 717px
       phone — and its content ran 392px wide inside a 315px viewport, so the PAGE scrolled
       sideways. A permanent bar has to earn its height in a way a dialog does not.

       So the buttons size to their labels and wrap naturally: five fit in two rows. 44px minimum
       keeps them thumb-sized without stretching. */
    .wo-im[b-nn7omfcaki]  .im-actions {
        width: 100%;
        min-width: 0;
        gap: 7px;
    }

    /* A three-column grid rather than a wrapping flex row. Wrapping sized each button to its
       label, so "Deactivate" was twice the width of "Edit" and the two rows never lined up.
       Equal cells read as one control surface and give every action the same target size. */
    .wo-im[b-nn7omfcaki]  .im-actions {
        display: grid;
        grid-template-columns: repeat(3, 1fr);
        gap: 6px;
    }

    /* Icon above label, not beside it. Beside it, "Deactivate" plus a 16px icon does not fit a
       110px cell without shrinking the text below legibility; stacked, every label fits at a
       readable size and the buttons stay square-ish and thumb-sized. */
    .wo-im[b-nn7omfcaki]  .im-actions > * {
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        gap: 3px;
        min-height: 58px;
        padding: 7px 4px;
        font-size: .7rem;
        line-height: 1.15;
        text-align: center;
    }

    /* --- icons ------------------------------------------------------------------------------

       Drawn with mask-image rather than background-image so each one takes the button's own
       colour: the two destructive actions are red and their icons come through red with them,
       which a background-image of a fixed-colour SVG could not do.

       WHICH BUTTON GETS WHICH IS PARTLY POSITIONAL, and that is the fragile part of doing this
       from a stylesheet the markup does not know about. The library renders, in order: Add item
       (already carries its own svg), Edit, Clone, then EITHER Activate OR Deactivate — never both
       — then Delete. Delete is pinned by :last-child and the destructive pair by .danger, so only
       Edit and Clone rely on their position. If that button order ever changes in
       AdvDeli.Catalog.UI, these two need revisiting; nothing else here does. */
    .wo-im[b-nn7omfcaki]  .im-actions > .im-btn::before {
        content: "";
        width: 17px;
        height: 17px;
        flex: none;
        background: currentColor;
        -webkit-mask: center / contain no-repeat var(--ic);
        mask: center / contain no-repeat var(--ic);
    }

    /* Add item already ships an <svg class="im-i">, so it must not grow a second icon. */
    .wo-im[b-nn7omfcaki]  .im-actions > .im-btn.primary::before { content: none; }
    .wo-im[b-nn7omfcaki]  .im-actions > .im-btn .im-i { width: 17px; height: 17px; }

    /* Edit — pencil. */
    .wo-im[b-nn7omfcaki]  .im-actions > .im-btn:nth-of-type(2) {
        --ic: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 20h9'/%3E%3Cpath d='M16.5 3.5a2.1 2.1 0 0 1 3 3L7 19l-4 1 1-4z'/%3E%3C/svg%3E");
    }

    /* Clone — two sheets. */
    .wo-im[b-nn7omfcaki]  .im-actions > .im-btn:nth-of-type(3) {
        --ic: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='9' y='9' width='12' height='12' rx='2'/%3E%3Cpath d='M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1'/%3E%3C/svg%3E");
    }

    /* Activate — the non-destructive one of the pair, so it is the 4th button without .danger. */
    .wo-im[b-nn7omfcaki]  .im-actions > .im-btn:nth-of-type(4):not(.danger) {
        --ic: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='9'/%3E%3Cpath d='M8.5 12.5l2.4 2.4L15.5 10'/%3E%3C/svg%3E");
    }

    /* Deactivate — destructive, but not the last button. */
    .wo-im[b-nn7omfcaki]  .im-actions > .im-btn.danger:not(:last-child) {
        --ic: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='9'/%3E%3Cpath d='M5.6 5.6l12.8 12.8'/%3E%3C/svg%3E");
    }

    /* Delete — always last. */
    .wo-im[b-nn7omfcaki]  .im-actions > .im-btn.danger:last-child {
        --ic: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 6h18'/%3E%3Cpath d='M8 6V4h8v2'/%3E%3Cpath d='M6 6l1 14h10l1-14'/%3E%3C/svg%3E");
    }

    /* Nothing in the bar may set its own width past the screen. */
    .wo-im[b-nn7omfcaki]  .im-foot,
    .wo-im[b-nn7omfcaki]  .im-count { min-width: 0; max-width: 100%; }

    .wo-im[b-nn7omfcaki]  .im-count { font-size: .78rem; line-height: 1.3; }

    /* The fetch/render timings go. They are diagnostics — genuinely useful when someone reports
       the screen as slow, and not worth a line of a phone's permanent furniture. The counts they
       sit beside stay. */
    .wo-im[b-nn7omfcaki]  .im-selinfo { display: none; }

    /* Matches the two-row bar above. Deliberately generous: too little and the last card of the
       catalogue hides behind the buttons, which is the bug this padding exists to prevent and the
       one the first attempt shipped with. */
    .wo-im[b-nn7omfcaki]  .im { padding-bottom: 150px; }
}

/* Hidden by default: on a desktop the shell pins its own chrome and there is nothing to travel
   back to. Shown only in the phone block below. */
.wo-totop[b-nn7omfcaki] { display: none; }

/* =============================================================================================
   CARDS — nine columns of catalogue on a phone, with nothing hidden and nothing to scroll to.

   The rest of the Web Office does this with a .t-cards class and a data-label on every cell (see
   app.css). Neither is available here: both live in markup this project does not own. So the
   labels are supplied from CSS instead, keyed on the column classes the library already puts on
   its cells — c-sku, c-name, c-cat, c-num, c-mod, c-type, c-stat — which are stable because they
   are what its own layout and sorting are built on.

   THE TWO c-num CELLS are Price and Current stock and carry the same class, so they cannot be told
   apart by class alone. `.c-num ~ .c-num` matches only a c-num that follows another one — the
   stock cell — so labelling every c-num "Price" and then overriding the later one is correct
   whether or not the stock column is rendered at all. It is conditional on the store managing
   stock, which is exactly why counting positions with nth-child would have been fragile.
   ============================================================================================= */

@media (max-width: 700px) {

    /* --- the sort row stays -----------------------------------------------------------------
       Hiding thead is what a card layout normally does, and here it would silently remove
       SORTING: those th elements carry the click handlers. On a catalogue of 143 items, ordering
       by price or stock is most of the value of the screen. So the header becomes a wrapped row
       of chips instead — the same controls, in a shape that fits. */
    .wo-im[b-nn7omfcaki]  .im-tbl thead { display: block; }

    /* ONE ROW THAT SCROLLS, not a wrapping block. Nine chips wrapped to three rows and cost 125px
       — as much as the KPI tiles — on a screen where the whole point of the exercise is getting
       the list above the fold. A chip rail is a pattern a phone user already knows, and the first
       few chips being visible is enough to say the row is scrollable. */
    .wo-im[b-nn7omfcaki]  .im-tbl thead tr {
        display: flex;
        flex-wrap: nowrap;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
        gap: 6px;
        padding: 6px 2px 8px;
        /* Chips are laid out by content width; without this they compress to fit instead of
           overflowing, which is what makes the rail scroll rather than squash. */
        scrollbar-width: none;
    }

    .wo-im[b-nn7omfcaki]  .im-tbl thead tr::-webkit-scrollbar { display: none; }
    .wo-im[b-nn7omfcaki]  .im-tbl thead th { flex: 0 0 auto; }

    .wo-im[b-nn7omfcaki]  .im-tbl thead th {
        display: inline-flex;
        align-items: center;
        gap: 4px;
        width: auto;
        padding: 7px 11px;
        border: 1px solid var(--c-line, #e3e8ef);
        border-radius: 999px;
        background: var(--c-surface, #fff);
        font-size: .78rem;
        white-space: nowrap;
        position: static;   /* the desktop header is sticky; a sticky chip row is not wanted */
    }

    /* The thumbnail column's header is deliberately empty — as a chip it is a blank pill. */
    .wo-im[b-nn7omfcaki]  .im-tbl thead th.c-thumb { display: none; }

    /* --- rows become cards ------------------------------------------------------------------ */
    .wo-im[b-nn7omfcaki]  .im-tbl,
    .wo-im[b-nn7omfcaki]  .im-tbl tbody,
    .wo-im[b-nn7omfcaki]  .im-tbl tr,
    .wo-im[b-nn7omfcaki]  .im-tbl td { display: block; width: auto; }

    .wo-im[b-nn7omfcaki]  .im-tbl tr {
        border: 1px solid var(--c-line, #e3e8ef);
        border-radius: 12px;
        margin: 0 0 10px;
        padding: 4px 0 6px;
        background: var(--c-surface, #fff);
    }

    .wo-im[b-nn7omfcaki]  .im-tbl td {
        display: flex;
        justify-content: space-between;
        align-items: baseline;
        gap: 14px;
        /* 4px, not 7. Nine rows means every pixel of row padding costs eighteen off the card, and
           the card is competing with 489px of chrome and a 140px action bar on a 717px screen.
           Tightening rows loses nothing — the label and value stay on one line either way. */
        padding: 4px 12px;
        line-height: 1.35;
        border: 0;
        text-align: right;
        /* Undoes the library's ≤820px rule, which hides SKU and Category outright. Nothing is
           omitted here — a catalogue screen that quietly drops the code you identify items by is
           worse on a phone than a longer card. */
        white-space: normal;
    }

    .wo-im[b-nn7omfcaki]  .im-tbl td + td { border-top: 1px solid var(--c-line, #eef1f5); }

    .wo-im[b-nn7omfcaki]  .im-tbl td::before {
        flex: 0 0 auto;
        text-align: left;
        font-size: .72rem;
        font-weight: 700;
        text-transform: uppercase;
        letter-spacing: .4px;
        color: var(--c-text-dim, #6b7785);
    }

    /* The labels the markup cannot give us. */
    .wo-im[b-nn7omfcaki]  .im-tbl td.c-sku::before  { content: "SKU"; }
    .wo-im[b-nn7omfcaki]  .im-tbl td.c-cat::before  { content: "Category"; }
    .wo-im[b-nn7omfcaki]  .im-tbl td.c-num::before  { content: "Price"; }
    .wo-im[b-nn7omfcaki]  .im-tbl td.c-num ~ td.c-num::before { content: "Current stock"; }
    .wo-im[b-nn7omfcaki]  .im-tbl td.c-mod::before  { content: "Modifiers"; }
    .wo-im[b-nn7omfcaki]  .im-tbl td.c-type::before { content: "Type"; }
    .wo-im[b-nn7omfcaki]  .im-tbl td.c-stat::before { content: "Status"; }

    /* Both were display:none below 820px in the library. Restored, and as labelled rows. */
    .wo-im[b-nn7omfcaki]  .im-tbl td.c-sku,
    .wo-im[b-nn7omfcaki]  .im-tbl td.c-cat { display: flex; }

    /* The item name heads the card rather than being one more labelled field — it is what the row
       IS, and a card titled "NAME  Chai" reads worse than one titled "Chai". */
    .wo-im[b-nn7omfcaki]  .im-tbl td.c-name {
        display: block;
        text-align: left;
        font-size: 1.02rem;
        font-weight: 700;
        padding: 2px 12px 8px;
        color: var(--c-text, #1f2733);
    }

    /* THE AVATAR GOES, and it is the one thing on this card that can go without losing anything.

       It is not a photograph: the cell holds Avatar.Initials(row.Name) — the first letters of the
       item's own name, which is the card's heading immediately below it. On a desktop grid that
       is a useful anchor for the eye running down a column of rows. On a card it repeats the
       title back to itself, one line above the title, for 48px of a 324px card.

       Everything else here is data the operator cannot get elsewhere on the screen. This is the
       only row that was already saying what the row beneath it says. */
    .wo-im[b-nn7omfcaki]  .im-tbl td.c-thumb { display: none; }

    /* Money and counts on one line — see the c-num note above. */
    .wo-im[b-nn7omfcaki]  .im-tbl td.c-num { white-space: nowrap; }

    /* The loading and no-results rows span everything and have no label of their own. */
    .wo-im[b-nn7omfcaki]  .im-tbl td.im-empty {
        display: block;
        text-align: center;
        padding: 18px 12px;
    }
    .wo-im[b-nn7omfcaki]  .im-tbl td.im-empty::before { content: none; }

    /* The wrap no longer has anything to scroll sideways, so the inner scrollbar goes. */
    .wo-im[b-nn7omfcaki]  .im-grid-wrap { overflow: visible; }

    /* --- the top bar, and why it looked right in an emulator and wrong on a handset -----------

       .im-topbar is a flex row with NO flex-wrap, and .im-ghost carries no flex-shrink. Given
       less width than its contents want, flex does not wrap — it SHRINKS, and it shrinks each
       item in proportion to its base size. Refresh is the wider of the two buttons, so it gave up
       more than Close: different widths, compressed padding, and the icon and label pulled out of
       line with their neighbour. At an emulated 440px there is enough room to hide it; at a real
       360-390px there is not, which is exactly why this reproduced on the phone and not in
       Chrome.

       Two fixes, both needed. Let the bar wrap, so the actions take their own row instead of
       competing with the title. And stop the buttons shrinking at all, so whatever room they get
       they share equally. */
    .wo-im[b-nn7omfcaki]  .im-topbar {
        flex-wrap: wrap;
        gap: 10px;
        padding: 10px 12px;
    }

    .wo-im[b-nn7omfcaki]  .im-brand { min-width: 0; flex: 1 1 auto; }

    .wo-im[b-nn7omfcaki]  .im-topact {
        flex: 0 0 auto;
        width: 100%;
    }

    /* Never shrink; share the row evenly. Equal widths are what makes them read as a pair. */
    .wo-im[b-nn7omfcaki]  .im-topact .im-ghost {
        flex: 1 1 0;
        min-width: 0;
        padding: 0 12px;
        justify-content: center;
    }

    /* --- the KPI tiles, 2x2 and compact -----------------------------------------------------

       They are `repeat(auto-fit, minmax(200px, 1fr))`, which on any phone resolves to a single
       column: four tiles stacked, about 340px of headroom before a single item is visible. The
       numbers are worth keeping — they answer "how much of the catalogue am I looking at" while
       the filters are being used — but not at the cost of the list they describe.

       Two columns fixed, rather than a smaller minmax: at this width auto-fit has no useful
       decision left to make, and stating 1fr 1fr is what guarantees 2x2 rather than hoping the
       track size lands right.

       Compacting matters as much as the columns. Two rows of the desktop tile would still be
       ~170px; shrinking the chip and padding brings the whole block to about a third of what it
       was, which is the difference between seeing one card on load and seeing three. */
    .wo-im[b-nn7omfcaki]  .im-stats {
        grid-template-columns: 1fr 1fr;
        gap: 8px;
        padding: 10px 12px 2px;
    }

    .wo-im[b-nn7omfcaki]  .im-stat {
        gap: 9px;
        padding: 9px 10px;
        border-radius: 10px;
        min-width: 0;
    }

    .wo-im[b-nn7omfcaki]  .im-stat-ic {
        width: 32px;
        height: 32px;
        font-size: .92rem;
    }

    .wo-im[b-nn7omfcaki]  .im-stat-ic svg { width: 16px; height: 16px; }

    /* The text column must be allowed to shrink, or "With modifiers" and "Average price" push
       their tile wider than its track and the grid stops being square. */
    .wo-im[b-nn7omfcaki]  .im-stat > div:last-child { min-width: 0; }

    .wo-im[b-nn7omfcaki]  .im-stat-v { font-size: 1.05rem; line-height: 1.15; }
    .wo-im[b-nn7omfcaki]  .im-stat-k { font-size: .68rem; line-height: 1.2; }

    /* --- the toolbar, paired rather than stacked --------------------------------------------

       Four controls, each taking a full row at ~52px: 273px, the largest single block of chrome on
       the screen and more than the tiles it sits under. Search and the Menu/Modifiers/Ingredients
       segments genuinely want the full width — one is typed into, the other holds three labels.
       The category select and the Include-inactive switch do not: they are 180px and 171px of
       content sharing a 359px row, which is exactly two. */
    .wo-im[b-nn7omfcaki]  .im-toolbar {
        display: flex;
        flex-wrap: wrap;
        gap: 8px;
        padding: 8px 12px;
    }

    .wo-im[b-nn7omfcaki]  .im-search,
    .wo-im[b-nn7omfcaki]  .im-seg { flex: 1 1 100%; min-width: 0; }

    .wo-im[b-nn7omfcaki]  .im-select,
    .wo-im[b-nn7omfcaki]  .im-switch { flex: 1 1 calc(50% - 4px); min-width: 0; }

    /* --- back to top ------------------------------------------------------------------------
       Sits clear of the pinned action bar rather than over it — the bar holds Delete, and a
       floating control overlapping it is a mis-tap waiting to happen. */
    .wo-totop[b-nn7omfcaki] {
        display: flex;
        align-items: center;
        justify-content: center;
        position: fixed;
        right: 12px;
        bottom: calc(150px + env(safe-area-inset-bottom));
        z-index: 31;
        width: 46px;
        height: 46px;
        border-radius: 50%;
        background: var(--c-surface, #fff);
        border: 1px solid var(--c-line, #e3e8ef);
        box-shadow: 0 4px 14px rgba(0, 0, 0, .18);
        color: var(--c-text, #1f2733);
        /* It is a <button> — see the note in Items.razor for why it is not an anchor. Padding and
           appearance are reset because a button brings its own on iOS. */
        padding: 0;
        cursor: pointer;
        -webkit-appearance: none;
        appearance: none;
    }

    .wo-totop:active[b-nn7omfcaki] { transform: translateY(1px); }

    .wo-totop svg[b-nn7omfcaki] { width: 20px; height: 20px; }
}

/* _content/AdvDeli.WebOffice/Components/Pages/Login.razor.rz.scp.css */
/* =============================================================================================
   Back Office sign-in.

   FIRST WEB OFFICE SCREEN ON THE SHARED DESIGN SYSTEM. Everything here comes from
   _content/AdvDeli.Catalog.UI/theme.css, which this host links in Components/App.razor.

   ONE THING DIFFERS FROM THE CASHIER, and it is the reason for the two explicit font-family
   declarations below. In the Cashier heads theme.css is linked AFTER app.css so it wins html
   and body; here it is linked BEFORE, deliberately, so the Web Office keeps its own navy/copper
   chrome on every screen that has not been redesigned yet. The consequence is that theme.css's
   base rules do NOT apply — its tokens resolve, but body is still Segoe UI from app.css. So a
   converted page has to opt into the typeface itself. Do the same on the next screen you
   convert, or it will inherit the old face and look subtly wrong next to this one.

   When the whole Web Office is on the system, move that link below app.css and every one of
   these font-family lines becomes redundant.

   THE 44px TOUCH FLOOR DOES NOT APPLY HERE. The Cashier runs on a touchscreen till, so every
   control there is 44px minimum and most are 48-52px. The Web Office is a browser application
   driven by a mouse, where that sizing just reads as oversized and pushes the form down the
   page. Fields are 42px and the button 44px — conventional web scale. Do not "fix" these to
   match the till; the two apps have different input devices and should have different metrics.
   ============================================================================================= */

.lg[b-lae1jk2ohf] {
    min-height: 100vh;
    display: grid;
    place-items: center;
    padding: 24px;
    position: relative;
    isolation: isolate;
    background: var(--c-s0);
    color: var(--c-text);
    font-family: var(--font);
}

/* The colour ground. A glass card over a flat page is just a lighter rectangle — the material
   needs something with hue and shape behind it to refract. Same four-point mesh as the till, so
   the two products read as one. */
.lg[b-lae1jk2ohf]::before {
    content: "";
    position: fixed;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    background:
        radial-gradient(62% 58% at 8% 6%, var(--mesh-a), transparent 68%),
        radial-gradient(58% 62% at 94% 16%, var(--mesh-b), transparent 68%),
        radial-gradient(66% 60% at 16% 92%, var(--mesh-c), transparent 70%),
        radial-gradient(60% 56% at 88% 88%, var(--mesh-d), transparent 70%);
}

/* The card KEEPS its backdrop-filter, unlike the full-page panes elsewhere in the system.

   The rule there is that a pane covering the whole screen gets fill only, because blurring a
   smooth gradient returns the same gradient and the filter costs every popover inside it its
   own blur. Neither applies here: this card is 420px wide with real ground visible around it,
   so the blur has an edge to work against and reads as frosted glass — and nothing inside it
   needs a backdrop of its own. */
.lg-card[b-lae1jk2ohf] {
    width: min(420px, 100%);
    display: flex;
    flex-direction: column;
    gap: 16px;
    padding: 34px 30px 30px;
    background: var(--modal-fill);
    border: 1px solid var(--glass-line-hi);
    border-radius: var(--r-lg);
    -webkit-backdrop-filter: var(--modal-blur);
    backdrop-filter: var(--modal-blur);
    box-shadow: var(--shadow-modal), var(--glass-edge);
}

/* ---------------------------------------------------------------------------------------------
   Brand block — mark on top, product name under it, centred.
   --------------------------------------------------------------------------------------------- */
.lg-brand[b-lae1jk2ohf] {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 2px;
    margin-bottom: 10px;
}

/* Saffron tile with the æ knocked out in ink — the same lockup as the till's sign-in screen.
   Sized by font-size because the mark is 1em tall; there is no width rule on the svg. */
.lg-logo[b-lae1jk2ohf] {
    width: 60px;
    height: 60px;
    margin-bottom: 12px;
    border-radius: var(--r-md);
    display: grid;
    place-items: center;
    background: var(--c-accent);
    color: var(--c-accent-ink);
    font-size: 34px;
    box-shadow: 0 10px 26px -8px rgba(245, 165, 36, .5);
}

/* Set as signage rather than as a heading, matching the Cashier's wordmark: heaviest weight,
   negative tracking (display type wants tighter fit than text type), and a soft saffron halo
   that ties it to the mark above. The sub-line deliberately stays light and normally tracked —
   if both are display-set, neither reads as the title. */
.lg-title[b-lae1jk2ohf] {
    font-size: 1.7rem;
    font-weight: 800;
    letter-spacing: -.022em;
    line-height: 1.1;
    color: var(--c-text);
    text-shadow:
        0 0 18px rgba(245, 165, 36, .26),
        0 0 46px rgba(245, 165, 36, .14);
}
.lg-sub[b-lae1jk2ohf] {
    font-size: .82rem;
    font-weight: 500;
    color: var(--c-text-dim);
    margin-top: 3px;
}

/* ---------------------------------------------------------------------------------------------
   Form.
   --------------------------------------------------------------------------------------------- */
.lg-err[b-lae1jk2ohf] {
    background: color-mix(in srgb, var(--c-stop) 13%, var(--c-s2));
    border: 1px solid color-mix(in srgb, var(--c-stop) 40%, transparent);
    color: var(--c-stop-text);
    padding: 12px 14px;
    border-radius: var(--r-sm);
    font-size: .86rem;
    font-weight: 600;
    line-height: 1.45;
}

.lg-fld[b-lae1jk2ohf] { display: flex; flex-direction: column; gap: 7px; }
.lg-fld > span[b-lae1jk2ohf] {
    font-size: .74rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: var(--track-label);
    color: var(--c-text-faint);
}

/* ::deep IS LOAD-BEARING, AND THIS RULE HAS NEVER WORKED WITHOUT IT.

   The fields are <InputText>, a component, not a bare <input>. Blazor's CSS isolation stamps its
   scope attribute onto elements THIS component renders directly; markup rendered by a child
   component never gets it. So a plain `.lg-in { … }` compiles to `.lg-in[b-xxx]`, the actual
   <input> InputText emits carries no b-xxx, and the rule matches nothing at all. It fails
   silently — the class is on the element, the CSS is in the bundle, and the field just renders
   with browser defaults.

   That was true of the original stylesheet too: these fields have been unstyled since the page
   was written. ::deep drops the scope requirement for everything below .lg-fld, which is what
   lets the rule reach into InputText's output.

   Solid, not glass, for the usual reason: a translucent field inside a translucent card over a
   gradient has no stable contrast, and this is where a password gets typed. */
.lg-fld[b-lae1jk2ohf]  .lg-in {
    min-height: 42px;
    border: 1px solid var(--glass-line-hi);
    border-radius: var(--r-sm);
    padding: 0 14px;
    font-family: var(--font);
    font-size: .95rem;
    background: var(--c-s2);
    color: var(--c-text);
    width: 100%;
    transition: border-color .15s ease, box-shadow .15s ease;
}
.lg-fld[b-lae1jk2ohf]  .lg-in:focus {
    outline: none;
    border-color: var(--c-accent);
    box-shadow: 0 0 0 3px var(--c-accent-wash);
}
.lg-fld[b-lae1jk2ohf]  .lg-in::placeholder { color: var(--c-text-faint); }

/* ---- Keep me signed in ----
   The whole row is the label, so the words are part of the target rather than something to aim
   past on the way to a 16px box — see the note on .lg-fld for why the fields above are 42px.

   ::deep for the same reason as the fields: the box is an <InputCheckbox>, a child component, so
   the scope attribute is never stamped on the <input> it renders and an unprefixed rule would
   match nothing while looking perfectly correct. */
.lg-check[b-lae1jk2ohf] {
    display: flex;
    align-items: flex-start;
    gap: 11px;
    margin-top: 2px;
    padding: 10px 12px;
    border: 1px solid var(--glass-line);
    border-radius: var(--r-sm);
    background: var(--c-s2);
    cursor: pointer;
    transition: border-color .15s ease, background-color .15s ease;
}

.lg-check:hover[b-lae1jk2ohf] { border-color: var(--glass-line-hi); }

.lg-check[b-lae1jk2ohf]  input[type="checkbox"] {
    /* 18px and pushed down a hair so it sits on the first line's optical centre rather than its
       box top, which at this line-height reads as misaligned. */
    width: 18px;
    height: 18px;
    margin: 2px 0 0;
    flex: 0 0 auto;
    cursor: pointer;
    accent-color: var(--c-accent);
}

.lg-check > span[b-lae1jk2ohf] {
    display: flex;
    flex-direction: column;
    gap: 2px;
    font-size: .88rem;
    font-weight: 600;
    color: var(--c-text);
    line-height: 1.35;
}

/* The consequence, in the operator's terms. A bare "Keep me signed in" is a promise with no
   stated limit, and on a screen that guards takings and staff records the limit is the part worth
   reading — it is also the honest answer to "for how long?", which is the first thing anybody
   sensible asks of a box like this. */
.lg-check small[b-lae1jk2ohf] {
    font-size: .76rem;
    font-weight: 500;
    color: var(--c-text-faint);
    line-height: 1.4;
}

/* Saffron here, unlike the back-office screens where the primary is ink.

   The argument against saffron there was that a settings page is calm data entry and a saffron
   slab in the footer reads as an alert. This is the opposite situation: one card, one action,
   nothing else on the screen to compete with. Saffron is doing exactly what it is for — naming
   the single thing to act on — and it ties the button to the mark at the top of the card. */
.lg-btn[b-lae1jk2ohf] {
    margin-top: 6px;
    min-height: 44px;
    border: 1px solid var(--c-accent);
    border-radius: var(--r-sm);
    padding: 0 18px;
    font-family: var(--font);
    font-size: .95rem;
    font-weight: 700;
    letter-spacing: var(--track-tight);
    cursor: pointer;
    background: var(--c-accent);
    color: var(--c-accent-ink);
    box-shadow: 0 6px 18px -6px rgba(245, 165, 36, .5);
    transition: background-color .15s ease, transform .08s ease;
}
.lg-btn:hover[b-lae1jk2ohf] { background: var(--c-accent-press); border-color: var(--c-accent-press); }
.lg-btn:active[b-lae1jk2ohf] { transform: translateY(1px); }

.lg-note[b-lae1jk2ohf] {
    margin: 6px 0 0;
    color: var(--c-text-faint);
    font-size: .78rem;
    line-height: 1.55;
}

.lg-ver[b-lae1jk2ohf] {
    margin: 14px 0 0;
    text-align: center;
    color: var(--c-text-faint);
    font-size: .72rem;
    opacity: .75;
}
/* _content/AdvDeli.WebOffice/Components/Pages/ModifierGroups.razor.rz.scp.css */
.mg[b-se21bpbb2a] { max-width: 1240px; margin: 0 auto; padding: 8px 4px; color: #1f2733; }

.mg-err[b-se21bpbb2a] { background: #fbe4e2; border: 1px solid #e6a9a3; color: #8a1f18; padding: 9px 12px;
    border-radius: 8px; font-size: .85rem; margin: 0 6px 14px; }

/* Three panes that narrow together: classes and groups are short lists, options is a table. */
.mg-cols[b-se21bpbb2a] { display: grid; grid-template-columns: 1fr 1fr 1.6fr; gap: 16px; align-items: start; }
@media (max-width: 1000px) { .mg-cols[b-se21bpbb2a] { grid-template-columns: 1fr; } }

.mg-col[b-se21bpbb2a] { background: #fff; border: 1px solid #e4e9f0; border-radius: 14px; overflow: hidden;
    box-shadow: 0 1px 3px rgba(20, 30, 50, .05), 0 12px 30px rgba(20, 30, 50, .04); }
.mg-colhd[b-se21bpbb2a] { display: flex; align-items: center; justify-content: space-between; gap: 10px;
    padding: 12px 14px; border-bottom: 1px solid #e4e9f0; background: #f7f9fc; }
.mg-colhd h3[b-se21bpbb2a] { margin: 0; font-size: .95rem; font-weight: 800; }

.mg-add[b-se21bpbb2a] { border: 1px solid #4f5bd5; background: #4f5bd5; color: #fff; border-radius: 8px;
    padding: 5px 12px; font-size: .82rem; font-weight: 700; cursor: pointer; }
.mg-add:disabled[b-se21bpbb2a] { opacity: .45; cursor: default; }
.mg-add.sm[b-se21bpbb2a] { padding: 3px 10px; font-size: .78rem; }

.mg-state[b-se21bpbb2a] { padding: 26px 14px; color: #8a94a2; font-size: .88rem; font-style: italic; }

.mg-list[b-se21bpbb2a] { list-style: none; margin: 0; padding: 6px; display: flex; flex-direction: column; gap: 4px; }
/* minmax(0, 1fr), not 1fr: a 1fr track's automatic minimum is its content's min-content width,
   and an unbroken name ("Chicken-Tikka-Masala-Extra…") has no break opportunity, so the track
   refuses to shrink. The row then outgrows the card and .mg-col's overflow:hidden clips the
   Edit button clean off the screen. minmax(0, …) lets the track shrink so the text can ellipse. */
.mg-list li[b-se21bpbb2a] { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: 4px 10px;
    padding: 9px 11px; border-radius: 9px; cursor: pointer; border: 1px solid transparent; }
.mg-list li:hover[b-se21bpbb2a] { background: #f5f8ff; }
.mg-list li.on[b-se21bpbb2a] { background: #edf0fe; border-color: #c6ccf7; }
/* One line each, ellipsed. min-width:0 is required as well as overflow:hidden — these are grid
   items, and their own automatic minimum would otherwise keep them at full width. */
.mg-nm[b-se21bpbb2a], .mg-sub[b-se21bpbb2a], .mg-off[b-se21bpbb2a] { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mg-nm[b-se21bpbb2a] { font-size: .9rem; font-weight: 650; color: #24313f; }
.mg-sub[b-se21bpbb2a] { grid-column: 1; font-size: .76rem; color: #8a94a2; }
.mg-off[b-se21bpbb2a] { grid-column: 1; font-size: .72rem; color: #b5651d; font-weight: 700; text-transform: uppercase; }

/* nowrap so a squeezed row never breaks the caption to "Ed / it"; the button keeps its natural
   width and the name column gives way instead. */
.mg-edit[b-se21bpbb2a], .mg-del[b-se21bpbb2a] { grid-column: 2; grid-row: 1 / span 2; border: 1px solid #d7dfe9; background: #fff;
    border-radius: 7px; padding: 4px 10px; font-size: .78rem; font-weight: 600; cursor: pointer; color: #55636f;
    white-space: nowrap; }
.mg-edit:hover[b-se21bpbb2a] { border-color: #4f5bd5; color: #4f5bd5; }
.mg-del[b-se21bpbb2a] { color: #b3261e; }
.mg-del:hover[b-se21bpbb2a] { border-color: #b3261e; }

/* table-layout:fixed so one long option name can't widen the table past the card, which
   overflow:hidden would then clip the Edit/Remove buttons out of reach. */
.mg-tbl[b-se21bpbb2a] { width: 100%; border-collapse: collapse; font-size: .88rem; table-layout: fixed; }
.mg-tbl thead th[b-se21bpbb2a] { text-align: left; background: #f7f9fc; color: #55636f; font-weight: 700;
    font-size: .72rem; text-transform: uppercase; letter-spacing: .5px; padding: 10px 12px;
    border-bottom: 1px solid #e4e9f0; }
.mg-tbl thead th.num[b-se21bpbb2a], .mg-tbl tbody td.num[b-se21bpbb2a] { text-align: right; }
/* Fixed layout splits columns evenly unless told otherwise, which would starve the option name.
   Pin the narrow columns; the first (unset) column absorbs whatever is left. */
.mg-tbl thead th.num[b-se21bpbb2a] { width: 88px; }
.mg-tbl thead th:nth-child(4)[b-se21bpbb2a] { width: 84px; }
.mg-tbl thead th:last-child[b-se21bpbb2a] { width: 148px; }
.mg-tbl tbody td[b-se21bpbb2a] { padding: 9px 12px; border-bottom: 1px solid #eef1f6; }
.mg-tbl tbody td:first-child[b-se21bpbb2a] { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mg-tbl tbody tr:last-child td[b-se21bpbb2a] { border-bottom: none; }
.mg-tbl td.act[b-se21bpbb2a] { text-align: right; white-space: nowrap; display: flex; gap: 6px; justify-content: flex-end; }
.mg-tbl td.act button[b-se21bpbb2a] { position: static; }

.mg-pick[b-se21bpbb2a] { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 5px;
    max-height: 340px; overflow-y: auto; }
/* Same minmax(0, …) reason as .mg-list li — this list carries item names too. */
.mg-pick li[b-se21bpbb2a] { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: 2px 10px;
    padding: 8px 10px; background: #f6f8fc; border: 1px solid #e6ecf3; border-radius: 9px; }
.mg-pick .mg-sub[b-se21bpbb2a] { grid-column: 1; }
.mg-pick button[b-se21bpbb2a] { grid-column: 2; grid-row: 1 / span 2; }
/* _content/AdvDeli.WebOffice/Components/Pages/OrderItemStatuses.razor.rz.scp.css */
/* The status list.

   Scoped rather than added to app.css: the `mg-` button classes this page uses are themselves
   scoped to ModifierGroups, so without local copies the buttons here would render as bare browser
   controls. Defining them beside the markup that uses them keeps the page whole, and does not
   change any other page.

   The list is the control, not a table. Order is half a status's meaning here — it is the sequence
   the kitchen walks — so the row shows its position, and moving one is a tap on the row rather
   than a number typed into a dialog. */

.oi-list[b-15uyf0khwx] {
    list-style: none;
    margin: 4px 6px 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.oi-row[b-15uyf0khwx] {
    display: flex;
    align-items: center;
    gap: 12px;
    background: #fff;
    border: 1px solid #e6ecf3;
    border-radius: 11px;
    padding: 11px 14px;

    /* The status's own colour, along the leading edge. A chef reads this colour on the kitchen
       card, so the person choosing it should see the same thing, not a swatch in a dialog. */
    border-left: 5px solid var(--oi-color, #64748b);
}

/* Retired: still listed, because lines that already reached it must keep rendering under its real
   name — but visibly not part of the live sequence. */
.oi-row.off[b-15uyf0khwx] { opacity: .55; background: #f7f9fc; }

.oi-seq[b-15uyf0khwx] {
    flex: none;
    width: 24px; height: 24px;
    border-radius: 50%;
    background: #4f5bd5; color: #fff;
    display: grid; place-items: center;
    font-size: .74rem; font-weight: 800;
    font-variant-numeric: tabular-nums;
}

.oi-dot[b-15uyf0khwx] {
    flex: none;
    width: 12px; height: 12px;
    border-radius: 50%;
    background: var(--oi-color, #64748b);
}

.oi-id[b-15uyf0khwx] { flex: 1; min-width: 0; }

.oi-name[b-15uyf0khwx] {
    display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
    font-size: .96rem; font-weight: 650; color: #1f2733;
}

.oi-sub[b-15uyf0khwx] {
    display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
    margin-top: 3px;
    font-size: .78rem; color: #8a94a2;
}

.oi-code[b-15uyf0khwx] { font-weight: 700; letter-spacing: .02em; }

.oi-role[b-15uyf0khwx] { color: #5c6674; }

.oi-chip[b-15uyf0khwx] {
    background: #eef2f6; color: #5c6674;
    border-radius: 20px; padding: 1px 9px;
    font-size: .7rem; font-weight: 700;
    text-transform: lowercase;
}

/* The predefined marker. Amber rather than grey: it is the one chip on the row that changes what
   the buttons beside it will do. */
.oi-chip.lock[b-15uyf0khwx] { background: #fdf3e3; color: #8a5a12; }

.oi-acts[b-15uyf0khwx] { display: flex; align-items: center; gap: 6px; flex: none; }

.mg-add[b-15uyf0khwx] {
    border: 1px solid #4f5bd5; background: #4f5bd5; color: #fff;
    border-radius: 8px; padding: 7px 14px;
    font-size: .85rem; font-weight: 650; cursor: pointer;
}

.mg-add:disabled[b-15uyf0khwx] { opacity: .45; cursor: default; }

.mg-edit[b-15uyf0khwx], .mg-del[b-15uyf0khwx] {
    border: 1px solid #d7dfe9; background: #fff; color: #3d4756;
    border-radius: 8px; padding: 6px 12px;
    font-size: .82rem; font-weight: 600; cursor: pointer;
}

.mg-edit:hover:not(:disabled)[b-15uyf0khwx] { border-color: #4f5bd5; color: #4f5bd5; }
.mg-del[b-15uyf0khwx] { color: #b3261e; }
.mg-del:hover:not(:disabled)[b-15uyf0khwx] { border-color: #b3261e; }

/* Disabled is the ordinary state of Delete on this page — five of the rows can never be removed —
   so it has to read as "not available here" rather than as a control that failed. */
.mg-edit:disabled[b-15uyf0khwx], .mg-del:disabled[b-15uyf0khwx] { opacity: .4; cursor: not-allowed; }

@media (max-width: 720px) {
    .oi-row[b-15uyf0khwx] { flex-wrap: wrap; }
    .oi-acts[b-15uyf0khwx] { width: 100%; justify-content: flex-end; }
}
/* _content/AdvDeli.WebOffice/Components/Pages/Roles.razor.rz.scp.css */
/* =========================================================
Permission Dialog
========================================================= */

.permission-dialog[b-zgszr39yzl] {
    display: flex;
    flex-direction: column;
    gap: 16px;
}

/* ---------- Summary ---------- */

.permission-summary[b-zgszr39yzl] {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 16px;
    border: 1px solid #e5e7eb;
    border-radius: 12px;
    background: #f8fafc;
}

.permission-summary-icon[b-zgszr39yzl] {
    width: 42px;
    height: 42px;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 10px;
    background: #e8f0fe;
    font-size: 20px;
}

.permission-summary-content[b-zgszr39yzl] {
    flex: 1;
    min-width: 0;
}

.permission-summary-title[b-zgszr39yzl] {
    font-size: 15px;
    font-weight: 700;
    color: #1f2937;
    margin-bottom: 3px;
}

.permission-summary-text[b-zgszr39yzl] {
    font-size: 13px;
    line-height: 1.45;
    color: #6b7280;
}

.permission-summary-count[b-zgszr39yzl] {
    min-width: 65px;
    text-align: center;
    padding-left: 14px;
    border-left: 1px solid #e5e7eb;
}

    .permission-summary-count strong[b-zgszr39yzl] {
        display: block;
        font-size: 20px;
        line-height: 1.1;
        color: #2563eb;
    }

    .permission-summary-count span[b-zgszr39yzl] {
        font-size: 11px;
        color: #6b7280;
    }

/* ---------- Information ---------- */

.permission-info[b-zgszr39yzl] {
    display: flex;
    align-items: flex-start;
    gap: 9px;
    padding: 11px 13px;
    border-radius: 8px;
    background: #f1f5f9;
    color: #475569;
    font-size: 12px;
    line-height: 1.45;
}

.permission-info-icon[b-zgszr39yzl] {
    flex-shrink: 0;
    font-size: 15px;
    color: #64748b;
}

/* ---------- Modules ---------- */

/* auto-fill, not a fixed 2 columns. The dialog is now RefDialog.Wide (~1040px), which fits three
   of these; on a narrow laptop the same rule falls back to two and then one with no breakpoint
   needed. 280px is the width at which a module's longest permission name stops wrapping to three
   lines. */
.permission-modules[b-zgszr39yzl] {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: 14px;
    /* Groups are read down a column, so a tall STATION module beside a short ACCESS one should
       not stretch ACCESS to match it. */
    align-items: start;
}

.permission-module[b-zgszr39yzl] {
    overflow: hidden;
    border: 1px solid #e5e7eb;
    border-radius: 10px;
    background: #ffffff;
}

/* ---------- Module Header ---------- */

.permission-module-header[b-zgszr39yzl] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 12px 14px;
    border-bottom: 1px solid #e5e7eb;
    background: #f8fafc;
}

.permission-module-title[b-zgszr39yzl] {
    display: flex;
    align-items: center;
    gap: 10px;
    min-width: 0;
}

.permission-module-icon[b-zgszr39yzl] {
    width: 32px;
    height: 32px;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 8px;
    background: #eef2ff;
    font-size: 15px;
}

.permission-module-name[b-zgszr39yzl] {
    font-size: 13px;
    font-weight: 700;
    color: #1f2937;
}

.permission-module-subtitle[b-zgszr39yzl] {
    margin-top: 2px;
    font-size: 11px;
    color: #9ca3af;
}

.permission-module-actions[b-zgszr39yzl] {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-shrink: 0;
}

.permission-selected-count[b-zgszr39yzl] {
    font-size: 11px;
    font-weight: 600;
    color: #64748b;
}

.permission-select-btn[b-zgszr39yzl] {
    border: 0;
    padding: 4px 8px;
    border-radius: 5px;
    background: transparent;
    color: #2563eb;
    font-size: 11px;
    font-weight: 600;
    cursor: pointer;
}

    .permission-select-btn:hover[b-zgszr39yzl] {
        background: #e8f0fe;
    }

/* ---------- Permission Rows ---------- */

.permission-list[b-zgszr39yzl] {
    display: flex;
    flex-direction: column;
}

.permission-item[b-zgszr39yzl] {
    position: relative;
    display: flex;
    align-items: center;
    gap: 10px;
    min-height: 54px;
    padding: 8px 12px;
    border-bottom: 1px solid #f1f5f9;
    cursor: pointer;
    transition: background 0.12s ease;
}

    .permission-item:last-child[b-zgszr39yzl] {
        border-bottom: 0;
    }

    .permission-item:hover[b-zgszr39yzl] {
        background: #f8fafc;
    }

    .permission-item.selected[b-zgszr39yzl] {
        background: #f8fbff;
    }

    .permission-item input[b-zgszr39yzl] {
        position: absolute;
        opacity: 0;
        pointer-events: none;
    }

/* ---------- Custom Checkbox ---------- */

.permission-check[b-zgszr39yzl] {
    width: 19px;
    height: 19px;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 1.5px solid #cbd5e1;
    border-radius: 5px;
    background: #ffffff;
    color: #ffffff;
    font-size: 12px;
    font-weight: 700;
}

.permission-item.selected .permission-check[b-zgszr39yzl] {
    border-color: #2563eb;
    background: #2563eb;
}

/* ---------- Permission Details ---------- */

.permission-details[b-zgszr39yzl] {
    display: flex;
    flex-direction: column;
    gap: 3px;
    min-width: 0;
}

.permission-name[b-zgszr39yzl] {
    font-size: 13px;
    font-weight: 600;
    color: #334155;
}

.permission-code[b-zgszr39yzl] {
    width: fit-content;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    padding: 2px 6px;
    border-radius: 4px;
    background: #f1f5f9;
    color: #64748b;
    font-family: Consolas, "Courier New", monospace;
    font-size: 10px;
}

.permission-item.selected .permission-code[b-zgszr39yzl] {
    background: #e8f0fe;
    color: #2563eb;
}

/* ---------- Empty State ---------- */

.permission-empty[b-zgszr39yzl] {
    padding: 40px 20px;
    text-align: center;
    border: 1px dashed #cbd5e1;
    border-radius: 10px;
    background: #f8fafc;
}

.permission-empty-icon[b-zgszr39yzl] {
    font-size: 28px;
    margin-bottom: 8px;
}

.permission-empty-title[b-zgszr39yzl] {
    font-size: 14px;
    font-weight: 700;
    color: #334155;
}

.permission-empty-text[b-zgszr39yzl] {
    margin-top: 4px;
    font-size: 12px;
    color: #64748b;
}

/* ---------- The master's role ----------
   Every box ticked and disabled. Muted rather than greyed to unreadability: the point is that
   somebody can READ the full list of what the support account holds, not that the list is
   unavailable. cursor: default because the label is no longer a control. */
.permission-item.locked[b-zgszr39yzl] {
    cursor: default;
    opacity: .82;
}

.permission-item.locked input[type=checkbox][b-zgszr39yzl] {
    cursor: default;
}

.permission-info.master[b-zgszr39yzl] {
    border-color: #c9a227;
    background: #fffaeb;
    color: #6b5312;
}

/* ---------- Responsive ---------- */

@media (max-width: 850px) {
    .permission-modules[b-zgszr39yzl] {
        grid-template-columns: 1fr;
    }
}

/* THE TWO ``` FENCES THAT USED TO BE IN THIS BLOCK WERE MARKDOWN, pasted in with the rules and
   never noticed. They are a parse error: the browser discarded everything from the first fence to
   the end of the block, so none of these four rules had ever applied and the dialog had no narrow
   layout at all. Removed 2026-08-26. */
@media (max-width: 550px) {
    .permission-summary[b-zgszr39yzl] {
        align-items: flex-start;
    }

    .permission-summary-count[b-zgszr39yzl] {
        display: none;
    }

    .permission-module-header[b-zgszr39yzl] {
        align-items: flex-start;
    }

    .permission-module-actions[b-zgszr39yzl] {
        flex-direction: column;
        align-items: flex-end;
        gap: 2px;
    }
}
/* _content/AdvDeli.WebOffice/Components/Pages/SwitchStore.razor.rz.scp.css */
.sw[b-bngxw7hly0] { min-height: 100vh; display: grid; place-items: center; padding: 24px; background: #f2f5f9; }
.sw-card[b-bngxw7hly0] { width: min(460px, 100%); background: #fff; border: 1px solid #e4e9f0; border-radius: 16px;
    padding: 28px; box-shadow: 0 16px 44px rgba(20, 30, 50, .12); display: flex; flex-direction: column; gap: 16px; }
.sw-card h1[b-bngxw7hly0] { font-size: 1.3rem; margin: 0; color: #1f2733; }
.sw-lead[b-bngxw7hly0] { margin: 0; color: #64707e; font-size: .9rem; line-height: 1.6; }

.sw-err[b-bngxw7hly0] { background: #fbe4e2; border: 1px solid #e6a9a3; color: #8a1f18;
    padding: 10px 12px; border-radius: 9px; font-size: .85rem; font-weight: 600; }
.sw-empty[b-bngxw7hly0] { background: #fdf3e3; border: 1px solid #e8d3a8; color: #8a5a12;
    padding: 12px 14px; border-radius: 9px; font-size: .88rem; line-height: 1.55; }

.sw-list[b-bngxw7hly0] { display: flex; flex-direction: column; gap: 8px; max-height: 46vh; overflow-y: auto; }
.sw-opt[b-bngxw7hly0] { position: relative; display: grid; grid-template-columns: 1fr auto; align-items: center;
    gap: 2px 10px; border: 1px solid #d6dce6; border-radius: 10px; padding: 11px 13px; cursor: pointer; }
.sw-opt:hover[b-bngxw7hly0] { background: #f5f8ff; }

/* Selection is drawn from the radio itself, so the card responds to the click immediately.
   The page is statically rendered — there is no circuit to re-render it — so a class decided
   on the server only catches up after the post. */
.sw-opt:has(input:checked)[b-bngxw7hly0] { border-color: #4f5bd5; background: #edf0fe; }

/* Hidden without being removed: display:none takes the radio out of the tab order too, which
   left the keyboard unable to choose a store at all. Off-screen and zero-sized it still takes
   focus and still answers the arrow keys. */
.sw-opt input[b-bngxw7hly0] { position: absolute; width: 1px; height: 1px; opacity: 0; margin: 0; }

/* And since nothing visible has the focus, the card has to show it. */
.sw-opt:has(input:focus-visible)[b-bngxw7hly0] { outline: 2px solid #4f5bd5; outline-offset: 2px; }
.sw-opt-nm[b-bngxw7hly0] { font-size: .94rem; font-weight: 650; color: #24313f; }
.sw-opt-cd[b-bngxw7hly0] { grid-column: 1; font-size: .76rem; color: #8a94a2; font-weight: 700; }
.sw-cur[b-bngxw7hly0] { grid-column: 2; grid-row: 1 / span 2; font-size: .68rem; font-weight: 800; color: #2f9e44;
    background: #e6f4ea; border-radius: 999px; padding: 2px 9px; text-transform: uppercase; }

.sw-acts[b-bngxw7hly0] { display: flex; justify-content: flex-end; gap: 10px; }
.sw-btn[b-bngxw7hly0] { border-radius: 10px; padding: 10px 18px; font-weight: 700; font-size: .9rem;
    cursor: pointer; text-decoration: none; display: inline-block; border: 1px solid #d6dce6; background: #fff; color: #1f2733; }
.sw-btn.primary[b-bngxw7hly0] { background: #4f5bd5; border-color: #4f5bd5; color: #fff; }
.sw-btn.primary:disabled[b-bngxw7hly0] { opacity: .5; cursor: default; }
.sw-btn.ghost:hover[b-bngxw7hly0] { background: #f1f4f9; }
/* _content/AdvDeli.WebOffice/Components/Reports/ReportPaper.razor.rz.scp.css */
/* =================================================================================================
   THE PAPER. A4 sheets on screen that print as themselves.

   ONE SET OF RULES FOR BOTH MEDIA, which is the point. The screen rules give the sheet its real
   printed proportions and the print block only strips the things that exist to make it look like
   paper — the shadow, the grey desk behind it, the page gaps. Anything that changed the LAYOUT
   between the two would make the preview a drawing of a report rather than the report.
   ================================================================================================= */

.paper-stack[b-icxmsbcn5b] {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 18px;
    padding: 18px 0 28px;
    /* The desk the sheets lie on. Neutral and slightly darker than the app so white paper reads as
       paper rather than as another panel. */
    background: var(--bo-surface-sunk, #eceef1);
    border-radius: 8px;
}

/* 210mm is A4. Stated in millimetres rather than pixels because that is what it IS — the browser
   converts for the screen and uses it directly when printing, so the column widths a report is
   designed against are the ones it gets on paper.

   min-height, not height: a sheet with a wrapped row grows rather than clipping the row. */
.sheet[b-icxmsbcn5b] {
    width: 210mm;
    min-height: 297mm;
    box-sizing: border-box;
    padding: 14mm 12mm 12mm;
    background: #fff;
    color: #111;
    box-shadow: 0 2px 14px rgba(0, 0, 0, .16);
    display: flex;
    flex-direction: column;
    /* Paper is paper in both themes. The Back Office may be dark; a preview that inverts is a
       preview of something that will never come out of a printer. */
    color-scheme: light;
    font-family: "Segoe UI", system-ui, -apple-system, sans-serif;
    font-size: 9.5pt;
    line-height: 1.35;
}

/* ---- running head ---- */
.sheet-head[b-icxmsbcn5b] {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 12mm;
    padding-bottom: 3mm;
    border-bottom: 1.5pt solid #111;
    flex: 0 0 auto;
}

.sheet-org[b-icxmsbcn5b] {
    font-size: 8pt;
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: #555;
}

.sheet-title[b-icxmsbcn5b] { font-size: 16pt; font-weight: 700; margin: 1mm 0 0; letter-spacing: -.01em; }
.sheet-sub[b-icxmsbcn5b] { font-size: 9pt; color: #444; margin-top: 1mm; }

/* The applied filters, right-aligned against the title. Small and stacked: this is the block
   somebody checks BEFORE reading the figures, and a column of short lines is scanned faster than
   a paragraph of them. */
.sheet-head-r[b-icxmsbcn5b] {
    text-align: right;
    font-size: 8pt;
    color: #333;
    max-width: 78mm;
}
.sheet-filter[b-icxmsbcn5b] { padding: .3mm 0; }

/* ---- body ---- */
.sheet-body[b-icxmsbcn5b] { flex: 1 1 auto; padding-top: 4mm; }

.sheet-sec[b-icxmsbcn5b] {
    font-size: 10.5pt;
    font-weight: 700;
    margin: 5mm 0 2mm;
    padding-bottom: 1mm;
    border-bottom: .75pt solid #bbb;
}
.sheet-sec:first-child[b-icxmsbcn5b] { margin-top: 0; }
.sheet-sec.cont[b-icxmsbcn5b] { color: #555; font-weight: 600; }
.sheet-sec.cont span[b-icxmsbcn5b] { font-weight: 400; font-style: italic; }

.sheet-empty[b-icxmsbcn5b] { color: #666; font-style: italic; padding: 20mm 0; text-align: center; }

.sheet-tbl[b-icxmsbcn5b] {
    width: 100%;
    border-collapse: collapse;
    /* fixed, so a long item name cannot widen its column and push the money columns out of
       alignment with the same report printed yesterday. */
    table-layout: auto;
}

.sheet-tbl th[b-icxmsbcn5b] {
    font-size: 8pt;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: #333;
    border-bottom: .75pt solid #444;
    padding: 1.6mm 2mm;
    white-space: nowrap;
}

.sheet-tbl td[b-icxmsbcn5b] {
    padding: 1.4mm 2mm;
    border-bottom: .25pt solid #ddd;
    vertical-align: top;
}

/* Figures right, words left. A column of money can only be read down if the units digits line up,
   and tabular-nums stops a 1 being narrower than a 7 and breaking that alignment. */
.sheet-tbl .r[b-icxmsbcn5b] { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.sheet-tbl .c[b-icxmsbcn5b] { text-align: center; }
.sheet-tbl .l[b-icxmsbcn5b] { text-align: left; }

.sheet-tbl tr.tot td[b-icxmsbcn5b] {
    font-weight: 700;
    border-top: .75pt solid #444;
    border-bottom: none;
    background: #f4f4f6;
}

/* ---- the fixed-width block ----------------------------------------------
   For the Shift Report, which reproduces the roll the till prints at close of shift rather than a
   table. The lines arrive already composed to 48 characters, so the only job here is not to
   disturb them: a monospace face, no wrapping, and no inherited text-indent or letter-spacing.

   CENTRED ON THE SHEET, not left-aligned. A 48-character roll is about half the width of A4, and
   against the left margin it reads as a table that failed to lay out. Centred, it reads as what it
   is — a receipt, reproduced.

   The size is in pt and deliberately small: 48 characters have to fit inside the sheet's text
   width at every zoom the preview is viewed at, and a monospace face at 9pt clears it with room. */
.sheet-pre[b-icxmsbcn5b] {
    font-family: "Cascadia Mono", "Consolas", "DejaVu Sans Mono", "Courier New", monospace;
    font-size: 9pt;
    line-height: 1.35;
    white-space: pre;
    margin: 0 auto;
    padding: 0;
    display: block;
    width: max-content;
    max-width: 100%;
    color: #111;
    /* Rules in the receipt are drawn with - and = characters, so tabular figures keep them and the
       amounts above them on the same grid. */
    font-variant-numeric: tabular-nums;
}

/* ---- running foot ---- */
.sheet-foot[b-icxmsbcn5b] {
    flex: 0 0 auto;
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 8mm;
    margin-top: 4mm;
    padding-top: 2mm;
    border-top: .5pt solid #bbb;
    font-size: 7.5pt;
    color: #666;
}
.sheet-pg[b-icxmsbcn5b] { white-space: nowrap; font-weight: 600; }

/* =================================================================================================
   PRINT

   Only the paper survives. The application shell is hidden by a global rule in app.css — it has to
   be global because the things to hide (the sidebar, the top bar) belong to the layout, and a
   scoped stylesheet cannot reach them.
   ================================================================================================= */
/* =============================================================================================
   PHONE — the one screen that is deliberately NOT reflowed.

   .sheet is 210mm because it is A4, and those millimetres are what comes out of the printer. Two
   things could be done on a phone and both are worse than panning:

     — Reflow it. This is a preview of a document; a preview that does not match the paper is not
       a preview. The monospace fragments say it outright: "the alignment IS the layout".
     — Scale it to fit. 794px into 360px is 0.45, and 9.5pt body text becomes about 4pt. The whole
       page would be visible and none of it legible.

   So the sheet keeps its true geometry and the stack scrolls under it. Someone checking a report
   before printing it can pan; someone who wants to READ the figures on a phone has the report's
   own screen view, which is cards.
   ============================================================================================= */
@media (max-width: 860px) {
    .paper-stack[b-icxmsbcn5b] {
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
        padding: 10px;
        /* Without this the flex centring pins the sheet's left edge off-screen, and the start of
           every line is unreachable no matter how far you scroll. */
        justify-content: flex-start;
    }
}

@media print {
    .paper-stack[b-icxmsbcn5b] {
        display: block;
        gap: 0;
        padding: 0;
        background: none;
        border-radius: 0;
    }

    .sheet[b-icxmsbcn5b] {
        width: auto;              /* the sheet IS the page now; @page owns the size */
        min-height: 0;
        margin: 0;
        padding: 0;
        box-shadow: none;
        /* Every sheet but the last starts a new page. break-after on the last one would emit a
           trailing blank page, which is the classic print bug and the reason this is :not(:last). */
        break-inside: avoid;
    }

    .paper-stack .sheet:not(:last-child)[b-icxmsbcn5b] { break-after: page; }

    /* Ink, not screen grey — a shaded total row that prints as a solid block is worse than no
       shading at all on a mono printer. */
    .sheet-tbl tr.tot td[b-icxmsbcn5b] { background: none; border-top: 1pt solid #000; }

    .sheet-head[b-icxmsbcn5b] { border-bottom-color: #000; }
}

/* ---- LANDSCAPE ------------------------------------------------------------------------------
   A4 on its side: 297 wide by 210 tall. For the reports that carry more columns than a portrait
   sheet can hold without wrapping every row — the stock movement detail, whose before/after pair
   adds two numeric columns to an already wide ledger.

   THE SCREEN HALF ONLY. The @page size is a document-level rule and cannot be set from a scoped
   stylesheet, so the print orientation is emitted by the page itself — see Reports.razor. This
   makes the PREVIEW the right shape, which is what makes the preview worth having. */
.paper-stack.landscape .sheet[b-icxmsbcn5b] {
    width: 297mm;
    min-height: 210mm;
}

/* The head's right-hand filter block is capped at 78mm to stop it crowding the title on a portrait
   sheet. There is 87mm more width here, so it can breathe — a landscape report is usually the one
   with the most filters applied. */
.paper-stack.landscape .sheet-head-r[b-icxmsbcn5b] { max-width: 120mm; }
/* _content/AdvDeli.WebOffice/Components/Shared/RefDialog.razor.rz.scp.css */
.rd-ov[b-hb76m7ph5r] { position: fixed; inset: 0; background: rgba(16, 24, 38, .45); display: grid; place-items: center;
    z-index: 60; padding: 20px; }
.rd[b-hb76m7ph5r] { width: min(460px, 96vw); max-height: 92vh; overflow: hidden; display: flex; flex-direction: column;
    background: #fff; border-radius: 16px; box-shadow: 0 24px 60px rgba(0, 0, 0, .4); }

/* See RefDialog.Wide. 1040px fits three permission-module columns at the widths the Roles screen
   asks for; below that its own grid falls back to two and then one, so this is a ceiling rather
   than a fixed size. max-height rises with it because the whole point is seeing more at once. */
.rd.wide[b-hb76m7ph5r] { width: min(1040px, 96vw); max-height: 94vh; }

.rd-head[b-hb76m7ph5r] { display: flex; align-items: center; justify-content: space-between; padding: 15px 18px;
    font-weight: 800; font-size: 1.05rem; color: #1f2733; border-bottom: 1px solid #e4e9f0;
    background: linear-gradient(180deg, #f8fafc, #f1f4f9); }
.rd-x[b-hb76m7ph5r] { border: 0; background: none; font-size: 1rem; color: #8a94a2; cursor: pointer; padding: 2px 4px; }
.rd-x:hover[b-hb76m7ph5r] { color: #1f2733; }

/* min-height: 0 is load-bearing, not tidying. A flex item defaults to min-height: auto, which
   refuses to shrink below its content — so overflow-y: auto never engages, and .rd (overflow:
   hidden) simply clips whatever does not fit. A long body such as the Roles permission list then
   has a section nobody can reach. */
.rd-body[b-hb76m7ph5r] { padding: 16px 18px; overflow-y: auto; min-height: 0; display: flex; flex-direction: column; gap: 12px; }

/* The second half of the same problem. A flex item shrinks by default, so when the body is a
   column and its content is taller than the dialog, every child squashes proportionally to fit
   instead of the body overflowing — and a child with overflow:hidden (the Roles permission
   modules) then clips its own rows. Nothing scrolls, because nothing overflows. Children keep
   their natural height; the body is the only thing allowed to scroll.

   THIS COMMENT USED TO CLOSE HERE, one line early. A comment-close sequence sat mid-sentence in
   the prose, and CSS honours the first one it meets: everything after it parsed as a selector,
   which then swallowed the rule below as its block. The rule was absent from the built stylesheet
   entirely — verified in the browser — so the squashing described above had been happening the
   whole time, and the fix written for it never ran.

   Do not write the close sequence inside this comment while describing it. Doing so reintroduces
   the fault verbatim, which is exactly what happened on the first attempt at this repair.

   ::deep is required for the same reason it is on the file inputs: these children come from
   @Body, a RenderFragment owned by the PAGE, so they carry the page's scope attribute and not
   this component's. Without it the rule compiles to ".rd-body > *[b-refdialog]" and matches
   nothing at all. */
.rd-body[b-hb76m7ph5r]  > * { flex-shrink: 0; }

/* Sticky so it cannot be scrolled away from the field it refers to. Negative margins cancel the
   body padding so it reads as a banner rather than a floating box. */
.rd-err[b-hb76m7ph5r] { position: sticky; top: -16px; z-index: 3; margin: -16px -18px 0; padding: 10px 18px;
    background: #fbe4e2; border-bottom: 1px solid #e6a9a3; color: #8a1f18; font-size: .85rem; font-weight: 600; }

.rd-foot[b-hb76m7ph5r] { display: flex; align-items: center; justify-content: flex-end; gap: 10px; padding: 13px 18px;
    border-top: 1px solid #e4e9f0; background: #f8fafc; }
.rd-btn[b-hb76m7ph5r] { border: 1px solid #d6dce6; background: #fff; border-radius: 10px; padding: 9px 18px;
    font-weight: 700; font-size: .9rem; cursor: pointer; color: #1f2733; }
.rd-btn.primary[b-hb76m7ph5r] { background: #4f5bd5; border-color: #4f5bd5; color: #fff; }
.rd-btn.primary:disabled[b-hb76m7ph5r] { opacity: .6; cursor: default; }
.rd-btn.ghost:hover[b-hb76m7ph5r] { background: #f1f4f9; }

/* =============================================================================================
   PHONE

   This is the entry form for all twenty-one reference screens, so it is the one dialog worth
   getting right at 360px.
   ============================================================================================= */

@media (max-width: 560px) {
    /* The overlay's 20px of padding cost 40px of a 360px screen before the dialog started. */
    .rd-ov[b-hb76m7ph5r] { padding: 0; place-items: end stretch; }

    /* A SHEET, not a floating card. Anchored to the bottom, full width, square along the bottom
       edge: it is the pattern a phone user already knows, the controls land under the thumb
       rather than in the middle of the screen, and it gives the form every available pixel.

       dvh rather than vh for the reason the nav drawer uses it — vh is the height with the URL
       bar hidden, so a 92vh sheet is taller than what you can actually see, and the footer with
       Save in it sits below the fold. */
    .rd[b-hb76m7ph5r], .rd.wide[b-hb76m7ph5r] {
        width: 100%;
        max-width: 100%;
        max-height: 92dvh;
        border-radius: 16px 16px 0 0;
    }

    /* The keyboard is the real constraint on a phone form: it takes half the screen, and every
       pixel of chrome above the fields is one the fields do not get. */
    .rd-head[b-hb76m7ph5r] { padding: 13px 14px; font-size: 1rem; }
    .rd-body[b-hb76m7ph5r] { padding: 14px; }
    .rd-err[b-hb76m7ph5r] { margin: -14px -14px 0; padding: 10px 14px; top: -14px; }

    /* Save on the right, both full-height and equally weighted. Two small buttons crowded into a
       corner is a miss-tap on the one that discards a filled-in form. */
    .rd-foot[b-hb76m7ph5r] { padding: 11px 14px; gap: 8px; }
    .rd-foot .rd-btn[b-hb76m7ph5r] { flex: 1 1 0; padding: 12px 10px; min-height: 46px; }

    /* Same reason as the shell: iOS zooms the page in when a focused input is under 16px, and a
       zoomed-in modal cannot be scrolled back into view. */
    .rd-body[b-hb76m7ph5r]  input,
    .rd-body[b-hb76m7ph5r]  select,
    .rd-body[b-hb76m7ph5r]  textarea { font-size: 16px; }
}
