/* /Components/Dialogs/CancellationReasonDialog.razor.rz.scp.css */
/* Matches the order form's dialog: the chrome comes from .rz-dialog in app.css, so only the body
   lives here. */

.cancellation-reason[b-w4vflf5p3f] { display: block; }

.cancellation-reason-heading[b-w4vflf5p3f] {
    margin: 0 0 10px;
    font-size: 17px;
    font-weight: 600;
    letter-spacing: -.01em;
    color: var(--agra-primary);
}

.cancellation-reason-body[b-w4vflf5p3f] {
    margin: 0 0 12px;
    font-size: .9rem;
    line-height: 1.5;
    color: var(--agra-text);
}

.cancellation-reason-input[b-w4vflf5p3f] {
    width: 100%;
    box-sizing: border-box;
    padding: 10px 12px;
    border-radius: 6px;
    border: 1px solid var(--agra-hairline);
    font-family: inherit;
    font-size: .9rem;
    color: var(--agra-text);
    resize: vertical;
}

.cancellation-reason-input:focus[b-w4vflf5p3f] {
    outline: none;
    border-color: var(--agra-accent);
}

.cancellation-reason-error[b-w4vflf5p3f] {
    margin: 6px 0 0;
    font-size: .8rem;
    color: #c0392b;
}

.cancellation-reason-actions[b-w4vflf5p3f] {
    display: flex;
    gap: 12px;
    margin-top: 4px;
    padding-top: 16px;
    border-top: 1px solid var(--agra-hairline);
}

.cancellation-reason-actions .agra-button[b-w4vflf5p3f] {
    flex: 1 1 0;
    min-width: 0;
    margin: 0;
    white-space: nowrap;
}

.cancellation-reason-cancel[b-w4vflf5p3f] {
    background: #fff;
    color: var(--agra-text);
    box-shadow: inset 0 0 0 1px var(--agra-hairline);
}

.cancellation-reason-cancel:hover[b-w4vflf5p3f] { background: var(--agra-surface); }

.cancellation-reason-submit[b-w4vflf5p3f] {
    background: var(--agra-accent);
    color: #fff;
}

.cancellation-reason-submit:hover[b-w4vflf5p3f] { filter: brightness(1.07); }
/* /Components/Dialogs/SmsConsentDialog.razor.rz.scp.css */
/* Matches the order form's dialog: the chrome comes from .rz-dialog in app.css, so only the body
   lives here. */

.sms-consent[b-7dij3mjmft] { display: block; }

.sms-consent-heading[b-7dij3mjmft] {
    margin: 0 0 10px;
    font-size: 17px;
    font-weight: 600;
    letter-spacing: -.01em;
    color: var(--agra-primary);
}

.sms-consent-body[b-7dij3mjmft] {
    margin: 0;
    font-size: .9rem;
    line-height: 1.5;
    color: var(--agra-text);
}

.sms-consent-number[b-7dij3mjmft] {
    margin: 12px 0 0;
    padding: 10px 12px;
    border-radius: 6px;
    background: var(--agra-surface);
    font-size: .9rem;
    color: var(--agra-text);
}

.sms-consent-actions[b-7dij3mjmft] {
    display: flex;
    gap: 12px;
    margin-top: 4px;
    padding-top: 16px;
    border-top: 1px solid var(--agra-hairline);
}

.sms-consent-actions .agra-button[b-7dij3mjmft] {
    flex: 1 1 0;
    min-width: 0;
    margin: 0;
    white-space: nowrap;
}

/* Declining is a real answer, not a way out of the dialog, so it is not made harder to pick than
   accepting — same size, same prominence, just unfilled. */
.sms-consent-decline[b-7dij3mjmft] {
    background: #fff;
    color: var(--agra-text);
    box-shadow: inset 0 0 0 1px var(--agra-hairline);
}

.sms-consent-decline:hover[b-7dij3mjmft] { background: var(--agra-surface); }

.sms-consent-accept[b-7dij3mjmft] {
    background: var(--agra-accent);
    color: #fff;
}

.sms-consent-accept:hover[b-7dij3mjmft] { filter: brightness(1.07); }
/* /Components/Dialogs/TankOrderDialog.razor.rz.scp.css */
/* The order form's own rules. The rows themselves are .agra-item from app.css — the same ion-item
   metrics the auth screens use — so only the dialog's layout lives here.
   Source: modals/tank-order-form/tank-order-form.component.html */

.order-form[b-o8sjqbxm2f] {
    /* DialogService draws the card and its padding, so this is the ion-card-content the legacy form
       put inside it, not the card. */
    display: block;
}

/* A section label under the title bar, not a second title — the bar above already says which tank's
   order form this is. */
.order-form-heading[b-o8sjqbxm2f] {
    margin: 0 0 14px;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--agra-text-muted);
}

/* Stacked rows are field groups now, so the ion-item hairline under each one just boxes them in. */
.order-form .agra-item-stacked[b-o8sjqbxm2f] {
    border-bottom: none;
    padding: 0 0 14px;
}

/* Radzen's inputs render their own markup, so the row gives them the slack rather than sizing them:
   an input narrower than its row leaves the underline of .agra-item running past it.

   ::deep throughout, because the class lands on the Radzen component's own root element, and a child
   component's root does not carry this component's scope attribute — a plain `.order-form-control`
   rule here would compile to a selector that never matches anything. */
