/* /Components/Global/Components/IconSelect.razor.rz.scp.css */
.icon-select[b-ejk5pdcen7] {

    .mud-input-adornment {
        display: none;
    }

    .mud-input-slot[b-ejk5pdcen7] {
        padding: 0 !important;
        height: 100% !important;
        width: 100% !important;
    }

    .mud-icon-root[b-ejk5pdcen7] {
        align-items: end;
        vertical-align: bottom;
    }

    .mud-select-filler[b-ejk5pdcen7] {
        max-width: 1.65vw;
        margin-left: 0;
        margin-right: 0;
    }
}

.icon-select-popover[b-ejk5pdcen7] {
    width: fit-content !important;

    .mud-list > .mud-list-item {
        padding-left:8px;
        padding-right:8px;
    }
}
/* /Components/Global/Components/MudToolWindow.razor.rz.scp.css */
:root[b-xo4aigke6w] {
    --theme-primary: #1e499e;
    --theme-primary-overlay: #112a90cc;
    --DarkHighlight: #00000078;
}

.tool-window[b-xo4aigke6w] {
    
}

.tool-window-container[b-xo4aigke6w] {
    padding-bottom: 1rem;
    
}

.tool-window-footer[b-xo4aigke6w] {
    position: absolute;
    background-color:var(--DarkHighlight);
    top: 95%;
    left: 1px;
    padding: 0.25vh;
    width: 101%;
    
    h6 {
        font-size: 1.2rem;
    }
}
/* /Components/Global/Dialogs/LineItemDialog.razor.rz.scp.css */
/* Live price readout at the bottom of the mobile line editor. Mirrors the derived-values strip
   on the desktop grid so both surfaces show board feet and weight, not just the final amount. */

.ld-preview[b-mu0l306s0v] {
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: 8px;
    padding: 12px 14px;
    background-color: var(--mud-palette-background-gray, var(--mud-palette-background));
}

.ld-preview-grid[b-mu0l306s0v] {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 10px 16px;
}

.ld-preview-grid > div[b-mu0l306s0v] {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

.ld-preview-grid span[b-mu0l306s0v] {
    font-size: 11px;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--mud-palette-text-secondary);
}

.ld-preview-grid strong[b-mu0l306s0v] {
    font-size: 15px;
    font-variant-numeric: tabular-nums;
    color: var(--mud-palette-text-primary);
}

.ld-preview-total[b-mu0l306s0v] {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    margin-top: 12px;
    padding-top: 10px;
    border-top: 2px solid var(--mud-palette-lines-default);
}

.ld-preview-total span[b-mu0l306s0v] {
    font-size: 13px;
    font-weight: 500;
    color: var(--mud-palette-text-secondary);
}

.ld-preview-total strong[b-mu0l306s0v] {
    font-size: 22px;
    font-variant-numeric: tabular-nums;
    color: var(--mud-palette-text-primary);
}
/* /Components/Global/Dialogs/QuotePreviewDialog.razor.rz.scp.css */
/*
    The "document" half of the preview is a paper metaphor rendered honestly: a sheet with a real
    margin, hairline rules, and tabular figures. It is NOT a pixel copy of the QuestPDF output —
    that would look wrong on a phone. Both read from the same QuotePdfModel, so the content
    agrees; the presentation is native to the screen it is on.

    Everything is var(--mud-palette-*): three switchable themes, so a literal hex only looks
    right in one of them.
*/

.qpv-title[b-25oglh36l7] {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
}

.qpv-title-text[b-25oglh36l7] {
    display: flex;
    flex-direction: column;
    gap: 1px;
    margin-right: auto;
}

/* Color comes from the .mud-text-secondary class on the MudText itself, not from here — see
   Components/Global/Dialogs/QuotePreviewDialog.razor. */
.qpv-eyebrow[b-25oglh36l7] {
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.14em;
    text-transform: uppercase;
}

/* Color comes from Color="Color.Inherit" on the MudText itself (inherits body's
   var(--mud-palette-text-primary)) — this rule is layout/type only. */
.qpv-title-text h2[b-25oglh36l7] {
    margin: 0;
    font-family: "Roboto Slab", serif;
    font-size: 20px;
    font-weight: 500;
    line-height: 1.15;
}

/* The dialog body is the scroll container, not the page: a long quote scrolls inside a frame
   that keeps the tab strip and the action bar in view. */
/* The backdrop must differ from `.sheet` below (which is `surface`) or the "sheet of paper"
   reads as nothing at all — both were `surface`, i.e. the same color. `background-gray` is the
   recessed step below `surface` in MudBlazor's own elevation order, which is exactly the
   paper-on-a-desk relationship wanted here. It is safe to use now that every theme sets it
   explicitly: Lumber used to fall through to MudBlazor's cool #F5F5F5, which is why a neutral
   grey backdrop looked wrong against that theme's warm palette. */
.qpv-scroll[b-25oglh36l7] {
    max-height: min(66vh, 720px);
    overflow-y: auto;
    overflow-x: hidden;
    padding: 16px;
    background-color: var(--mud-palette-background-gray);
}

/* ---------------------------------------------------------------- the sheet */

.sheet[b-25oglh36l7] {
    max-width: 860px;
    margin: 0 auto;
    padding: 28px 30px 30px;
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: 10px;
    background-color: var(--mud-palette-surface);
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.06), 0 8px 28px rgba(0, 0, 0, 0.07);
    color: var(--mud-palette-text-primary);
}

.sheet-head[b-25oglh36l7] {
    display: grid;
    grid-template-columns: auto 1fr auto;
    align-items: start;
    gap: 18px;
    padding-bottom: 16px;
    /* Brand walnut is the printed document's only non-grey ink; the same rule anchors the
       header here. */
    border-bottom: 2px solid var(--mud-palette-primary);
}

.sheet-logo[b-25oglh36l7] {
    width: 92px;
    height: auto;
    object-fit: contain;
}

.sheet-co[b-25oglh36l7] {
    display: flex;
    flex-direction: column;
    gap: 1px;
    font-size: 12px;
    line-height: 1.45;
}

.sheet-co strong[b-25oglh36l7] {
    font-family: "Roboto Slab", serif;
    font-size: 15px;
    font-weight: 600;
    color: var(--mud-palette-primary);
}

.sheet-meta[b-25oglh36l7] {
    text-align: right;
}

.sheet-doctype[b-25oglh36l7] {
    font-family: "Roboto Slab", serif;
    font-size: 22px;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--mud-palette-primary);
}

.sheet-meta dl[b-25oglh36l7] {
    display: grid;
    grid-template-columns: auto auto;
    justify-content: end;
    gap: 2px 12px;
    margin: 8px 0 0;
    font-size: 12px;
}

.sheet-meta dt[b-25oglh36l7] {
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-size: 10px;
    align-self: center;
    color: var(--mud-palette-text-secondary);
}

.sheet-meta dd[b-25oglh36l7] {
    margin: 0;
    font-variant-numeric: tabular-nums;
}

/* ---------------------------------------------------------------- parties */

.sheet-parties[b-25oglh36l7] {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 20px;
    padding: 18px 0;
}

.party[b-25oglh36l7] {
    display: flex;
    flex-direction: column;
    gap: 1px;
    font-size: 13px;
    line-height: 1.5;
}

.party h3[b-25oglh36l7] {
    margin: 0 0 4px;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--mud-palette-text-secondary);
}

/* ---------------------------------------------------------------- line items */

.sheet-lines[b-25oglh36l7] {
    overflow-x: auto;
}

.sheet-lines table[b-25oglh36l7] {
    width: 100%;
    border-collapse: collapse;
    font-size: 13px;
}

.sheet-lines th[b-25oglh36l7] {
    padding: 7px 8px;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    text-align: left;
    white-space: nowrap;
    color: var(--mud-palette-text-secondary);
    background-color: var(--mud-palette-background-gray);
    border-bottom: 1px solid var(--mud-palette-lines-default);
}

.sheet-lines td[b-25oglh36l7] {
    padding: 9px 8px;
    border-bottom: 1px solid var(--mud-palette-lines-default);
    vertical-align: top;
}

/* .c-num / .c-amount are global — wwwroot/CSS/quote-ui.css. This sheet's table takes them as-is. */

.c-unit[b-25oglh36l7] {
    white-space: nowrap;
    font-size: 11px;
    letter-spacing: 0.04em;
    color: var(--mud-palette-text-secondary);
}

.c-activity[b-25oglh36l7] {
    white-space: nowrap;
    font-size: 12px;
    color: var(--mud-palette-primary);
}

.c-desc[b-25oglh36l7] {
    min-width: 220px;
}

/* ---------------------------------------------------------------- footer */

.sheet-foot[b-25oglh36l7] {
    display: grid;
    grid-template-columns: 1fr auto;
    gap: 28px;
    padding-top: 18px;
}

.sheet-notes[b-25oglh36l7] {
    font-size: 13px;
    line-height: 1.55;
    color: var(--mud-palette-text-secondary);
}

.sheet-notes h3[b-25oglh36l7] {
    margin: 0 0 4px;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
}

.sheet-notes p[b-25oglh36l7] {
    margin: 0 0 12px;
    white-space: pre-wrap;
}

.sheet-bf[b-25oglh36l7] {
    display: inline-flex;
    align-items: baseline;
    gap: 8px;
    padding: 6px 12px;
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: 8px;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

.sheet-bf strong[b-25oglh36l7] {
    font-size: 15px;
    font-variant-numeric: tabular-nums;
    color: var(--mud-palette-text-primary);
}

/* Even rhythm is the acceptance criterion Larry's QuickBooks complaint set: every row is the
   same height, and emphasis is carried by weight and a rule, never by extra padding. */
.sheet-totals[b-25oglh36l7] {
    min-width: 268px;
    margin: 0;
}

.tot[b-25oglh36l7] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 20px;
    height: 30px;
    font-size: 13px;
}

.tot dt[b-25oglh36l7] {
    color: var(--mud-palette-text-secondary);
}

.tot dd[b-25oglh36l7] {
    margin: 0;
    font-variant-numeric: tabular-nums;
}

.tot-strong[b-25oglh36l7] {
    border-top: 1px solid var(--mud-palette-lines-default);
    font-weight: 600;
}

.tot-strong dt[b-25oglh36l7],
.tot-strong dd[b-25oglh36l7] {
    color: var(--mud-palette-text-primary);
}

.tot-strongest[b-25oglh36l7] {
    border-top: 2px solid var(--mud-palette-primary);
    font-size: 15px;
    font-weight: 700;
}

.tot-strongest dt[b-25oglh36l7],
.tot-strongest dd[b-25oglh36l7] {
    color: var(--mud-palette-primary);
}

/* ---------------------------------------------------------------- narrow screens */

@media (max-width: 700px) {
    .qpv-scroll[b-25oglh36l7] {
        padding: 8px;
    }

    .sheet[b-25oglh36l7] {
        padding: 18px 16px 20px;
    }

    /* The three header blocks stop being columns and become a stack; a 92px logo beside two
       text blocks has nowhere to go at phone width. */
    .sheet-head[b-25oglh36l7] {
        grid-template-columns: 1fr;
        gap: 10px;
    }

    .sheet-meta[b-25oglh36l7] {
        text-align: left;
    }

    .sheet-meta dl[b-25oglh36l7] {
        justify-content: start;
    }

    .sheet-parties[b-25oglh36l7],
    .sheet-foot[b-25oglh36l7] {
        grid-template-columns: 1fr;
        gap: 16px;
    }

    .sheet-totals[b-25oglh36l7] {
        min-width: 0;
    }
}
/* /Components/Global/PageComponents/QuoteBreakdownView.razor.rz.scp.css */
/*
    Breakdown tab layout. The chart panels reuse the global .panel/.stat primitives
    (wwwroot/CSS/quote-ui.css); only the arrangement around them lives here.
*/