.order-form[b-o8sjqbxm2f]  .order-form-control {
    flex: 1 1 auto;
    width: 100%;
    min-width: 0;
}

/* Item is fixed by the tank the customer tapped — there is no picker, and choosing the tank is what
   chose the item. So it is shaped like the fields above and below it, at the same height and radius,
   but filled and borderless: it reads as a value the form is telling you, not one it is asking for. */
.order-form-readonly[b-o8sjqbxm2f] {
    display: block;
    padding: 10px 12px;
    border: 1px solid transparent;
    border-radius: 6px;
    background: var(--agra-surface);
    color: var(--agra-text);
    font-size: 1rem;
    font-weight: 500;
    line-height: 1.4;
}

.order-form-error[b-o8sjqbxm2f] {
    margin: 8px 0 0;
    font-size: .85rem;
    line-height: 1.4;
    color: var(--agra-danger);
}

.order-form-warning[b-o8sjqbxm2f] {
    margin: 8px 0 0;
    font-size: .85rem;
    line-height: 1.4;
    color: var(--agra-text-muted);
}

/* The legacy form put Cancel on the left and the green + on the right, separated by <br/>s. Side by
   side here so both commit actions are reachable with one thumb at the bottom of a phone screen. */
.order-form-actions[b-o8sjqbxm2f] {
    display: flex;
    gap: 12px;
    margin-top: 4px;
    padding-top: 16px;
    border-top: 1px solid var(--agra-hairline);
}

.order-form-button[b-o8sjqbxm2f] {
    flex: 1 1 0;
}

/* Add finishes the action the card's orange + started, so it carries that accent rather than the
   legacy FAB's green. */
.order-form-add[b-o8sjqbxm2f] {
    background: var(--agra-accent);
    color: #fff;
}

.order-form-add:hover[b-o8sjqbxm2f] { filter: brightness(1.07); }

/* Cancel was the danger red, which reads as "delete something" rather than "close this form". It is
   the secondary action, so it recedes: a quiet outlined button beside the filled one. */
.order-form-cancel[b-o8sjqbxm2f] {
    background: #fff;
    color: var(--agra-text);
    box-shadow: inset 0 0 0 1px var(--agra-hairline);
}

.order-form-cancel:hover[b-o8sjqbxm2f] { background: var(--agra-surface); }

/* Every field renders as the same bordered box. Previously the date and quantity had their borders
   stripped so they could sit on the row's hairline, while the text box and textarea kept Radzen's —
   so half the form was underlined fields and half was boxed ones, and Radzen's focus treatment on
   the stripped ones showed up as a heavy blue slab with a rule under it. */
.order-form[b-o8sjqbxm2f]  .rz-datepicker,
.order-form[b-o8sjqbxm2f]  .rz-numeric,
.order-form[b-o8sjqbxm2f]  .rz-textbox,
.order-form[b-o8sjqbxm2f]  .rz-textarea {
    width: 100%;
}

.order-form[b-o8sjqbxm2f]  .rz-inputtext,
.order-form[b-o8sjqbxm2f]  .order-form-control input,
.order-form[b-o8sjqbxm2f]  .order-form-control textarea {
    width: 100%;
    box-sizing: border-box;
    padding: 10px 12px;
    border: 1px solid var(--agra-hairline);
    border-radius: 6px;
    background: #fff;
    color: var(--agra-text);
    font-family: inherit;
    /* 16px minimum: iOS Safari zooms the viewport for anything smaller, which inside a dialog leaves
       the customer looking at a form they cannot scroll back into view. */
    font-size: 1rem;
    box-shadow: none;
}

/* One focus treatment, in the app's own blue rather than Radzen's indigo. */
.order-form[b-o8sjqbxm2f]  .rz-inputtext:focus,
.order-form[b-o8sjqbxm2f]  .order-form-control input:focus,
.order-form[b-o8sjqbxm2f]  .order-form-control textarea:focus,
.order-form[b-o8sjqbxm2f]  .rz-state-focused .rz-inputtext {
    outline: none;
    border-color: var(--agra-primary);
    box-shadow: 0 0 0 3px rgb(43 87 154 / 16%);
}

/* The calendar button sits inside the field's border rather than drawing one of its own. */
.order-form[b-o8sjqbxm2f]  .rz-datepicker-trigger {
    background: none;
    border: none;
    color: var(--agra-text-muted);
}
/* /Components/Layout/MainLayout.razor.rz.scp.css */
#blazor-error-ui[b-hdwistlv8f] {
    color-scheme: light only;
    background: lightyellow;
    bottom: 0;
    box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
    box-sizing: border-box;
    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-hdwistlv8f] {
        cursor: pointer;
        position: absolute;
        right: 0.75rem;
        top: 0.5rem;
    }
/* /Components/Layout/ReconnectModal.razor.rz.scp.css */
/* Visibility is driven entirely by the state classes blazor.web.js puts on the dialog — leave this
   block alone unless the framework's contract changes. Everything below it is ours, and follows the
   Ionic-derived card/button metrics in wwwroot/app.css so the modal looks like the rest of the app. */
.components-reconnect-first-attempt-visible[b-sjon0l7wra],
.components-reconnect-repeated-attempt-visible[b-sjon0l7wra],
.components-reconnect-failed-visible[b-sjon0l7wra],
.components-pause-visible[b-sjon0l7wra],
.components-resume-failed-visible[b-sjon0l7wra],
.components-rejoining-animation[b-sjon0l7wra] {
    display: none;
}

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

/* ion-card metrics: 4px radius, Material elevation 1, and a width that still leaves a margin on a
   narrow phone rather than the template's fixed 20rem. */
#components-reconnect-modal[b-sjon0l7wra] {
    background-color: #fff;
    width: min(20rem, calc(100vw - 32px));
    margin: 18vh auto;
    padding: 24px;
    border: 0;
    border-radius: 4px;
    color: var(--agra-text);
    box-shadow: 0 3px 1px -2px rgb(0 0 0 / 20%),
                0 2px 2px 0 rgb(0 0 0 / 14%),
                0 1px 5px 0 rgb(0 0 0 / 12%);
    opacity: 0;
    transition: display 0.5s allow-discrete, overlay 0.5s allow-discrete;
    animation: components-reconnect-modal-fadeOutOpacity-b-sjon0l7wra 0.5s both;
}

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

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

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

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

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

    100% {
        opacity: 1;
    }
}

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

    100% {
        opacity: 0;
    }
}

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

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

/* ion-card-title's weight and size, so the modal reads as part of the same app. */
.agra-reconnect-title[b-sjon0l7wra] {
    font-size: 20px;
    font-weight: 500;
    line-height: 1.3;
}

/* The buttons carry .agra-button/.agra-button-primary from app.css; only the modal's own spacing
   needs saying here. An #id descendant rule would outrank those classes, so keep it to layout. */
#components-reconnect-modal button[b-sjon0l7wra] {
    margin-top: 8px;
}

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

    .components-rejoining-animation div[b-sjon0l7wra] {
        position: absolute;
        border: 3px solid var(--agra-primary);
        opacity: 1;
        border-radius: 50%;
        animation: components-rejoining-animation-b-sjon0l7wra 1.5s cubic-bezier(0, 0.2, 0.8, 1) infinite;
    }

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

@keyframes components-rejoining-animation-b-sjon0l7wra {
    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/Pages/OrderConfirm.razor.rz.scp.css */
/* --------------------------------------------------------------------------
   Order Cart (/order-confirm).

   Everything structural — the 48px .agra-item rows, the ion-item-divider, the
   uppercase block buttons — comes from app.css, which already reproduces
   Ionic's Material metrics. Only what is specific to this one page lives here.
   Source: order-confirmation/order-confirmation.component.html
           (its .scss is empty — the Ionic page added no styling of its own).
   -------------------------------------------------------------------------- */

/* ion-footer, fixed to the bottom of the viewport. This route is outside the tabbed shell
   (AgraMobileShellRoutes), exactly as order-confirmation was a top-level route rather than a child
   of tabs, so the bottom strip is this page's own — the tab bar is not drawn over it.

   fixed rather than sticky: sticky only pins once the content is tall enough to scroll, so a
   one-tank cart left the buttons floating halfway up the screen. The spacer in the markup gives back
   the height this takes out of flow — both read the same custom property so they cannot disagree. */
.cart-footer[b-jejlqcukl2],
.cart-footer-spacer[b-jejlqcukl2] {
    /* One 44px row, the strip's 8px top padding, and its border. */
    --cart-footer-height: calc(53px + max(8px, env(safe-area-inset-bottom)));
}

.cart-footer[b-jejlqcukl2] {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 20;
    padding: 8px 16px;
    /* Clears the iOS home indicator, which this page sits directly above — the tab bar used to carry
       that inset. Must follow the shorthand above. */
    padding-bottom: max(8px, env(safe-area-inset-bottom));
    background: #fff;
    border-top: 1px solid var(--agra-hairline);
    box-shadow: 0 -2px 8px rgb(0 0 0 / 8%);
    /* Side by side, sharing the width evenly. Stacked, the two filled bars took a third of a phone
       screen for two taps that are one decision. */
    display: flex;
    gap: 10px;
}

.cart-footer-spacer[b-jejlqcukl2] { height: var(--cart-footer-height); }

/* .agra-button is display:block with a 16px top margin, written for the stacked forms it came from;
   in a row it has to be a flex box of its own so the icon sits beside the label rather than above
   it, and it takes its rhythm from the strip. */
.cart-footer .agra-button[b-jejlqcukl2] {
    flex: 1 1 0;
    /* 0 lets a button shrink below its content on a narrow phone instead of widening the row. */
    min-width: 0;
    margin: 0;
    padding: 0 10px;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    /* The labels are two words each; wrapping them would make the row two lines tall. */
    white-space: nowrap;
}

.cart-button-icon[b-jejlqcukl2] {
    flex: 0 0 auto;
    /* The label is uppercase and optically sits high against a full-height glyph. */
    margin-top: -1px;
}

/* .agra-button carries a 16px top margin for the forms it was written for; the
   footer sets its own rhythm. */
.cart-footer .agra-button[b-jejlqcukl2] { margin-top: 8px; }

.cart-footer .agra-button:disabled[b-jejlqcukl2] { opacity: .6; cursor: default; }

/* The partial-failure notice. Tinted rather than solid danger: it is reporting a
   mixed outcome — some tanks went through — and a full red panel reads as "the
   whole thing failed". */
.cart-failures[b-jejlqcukl2] {
    margin: 0 0 16px;
    padding: 12px 16px;
    border-radius: 4px;
    border-left: 4px solid var(--agra-danger);
    background: rgb(235 68 90 / 8%);
}

.cart-failures-title[b-jejlqcukl2] {
    margin: 0 0 8px;
    font-size: 1rem;
    font-weight: 600;
    color: var(--agra-text);
}

.cart-failures-note[b-jejlqcukl2] {
    margin: 8px 0 0;
    font-size: .85rem;
    line-height: 1.45;
    color: var(--agra-text);
}

.cart-failures-list[b-jejlqcukl2] {
    margin: 0;
    padding-left: 18px;
    font-size: .9rem;
    line-height: 1.45;
}

.cart-failures-list li[b-jejlqcukl2] { margin-bottom: 6px; }

.cart-failures-list strong[b-jejlqcukl2] { display: block; }

/* The "Current Orders in Cart" line, as a section label rather than a heading — the same treatment
   the order form gives "Enter Order Details". */
.cart-list-header[b-jejlqcukl2] {
    margin: 6px 0 2px;
    /* Centred over the cards, which are a 30rem column centred in the page — left-aligned it sat
       against the viewport edge, yards from the content it labels on anything wider than a phone. */
    text-align: center;
    font-size: 13px;
    font-weight: 600;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--agra-text-muted);
}