.bd[b-69i81jcrkr] {
    display: flex;
    flex-direction: column;
    gap: 14px;
    max-width: 980px;
    margin: 0 auto;
}

.bd-kpis[b-69i81jcrkr] {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(132px, 1fr));
    gap: 10px;
}

/* Two charts side by side on a wide dialog, stacked below it. Both are horizontal bar charts
   whose height is driven by their row count, so they don't need to match. */
.bd-pair[b-69i81jcrkr] {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 14px;
    align-items: start;
}

.bd-panel[b-69i81jcrkr] {
    min-width: 0;
}

.bd-body[b-69i81jcrkr] {
    padding: 10px 12px 4px;
}

/* ---------------------------------------------------------------- table view */

.bd-table[b-69i81jcrkr] {
    overflow-x: auto;
}

.bd-table table[b-69i81jcrkr] {
    width: 100%;
    border-collapse: collapse;
    font-size: 13px;
}

.bd-table th[b-69i81jcrkr] {
    padding: 8px 12px;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    text-align: left;
    white-space: nowrap;
    color: var(--mud-palette-text-secondary);
    background-color: var(--mud-palette-background-gray);
    border-bottom: 1px solid var(--mud-palette-lines-default);
}

.bd-table td[b-69i81jcrkr] {
    padding: 9px 12px;
    border-bottom: 1px solid var(--mud-palette-lines-default);
    color: var(--mud-palette-text-primary);
}

.bd-table tbody tr:last-child td[b-69i81jcrkr] {
    border-bottom: none;
}

/* .c-num / .c-amount are global — wwwroot/CSS/quote-ui.css. This table takes them as-is. */

@media (max-width: 820px) {
    .bd-pair[b-69i81jcrkr] {
        grid-template-columns: 1fr;
    }
}
/* /Components/Layout/MainLayout.razor.rz.scp.css */
/* Layout shell styling. All of this used to be inline style attributes (the appbar flex
   row, the hardcoded cream icon colors) or missing entirely — this file is the shell's
   CSS-isolation home. Colors come from the live palette vars only; the shell has to look
   right in all three themes.

   Scope-attribute gotcha (see AppContext.md): a Class= passed to a MudBlazor component
   lands on an element WITHOUT this file's scope attribute, so those are reached with
   `.owned-wrapper ::deep .class` — never bare `.class`. */

.appbar-row[b-tso5dieh0f] {
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    min-width: 0;
}

.appbar-brand[b-tso5dieh0f] {
    display: flex;
    align-items: center;
    gap: 12px;
    min-width: 0;
}