/* --------------------------------------------------------------------------
   A tank's queued loads, in the three-column shape Order History uses for the
   orders those loads become. Date, tons, and the remove control.
   -------------------------------------------------------------------------- */
.cart-grid[b-jejlqcukl2] {
    display: grid;
    grid-template-columns: 1fr auto auto;
    /* stretch, so the rule between rows lands at the same height in every column. */
    align-items: stretch;
    column-gap: 10px;
}

.cart-grid-head[b-jejlqcukl2] {
    padding-bottom: 6px;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--agra-text-muted);
}

.cart-grid-head-tons[b-jejlqcukl2] { text-align: right; }

.cart-grid-date[b-jejlqcukl2],
.cart-grid-tons[b-jejlqcukl2],
.cart-grid-action[b-jejlqcukl2] {
    display: flex;
    align-items: center;
    padding: 4px 0;
    border-top: 1px solid var(--agra-hairline);
}

.cart-grid-date[b-jejlqcukl2] {
    font-size: .9rem;
    color: var(--agra-text);
}

.cart-grid-tons[b-jejlqcukl2] {
    justify-content: flex-end;
    font-size: .9rem;
    font-weight: 600;
    color: var(--agra-text);
    white-space: nowrap;
}

.cart-grid-action[b-jejlqcukl2] { justify-content: flex-end; }

/* One per row, so it recedes the way the cancellation control on Order History does. A column of
   filled red squares reads as a warning rather than as a set of controls. */
.cart-remove[b-jejlqcukl2] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    padding: 0;
    border: none;
    border-radius: 50%;
    background: none;
    color: var(--agra-danger);
    cursor: pointer;
}

.cart-remove:hover[b-jejlqcukl2] { background: rgb(235 68 90 / 12%); }

.cart-remove:focus-visible[b-jejlqcukl2] {
    outline: 2px solid var(--agra-danger);
    outline-offset: -2px;
}

.cart-remove:disabled[b-jejlqcukl2] { color: var(--agra-text-muted); cursor: default; background: none; }

/* Place Order finishes what the tank card's orange + started, so it carries that accent; Clear Cart
   is the way out, not the way forward, and recedes to an outline. */
.cart-place[b-jejlqcukl2] {
    background: var(--agra-accent);
    color: #fff;
}

.cart-place:hover[b-jejlqcukl2] { filter: brightness(1.07); }

.cart-clear[b-jejlqcukl2] {
    background: #fff;
    color: var(--agra-danger);
    box-shadow: inset 0 0 0 1px var(--agra-hairline);
}

.cart-clear:hover[b-jejlqcukl2] { background: rgb(235 68 90 / 8%); }

/* The order-level PO#, under the load count in the card's title block. */
.cart-po[b-jejlqcukl2] {
    margin: 2px 0 0;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: .02em;
    color: var(--agra-primary);
}

/* A load's note, spanning the grid under the row it belongs to. Indented and quieted: it is a
   qualifier on the line above, not another line. */
.cart-grid-memo[b-jejlqcukl2] {
    grid-column: 1 / -1;
    padding: 0 0 8px 12px;
    border-left: 2px solid var(--agra-hairline);
    margin-left: 2px;
    font-size: .82rem;
    line-height: 1.4;
    color: var(--agra-text-muted);
    overflow-wrap: anywhere;
}

/* --------------------------------------------------------------------------
   The totals card. Sits after the last tank, so the running total is the last
   thing read before the buttons that act on it.
   -------------------------------------------------------------------------- */
.cart-totals-row[b-jejlqcukl2] {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    padding: 6px 0;
}

.cart-totals-label[b-jejlqcukl2] {
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--agra-text-muted);
}

.cart-totals-value[b-jejlqcukl2] {
    font-size: .95rem;
    font-weight: 600;
    color: var(--agra-text);
}

/* The figure the customer is actually checking. */
.cart-totals-row-grand[b-jejlqcukl2] {
    margin-top: 4px;
    padding-top: 12px;
    border-top: 1px solid var(--agra-hairline);
}

.cart-totals-row-grand .cart-totals-label[b-jejlqcukl2] { color: var(--agra-primary); }

.cart-totals-row-grand .cart-totals-value[b-jejlqcukl2] {
    font-size: 1.25rem;
    color: var(--agra-primary);
}

/* --------------------------------------------------------------------------
   Empty cart.

   Reachable directly — typed, bookmarked, or left open while the cart drained —
   so it has to say something. It was a sentence and a link; it is a proper empty
   state now, because this is also the first thing a customer sees if they open
   the cart before adding anything.
   -------------------------------------------------------------------------- */
.cart-empty[b-jejlqcukl2] { margin-top: 12px; }

.cart-empty-content[b-jejlqcukl2] {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    padding: 32px 24px 28px;
}

.cart-empty-icon[b-jejlqcukl2] {
    color: var(--agra-primary);
    opacity: .35;
}

.cart-empty-title[b-jejlqcukl2] {
    margin: 14px 0 0;
    font-size: 17px;
    font-weight: 600;
    letter-spacing: -.01em;
    color: var(--agra-text);
}

.cart-empty-body[b-jejlqcukl2] {
    margin: 8px 0 0;
    max-width: 22rem;
    font-size: .9rem;
    line-height: 1.5;
    color: var(--agra-text-muted);
}

/* An <a> carrying .agra-button, which was written for <button>. */
.cart-empty-action[b-jejlqcukl2] {
    width: auto;
    margin: 20px 0 0;
    padding: 0 20px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--agra-accent);
    color: #fff;
    text-decoration: none;
}

.cart-empty-action:hover[b-jejlqcukl2] { filter: brightness(1.07); }
/* /Components/Pages/OrderStatus.razor.rz.scp.css */
/* Order Status.

   The cards, titles and subtitles come from app.css (.agra-card / .agra-card-title /
   .agra-card-subtitle), which already reproduces Ionic's Material metrics. What is here is only what
   this page adds: the ion-list-header, the ion-item rows inside a card, and the cancellation
   affordances the legacy read-only tab had no counterpart for.
   Source: mwpms-mobile-ordering/src/app/order-status-tab/order-status-tab.page.html
   (its .scss file is empty — the page was entirely stock Ionic). */

.order-status-loading[b-dcxppq7uvb],
.order-status-empty[b-dcxppq7uvb] {
    margin: 24px 16px;
    text-align: center;
    color: var(--agra-text-muted);
    font-size: .95rem;
}

.order-status-empty a[b-dcxppq7uvb] {
    color: var(--agra-primary);
}

/* The cancellation thread's current answer (D23). Colour-coded, but never colour alone — the word
   says which it is, so it still reads on a phone in sunlight or to a colour-blind customer. */
.order-status-cancellation[b-dcxppq7uvb] {
    flex: 0 0 auto;
    padding: 2px 8px;
    border-radius: 10px;
    font-size: .75rem;
    font-weight: 500;
    line-height: 1.6;
    white-space: nowrap;
    background: rgb(0 0 0 / 6%);
    color: var(--agra-text-muted);
}

.order-status-cancellation[data-state="requested"][b-dcxppq7uvb] {
    background: rgb(255 196 9 / 22%);
    color: #8a6100;
}

.order-status-cancellation[data-state="cancelled"][b-dcxppq7uvb] {
    background: rgb(235 68 90 / 14%);
    color: var(--agra-danger-shade);
}

.order-status-cancellation[data-state="declined"][b-dcxppq7uvb] {
    background: rgb(56 128 255 / 14%);
    color: var(--agra-primary-shade);
}

/* A text button rather than a filled one: it sits inside a list row, and giving a cancellation the
   most prominent control on the card would invite taps that the confirm dialog then has to talk
   people back out of. */
.order-status-cancel[b-dcxppq7uvb] {
    flex: 0 0 auto;
    padding: 6px 8px;
    border: none;
    border-radius: 4px;
    background: transparent;
    color: var(--agra-danger);
    font-family: inherit;
    font-size: .8rem;
    font-weight: 500;
    /* 44px is the iOS minimum touch target; the padding above alone leaves it short. */
    min-height: 44px;
    cursor: pointer;
}

.order-status-cancel:hover[b-dcxppq7uvb] {
    background: rgb(235 68 90 / 8%);
}

.order-status-cancel:disabled[b-dcxppq7uvb] {
    color: var(--agra-text-muted);
    cursor: default;
}

/* The switcher/refresh row, above the first card so it does not scroll away between orders. */
.order-status-controls[b-dcxppq7uvb] {
    display: flex;
    align-items: center;
    gap: 8px;
    max-width: 30rem;
    margin: 0 auto;
    padding: 4px 0;
}

.order-status-company[b-dcxppq7uvb] {
    flex: 1 1 auto;
    min-width: 0;
}

.order-status-refresh[b-dcxppq7uvb] {
    flex: 0 0 auto;
    margin-left: auto;
    padding: 0 12px;
    min-height: 44px;
    border: none;
    border-radius: 4px;
    background: transparent;
    color: var(--agra-primary);
    font-family: inherit;
    font-size: .875rem;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: .03em;
    cursor: pointer;
}

.order-status-refresh:hover[b-dcxppq7uvb] {
    background: rgb(56 128 255 / 8%);
}

.order-status-refresh:disabled[b-dcxppq7uvb] {
    color: var(--agra-text-muted);
    cursor: default;
}

.order-status-error .agra-card-content[b-dcxppq7uvb] {
    color: var(--agra-text);
}

/* --------------------------------------------------------------------------
   Status bubbles, following the badge idiom Agra.Ops uses in its own queues —
   a tinted pill rather than a coloured word. Keyed off a data attribute so an
   unrecognised status still renders, in the neutral tint.
   -------------------------------------------------------------------------- */