.appbar-brand[b-tso5dieh0f]  .appbar-title {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.appbar-actions[b-tso5dieh0f] {
    display: flex;
    align-items: center;
}

/* Responsive branding, CSS-only so the first paint is already correct:
   below 600px (MudBlazor's Xs) the title goes and the nav hamburger appears;
   at 600px+ the drawer is a persistent mini rail, so the hamburger goes. */
@media (max-width: 599.98px) {
    .appbar-brand[b-tso5dieh0f]  .appbar-title {
        display: none;
    }
}

@media (min-width: 600px) {
    .appbar-brand[b-tso5dieh0f]  .appbar-nav-toggle {
        display: none;
    }
}

/* Drawer footer: the desktop collapse/expand chevron, separated from the nav by a
   hairline in the theme's divider color and inked with the drawer's own icon slot. */
.drawer-foot[b-tso5dieh0f] {
    border-top: 1px solid var(--mud-palette-divider);
    padding: 6px;
    display: flex;
    justify-content: flex-end;
}

.drawer-foot[b-tso5dieh0f]  .mud-icon-button {
    color: var(--mud-palette-drawer-icon);
}
/* /Components/Layout/NavMenu.razor.rz.scp.css */
/* Theme-aware nav styling. Every color here resolves from the active palette's
   drawer-* slots (white drawer in Light, warm near-black in Dark, brand walnut in
   Lumber), so all three themes restyle the nav without a single literal hex.

   The tinted hover/active fills are derived from the drawer's own text ink via
   color-mix rather than a fixed grey: drawer-text is guaranteed to contrast with
   drawer-background in every theme (ThemeContrastTests asserts it), so a 10-16%
   tint of it always reads as "slightly raised" on that drawer. The plain rgba()
   line before each color-mix is the fallback for anything too old to know
   color-mix — the modern line wins whenever it parses. */

.nav-menu[b-ikuxkdbv4j] {
    padding: 12px 8px;
}

.nav-menu[b-ikuxkdbv4j]  .mud-nav-link {
    border-radius: 8px;
    margin: 2px 0;
    color: var(--mud-palette-drawer-text);
    transition: background-color 120ms ease;
}

.nav-menu[b-ikuxkdbv4j]  .mud-nav-link .mud-icon-root {
    color: var(--mud-palette-drawer-icon);
}

.nav-menu[b-ikuxkdbv4j]  .mud-nav-link:hover:not(.active) {
    background-color: rgba(128, 128, 128, 0.14);
    background-color: color-mix(in srgb, var(--mud-palette-drawer-text) 10%, transparent);
}

/* Active = tinted fill + a rail on the leading edge in the drawer's icon accent,
   + heavier text. The rail is an inset box-shadow rather than a border so it adds
   no width and survives the mini (icon-only) collapsed state, where it is the
   main "you are here" signal since the label is hidden. */
.nav-menu[b-ikuxkdbv4j]  .mud-nav-link.active:not(.mud-nav-link-disabled) {
    background-color: rgba(128, 128, 128, 0.18);
    background-color: color-mix(in srgb, var(--mud-palette-drawer-text) 16%, transparent);
    box-shadow: inset 3px 0 0 0 var(--mud-palette-drawer-icon);
}

.nav-menu[b-ikuxkdbv4j]  .mud-nav-link.active:not(.mud-nav-link-disabled) .mud-nav-link-text {
    font-weight: 600;
}
/* /Components/Pages/Account/Login.razor.rz.scp.css */
/* Colors come from MudBlazor palette variables only — this app has three switchable themes and a
   literal hex only looks right in one of them. `.panel` / `.panel-head` are the shared primitives
   from wwwroot/CSS/quote-ui.css, so this file only handles the page's own layout. */

.login-page[b-s78z9x7amk] {
    display: flex;
    justify-content: center;
    padding: 3rem 1rem;
}

.login-panel[b-s78z9x7amk] {
    width: 100%;
    max-width: 26rem;
}

.login-body[b-s78z9x7amk] {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    padding: 1.25rem;
}

.login-form[b-s78z9x7amk] {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.login-note[b-s78z9x7amk] {
    font-size: 0.8125rem;
    margin: 0;
}
/* /Components/Pages/BuildQuote.razor.rz.scp.css */
/* Quote builder.

   Everything here is expressed in MudBlazor palette variables rather than literal colours,
   because the app ships three themes (Light / Dark / the cream "Lumber" theme) and the user can
   switch between them at any time from the appbar. Hard-coded hexes would look correct in
   exactly one of the three. */

.qp[b-pftf6gk5rh] {
    display: flex;
    flex-direction: column;
    gap: 20px;
}

/* ---------------------------------------------------------------- page header */

.qp-head[b-pftf6gk5rh] {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    justify-content: space-between;
    gap: 16px;
}

.qp-eyebrow[b-pftf6gk5rh] {
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--mud-palette-text-secondary);
}

.qp-title[b-pftf6gk5rh] {
    margin: 2px 0 0;
    font-family: "Roboto Slab", serif;
    font-size: 30px;
    font-weight: 500;
    line-height: 1.15;
    color: var(--mud-palette-text-primary);
}

/* The finalized badge sits under the title, not beside it — the title is the quote number and
   needs to stay the thing you read first. */
.qp-head-title .badge[b-pftf6gk5rh] {
    margin-top: 8px;
}

.qp-stats[b-pftf6gk5rh] {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
}

/* Live running figures. Board feet and weight are up here rather than buried in the table
   because the spec asks for the board-foot calculation to be *shown*, and freight weight is
   what the yard quotes on. */



.stat strong small[b-pftf6gk5rh] {
    margin-left: 3px;
    font-size: 11px;
    font-weight: 500;
    color: var(--mud-palette-text-secondary);
}

.stat-due[b-pftf6gk5rh] {
    border-color: var(--mud-palette-primary);
    box-shadow: inset 0 0 0 1px var(--mud-palette-primary);
}

.stat-due strong[b-pftf6gk5rh] {
    color: var(--mud-palette-primary);
}

/* ---------------------------------------------------------------- panels */

.qp-body[b-pftf6gk5rh] {
    display: flex;
    flex-direction: column;
    gap: 20px;
}







.panel-body[b-pftf6gk5rh] {
    padding: 18px 16px;
}

.totals-wrap[b-pftf6gk5rh] {
    display: flex;
    justify-content: flex-end;
}

.panel-totals[b-pftf6gk5rh] {
    width: 100%;
    max-width: 460px;
}

/* ---------------------------------------------------------------- details form */

.form-stack[b-pftf6gk5rh] {
    display: flex;
    flex-direction: column;
    gap: 22px;
}

.form-section-head[b-pftf6gk5rh] {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 12px;
    padding-bottom: 8px;
    border-bottom: 1px solid var(--mud-palette-divider);
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--mud-palette-text-secondary);
}

.form-section-head[b-pftf6gk5rh]  .mud-icon-root {
    font-size: 17px;
    color: var(--mud-palette-text-secondary);
}

/* Wholesale is a pricing-relevant fact about the customer, so it reads as a badge next to the
   customer heading rather than as a checkbox the operator has to go looking for. Rendered via
   <StatusBadge> (Components/Global/Components/StatusBadge.razor) — its background+text pairing
   comes from MudBlazor's `mud-theme-warning`/`mud-theme-secondary` classes, not a rule here. */

/* Primary rather than the `dark` palette slot: primary is the brand walnut and is set
   explicitly on all three themes, whereas `dark` falls through to a MudBlazor default. */

/* ---------------------------------------------------------------- finalized (read-only) state

   A finalized quote is a record to read, not a form that happens to be broken, so this does the
   opposite of fading the page out: values stay at full contrast and it is the *input chrome*
   that goes away — borders, fill, dropdown carets, clear buttons. What is left reads as a
   printed document.

   `fieldset[disabled]` (set in the markup) is what actually enforces the lock: it removes every
   control inside from the tab order natively, so it cannot be defeated with a keyboard. The
   rules below only handle presentation, plus the MudBlazor widgets whose click target is a div
   rather than a real form control — `disabled` has no effect on those. */

.lockable[b-pftf6gk5rh] {
    /* Neutralise the fieldset's own UA styling; min-width:0 stops its default min-content
       sizing from blowing out the flex/grid layouts it now wraps. */
    border: 0;
    margin: 0;
    padding: 0;
    min-width: 0;
}