.order-status-pill[b-dcxppq7uvb] {
    display: inline-block;
    padding: 2px 10px;
    border-radius: 10px;
    font-size: .72rem;
    font-weight: 600;
    line-height: 1.6;
    white-space: nowrap;
    background: rgb(0 0 0 / 6%);
    color: var(--agra-text-muted);
}

.order-status-pill[data-status="pending"][b-dcxppq7uvb] {
    background: rgb(255 196 9 / 22%);
    color: #8a6100;
}

.order-status-pill[data-status="confirmed"][b-dcxppq7uvb] {
    background: rgb(43 87 154 / 12%);
    color: var(--agra-primary);
}

.order-status-pill[data-status="scheduled"][b-dcxppq7uvb] {
    background: rgb(235 116 19 / 16%);
    color: #a2500d;
}

.order-status-pill[data-status="completed"][b-dcxppq7uvb] {
    background: rgb(45 211 111 / 18%);
    color: #14663a;
}

.order-status-pill[data-status="cancelled"][b-dcxppq7uvb] {
    background: rgb(235 68 90 / 14%);
    color: var(--agra-danger-shade);
}

/* --------------------------------------------------------------------------
   The per-tank card's order grid.

   One row per load: date, tons, status, action. The first shape gave each order
   a spanning reference row and each cancellable load a spanning action row, so
   a tank with twelve single-load orders rendered thirty-six rows and ran well
   past the fold. The reference moved under the date and the action became an
   icon in its own column, which puts a load back on one line.
   -------------------------------------------------------------------------- */
.order-grid[b-dcxppq7uvb] {
    display: grid;
    grid-template-columns: 1fr auto auto auto;
    /* stretch, not center: the rule between rows is drawn on each cell's own top edge, so a cell
       shorter than its row — tons and status beside a two-line date — would be centred in the track
       and draw its rule lower than the date's. Every cell fills the row height and the content is
       centred inside the cell instead, which lines the four rules up. */
    align-items: stretch;
    column-gap: 10px;
}

.order-grid-head[b-dcxppq7uvb] {
    padding-bottom: 6px;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--agra-text-muted);
}

.order-grid-head-tons[b-dcxppq7uvb],
.order-grid-head-status[b-dcxppq7uvb] { text-align: right; }

/* Every body cell rules off from the one above, which is what separates the rows without a border
   per card or a spacer row per order. */
.order-grid-date[b-dcxppq7uvb],
.order-grid-tons[b-dcxppq7uvb],
.order-grid-status[b-dcxppq7uvb],
.order-grid-action[b-dcxppq7uvb] {
    padding: 7px 0;
    border-top: 1px solid var(--agra-hairline);
}

.order-grid-date[b-dcxppq7uvb] {
    display: flex;
    flex-direction: column;
    justify-content: center;
    font-size: .9rem;
    color: var(--agra-text);
}

/* Date and its qualifier on one line: "09/17/2026 SCHEDULED". Inline rather than stacked because
   the first row of each order already carries the reference underneath, and a third line would make
   every order taller for a distinction that is two words. */
.order-grid-date-value[b-dcxppq7uvb] {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 6px;
}

/* Quiet: it qualifies the date, it is not a second fact competing with it. */
.order-grid-date-kind[b-dcxppq7uvb] {
    font-size: 10px;
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--agra-text-muted);
}

/* The order's own reference, tucked under the first load's date. */
.order-grid-ref[b-dcxppq7uvb] {
    margin-top: 1px;
    font-size: 11px;
    font-weight: 600;
    color: var(--agra-primary);
}

.order-grid-tons[b-dcxppq7uvb] {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    font-size: .9rem;
    font-weight: 600;
    color: var(--agra-text);
    white-space: nowrap;
}

.order-grid-status[b-dcxppq7uvb] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: flex-end;
    gap: 4px;
}

/* An empty action cell still has to draw its share of the rule, so it keeps its box. */

.order-grid-action[b-dcxppq7uvb] {
    display: flex;
    align-items: center;
    justify-content: flex-end;
}

/* The cancellation request, as an icon. The confirm dialog it already opened is what keeps this
   safe to put one tap away. */
.order-cancel-icon[b-dcxppq7uvb] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    padding: 0;
    border: none;
    border-radius: 50%;
    background: none;
    color: var(--agra-danger);
    cursor: pointer;
}

.order-cancel-icon:hover[b-dcxppq7uvb] { background: rgb(235 68 90 / 12%); }

.order-cancel-icon:focus-visible[b-dcxppq7uvb] {
    outline: 2px solid var(--agra-danger);
    outline-offset: -2px;
}

.order-cancel-icon:disabled[b-dcxppq7uvb] {
    color: var(--agra-text-muted);
    cursor: default;
    background: none;
}

/* --------------------------------------------------------------------------
   No orders for the selected company.

   Shaped like the empty cart rather than a line of grey text: this is the whole
   screen for a customer who has not ordered yet, and a sentence floating on a
   blank page reads as a load failure.
   -------------------------------------------------------------------------- */
.order-status-blank[b-dcxppq7uvb] { margin-top: 12px; }

.order-status-blank-content[b-dcxppq7uvb] {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    padding: 32px 24px 28px;
}

.order-status-blank-icon[b-dcxppq7uvb] {
    color: var(--agra-primary);
    opacity: .35;
}