/* Scoped to the widgets rather than the whole subtree on purpose: a blanket
   `pointer-events: none` would also kill the line-item grid's horizontal scroll, and a wide
   finalized quote still has to be readable out to the Amount column. */
.lockable[disabled][b-pftf6gk5rh]  .mud-input-control,
.lockable[disabled][b-pftf6gk5rh]  .mud-toggle-group,
.lockable[disabled][b-pftf6gk5rh]  .mud-switch {
    pointer-events: none;
}

/* MudBlazor greys disabled controls out; undo that, then restore the text colour. Safari needs
   -webkit-text-fill-color specifically — it paints disabled input text with that rather than
   `color`, and this app targets iMac/iPad/iPhone. */
.lockable[disabled][b-pftf6gk5rh]  .mud-disabled {
    opacity: 1 !important;
}

.lockable[disabled][b-pftf6gk5rh]  input,
.lockable[disabled][b-pftf6gk5rh]  textarea,
.lockable[disabled][b-pftf6gk5rh]  .mud-input-slot,
.lockable[disabled][b-pftf6gk5rh]  .mud-select-input .mud-input-slot {
    color: var(--mud-palette-text-primary) !important;
    -webkit-text-fill-color: var(--mud-palette-text-primary) !important;
}

.lockable[disabled][b-pftf6gk5rh]  .mud-input-label,
.lockable[disabled][b-pftf6gk5rh]  .mud-switch .mud-typography {
    color: var(--mud-palette-text-secondary) !important;
}

/* Drop the box around each value — this is the change that turns fields into text. */
.lockable[disabled][b-pftf6gk5rh]  .mud-input-outlined-border {
    border-color: transparent !important;
}

.lockable[disabled][b-pftf6gk5rh]  .mud-input.mud-input-outlined {
    background-color: transparent !important;
}

/* Trailing affordances (clear ✕, dropdown caret, date-picker icon) promise an interaction that
   is no longer on offer. Leading adornments — the "$" on money fields — are part of the value
   and stay.

   The clear button needs naming separately: MudBlazor renders it as a direct child of
   .mud-input rather than inside the end adornment, so hiding the adornment misses it. */
.lockable[disabled][b-pftf6gk5rh]  .mud-input-adornment-end,
.lockable[disabled][b-pftf6gk5rh]  .mud-input-clear-button {
    display: none;
}

/* A value that has no input to sit in — currently the fulfillment choice, whose meaning is
   carried by which half of a toggle is filled rather than by any text. Styled to sit on the
   same baseline as the read-only fields around it. */
.locked-value[b-pftf6gk5rh] {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 4px 0;
    font-size: 16px;
    color: var(--mud-palette-text-primary);
}

.locked-value[b-pftf6gk5rh]  .mud-icon-root {
    font-size: 19px;
    color: var(--mud-palette-text-secondary);
}

.switch-row[b-pftf6gk5rh] {
    display: flex;
    flex-wrap: wrap;
    gap: 8px 28px;
}

.fulfil-toggle[b-pftf6gk5rh] {
    max-width: 320px;
}

/* ---------------------------------------------------------------- line item grid */

.table-scroll[b-pftf6gk5rh] {
    overflow-x: auto;
}

.line-table[b-pftf6gk5rh] {
    width: 100%;
    min-width: 1180px;
    border-collapse: collapse;
    /* Spec: noticeably larger than the QuickBooks output this replaces — read at a shop
       counter, and sometimes off paper. */
    font-size: 15px;
}

.line-table th[b-pftf6gk5rh] {
    padding: 10px 8px;
    border-bottom: 1px solid var(--mud-palette-divider);
    background-color: var(--mud-palette-background-gray, var(--mud-palette-background));
    text-align: left;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--mud-palette-text-secondary);
    white-space: nowrap;
}

.line-table td[b-pftf6gk5rh] {
    padding: 8px;
    vertical-align: middle;
}

.row-main > td[b-pftf6gk5rh] {
    padding-top: 12px;
    padding-bottom: 4px;
}

/* Spec calls for a full, visible horizontal rule under every line item — explicitly not
   subtle zebra striping. The primary row and its derived-values row are one logical item, so
   the rule goes under the pair. */
.row-meta > td[b-pftf6gk5rh] {
    padding-top: 0;
    padding-bottom: 12px;
    border-bottom: 2px solid var(--mud-palette-lines-default);
}

.row-main:hover > td[b-pftf6gk5rh],
.row-main:hover + .row-meta > td[b-pftf6gk5rh] {
    background-color: var(--mud-palette-table-hover);
}

.row-flagged > td:first-child[b-pftf6gk5rh] {
    box-shadow: inset 3px 0 0 var(--mud-palette-warning);
}

.c-idx[b-pftf6gk5rh] { width: 40px; }
.c-qty[b-pftf6gk5rh] { width: 84px; }
.c-item[b-pftf6gk5rh] { width: 330px; }
.c-size[b-pftf6gk5rh] { width: 150px; }
.c-opt[b-pftf6gk5rh] { width: 250px; }
.c-act[b-pftf6gk5rh] { width: 48px; }

/* .c-num / .c-amount themselves are global (wwwroot/CSS/quote-ui.css). What stays here is only
   what belongs to *this* table: the desktop entry grid is a fixed-width layout (see the sibling
   .c-* widths above and .line-table's min-width), so Rate/Amount get a column width the other
   two tables — which are fluid — must not inherit. Scoped selectors carry the Blazor scope
   attribute, so these out-specify the global rule regardless of link order. */
.c-num[b-pftf6gk5rh] { width: 108px; }

/* Larger and at full contrast because this grid is the data-entry surface: the Amount figure
   has to stay readable at a shop counter against 14px inputs. */
.c-amount[b-pftf6gk5rh] {
    font-size: 16px;
    color: var(--mud-palette-text-primary);
}

.idx[b-pftf6gk5rh] {
    display: inline-grid;
    place-items: center;
    width: 24px;
    height: 24px;
    border-radius: 50%;
    background-color: var(--mud-palette-background-gray, var(--mud-palette-background));
    border: 1px solid var(--mud-palette-lines-default);
    font-size: 12px;
    font-weight: 600;
    color: var(--mud-palette-text-secondary);
}

.item-cell[b-pftf6gk5rh],
.size-cell[b-pftf6gk5rh],
.opt-cell[b-pftf6gk5rh] {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.opt-cell[b-pftf6gk5rh] {
    flex-direction: row;
    flex-wrap: wrap;
    gap: 6px;
}

.opt-cell > *[b-pftf6gk5rh] {
    flex: 1 1 108px;
    min-width: 92px;
}

.size-fixed[b-pftf6gk5rh],
.uom-fixed[b-pftf6gk5rh] {
    display: inline-flex;
    align-items: center;
    font-size: 13px;
    color: var(--mud-palette-text-secondary);
    white-space: nowrap;
}

/* Product picker rows: SKU is the audit key, the description is what people actually read. */
.ac-item[b-pftf6gk5rh] {
    display: flex;
    flex-direction: column;
    line-height: 1.3;
}

.ac-sku[b-pftf6gk5rh] {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.04em;
    color: var(--mud-palette-text-secondary);
}

.ac-desc[b-pftf6gk5rh] {
    font-size: 14px;
}

/* Derived values live on a second line so the primary row stays scannable, but they are always
   on screen — the notes ask for the board-foot figure to be shown, not just used internally. */
.meta[b-pftf6gk5rh] {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

.tag[b-pftf6gk5rh] {
    display: inline-flex;
    align-items: center;
    padding: 2px 9px;
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: 999px;
    background-color: var(--mud-palette-background-gray, var(--mud-palette-background));
    font-size: 12px;
    color: var(--mud-palette-text-secondary);
    white-space: nowrap;
}

.tag-num[b-pftf6gk5rh] {
    font-variant-numeric: tabular-nums;
}

.meta-error[b-pftf6gk5rh] {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 13px;
    color: var(--mud-palette-warning-darken, var(--mud-palette-warning));
}

.meta-error[b-pftf6gk5rh]  .mud-icon-root {
    font-size: 16px;
    color: var(--mud-palette-warning);
}

.meta-hint[b-pftf6gk5rh] {
    font-size: 13px;
    font-style: italic;
    color: var(--mud-palette-text-disabled);
}

/* Tighten MudBlazor's default input chrome inside the grid — at default spacing the rows get
   tall enough that only three or four line items fit on screen at once. */
.line-table[b-pftf6gk5rh]  .mud-input-control {
    margin-top: 0 !important;
}

.line-table[b-pftf6gk5rh]  .mud-input.mud-input-outlined .mud-input-slot {
    font-size: 14px;
}

/* ---------------------------------------------------------------- empty state */




/* ---------------------------------------------------------------- totals */

.totals[b-pftf6gk5rh] {
    display: flex;
    flex-direction: column;
}

/* Spec: even vertical spacing between Subtotal / Tax / Shipping / Total. The rows that hold an
   input and the rows that hold a plain figure are given the same min-height so the column of
   numbers on the right stays on a steady rhythm instead of jumping around the input boxes. */
.tot-row[b-pftf6gk5rh] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    min-height: 46px;
    padding: 2px 0;
}

.tot-label[b-pftf6gk5rh] {
    font-size: 15px;
    color: var(--mud-palette-text-secondary);
}

.tot-label-wrap[b-pftf6gk5rh] {
    max-width: 62%;
    line-height: 1.25;
}

.tot-value[b-pftf6gk5rh] {
    font-size: 16px;
    font-variant-numeric: tabular-nums;
    color: var(--mud-palette-text-primary);
}

.tot-field[b-pftf6gk5rh] {
    width: 132px;
    flex: 0 0 132px;
}

.tot-field[b-pftf6gk5rh]  .mud-input-control {
    margin-top: 0 !important;
}

.tot-field[b-pftf6gk5rh]  input {
    text-align: right;
    font-variant-numeric: tabular-nums;
}

.tot-row-total[b-pftf6gk5rh] {
    margin-top: 6px;
    border-top: 2px solid var(--mud-palette-lines-default);
}

.tot-row-total .tot-label[b-pftf6gk5rh] {
    font-size: 16px;
    font-weight: 600;
    color: var(--mud-palette-text-primary);
}

.tot-row-total .tot-value[b-pftf6gk5rh] {
    font-size: 20px;
    font-weight: 600;
}

.tot-row-due[b-pftf6gk5rh] {
    margin-top: 2px;
    padding: 10px 12px;
    border-radius: 10px;
    background-color: var(--mud-palette-background-gray, var(--mud-palette-background));
    border: 1px solid var(--mud-palette-primary);
}

.tot-row-due .tot-label[b-pftf6gk5rh] {
    font-size: 15px;
    font-weight: 700;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    color: var(--mud-palette-text-primary);
}

.tot-row-due .tot-value[b-pftf6gk5rh] {
    font-size: 24px;
    font-weight: 700;
    color: var(--mud-palette-primary);
}

/* ---------------------------------------------------------------- mobile wizard */

.wiz[b-pftf6gk5rh] {
    display: flex;
    flex-direction: column;
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: 12px;
    background-color: var(--mud-palette-surface);
    overflow: hidden;
}

.wiz-rail[b-pftf6gk5rh] {
    display: flex;
    margin: 0;
    padding: 6px 4px 4px;
    list-style: none;
    border-bottom: 1px solid var(--mud-palette-divider);
    background-color: var(--mud-palette-background-gray, var(--mud-palette-background));
}

.wiz-step[b-pftf6gk5rh] {
    position: relative;
    flex: 1;
}

/* Connector between the step dots. Drawn from each step back toward the previous one so it
   never overhangs the first or last dot. */
.wiz-step + .wiz-step[b-pftf6gk5rh]::before {
    content: "";
    position: absolute;
    top: 25px;
    right: 50%;
    left: -50%;
    height: 2px;
    background-color: var(--mud-palette-lines-default);
}

.wiz-step.is-active[b-pftf6gk5rh]::before,
.wiz-step.is-done[b-pftf6gk5rh]::before {
    background-color: var(--mud-palette-primary);
}

.wiz-step button[b-pftf6gk5rh] {
    position: relative;
    z-index: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    width: 100%;
    padding: 8px 2px;
    border: 0;
    background: none;
    cursor: pointer;
    color: var(--mud-palette-text-secondary);
    font: inherit;
}

.wiz-dot[b-pftf6gk5rh] {
    display: grid;
    place-items: center;
    width: 34px;
    height: 34px;
    border-radius: 50%;
    border: 2px solid var(--mud-palette-lines-default);
    background-color: var(--mud-palette-surface);
    font-size: 14px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

.wiz-dot[b-pftf6gk5rh]  .mud-icon-root {
    font-size: 18px;
    color: inherit;
}

.is-active .wiz-dot[b-pftf6gk5rh] {
    border-color: var(--mud-palette-primary);
    background-color: var(--mud-palette-primary);
    color: var(--mud-palette-primary-text);
}

.is-done .wiz-dot[b-pftf6gk5rh] {
    border-color: var(--mud-palette-primary);
    color: var(--mud-palette-primary);
}

.wiz-label[b-pftf6gk5rh] {
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.04em;
}

.is-active .wiz-label[b-pftf6gk5rh] {
    color: var(--mud-palette-primary);
}

.wiz-body[b-pftf6gk5rh] {
    padding: 18px 14px;
}

/* Kept in reach of a thumb, and always showing the number the customer is about to be told. */
.wiz-actions[b-pftf6gk5rh] {
    position: sticky;
    bottom: 0;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 10px 12px;
    border-top: 1px solid var(--mud-palette-divider);
    background-color: var(--mud-palette-surface);
}

.wiz-actions-due[b-pftf6gk5rh] {
    display: flex;
    flex-direction: column;
    align-items: center;
    line-height: 1.15;
}

.wiz-actions-due span[b-pftf6gk5rh] {
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    color: var(--mud-palette-text-secondary);
}

.wiz-actions-due strong[b-pftf6gk5rh] {
    font-size: 17px;
    font-variant-numeric: tabular-nums;
    color: var(--mud-palette-text-primary);
}

/* ---------------------------------------------------------------- mobile line cards */

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

.card[b-pftf6gk5rh] {
    display: flex;
    align-items: center;
    gap: 4px;
    padding: 4px 4px 4px 12px;
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: 10px;
    background-color: var(--mud-palette-surface);
}

.card-flagged[b-pftf6gk5rh] {
    border-color: var(--mud-palette-warning);
    box-shadow: inset 3px 0 0 var(--mud-palette-warning);
}

.card-tap[b-pftf6gk5rh] {
    flex: 1;
    min-width: 0;
    padding: 8px 0;
    cursor: pointer;
}

.card-top[b-pftf6gk5rh] {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 10px;
}

.card-desc[b-pftf6gk5rh] {
    flex: 1;
    min-width: 0;
    font-size: 15px;
    font-weight: 500;
    color: var(--mud-palette-text-primary);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.card-amt[b-pftf6gk5rh] {
    font-size: 16px;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
    color: var(--mud-palette-text-primary);
}

.card-meta[b-pftf6gk5rh] {
    display: flex;
    flex-wrap: wrap;
    gap: 5px;
    margin-top: 7px;
}

.card-error[b-pftf6gk5rh] {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-top: 7px;
    font-size: 13px;
    color: var(--mud-palette-warning-darken, var(--mud-palette-warning));
}

.card-error[b-pftf6gk5rh]  .mud-icon-root {
    font-size: 16px;
    color: var(--mud-palette-warning);
}

/* ---------------------------------------------------------------- narrow screens */

@media (max-width: 600px) {
    .qp-title[b-pftf6gk5rh] {
        font-size: 24px;
    }

    .qp-stats[b-pftf6gk5rh] {
        width: 100%;
        display: grid;
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .stat[b-pftf6gk5rh] {
        min-width: 0;
    }
}
/* /Components/Pages/QuoteList.razor.rz.scp.css */
/* Saved quotes list.

   Same rules as the quote builder: MudBlazor palette variables only, never literal colours —
   the app ships three switchable themes (Light / Dark / the cream "Lumber" theme) and a
   hard-coded hex only looks right in one of them.

   The primitives in the first section (.stat / .panel / .badge / .empty) intentionally mirror
   BuildQuote.razor.css so the two pages read as one product. They are duplicated rather than
   shared because Blazor scopes each component's CSS to that component — a rule in
   BuildQuote.razor.css cannot reach this page. If a third page needs them, promote the block to
   a global stylesheet instead of copying it again. */

.ql[b-ol6f34jg0u] {
    display: flex;
    flex-direction: column;
    gap: 20px;
}

/* ---------------------------------------------------------------- page header */

.ql-head[b-ol6f34jg0u] {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    justify-content: space-between;
    gap: 16px;
}

.ql-eyebrow[b-ol6f34jg0u] {
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--mud-palette-text-secondary);
}

.ql-title[b-ol6f34jg0u] {
    margin: 2px 0 0;
    font-family: "Roboto Slab", serif;
    font-size: 30px;
    font-weight: 500;
    line-height: 1.15;
    color: var(--mud-palette-text-primary);
}

.ql-stats[b-ol6f34jg0u] {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
}




/* The money figure gets the same emphasis treatment the builder gives Amount Due, so the one
   number an operator scans for reads the same on both screens. */


/* ---------------------------------------------------------------- panel */







/* ---------------------------------------------------------------- filter toolbar */

/* Sits on the same gray band the table headers use, so the filters read as part of the table
   chrome rather than as free-floating form fields on the page. */
.ql-toolbar[b-ol6f34jg0u] {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    gap: 12px;
    padding: 12px 14px;
    border-bottom: 1px solid var(--mud-palette-divider);
    background-color: var(--mud-palette-background-gray, var(--mud-palette-background));
}

.ql-search[b-ol6f34jg0u] {
    flex: 1 1 240px;
    max-width: 340px;
}

.ql-status-filter[b-ol6f34jg0u] {
    flex: 0 0 200px;
}

.ql-toolbar[b-ol6f34jg0u]  .mud-input-control {
    margin-top: 0 !important;
}

/* ---------------------------------------------------------------- table */

/* The table sits inside .panel, which already provides the surface and the border. */
.ql-table[b-ol6f34jg0u]  .mud-table {
    background-color: transparent;
}

.ql-table[b-ol6f34jg0u]  .mud-table-sort-label {
    color: inherit;
}

.ql-table[b-ol6f34jg0u]  .mud-table-sort-label-icon {
    font-size: 15px;
}

.ql-table[b-ol6f34jg0u]  .mud-table-head .mud-table-cell {
    padding: 10px 12px;
    border-bottom: 1px solid var(--mud-palette-divider);
    background-color: var(--mud-palette-background-gray, var(--mud-palette-background));
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--mud-palette-text-secondary);
    white-space: nowrap;
}

.ql-table[b-ol6f34jg0u]  .mud-table-body .mud-table-cell {
    padding: 12px;
    /* Spec calls for a full visible rule under each row rather than zebra striping — matching
       the line-item grid in the builder. */
    border-bottom: 2px solid var(--mud-palette-lines-default);
    font-size: 15px;
}

/* Every body row opens its quote (OnRowClick), so the pointer is the affordance for that.
   Reached through the .ql-table wrapper above rather than MudTable's RowStyle: presentation
   belongs in the stylesheet, and an inline style is invisible to the theme review. */
.ql-table[b-ol6f34jg0u]  .mud-table-body .mud-table-row {
    cursor: pointer;
}

.ql-table[b-ol6f34jg0u]  .mud-table-body .mud-table-row:hover .mud-table-cell {
    background-color: var(--mud-palette-table-hover);
}

/* The panel edge already closes the list off; a rule under the final row doubles it up. */
.ql-table[b-ol6f34jg0u]  .mud-table-body .mud-table-row:last-child .mud-table-cell {
    border-bottom: 0;
}

/* A finalized quote is settled: flag it the way the builder flags a row needing attention,
   but in the brand colour rather than the warning colour. */
.ql-table[b-ol6f34jg0u]  .mud-table-body .row-finalized .mud-table-cell:first-child {
    box-shadow: inset 3px 0 0 var(--mud-palette-primary);
}

.ql-table[b-ol6f34jg0u]  .mud-table-pagination {
    border-top: 0;
}

/* Quote number is the audit key — same treatment the builder gives a product SKU. */
.cell-number[b-ol6f34jg0u] {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    letter-spacing: 0.02em;
    white-space: nowrap;
}

.cell-customer[b-ol6f34jg0u] {
    display: flex;
    flex-direction: column;
    line-height: 1.3;
}

.cell-company[b-ol6f34jg0u] {
    font-size: 12px;
    color: var(--mud-palette-text-secondary);
}

.cell-muted[b-ol6f34jg0u] {
    color: var(--mud-palette-text-secondary);
}

.cell-amount[b-ol6f34jg0u] {
    display: block;
    text-align: right;
    font-size: 16px;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
    color: var(--mud-palette-text-primary);
}

/* Amount Due (6th column) is the one right-aligned column, so its header has to follow the
   figures. Addressed positionally because MudTh renders the <th> itself — a class passed to it
   lands outside this component's scope and cannot be selected directly. */
.ql-table[b-ol6f34jg0u]  .mud-table-head .mud-table-cell:nth-child(6) {
    text-align: right;
}

.ql-table[b-ol6f34jg0u]  .mud-table-head .mud-table-cell:nth-child(6) .mud-table-sort-label {
    justify-content: flex-end;
}

/* ---------------------------------------------------------------- badges */



/* Status reads as a progression rather than three unrelated colours:
   Draft is provisional (outline only, no fill), Sent is live and awaiting an answer (the
   brand's teal, its "active" colour), Accepted is resolved (success). */




/* ---------------------------------------------------------------- empty state */




/* ---------------------------------------------------------------- narrow screens */

@media (max-width: 600px) {
    .ql-title[b-ol6f34jg0u] {
        font-size: 24px;
    }

    .ql-stats[b-ol6f34jg0u] {
        width: 100%;
        display: grid;
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }

    .stat[b-ol6f34jg0u] {
        min-width: 0;
        padding: 8px 10px;
    }

    .stat strong[b-ol6f34jg0u] {
        font-size: 16px;
    }

    .ql-search[b-ol6f34jg0u],
    .ql-status-filter[b-ol6f34jg0u] {
        flex-basis: 100%;
        max-width: none;
    }
}