.order-status-blank-title[b-dcxppq7uvb] {
    margin: 14px 0 0;
    font-size: 17px;
    font-weight: 600;
    letter-spacing: -.01em;
    color: var(--agra-text);
}

.order-status-blank-body[b-dcxppq7uvb] {
    margin: 8px 0 0;
    max-width: 22rem;
    font-size: .9rem;
    line-height: 1.5;
    color: var(--agra-text-muted);
}

/* An <a> carrying .agra-button, which was written for <button>. */
.order-status-blank-action[b-dcxppq7uvb] {
    width: auto;
    margin: 20px 0 0;
    padding: 0 20px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--agra-accent);
    color: #fff;
    text-decoration: none;
}

.order-status-blank-action:hover[b-dcxppq7uvb] { filter: brightness(1.07); }
/* /Components/Pages/Tanks.razor.rz.scp.css */
/* The Tanks tab's own rules, ported from tanks-tab.page.scss. Everything shared with the rest of the
   app — the card, its header, its title and subtitles — is already in app.css as .agra-card and
   friends, at the same Ionic Material metrics; only what this one screen drew lives here. */

/* .customer-select. The legacy box outlined itself in the logo's blue and carried a heavier shadow
   than anything below it, which made the switcher shout over the content it filters. It is a card
   like the rest now — same width, same radius, same elevation — so the screen reads as one stack
   rather than a banner sitting on a list. */
.customer-select[b-9tus02o896] {
    max-width: 30rem;
    /* border-box, because this card pads itself while .agra-card pads its children instead. Without
       it the 32px of padding and 2px of border land *outside* the 30rem, and this one card ends up
       34px wider than every card under it. There is no global box-sizing reset to rely on. */
    box-sizing: border-box;
    margin: 12px auto;
    /* Tightened with the greeting below it: the pair were taking a third of a phone screen before a
       single tank appeared. */
    padding: 10px 16px 12px;
    border: 1px solid var(--agra-hairline);
    border-radius: 4px;
    box-shadow: 0 3px 1px -2px rgb(0 0 0 / 20%),
                0 2px 2px 0 rgb(0 0 0 / 14%),
                0 1px 5px 0 rgb(0 0 0 / 12%);
    background: #fff;
}

/* A field label, not a sentence: small, upper, muted, the way Agra.Ops labels its form rows. */
.customer-select-label[b-9tus02o896] {
    display: block;
    margin-bottom: 4px;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--agra-text-muted);
}


/* The legacy <hr> drew a full rule between the label and the select, which at this size reads as a
   divider between two sections rather than part of one field. Kept in the markup, hidden here. */
.customer-select hr[b-9tus02o896] {
    display: none;
}


.tanks-loading[b-9tus02o896] {
    display: flex;
    align-items: center;
    gap: 10px;
    color: var(--agra-text-muted);
}

.tanks-error[b-9tus02o896] {
    color: var(--agra-danger);
}

/* .tank-card — now a sibling of the greeting card rather than a child of it, so it sits on the
   page's grey and can carry its own elevation again. One soft shadow, no border: a border plus a
   shadow on the same edge is what made these look like cut-out slabs. */
.tank-card[b-9tus02o896] {
    border: none;
    border-radius: 10px;
    box-shadow: 0 1px 2px rgb(0 0 0 / 8%), 0 2px 8px rgb(0 0 0 / 6%);
}

/* Roomier than .agra-card-header's shared 16px: this header carries four stacked lines and a 48px
   button beside them, and at 16px the text sat hard against the card edge. */
.tank-card .agra-card-header[b-9tus02o896] {
    padding: 18px 18px 16px;
}

/* The level block is a second section within the card, so it gets a rule rather than just a gap —
   otherwise the tonnage reads as one more subtitle under the tank name. */
.tank-card .agra-card-content[b-9tus02o896] {
    padding: 14px 18px 18px;
    border-top: 1px solid var(--agra-hairline);
}

/* --------------------------------------------------------------------------
   Several sensors on one tank.

   One compact row each — label and figure on a line, a slim bar under it —
   instead of the full block, which at four sensors ran a single card past a
   phone screen on its own.
   -------------------------------------------------------------------------- */
.tank-level-row + .tank-level-row[b-9tus02o896] {
    margin-top: 12px;
}

.tank-level-row-head[b-9tus02o896] {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 10px;
    margin-bottom: 5px;
}

.tank-level-row-label[b-9tus02o896] {
    min-width: 0;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--agra-text-muted);
}

.tank-level-row-value[b-9tus02o896] {
    flex: 0 0 auto;
    font-size: .95rem;
    font-weight: 600;
    color: var(--agra-text);
    white-space: nowrap;
}

/* The capacity is context for the figure beside it, not a second figure. */
.tank-level-row-of[b-9tus02o896] {
    font-weight: 400;
    color: var(--agra-text-muted);
}

/* Slimmer than the single-sensor bar: there are several of them stacked. */
.tank-level-row .progress[b-9tus02o896]  .rz-progressbar {
    height: 7px;
    border-radius: 4px;
}

/* Only drawn when the sensors disagree about when they last reported. */
.tank-level-row-date[b-9tus02o896] {
    margin-top: 3px;
    font-size: .75rem;
    color: var(--agra-text-muted);
}

/* The shared "as of" line, under the whole group. */
.tank-levels .tank-reading-date[b-9tus02o896] {
    margin-top: 12px;
    padding-top: 10px;
    border-top: 1px solid var(--agra-hairline);
}

/* The legacy .add-button floated the FAB right and pulled it up 30px so it straddled the header.
   Positioned rather than floated here: a float inside a flex header does nothing, and the header
   needs to be flex anyway so the title block can take the slack beside the button. */
.tank-card-header[b-9tus02o896] {
    display: flex;
    align-items: flex-start;
    gap: 12px;
}

.tank-card-heading[b-9tus02o896] {
    flex: 1 1 auto;
    min-width: 0;
}

/* Was ion-fab-button color="success". It opens the order form — the same "add to cart" action the
   bottom FAB completes — so it carries the same accent rather than a green that belongs to nothing
   else on the screen. 48px, Material's minimum comfortable target, down from the legacy 50. */
.tank-add-button[b-9tus02o896] {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 48px;
    height: 48px;
    border: none;
    border-radius: 100%;
    background: var(--agra-accent);
    color: #fff;
    cursor: pointer;
    box-shadow: 0 2px 4px rgb(0 0 0 / 18%), 0 1px 2px rgb(0 0 0 / 12%);
    transition: filter .15s ease-in-out;
}

.tank-add-button:hover[b-9tus02o896] { filter: brightness(1.07); }

.tank-add-button:focus-visible[b-9tus02o896] {
    outline: 2px solid var(--agra-primary);
    outline-offset: 2px;
}

/* The level block's own heading was an <h5> inside the card content. */
.tank-level-title[b-9tus02o896] {
    margin: 0 0 8px;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--agra-text-muted);
}

/* The progress bar is rendered by RadzenProgressBar, a child component, so scoped selectors do not
   reach it without ::deep. Sized down from Radzen's default, which is built for a desktop dashboard
   rather than a line in a phone card, and recoloured: Radzen's stock primary is an indigo that
   matches nothing else on the screen now that the chrome is Agra.Ops blue. */
.progress[b-9tus02o896]  .rz-progressbar {
    height: 10px;
    border-radius: 5px;
    background: var(--agra-surface);
    box-shadow: inset 0 0 0 1px var(--agra-hairline);
}

.progress[b-9tus02o896]  .rz-progressbar-value {
    background: var(--agra-primary);
    border-radius: 5px;
}

/* .tank-quantity-text — the one figure on the card a customer is actually looking for. */
.tank-quantity-text[b-9tus02o896] {
    padding: 8px 5px 2px;
    text-align: center;
    font-size: 1.05rem;
    font-weight: 600;
    color: var(--agra-text);
}

.tank-reading-date[b-9tus02o896] {
    text-align: center;
    font-size: .8rem;
    color: var(--agra-text-muted);
}

/* --------------------------------------------------------------------------
   Live sensor read.

   Only rendered for a tank with a Vega sensor — see AgraMobileTankLevel.IsLiveCapable.
   Understated on purpose: the stored reading is the normal answer and is
   usually fresh enough, so this is an affordance for the customer who wants to
   be sure, not the primary thing on the card.
   -------------------------------------------------------------------------- */
.tank-card .tank-live[b-9tus02o896] {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 10px;
    padding-top: 12px;
}

.tank-live-button[b-9tus02o896] {
    padding: 0;
    border: none;
    background: none;
    font-family: inherit;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--agra-primary);
    cursor: pointer;
}

.tank-live-button:hover[b-9tus02o896] { text-decoration: underline; }

.tank-live-button:disabled[b-9tus02o896] {
    color: var(--agra-text-muted);
    cursor: default;
    text-decoration: none;
}

.tank-live-note[b-9tus02o896] {
    font-size: .8rem;
    color: var(--agra-text-muted);
}

/* --------------------------------------------------------------------------
   Greeting.

   A single row: who they are and which company on the left, refresh on the
   right. It was a card header over a card content section, each with its own
   16px padding, for two lines of text.
   -------------------------------------------------------------------------- */
.tanks-greeting-row[b-9tus02o896] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 14px 18px;
}

.tanks-greeting-text[b-9tus02o896] {
    min-width: 0;
}

.tanks-greeting-title[b-9tus02o896] {
    margin: 0;
    font-size: 17px;
    font-weight: 600;
    letter-spacing: -.01em;
    line-height: 1.25;
    color: var(--agra-text);
}

/* The switcher directly above already names the company, so this is a reminder rather than news —
   set as a subtitle instead of the sentence it used to be. */
.tanks-greeting-subtitle[b-9tus02o896] {
    margin: 2px 0 0;
    font-size: 13px;
    line-height: 1.4;
    color: var(--agra-text-muted);
}

/* An action, not a link in a sentence. Sized to the same 40px target as the other icon buttons. */
.tanks-refresh[b-9tus02o896] {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    padding: 0;
    border: none;
    border-radius: 50%;
    background: none;
    color: var(--agra-primary);
    cursor: pointer;
}

.tanks-refresh:hover[b-9tus02o896] { background: rgb(43 87 154 / 10%); }

.tanks-refresh:focus-visible[b-9tus02o896] {
    outline: 2px solid var(--agra-primary);
    outline-offset: -2px;
}

.tanks-refresh:disabled[b-9tus02o896] {
    color: var(--agra-text-muted);
    cursor: default;
    background: none;
}

/* The loading and error rows sit under the greeting row, so they supply their own inset. */
.tanks-greeting .tanks-loading[b-9tus02o896],
.tanks-greeting .tanks-error[b-9tus02o896] {
    padding: 0 18px 14px;
}
