/* /Features/Customers/CustomersLayout.razor.rz.scp.css */
.customers-layout[b-5ef0gt34zp] {
    display: flex;
    flex-direction: row;
    height: 100%;
    min-height: 100%;
}

.customers-content[b-5ef0gt34zp] {
    flex: 1;
    min-width: 0;
    min-height: 0;
    display: flex;
    flex-direction: column;
    overflow: auto;
    padding: 1rem 1rem 0 1rem;
}
/* /Features/Customers/Pages/CustomerLeads.razor.rz.scp.css */
/*
    Lead id and Customer name stay pinned to the left while the remaining
    columns scroll horizontally, so the two priority fields never leave the
    viewport. Sticky cells need an opaque background to sit above scrolled
    content; we inherit the table's own background var so theme + hover
    striping keep working.
*/
.customer-leads-table .col-sticky[b-4h0uevu05k] {
    position: sticky;
    background-color: var(--bs-table-bg, var(--bs-body-bg));
    z-index: 1;
}

.customer-leads-table thead .col-sticky[b-4h0uevu05k] {
    z-index: 2;
}

.customer-leads-table .col-sticky-id[b-4h0uevu05k] {
    left: 0;
}

/* Offset the customer column by the id column width so they stack flush. */
.customer-leads-table .col-sticky-customer[b-4h0uevu05k] {
    left: 7rem;
    max-width: 16rem;
}
/* /Features/Estimates/Components/EstimateOptionCard.razor.rz.scp.css */
/* The rule under the header has to reach both edges of the sheet to read as a real
   division — the panel's own padding would otherwise stop it short on each side.
   Pulled out by that padding and given it back as its own. */
.estimate-option-header[b-cpcnhyflr7] {
    margin-left: calc(var(--tab-panel-padding) * -1);
    margin-right: calc(var(--tab-panel-padding) * -1);
    padding-left: var(--tab-panel-padding);
    padding-right: var(--tab-panel-padding);
}

/* Cost and profit close the panel as a band of their own. Same pull-out as the header
   rule above so it spans the sheet edge to edge, plus a tint that sets the internal
   figures apart from the customer's totals sitting right above them. The negative
   bottom margin cancels the panel's own padding, seating the band on the sheet's foot. */
.estimate-option-margin[b-cpcnhyflr7] {
    margin-left: calc(var(--tab-panel-padding) * -1);
    margin-right: calc(var(--tab-panel-padding) * -1);
    margin-bottom: calc(var(--tab-panel-padding) * -1);
    padding-left: var(--tab-panel-padding);
    padding-right: var(--tab-panel-padding);
    background-color: var(--bg-surface-alt);
    border-radius: 0 0 var(--radius) var(--radius);
}

/* Each figure sits in a ruled row of its own, evenly spaced, so the totals read as a
   short statement rather than a block of text. The rule goes on the top of each row and
   the first one already has the panel's own divider above it. */
.estimate-option-total-row[b-cpcnhyflr7] {
    padding: 0.625rem 0;
    border-top: 1px solid var(--border-color);
}

/* One rule between the services and the totals, and it belongs to the services block —
   so it is there whether or not the add-service row is (a read-only option has none).
   The first total row then draws nothing of its own; two rules 16px apart were the
   doubled edge above the subtotal. */
.estimate-option-lines[b-cpcnhyflr7] {
    border-bottom: 1px solid var(--border-color);
}

.estimate-option-total-row:first-child[b-cpcnhyflr7] {
    border-top: 0;
}

/* A column held open on every row for its controls. Only the discount carries any today,
   but without the reservation its buttons pushed that row's figure left of the amounts
   above and below it — the one thing a column of money must not do. */
.estimate-option-total-actions[b-cpcnhyflr7] {
    display: inline-flex;
    justify-content: flex-end;
    align-items: center;
    /* Two controls at their full tap size, plus the gap between them. Reserved on every
       row so the figures keep a straight right edge whether or not a row has actions. */
    gap: 0.5rem;
    width: 5rem;
    flex: 0 0 auto;
}

/* A row that is one offer — "add a discount", "add a service" — takes the click anywhere
   along it. Asking someone to hit a 28px plus sign is the harder version of the same
   action, and the tint on hover is what says the whole strip is live.

   Deliberately not pulled out to the panel's padding: the discount row is one of the
   totals, and widening it left its rule longer than the subtotal's above it. The tint
   stops where the row does. */
.estimate-option-row-actionable[b-cpcnhyflr7] {
    cursor: pointer;
    transition: background-color 0.15s ease;
}

.estimate-option-row-actionable:hover[b-cpcnhyflr7],
.estimate-option-row-actionable:focus-visible[b-cpcnhyflr7] {
    background-color: var(--bg-surface-alt);
}

/* Ruled off from the services above it, and closed below by the block's own rule — the
   same two edges the discount row has, without drawing the lower one twice. Same
   vertical rhythm as a total row so the two read as one family. */
.estimate-option-add-service[b-cpcnhyflr7] {
    padding: 0.625rem 0;
    border-top: 1px solid var(--border-color);
}

/* What a row that is an offer is written in — both its label and its plus. The discount's
   controls are real buttons and take the link colour from Bootstrap; these sit inside a
   clickable row instead, so they ask for that colour themselves rather than inheriting
   the body text and reading as two different things.

   The plus also gives up the shared hover tint: the row around it is the control and
   lights up as a whole, and a second box in the same colour would swallow the icon. */
.estimate-option-offer-text:hover[b-cpcnhyflr7],
.estimate-option-offer-text:focus-visible[b-cpcnhyflr7] {
    background-color: transparent;
}

.estimate-option-offer-text[b-cpcnhyflr7] {
    color: var(--bs-link-color);
}

/* A fixed square in the panel header, so a row of options doesn't jump as their
   pictures differ. The image scales inside without cropping, and the placeholder
   fills the same box when there is none. */
.estimate-option-thumb[b-cpcnhyflr7] {
    width: 5rem;
    height: 5rem;
    background-color: var(--bg-surface-alt);
}

.estimate-option-thumb img[b-cpcnhyflr7] {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
}

/* The picture doubles as the file picker, so it has to look like something you can
   click — otherwise there is no way to discover that adding an image is possible. */
.estimate-option-thumb-pickable[b-cpcnhyflr7] {
    cursor: pointer;
    transition: border-color 0.15s ease, background-color 0.15s ease;
}

/* Doubled class to outrank Bootstrap's own .border colour without !important. */
.estimate-option-thumb-pickable.estimate-option-thumb-pickable:hover[b-cpcnhyflr7] {
    border-color: var(--accent);
    background-color: var(--bg-elevated);
}
/* /Features/Estimates/Components/EstimateOptionLine.razor.rz.scp.css */
/* A flex child refuses to shrink below its content by default, so a long name or a
   pasted URL would push the block wider than the panel and bring back the horizontal
   scrollbar. These two let the text wrap instead of the layout stretching. */
.estimate-line-main[b-y85nnbb9ff],
.estimate-line-heading[b-y85nnbb9ff] {
    min-width: 0;
}

/* Smaller than the option's own thumbnail: a line is a part of the option, and matching
   its size would read as another option rather than an item inside one. */
.estimate-line-thumb[b-y85nnbb9ff] {
    width: 3.5rem;
    height: 3.5rem;
    background-color: var(--bg-surface-alt);
}

.estimate-line-thumb img[b-y85nnbb9ff] {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
}

/* The picture is the file picker, so it has to look like something you can click —
   otherwise there is no way to discover that adding an image is possible. */
.estimate-line-thumb-pickable[b-y85nnbb9ff] {
    cursor: pointer;
    transition: border-color 0.15s ease, background-color 0.15s ease;
}

/* Doubled class to outrank Bootstrap's own .border colour without !important. */
.estimate-line-thumb-pickable.estimate-line-thumb-pickable:hover[b-y85nnbb9ff] {
    border-color: var(--accent);
    background-color: var(--bg-elevated);
}

/* Price-book names run long, and it is usually the end of one ("...12ft", "...per post")
   that tells two of them apart — so it wraps rather than ending in an ellipsis. It is
   also the part that gives: the figures beside it have a known, short width, so the name
   takes the room that's left and wraps onto another line when there isn't enough. */
.estimate-line-name[b-y85nnbb9ff] {
    overflow-wrap: anywhere;
    flex: 1 1 12rem;
}

/* The three figures read as one statement of price, so they stay together on wide
   screens. On a narrow panel they wrap among themselves rather than overflowing it —
   holding the group rigid pushed ~70px past the panel edge between md and lg and brought
   the nested scrollbar back. Each figure still keeps its own value whole. */
.estimate-line-figures[b-y85nnbb9ff] {
    flex: 0 1 auto;
    flex-wrap: wrap;
    min-width: 0;
    /* A wrapped row shouldn't inherit the 1.5rem column gap as vertical space too. */
    row-gap: 0.5rem;
}

/* The labels stay on one line each. Letting "Total price" wrap pushed its value a line
   below the two beside it — the figures then read as if they belonged to different rows.
   Whole figures wrap to the next line instead, which keeps each label with its value. */
.estimate-line-figure-label[b-y85nnbb9ff] {
    white-space: nowrap;
}

/* A fixed column, so the same figure sits at the same place on every line. Sized from
   measurement rather than guessed: at this size an amount into the millions
   ($1,284,500.00) runs to 100px and the widest label ("Total price") to 71px, so 6.5rem
   holds both with room to spare. Without it each column took the width of whatever it
   happened to hold, and no two lines lined up. */
.estimate-line-figure[b-y85nnbb9ff] {
    width: 6.5rem;
    flex: 0 0 auto;
}

/* Ranged right and tabular: money is read from the decimal point, and lining figures
   keep the digits in step from one line to the next — proportional ones let a row of
   1s drift out of column against a row of 8s. */
.estimate-line-figure-value[b-y85nnbb9ff] {
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* The description is prose. pre-wrap keeps the line breaks the author typed, which HTML
   would otherwise collapse into spaces and run together; overflow-wrap breaks a pasted
   URL or part number that has no space to break at. */
.estimate-line-description[b-y85nnbb9ff] {
    white-space: pre-wrap;
    overflow-wrap: anywhere;
}

/* A band rather than a line of text: cost is a different kind of figure from the prices
   above it, and the tint says so at a glance where a label alone did not. The same surface
   the line's own thumbnail uses, so it reads as part of this component's vocabulary. */
.estimate-line-footer[b-y85nnbb9ff] {
    background-color: var(--bg-surface-alt);
}

/* Full body colour, deliberately. The band already says this is a different kind of
   figure, so greying the value on top of it only cost contrast against the tint — the
   distinction was made twice and read once. */
.estimate-line-cost-value[b-y85nnbb9ff] {
    color: var(--text-primary);
}

/* A rule between lines, but not under the last one — the option's totals already draw
   their own, and two together read as a mistake. */
.estimate-line + .estimate-line[b-y85nnbb9ff] {
    border-top: 1px solid var(--border-color);
}
/* /Features/Estimates/Components/EstimateProgressSteps.razor.rz.scp.css */
/* Equal columns, so the markers sit at even intervals whatever the label lengths —
   a flex row would space them by how wide each word happens to be, which would read as
   some stages mattering more than others. */
.estimate-progress[b-6nstve4u3j] {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: 1fr;
    margin: 0;
    padding: 0;
}

.estimate-progress-step[b-6nstve4u3j] {
    /* Declared here, not on the marker: both the marker's size and the line's offsets
       are written from it, so it has to be in scope for the whole step. Sized to give
       the icon inside room to read rather than to the dot it used to be. */
    --marker-size: 2.5rem;

    /* The two the connecting line has to skip over to reach the markers' middle: the
       reserved action line above them, and the gap this flex column puts between its
       children.

       The action line's height is computed from the same font-size and line-height the line
       itself uses, rather than restated as a number that stops matching the moment either
       is edited — the run would then be drawn across the markers instead of through them. */
    --action-font-size: 0.6875rem;
    --action-line-height: 1.3;
    --action-line: calc(var(--action-font-size) * var(--action-line-height));
    --step-gap: 0.5rem;

    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--step-gap);
    position: relative;
    min-width: 0;
}

/* The connecting line: each step draws the segment reaching back to the previous marker,
   so the strip reads as one run rather than six loose circles. The first step has nothing
   to its left.

   It stays neutral whatever the states are. Filling it up to the current step would draw
   a path that was walked — but stages can be completed in any order and skipped outright,
   so a filled run would claim progress that never happened. The markers carry the states;
   the line only connects them. */
.estimate-progress-step[b-6nstve4u3j]::before {
    content: "";
    position: absolute;
    /* Measured from the top of the step, which starts at the reserved action line rather
       than at the marker — so that line and the gap under it are added on, or the run would
       be drawn across the markers' upper edge instead of through their middle. */
    top: calc(var(--action-line) + var(--step-gap) + var(--marker-size) / 2);
    right: 50%;
    left: -50%;
    height: 2px;
    margin-right: calc(var(--marker-size) / 2 + 0.5rem);
    margin-left: calc(var(--marker-size) / 2 + 0.5rem);
    background-color: var(--border-color);
    transform: translateY(-1px);
}

.estimate-progress-step:first-child[b-6nstve4u3j]::before {
    content: none;
}

/* The line above the marker, where a booked step offers its way back. Reserved on every
   step even when empty — a line only one step carried would stand it taller than the other
   five and pull the row of markers out of line, the same reason the note below is reserved.

   Its height is computed from the two values that decide it rather than written as a number
   that silently stops matching when either is edited. */
.estimate-progress-action[b-6nstve4u3j] {
    /* The step above owns the two values, because the connecting line is positioned from
       them too — they must be one source, not two that can drift apart. */
    min-height: var(--action-line);
    font-size: var(--action-font-size);
    line-height: var(--action-line-height);
    text-align: center;
}

/* Reads as the control it belongs to, so it is not mistaken for another timestamp: the
   step's own colour, and underlined the way a way-back usually is. */
.estimate-progress-undo[b-6nstve4u3j] {
    color: var(--primary);
    /* text-decoration: underline; */
    text-underline-offset: 2px;
}

.estimate-progress-marker[b-6nstve4u3j] {
    width: var(--marker-size);
    height: var(--marker-size);
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    /* Sits above the line, which runs behind it. */
    position: relative;
    z-index: 1;
    background-color: var(--bg-body);
    border: 2px solid var(--border-color);
    font-size: 1rem;
    line-height: 1;
    /* The icon is what makes a stage recognisable before the label is read, so a pending
       step shows it too — muted, not hidden. */
    color: var(--text-secondary);
}

/* The step reached but not finished: an open ring, thick enough to read as "here"
   without becoming the solid dot that means done. */
.estimate-progress-step.is-current .estimate-progress-marker[b-6nstve4u3j] {
    border-color: var(--primary);
    color: var(--primary);
    box-shadow: 0 0 0 3px rgba(26, 115, 232, 0.15);
}

.estimate-progress-step.is-done .estimate-progress-marker[b-6nstve4u3j] {
    background-color: var(--primary);
    border-color: var(--primary);
    color: var(--text-on-primary);
}

/* The Schedule step's control. The button takes over the column layout the step itself lays
   out, so an actionable step is pixel-identical to the five inert ones — what marks it as a
   control is the pointer and the hover below, not a different shape that would break the
   even strip. */
.estimate-progress-toggle[b-6nstve4u3j] {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.5rem;
    background: none;
    border: 0;
    padding: 0;
    color: inherit;
    font: inherit;
    cursor: pointer;
}

.estimate-progress-toggle:focus-visible[b-6nstve4u3j] {
    outline: 2px solid var(--primary);
    outline-offset: 4px;
    border-radius: var(--radius);
}

/* Hovering the marker says the step does something. It carries the whole hint on the step
   that has nothing booked, where the label already names the action ("Schedule") and no
   "Undo" is shown; on a booked one it just confirms what that word already offers. */
.estimate-progress-toggle:hover .estimate-progress-marker[b-6nstve4u3j],
.estimate-progress-toggle:focus-visible .estimate-progress-marker[b-6nstve4u3j] {
    border-color: var(--primary);
    color: var(--primary);
}

/* A booked visit is a filled marker, so it inverts instead: keeping the rule above would
   leave the hover invisible on exactly the step that has something to undo. */
.estimate-progress-step.is-done .estimate-progress-toggle:hover .estimate-progress-marker[b-6nstve4u3j],
.estimate-progress-step.is-done .estimate-progress-toggle:focus-visible .estimate-progress-marker[b-6nstve4u3j] {
    background-color: var(--bg-body);
    color: var(--primary);
}

.estimate-progress-label[b-6nstve4u3j] {
    font-size: 0.75rem;
    letter-spacing: 0.04em;
    text-align: center;
    color: var(--text-secondary);
    line-height: 1.2;
    /* Long labels ("Copy to job") wrap rather than widening their column and pushing
       the markers off their even spacing. */
    overflow-wrap: anywhere;
}

/* The line under the label: a timestamp or a short comment. The space is reserved whether
   or not anything fills it — an empty note still holds its rows, so stamping a stage does
   not grow the strip and shove the cards below it down the page.

   The reservation is computed from the two values that decide it, rather than written as a
   number that silently stops matching when either one is edited: a note is at most a date
   over a time, so `--note-lines` of `line-height` at this `font-size`. */
.estimate-progress-note[b-6nstve4u3j] {
    --note-lines: 2;
    --note-font-size: 0.6875rem;
    --note-line-height: 1.3;

    /* Sits closer to the label than the label does to the marker: the two are one block
       of text about the stage, and the step's own gap would read as a third tier. */
    margin-top: -0.25rem;
    min-height: calc(var(--note-lines) * var(--note-font-size) * var(--note-line-height));
    display: flex;
    flex-direction: column;
    align-items: center;
    font-size: var(--note-font-size);
    line-height: var(--note-line-height);
    text-align: center;
    color: var(--text-secondary);
    font-variant-numeric: tabular-nums;
}

/* The date and the time each hold their own line, so a stage reads as two short rows
   rather than one string breaking wherever the column ends.

   Kept to one line each, because the height above is reserved for exactly two: a range
   ("11:30 AM - 12:30 PM CDT") is wider than the column and would otherwise wrap onto a
   third row and push the page down — the very shift the reservation exists to prevent.

   Overflow is visible rather than clipped: a time is the content, and hiding half of it
   behind an ellipsis is worse than letting the widest stamp reach a little into the gap
   between two stages. */
.estimate-progress-note-line[b-6nstve4u3j] {
    white-space: nowrap;
}

.estimate-progress-step.is-current .estimate-progress-label[b-6nstve4u3j] {
    color: var(--primary);
    font-weight: 600;
}

.estimate-progress-step.is-done .estimate-progress-label[b-6nstve4u3j] {
    color: var(--text-primary);
}

/* The ring's halo is a brand tint, and the brand colour changes with the theme. */
@media (prefers-color-scheme: dark) {
    .estimate-progress-step.is-current .estimate-progress-marker[b-6nstve4u3j] {
        box-shadow: 0 0 0 3px rgba(138, 180, 248, 0.2);
    }
}
/* /Features/Pipeline/Estimates/Components/EstimateKanbanCard.razor.rz.scp.css */
/* Full-bleed divider above the timestamps: the negative margins cancel the
   .kanban-card horizontal padding (0.875rem) so the line reaches both card edges,
   framing the two values at the bottom. */
.times-footer[b-eiwvnj4zb9] {
    border-top: 1px solid var(--border-color);
    margin: 0 -0.875rem;
    padding: 0.5rem 0.875rem 0;
}
/* /Features/Pipeline/Estimates/Pages/EstimatesPipeline.razor.rz.scp.css */
.estimates-pipeline-page[b-1v5l7l67my] {
    min-height: 100%;
    display: flex;
    flex-direction: column;
}
/* /Features/Pipeline/Leads/Components/LeadKanbanCard.razor.rz.scp.css */
/* Full-bleed divider above the timestamps: the negative margins cancel the
   .kanban-card horizontal padding (0.875rem) so the line reaches both card edges,
   framing the two values at the bottom. */
.times-footer[b-j5bb95yh3z] {
    border-top: 1px solid var(--border-color);
    margin: 0 -0.875rem;
    padding: 0.5rem 0.875rem 0;
}
/* /Features/Pipeline/Leads/Pages/LeadsPipeline.razor.rz.scp.css */
.leads-pipeline-page[b-1m8xeum0ej] {
    min-height: 100%;
    display: flex;
    flex-direction: column;
}
/* /Features/Pipeline/PipelineLayout.razor.rz.scp.css */
.pipeline-layout[b-ar0slexlf1] {
    display: flex;
    flex-direction: row;
    height: 100%;
    min-height: 100%;
}

[b-ar0slexlf1] .side-nav-section {
    margin-top: 2rem;
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
}

[b-ar0slexlf1] .side-nav-section-title {
    padding: 0.25rem 0.75rem;
    font-size: 0.75rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-secondary);
}

.pipeline-content[b-ar0slexlf1] {
    flex: 1;
    min-width: 0;
    min-height: 0;
    display: flex;
    flex-direction: column;
    overflow: auto;
    padding: 1rem 1rem 0 1rem;
}
/* /Features/PriceBook/Components/PriceBookCard.razor.rz.scp.css */
.pricebook-card[b-7fe1gvjvlh] {
    overflow: hidden;
    transition: transform .15s ease, box-shadow .15s ease;
}

.pricebook-card-clickable[b-7fe1gvjvlh] {
    cursor: pointer;
}

.pricebook-card-clickable:hover[b-7fe1gvjvlh],
.pricebook-card-clickable:focus-visible[b-7fe1gvjvlh] {
    transform: translateY(-2px);
    box-shadow: var(--bs-box-shadow);
}

/* A fixed ratio keeps every tile the same height whether or not an image is set.
   The children are taken out of the flow (absolute) so neither a loaded image nor
   the placeholder icon can grow the box beyond that ratio. */
.pricebook-card-media[b-7fe1gvjvlh] {
    position: relative;
    aspect-ratio: 4 / 3;
    width: 100%;
    overflow: hidden;
    background-color: var(--bs-tertiary-bg);
}

.pricebook-card-media img[b-7fe1gvjvlh] {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.pricebook-card-placeholder[b-7fe1gvjvlh] {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--bs-secondary-color);
    font-size: 2rem;
}

.pricebook-card-menu[b-7fe1gvjvlh] {
    position: absolute;
    top: .5rem;
    right: .5rem;
}

/* The trigger sits over the image, so it carries its own contrast instead of a
   filled background. */
.pricebook-card-menu[b-7fe1gvjvlh]  .pricebook-card-menu-trigger {
    color: #fff;
    text-shadow: 0 1px 3px rgb(0 0 0 / .6);
}

.pricebook-card-menu[b-7fe1gvjvlh]  .pricebook-card-menu-trigger:hover,
.pricebook-card-menu[b-7fe1gvjvlh]  .pricebook-card-menu-trigger:focus-visible {
    color: #fff;
    opacity: .8;
}
/* /Features/PriceBook/Components/PriceBookEmptyState.razor.rz.scp.css */
.pricebook-empty-icon[b-nrxem08etx] {
    font-size: 2.5rem;
    opacity: .5;
}
/* /Features/PriceBook/Components/PriceBookImagePicker.razor.rz.scp.css */
.pricebook-image-preview[b-fe4az0be9b] {
    width: 6rem;
    aspect-ratio: 1;
    border-radius: var(--bs-border-radius);
    overflow: hidden;
    background-color: var(--bs-tertiary-bg);
}

/* Stacked layout has room for a slightly bigger preview, but it shares the row with
   the name and description — so only slightly. */
.pricebook-image-preview-lg[b-fe4az0be9b] {
    width: 7rem;
}

.pricebook-image-preview img[b-fe4az0be9b] {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.pricebook-image-empty[b-fe4az0be9b] {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100%;
    color: var(--bs-secondary-color);
    font-size: 1.5rem;
}
/* /Features/PriceBook/Components/PriceBookServiceModal.razor.rz.scp.css */
/* Pricing is boxed so the derived figures belong to the amounts above them rather
   than trailing off the end of the form. */
.service-pricing[b-qelbtpp6qe] {
    border: 1px solid var(--border-color);
    border-radius: var(--radius);
    padding: 1rem;
}

/* A float-free legend: sits on the border like a section title. */
.service-pricing-legend[b-qelbtpp6qe] {
    float: none;
    width: auto;
    margin: 0 0 .75rem;
    padding: 0;
    font-size: .875rem;
    font-weight: 600;
    color: var(--text-secondary);
}

/* Label left, value right, hairline between — a small running total under the
   inputs that produce it. */
.service-figures[b-qelbtpp6qe] {
    margin: 1rem 0 0;
    border-top: 1px solid var(--border-color);
}

.service-figure[b-qelbtpp6qe] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: .5rem 0;
}

.service-figure + .service-figure[b-qelbtpp6qe] {
    border-top: 1px solid var(--border-color);
}

.service-figure dt[b-qelbtpp6qe] {
    display: flex;
    align-items: center;
    gap: .375rem;
    margin: 0;
    font-weight: 400;
    color: var(--text-secondary);
}

.service-figure dd[b-qelbtpp6qe] {
    margin: 0;
    font-variant-numeric: tabular-nums;
    font-weight: 600;
}
/* /Features/PriceBook/Pages/PriceBook.razor.rz.scp.css */
/* Keeps the two choice cards from stretching across a wide viewport. */
.pricebook-branch-choice[b-z1lwsgp12c] {
    max-width: 32rem;
}

/* The row menu is absolutely positioned inside its cell, so nothing in the table's
   ancestry may establish a clipping context (this is why there is no
   .table-responsive wrapper here). */
.pricebook-services[b-z1lwsgp12c] {
    overflow: visible;
}

/* The description is the long text, so it takes the slack; every other column is
   sized to its content so the figures stay in a straight line down the table. */
.pricebook-col-description[b-z1lwsgp12c] {
    width: 40%;
    white-space: normal;
}

.pricebook-col-money[b-z1lwsgp12c] {
    width: 8rem;
}

.pricebook-col-unit[b-z1lwsgp12c] {
    width: 6rem;
}

.pricebook-col-tax[b-z1lwsgp12c] {
    width: 6rem;
}

.pricebook-col-actions[b-z1lwsgp12c] {
    width: 3rem;
}

/* The thumbnail column is only as wide as the image itself. */
.pricebook-service-thumb-cell[b-z1lwsgp12c] {
    width: 1%;
}

/* The name opens the editor, but a column of link-blue names would read as noise —
   it keeps body colour and reveals itself on hover. */
.pricebook-service-name[b-z1lwsgp12c] {
    color: var(--text-primary);
    vertical-align: baseline;
}

.pricebook-service-name:hover[b-z1lwsgp12c],
.pricebook-service-name:focus-visible[b-z1lwsgp12c] {
    color: var(--bs-primary);
    text-decoration: underline !important;
}


.pricebook-service-thumb[b-z1lwsgp12c] {
    width: 3rem;
    height: 3rem;
    border-radius: var(--bs-border-radius);
    overflow: hidden;
    background-color: var(--bs-tertiary-bg);
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--bs-secondary-color);
}

.pricebook-service-thumb img[b-z1lwsgp12c] {
    width: 100%;
    height: 100%;
    object-fit: cover;
}
/* /Features/Schedule/Components/AssigneePicker.razor.rz.scp.css */
.assignee-chips[b-2560hd784k] {
    display: flex;
    flex-wrap: wrap;
    gap: 0.375rem;
    margin-top: 0.5rem;
}

.assignee-chip[b-2560hd784k] {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    background: var(--bg-surface-alt);
    border: 1px solid var(--border-color);
    border-radius: 999px;
    padding: 0.125rem 0.25rem 0.125rem 0.625rem;
    font-size: 0.8125rem;
    color: var(--text-primary);
}

.assignee-chip-remove[b-2560hd784k] {
    border: none;
    background: transparent;
    color: var(--text-secondary);
    border-radius: 50%;
    width: 20px;
    height: 20px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0;
}

.assignee-chip-remove:hover[b-2560hd784k] {
    background: color-mix(in srgb, var(--text-secondary) 15%, transparent);
    color: var(--text-primary);
}
/* /Features/Schedule/Components/MiniCalendar.razor.rz.scp.css */
.mini-cal[b-bftdrokn9i] {
    width: 100%;
    max-width: 260px;
    user-select: none;
}

.mini-cal-header[b-bftdrokn9i] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0.25rem 0.25rem 0.5rem 0.5rem;
}

.mini-cal-title[b-bftdrokn9i] {
    font-size: 0.875rem;
    font-weight: 600;
    color: var(--text-primary);
}

.mini-cal-nav-group[b-bftdrokn9i] {
    display: flex;
    gap: 0.125rem;
}

.mini-cal-nav[b-bftdrokn9i] {
    border: none;
    background: transparent;
    color: var(--text-secondary);
    border-radius: 50%;
    width: 28px;
    height: 28px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 0.75rem;
    transition: var(--transition);
}

.mini-cal-nav:hover[b-bftdrokn9i] {
    background: var(--bg-surface-alt);
    color: var(--text-primary);
}

.mini-cal-grid[b-bftdrokn9i] {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    row-gap: 2px;
}

.mini-cal-dow[b-bftdrokn9i] {
    text-align: center;
    font-size: 0.6875rem;
    font-weight: 600;
    color: var(--text-secondary);
    padding-bottom: 0.25rem;
}

.mini-cal-day[b-bftdrokn9i] {
    border: none;
    background: transparent;
    color: var(--text-primary);
    font-size: 0.75rem;
    height: 28px;
    border-radius: 50%;
    transition: background-color 0.15s ease-in-out;
}

.mini-cal-day:hover[b-bftdrokn9i] {
    background: var(--bg-surface-alt);
}

.mini-cal-day.is-outside[b-bftdrokn9i] {
    color: var(--text-secondary);
    opacity: 0.6;
}

/* The whole selected week reads as one pill across the row. */
.mini-cal-day.in-week[b-bftdrokn9i] {
    background: color-mix(in srgb, var(--primary) 14%, transparent);
    border-radius: 0;
}

.mini-cal-day.in-week-start[b-bftdrokn9i] {
    border-top-left-radius: 50%;
    border-bottom-left-radius: 50%;
}

.mini-cal-day.in-week-end[b-bftdrokn9i] {
    border-top-right-radius: 50%;
    border-bottom-right-radius: 50%;
}

.mini-cal-day.is-selected[b-bftdrokn9i] {
    background: color-mix(in srgb, var(--primary) 28%, transparent);
}

.mini-cal-day.is-today[b-bftdrokn9i] {
    background: var(--primary);
    color: var(--text-on-primary);
    font-weight: 600;
}
/* /Features/Schedule/Components/WeekCalendar.razor.rz.scp.css */
.week-cal[b-ec006t5xmn] {
    height: 100%;
    overflow-y: auto;
    background: var(--bg-surface);
    border: 1px solid var(--border-color);
    border-radius: var(--radius);
    min-width: 640px;
    user-select: none;
}

/* ---- Header (sticky inside the calendar's own scroll context so the day
   columns always line up with the grid below) ---- */

.week-cal-head[b-ec006t5xmn] {
    position: sticky;
    top: 0;
    z-index: 5;
    display: grid;
    grid-template-columns: 56px repeat(7, 1fr);
    background: var(--bg-surface);
    border-bottom: 1px solid var(--border-color);
}

.week-cal-corner[b-ec006t5xmn] {
    display: flex;
    align-items: flex-end;
    justify-content: flex-end;
    padding: 0.25rem 0.375rem;
}

.week-cal-tz[b-ec006t5xmn] {
    font-size: 0.625rem;
    color: var(--text-secondary);
}

.week-cal-dayhead[b-ec006t5xmn] {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.125rem;
    padding: 0.5rem 0.25rem 0.375rem;
    border-left: 1px solid var(--border-color);
    min-width: 0;
}

.week-cal-dow[b-ec006t5xmn] {
    font-size: 0.6875rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    color: var(--text-secondary);
}

.week-cal-daynum[b-ec006t5xmn] {
    font-size: 1.125rem;
    color: var(--text-primary);
    width: 32px;
    height: 32px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
}

.week-cal-daynum.is-today[b-ec006t5xmn] {
    background: var(--primary);
    color: var(--text-on-primary);
    font-weight: 600;
}

/* All-day holiday strip: informational chips above the hours. */
.week-cal-holidays[b-ec006t5xmn] {
    display: flex;
    flex-direction: column;
    gap: 2px;
    width: 100%;
}

.cal-holiday[b-ec006t5xmn] {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.25rem;
    font-size: 0.625rem;
    color: var(--text-primary);
    background: color-mix(in srgb, var(--warning) 25%, transparent);
    border-radius: 4px;
    padding: 1px 6px;
    cursor: pointer;
    transition: filter 0.15s ease-in-out;
}

.cal-holiday:hover[b-ec006t5xmn] {
    filter: brightness(0.97);
}

.cal-holiday-icon[b-ec006t5xmn] {
    font-size: 0.625rem;
    flex-shrink: 0;
}

.cal-holiday-name[b-ec006t5xmn] {
    min-width: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* ---- Time grid ---- */

.week-cal-grid[b-ec006t5xmn] {
    position: relative;
    display: grid;
    grid-template-columns: 56px repeat(7, 1fr);
}

.week-cal-gutter[b-ec006t5xmn] {
    position: relative;
}

.week-cal-hour[b-ec006t5xmn] {
    position: absolute;
    right: 0.375rem;
    transform: translateY(-50%);
    font-size: 0.625rem;
    color: var(--text-secondary);
    white-space: nowrap;
}

.week-cal-daycol[b-ec006t5xmn] {
    position: relative;
    border-left: 1px solid var(--border-color);
    min-width: 0;
    /* Hour lines at every 48px boundary (skipping the top edge). */
    background-image: repeating-linear-gradient(
        to bottom,
        transparent 0 47px,
        var(--border-color) 47px 48px);
}

.week-cal-daycol.can-create[b-ec006t5xmn] {
    cursor: pointer;
}

/* Out-of-business-hours shading (closed days are fully shaded). */
.cal-off-hours[b-ec006t5xmn] {
    position: absolute;
    left: 0;
    right: 0;
    background: color-mix(in srgb, var(--text-secondary) 10%, transparent);
    pointer-events: none;
    z-index: 0;
}

/* ---- Entries ---- */

.cal-entry[b-ec006t5xmn] {
    position: absolute;
    z-index: 2;
    display: flex;
    flex-direction: column;
    gap: 1px;
    padding: 3px 6px;
    border-radius: 6px;
    font-size: 0.75rem;
    line-height: 1.25;
    overflow: hidden;
    cursor: pointer;
    box-shadow: var(--card-shadow);
    transition: filter 0.15s ease-in-out;
}

.cal-entry:hover[b-ec006t5xmn] {
    filter: brightness(0.97);
}

.cal-entry-title[b-ec006t5xmn] {
    font-weight: 600;
    color: var(--text-primary);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.cal-entry-icon[b-ec006t5xmn] {
    font-size: 0.6875rem;
}

.cal-entry-subtitle[b-ec006t5xmn] {
    font-size: 0.6875rem;
    color: var(--text-secondary);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.cal-entry-time[b-ec006t5xmn] {
    font-size: 0.6875rem;
    color: var(--text-secondary);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.cal-entry-users[b-ec006t5xmn] {
    font-size: 0.6875rem;
    color: var(--text-secondary);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Single 30-min slots: everything on one vertically-centered line. */
.cal-entry--compact[b-ec006t5xmn] {
    flex-direction: row;
    align-items: center;
    gap: 0.375rem;
    padding: 0 6px;
}

.cal-entry--compact .cal-entry-title[b-ec006t5xmn] {
    flex: 0 1 auto;
    min-width: 0;
}

.cal-entry--compact .cal-entry-time[b-ec006t5xmn] {
    flex-shrink: 0;
}

.cal-entry--event[b-ec006t5xmn] {
    background: color-mix(in srgb, var(--primary) 22%, var(--bg-surface));
    border-left: 3px solid var(--primary);
}

.cal-entry--block[b-ec006t5xmn] {
    background: repeating-linear-gradient(
        45deg,
        color-mix(in srgb, var(--text-secondary) 16%, var(--bg-surface)) 0 6px,
        color-mix(in srgb, var(--text-secondary) 8%, var(--bg-surface)) 6px 12px);
    border-left: 3px solid var(--text-secondary);
}

.cal-entry--appointment[b-ec006t5xmn] {
    background: color-mix(in srgb, var(--success) 20%, var(--bg-surface));
    border-left: 3px solid var(--success);
}

/* ---- One-hour tentative selection ---- */

.cal-selection[b-ec006t5xmn] {
    position: absolute;
    left: 2px;
    right: 2px;
    z-index: 2;
    background: color-mix(in srgb, var(--primary) 22%, transparent);
    border: 1.5px dashed var(--primary);
    border-radius: 6px;
    padding: 2px 6px;
    font-size: 0.6875rem;
    font-weight: 600;
    color: var(--text-primary);
    pointer-events: none;
    overflow: hidden;
}

/* ---- Current time indicator ---- */

.cal-now[b-ec006t5xmn] {
    position: absolute;
    left: 0;
    right: 0;
    border-top: 2px solid var(--danger);
    z-index: 3;
    pointer-events: none;
}

.cal-now-dot[b-ec006t5xmn] {
    position: absolute;
    left: -4px;
    top: -5px;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--danger);
}

/* ---- Popovers (slot menu + entry details) ---- */

.cal-popover[b-ec006t5xmn] {
    position: absolute;
    z-index: 7;
}

.cal-entry-popover[b-ec006t5xmn] {
    background: var(--bg-elevated);
    border: 1px solid var(--border-color);
    border-radius: var(--radius);
    box-shadow: var(--card-shadow);
    padding: 0.75rem;
}

.cal-entry-popover-head[b-ec006t5xmn] {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.cal-entry-popover-title[b-ec006t5xmn] {
    font-weight: 600;
    color: var(--text-primary);
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.cal-entry-popover-close[b-ec006t5xmn] {
    font-size: 0.625rem;
    flex-shrink: 0;
}

.cal-entry-dot[b-ec006t5xmn] {
    width: 10px;
    height: 10px;
    border-radius: 3px;
    flex-shrink: 0;
}

.cal-entry-dot--event[b-ec006t5xmn] {
    background: var(--primary);
}

.cal-entry-dot--block[b-ec006t5xmn] {
    background: var(--text-secondary);
}

.cal-entry-dot--appointment[b-ec006t5xmn] {
    background: var(--success);
}

.cal-entry-dot--holiday[b-ec006t5xmn] {
    background: var(--warning);
}

.cal-entry-popover-body[b-ec006t5xmn] {
    font-size: 0.8125rem;
    color: var(--text-primary);
}

/* The customer and the assignees are their own blocks: spacing is what sets them
   apart from the lines above, so neither needs a rule or a divider. */
.cal-customer[b-ec006t5xmn],
.cal-entry-popover-assignees[b-ec006t5xmn] {
    margin-top: 0.625rem;
}

/* The icon leads the block from a column of its own; name, address and phone share
   the column beside it, so the whole card reads as one indented group. Letting the
   grid size that column keeps the alignment exact whatever the icon font metrics are. */
.cal-customer[b-ec006t5xmn] {
    display: grid;
    grid-template-columns: auto 1fr;
    column-gap: 0.25rem;
}

.cal-customer > *:not(.cal-customer-icon)[b-ec006t5xmn] {
    grid-column: 2;
}

.cal-customer-icon[b-ec006t5xmn] {
    /* Line up with the first line's text rather than the top of the box. */
    line-height: inherit;
}

.cal-customer-name[b-ec006t5xmn] {
    font-weight: 600;
    color: var(--text-primary);
}

.cal-entry-popover-actions[b-ec006t5xmn] {
    display: flex;
    justify-content: flex-end;
    gap: 0.5rem;
    margin-top: 0.75rem;
    padding-top: 0.625rem;
    border-top: 1px solid var(--border-color);
}
/* /Features/Schedule/Pages/Calendar.razor.rz.scp.css */
.calendar-page[b-5i4r5cxt8y] {
    height: 100%;
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    padding: 1rem;
}

/* ---- Toolbar ---- */

.calendar-toolbar[b-5i4r5cxt8y] {
    display: flex;
    align-items: center;
    gap: 0.25rem;
    flex-wrap: wrap;
    flex: 0 0 auto;
}

.cal-tool-btn[b-5i4r5cxt8y] {
    color: var(--text-secondary);
    border: none;
    border-radius: 50%;
    width: 36px;
    height: 36px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0;
}

.cal-tool-btn:hover[b-5i4r5cxt8y] {
    background: var(--bg-surface-alt);
    color: var(--text-primary);
}

.calendar-toolbar[b-5i4r5cxt8y]  .cal-range-btn {
    color: var(--text-primary);
    font-weight: 600;
    font-size: 1.0625rem;
    text-decoration: none;
    border: none;
    padding: 0.25rem 0.5rem;
    border-radius: var(--radius);
}

.calendar-toolbar[b-5i4r5cxt8y]  .cal-range-btn:hover {
    background: var(--bg-surface-alt);
}

.calendar-toolbar[b-5i4r5cxt8y]  .cal-range-caret {
    font-size: 0.75rem;
    color: var(--text-secondary);
}

.cal-fullday-toggle[b-5i4r5cxt8y] {
    color: var(--text-secondary);
    font-size: 0.875rem;
}

/* ---- Shell: slide-in sidebar + calendar ---- */

.calendar-shell[b-5i4r5cxt8y] {
    flex: 1;
    min-height: 0;
    display: flex;
    gap: 1rem;
}

.calendar-sidebar[b-5i4r5cxt8y] {
    flex: 0 0 auto;
    width: 0;
    opacity: 0;
    overflow: hidden;
    transform: translateX(-8px);
    transition: width 0.25s ease-in-out, opacity 0.2s ease-in-out, transform 0.25s ease-in-out;
}

.calendar-sidebar.open[b-5i4r5cxt8y] {
    width: 264px;
    opacity: 1;
    transform: none;
}

/* Fixed inner width so the content doesn't squish while the panel animates. */
.calendar-sidebar-inner[b-5i4r5cxt8y] {
    width: 264px;
    height: 100%;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: 1.25rem;
    padding-right: 0.25rem;
}

.calendar-side-title[b-5i4r5cxt8y] {
    font-size: 0.75rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-secondary);
}

.calendar-main[b-5i4r5cxt8y] {
    flex: 1;
    min-width: 0;
    min-height: 0;
    overflow-x: auto;
}
/* /Features/Settings/FeatureConfigurations/Pipeline/Boards/Leads/LeadBoardSettings.razor.rz.scp.css */
/* Automation flow on the pipeline-settings back face. A single top-to-bottom
   timeline for the whole stage: the lead enters, then each automation runs in
   sequence, ending at auto-archive (the terminal node). Reads as a progression
   and leaves room for more actions above the archive step.

   The markup is passed to KanbanBoard as a RenderFragment, so it renders under
   KanbanBoard's scope id — every rule here needs ::deep to reach it. */
[b-swinss7407] .automation-flow {
    position: relative;
    display: flex;
    flex-direction: column;
    padding: 0.25rem 0.25rem 0;
}

[b-swinss7407] .automation-flow__step {
    position: relative;
    display: grid;
    grid-template-columns: 24px 1fr;
    column-gap: 0.625rem;
    align-items: start;
    padding-bottom: 0.875rem;
}

[b-swinss7407] .automation-flow__step:last-child {
    padding-bottom: 0;
}

/* Give the entry step extra room so the connector to the first action breathes. */
[b-swinss7407] .automation-flow__step--start {
    padding-bottom: 1.75rem;
}

/* Vertical connector through the node column, capped at the first and last node
   centres so it spans exactly "enters → archived". Sits behind the nodes. */
[b-swinss7407] .automation-flow__step::before {
    content: "";
    position: absolute;
    left: 11px;
    top: 0;
    bottom: 0;
    width: 2px;
    background-color: color-mix(in srgb, var(--primary) 28%, var(--border-color));
    z-index: 0;
}

[b-swinss7407] .automation-flow__step--start::before {
    top: 12px;
}

[b-swinss7407] .automation-flow__step:last-child::before {
    bottom: auto;
    height: 12px;
}

[b-swinss7407] .automation-flow__node {
    position: relative;
    z-index: 1;
    width: 24px;
    height: 24px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    font-size: 0.72rem;
    background-color: var(--card-bg);
    border: 2px solid color-mix(in srgb, var(--primary) 35%, var(--border-color));
    color: var(--bs-primary, #1e1554);
}

/* Entry node: a quiet starting point. */
[b-swinss7407] .automation-flow__step--start .automation-flow__node {
    color: var(--text-secondary);
    border-color: var(--text-secondary);
}

/* Terminal (archive) node: filled — the destination the lead reaches. */
[b-swinss7407] .automation-flow__step--end .automation-flow__node {
    color: #fff;
    background-color: var(--bs-primary, #1e1554);
    border-color: var(--bs-primary, #1e1554);
    box-shadow: 0 2px 8px color-mix(in srgb, var(--primary) 35%, transparent);
}

[b-swinss7407] .automation-flow__content {
    min-width: 0;
}

/* Paused automation — everything but the on/off switch reads muted. */
[b-swinss7407] .automation-flow__step--off .automation-flow__node,
[b-swinss7407] .automation-flow__step--off .automation-flow__title,
[b-swinss7407] .automation-flow__step--off .automation-flow__meta {
    opacity: 0.55;
}

[b-swinss7407] .automation-flow__entry {
    font-size: 0.8rem;
    color: var(--text-secondary);
    line-height: 24px;
}

[b-swinss7407] .automation-flow__head {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    min-height: 24px;
}

[b-swinss7407] .automation-flow__title {
    flex: 1 1 auto;
    min-width: 0;
    font-weight: 600;
    line-height: 1.2;
}

[b-swinss7407] .automation-flow__meta {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.4rem;
    margin-top: 0.25rem;
    font-size: 0.78rem;
    color: var(--text-secondary);
}

[b-swinss7407] .automation-flow__wait {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    padding: 0.1rem 0.5rem;
    border-radius: 999px;
    font-weight: 600;
    white-space: nowrap;
    color: var(--bs-primary, #1e1554);
    background-color: var(--bs-primary-bg-subtle, rgba(30, 21, 84, 0.08));
    border: 1px solid color-mix(in srgb, var(--primary) 22%, transparent);
}

[b-swinss7407] .automation-flow__arrow {
    flex: 0 0 auto;
    display: inline-flex;
    color: var(--text-secondary);
}

/* Channel chip on a send-message step (Email / SMS). */
[b-swinss7407] .automation-flow__chip {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    padding: 0.05rem 0.45rem;
    border-radius: 999px;
    font-size: 0.72rem;
    font-weight: 500;
    color: var(--text-secondary);
    background-color: var(--bs-tertiary-bg);
    border: 1px solid var(--border-color);
}

/* Destination stage of a move — the variable bit, so give it weight. */
[b-swinss7407] .automation-flow__target {
    min-width: 0;
    font-weight: 600;
    color: var(--text-primary);
}
/* /Features/Settings/FeatureConfigurations/Pipeline/Pages/PipelineSettings.razor.rz.scp.css */
.pipeline-avatar[b-9i0ld459wk] {
    width: 48px;
    height: 48px;
    border-radius: 12px;
    background-color: var(--bs-primary-bg-subtle, rgba(30, 21, 84, 0.08));
    color: var(--bs-primary, #1e1554);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.4rem;
    flex-shrink: 0;
}

.pipeline-settings-page[b-9i0ld459wk] {
    min-height: 100%;
    display: flex;
    flex-direction: column;
}

/* Vertical fill chain: the board columns stretch to the full page height through
   the tab panes (Tabs component) and each board's own fill wrapper. ::deep is
   needed because these elements are rendered by child components. */
.pipeline-settings-page[b-9i0ld459wk]  .tab-content,
.pipeline-settings-page[b-9i0ld459wk]  .tab-content > .tab-pane.active,
.pipeline-settings-page[b-9i0ld459wk]  .pipeline-fill {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-height: 0;
}

/* Keep the secondary (Customize/Automations) segmented control right after the
   board tabs instead of pushed to the far edge, so it stays put as the screen
   grows wider. */
.pipeline-settings-page[b-9i0ld459wk]  .tabs-header {
    /* Bootstrap's justify-content-between / gap-2 utilities on the element use
       !important, so the override needs it too. */
    justify-content: flex-start !important;
    gap: 1rem !important;
}
/* /Features/Settings/FeatureConfigurations/PriceBook/Components/PriceBookImportStatus.razor.rz.scp.css */
/* Lets the flex children shrink so long file names truncate instead of overflowing —
   Bootstrap has no utility for this. */
.min-w-0[b-r1whrcs8ku] {
    min-width: 0;
}

/* A capped-but-still-long error list must not push the card down the page. */
.import-status-errors[b-r1whrcs8ku] {
    max-height: 12rem;
    overflow-y: auto;
}

/* The email is where the full result lives — on a truncated error list it is the only
   place the remaining lines exist — so it gets a tinted band of its own instead of
   trailing the text. Theme tokens keep it readable in light and dark. */
.import-status-email[b-r1whrcs8ku] {
    background-color: var(--bg-surface-alt);
    color: var(--text-primary);
}
/* /Features/Settings/FeatureConfigurations/PriceBook/Components/TaxRatesTab.razor.rz.scp.css */
/* The description takes the slack; the rate and the row menu are sized to their content,
   which keeps the figures in a straight line instead of stranded at the far edge.
   Same column sizing the price book's own service table uses. */
.tax-rate-col-rate[b-6u336cszza] {
    width: 8rem;
}

.tax-rate-col-actions[b-6u336cszza] {
    width: 3rem;
}
/* /Features/Settings/FeatureConfigurations/PriceBook/Pages/PriceBookSettings.razor.rz.scp.css */
.pricebook-settings-avatar[b-3zn10igqgc] {
    width: 48px;
    height: 48px;
    border-radius: 12px;
    background-color: var(--bs-primary-bg-subtle, rgba(30, 21, 84, 0.08));
    color: var(--bs-primary, #1e1554);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.4rem;
    flex-shrink: 0;
}
/* /Features/Settings/GlobalSettings/Company/Pages/CompanyDetails.razor.rz.scp.css */
.company-avatar[b-myblnxf06d] {
    width: 48px;
    height: 48px;
    border-radius: 12px;
    background-color: var(--bs-primary-bg-subtle, rgba(30, 21, 84, 0.08));
    color: var(--bs-primary, #1e1554);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.4rem;
    flex-shrink: 0;
}

.company-logo-preview[b-myblnxf06d] {
    max-height: 72px;
    max-width: 100%;
    object-fit: contain;
    border-radius: 8px;
}

.info-section-title[b-myblnxf06d] {
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--bs-secondary-color, #6c757d);
    margin-bottom: 0.75rem;
}

.info-label[b-myblnxf06d] {
    font-size: 0.75rem;
    color: var(--bs-secondary-color, #6c757d);
    margin-bottom: 0.15rem;
}

.info-value[b-myblnxf06d] {
    font-weight: 500;
}

.info-divider[b-myblnxf06d] {
    margin: 1.5rem 0;
    opacity: 0.12;
}

.business-hour-day[b-myblnxf06d] {
    font-weight: 500;
    min-width: 6.5rem;
}
/* /Features/Settings/GlobalSettings/Holding/Pages/HoldingDetails.razor.rz.scp.css */
.holding-avatar[b-4ebkh72qr8] {
    width: 48px;
    height: 48px;
    border-radius: 12px;
    background-color: var(--bs-primary-bg-subtle, rgba(30, 21, 84, 0.08));
    color: var(--bs-primary, #1e1554);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.4rem;
    flex-shrink: 0;
}

.info-section-title[b-4ebkh72qr8] {
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--bs-secondary-color, #6c757d);
    margin-bottom: 0.75rem;
}

.info-label[b-4ebkh72qr8] {
    font-size: 0.75rem;
    color: var(--bs-secondary-color, #6c757d);
    margin-bottom: 0.15rem;
}

.info-value[b-4ebkh72qr8] {
    font-weight: 500;
}

.info-divider[b-4ebkh72qr8] {
    margin: 1.5rem 0;
    opacity: 0.12;
}
/* /Features/Settings/SettingsLayout.razor.rz.scp.css */
.settings-layout[b-s7wcidocuo] {
    display: flex;
    flex-direction: row;
    height: 100%;
    min-height: 100%;
}

.settings-content[b-s7wcidocuo] {
    flex: 1;
    min-width: 0;
    min-height: 0;
    display: flex;
    flex-direction: column;
    overflow: auto;
    padding: 1rem 1rem 0 1rem;
}

.settings-nav-section-label[b-s7wcidocuo] {
    padding: 0.5rem 0.75rem 0.25rem 0.75rem;
    font-size: 0.7rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--text-secondary);
}
/* /Shared/Components/Attachments/AttachmentPreviewModal.razor.rz.scp.css */
/* The media sits inside the Modal component's BodyContent, so it renders under
   Modal's scope id — reach it with ::deep from this component's root. */

/* Preview modal media: cap to the viewport so tall images/videos don't scroll. */
[b-wo9fk7auaa] .attachment-preview-media {
    max-height: 70vh;
    object-fit: contain;
}

[b-wo9fk7auaa] .attachment-preview-frame {
    height: 75vh;
}
/* /Shared/Components/Attachments/AttachmentsCard.razor.rz.scp.css */
/* Preview tile: the clickable thumbnail that opens the preview modal. */
.attachment-tile[b-o16alpghm4] {
    transition: filter 0.15s ease;
}

.attachment-tile:hover[b-o16alpghm4] {
    filter: brightness(0.9);
}

.attachment-tile:focus-visible[b-o16alpghm4] {
    outline: 2px solid var(--primary);
    outline-offset: 2px;
}

/* Play badge overlaid on video thumbnails. */
.attachment-play-badge[b-o16alpghm4] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.75rem;
    height: 2.75rem;
    border-radius: 50%;
    background-color: rgba(0, 0, 0, 0.55);
    color: #fff;
    font-size: 1.5rem;
}
/* /Shared/Components/InfiniteScroll/InfiniteScrollSentinel.razor.rz.scp.css */
/* Zero-footprint markers observed by IntersectionObserver to trigger paging. */
.infinite-scroll-sentinel[b-8obpt1j4hr] {
    height: 1px;
    flex: 0 0 auto;
    pointer-events: none;
}
/* /Shared/Components/InfoTooltip.razor.rz.scp.css */
.info-tooltip[b-ovv2qbacjj] {
    position: relative;
    display: inline-flex;
    align-items: center;
}

.info-tooltip-trigger[b-ovv2qbacjj] {
    color: var(--bs-secondary-color);
    line-height: 1;
    text-decoration: none;
}

.info-tooltip-trigger:hover[b-ovv2qbacjj],
.info-tooltip-trigger:focus-visible[b-ovv2qbacjj] {
    color: var(--bs-primary);
}

/* Bootstrap's popover classes only carry the looks; placement is ours because the
   Popper-driven JS API isn't loaded.

   The bubble hangs below the trigger and is anchored to its left edge rather than
   centred: a centred bubble overflows the left side of whatever narrow column the
   trigger sits in, and without Popper nothing flips it back into view. Downward,
   because these live in modal bodies that scroll — an upward bubble would be
   clipped by the top of that scroll box. */
.info-tooltip-bubble[b-ovv2qbacjj] {
    position: absolute;
    top: calc(100% + .5rem);
    left: 0;
    width: max-content;
    max-width: min(16rem, 60vw);
    z-index: var(--bs-tooltip-zindex, 1080);
    white-space: normal;
    text-align: left;
}

/* .bs-popover-bottom places the arrow vertically; horizontally it sits over the
   trigger, since Popper normally supplies that offset inline. */
.info-tooltip-arrow[b-ovv2qbacjj] {
    left: .5rem;
}

/* The popover body inherits the small, muted type of the label it explains unless
   it is reset here. */
.info-tooltip-bubble .popover-body[b-ovv2qbacjj] {
    font-size: var(--bs-body-font-size);
    color: var(--bs-body-color);
}
/* /Shared/Components/Kanban/KanbanBoard.razor.rz.scp.css */
/* Every rule here is scoped to KanbanBoard's own markup. Two dependencies to
   keep in mind when editing:
   - The drag ghost is a cloneNode(true) appended to <body> (see
     KanbanBoard.razor.js). The clone keeps the scope attribute, so
     .kanban-column--ghost still matches outside the component tree.
   - Consumers style *inside* a card from their own scope (e.g. LeadKanbanCard's
     .times-footer cancels the .kanban-card padding with negative margins), so
     changing the padding below means checking those. */

.kanban-board[b-e2ksbvnkas] {
    display: flex;
    gap: 0.5rem;
    align-items: stretch;
    padding-bottom: 0.5rem;
    flex: 1 0 auto;
}

.kanban-column[b-e2ksbvnkas] {
    flex: 0 0 300px;
    /* Lock the column to its flex-basis: without this the flexbox automatic
       minimum size (min-width: auto) lets long header/card content widen the
       column, so columns end up sized by their content. All boards share this
       300px width; this just stops the overflow from growing it. Do NOT add
       max-width here — use flex-basis if a board ever needs a different width. */
    min-width: 0;
    background-color: var(--bg-surface-alt);
    border: 1px solid var(--border-color);
    border-radius: var(--radius);
    display: flex;
    flex-direction: column;
    transition: var(--transition);
}

.kanban-column--drag-over[b-e2ksbvnkas] {
    border-color: var(--accent);
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--primary) 30%, transparent);
}

.kanban-column--dragging[b-e2ksbvnkas] {
    opacity: 0.5;
}

.kanban-board--reorderable .kanban-column[b-e2ksbvnkas] {
    cursor: grab;
    touch-action: none;
    user-select: none;
}

/* Column excluded from reordering (ColumnReorderableSelector) — no grab affordance. */
.kanban-board--reorderable .kanban-column--static[b-e2ksbvnkas] {
    cursor: default;
}

/* Muted column (ColumnClassSelector) — e.g. a hidden pipeline stage in settings.
   A parent opacity would also fade the controls (children can't escape it), so
   the fade is a translucent wash (::after, page-background tinted) over the
   column box instead; interactive controls are lifted above the wash below.
   Flippable columns carry the box on their faces, plain columns on themselves. */
.kanban-column--dimmed:not(.kanban-column--flippable)[b-e2ksbvnkas],
.kanban-column--dimmed .kanban-column__face[b-e2ksbvnkas] {
    position: relative;
    border-color: color-mix(in srgb, var(--border-color) 55%, transparent);
}

.kanban-column--dimmed:not(.kanban-column--flippable)[b-e2ksbvnkas]::after,
.kanban-column--dimmed .kanban-column__face[b-e2ksbvnkas]::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
    background-color: color-mix(in srgb, var(--bg-body) 45%, transparent);
    pointer-events: none;
    z-index: 1;
}

/* Menus, buttons and switches pop above the wash — a hidden column is still
   fully operable. (The dropdown popup already sits at Bootstrap's z-index.)
   The controls come from the consumer's ColumnHeaderTemplate, so they render
   under the consumer's scope — ::deep is required to reach them. */
.kanban-column--dimmed[b-e2ksbvnkas]  button,
.kanban-column--dimmed[b-e2ksbvnkas]  .form-switch {
    position: relative;
    z-index: 2;
}

/* While reordering, the source column stays in flow as a translucent dashed
   placeholder that slides to the prospective slot, showing where the column
   will land. The column the user actually drags is the floating clone below. */
.kanban-board--reorderable .kanban-column--dragging[b-e2ksbvnkas] {
    cursor: grabbing;
    opacity: 0.45;
    border-style: dashed;
    border-color: var(--primary);
    box-shadow: none;
}

/* The floating clone: detached from the flow, follows the pointer and passes in
   front of every column. JS owns its position (fixed left/top/width/height). */
.kanban-column--ghost[b-e2ksbvnkas] {
    position: fixed;
    margin: 0;
    z-index: 1000;
    pointer-events: none;
    cursor: grabbing;
    opacity: 0.97;
    box-shadow: 0 18px 40px rgba(0, 0, 0, 0.28);
    border-color: var(--primary);
    /* Only the lift animates; left/top must track the pointer instantly. */
    transition: transform 0.12s ease;
    transform: scale(1.02);
    will-change: left, top;
}

/* Buttons/links inside a column come from consumer templates (another scope). */
.kanban-board--reorderable .kanban-column[b-e2ksbvnkas]  button,
.kanban-board--reorderable .kanban-column[b-e2ksbvnkas]  a {
    cursor: pointer;
}

/* Flip card: the column hosts two stacked faces (front = normal layout,
   back = alternate layout) and rotates in 3D to swap between them. The .kanban-column
   itself becomes a transparent perspective frame; the box styling moves to the faces. */
.kanban-column--flippable[b-e2ksbvnkas] {
    background-color: transparent;
    border: none;
    perspective: 1400px;
}

.kanban-column__flip[b-e2ksbvnkas] {
    /* Both faces share grid cell 1/1 so the card sizes to the taller face and
       neither is clipped, regardless of which side is showing. */
    display: grid;
    /* minmax(0, 1fr) + min-width: 0 pin the track to the column width so the
       column's locked width propagates to the faces; without this the grid's
       auto track grows with the face content (long descriptions), defeating the
       column's min-width: 0 lock. */
    grid-template-columns: minmax(0, 1fr);
    min-width: 0;
    flex: 1 1 auto;
    transform-style: preserve-3d;
    transition: transform 1s cubic-bezier(0.2, 0.7, 0.2, 1);
    transition-delay: var(--flip-delay, 0ms);
}

.kanban-column--flipped .kanban-column__flip[b-e2ksbvnkas] {
    transform: rotateY(180deg);
}

.kanban-column__face[b-e2ksbvnkas] {
    grid-area: 1 / 1;
    /* Let the face shrink to the grid track so its header/body content truncates
       instead of widening the card. */
    min-width: 0;
    display: flex;
    flex-direction: column;
    background-color: var(--bg-surface-alt);
    border: 1px solid var(--border-color);
    border-radius: var(--radius);
    backface-visibility: hidden;
    -webkit-backface-visibility: hidden;
}

/* The back is clearly "not the front": the whole face takes a brand-tinted tone
   (surface blended toward --primary) with a matching tinted border, so it reads as
   a different layer in both light and dark themes. */
.kanban-column__face--back[b-e2ksbvnkas] {
    transform: rotateY(180deg);
    background-color: color-mix(in srgb, var(--bg-surface-alt) 90%, var(--primary));
    border-color: color-mix(in srgb, var(--border-color) 80%, var(--primary));
    box-shadow: inset 0 0 24px rgba(0, 0, 0, 0.05);
}

.kanban-column__header[b-e2ksbvnkas] {
    padding: 0.875rem 1rem;
    border-bottom: 1px solid var(--border-color);
    flex: 0 0 auto;
}

.kanban-column__body[b-e2ksbvnkas] {
    padding: 0.75rem;
    display: flex;
    flex-direction: column;
    gap: 0.625rem;
    flex: 1 1 auto;
    min-height: 80px;
}

.kanban-column__empty[b-e2ksbvnkas] {
    border: 1px dashed var(--border-color);
    border-radius: 12px;
    padding: 1rem;
    text-align: center;
}

.kanban-card[b-e2ksbvnkas] {
    background-color: var(--card-bg);
    border: 1px solid var(--border-color);
    border-radius: 12px;
    box-shadow: var(--card-shadow);
    padding: 0.75rem 0.875rem;
    cursor: grab;
    transition: var(--transition);
}

.kanban-card:hover[b-e2ksbvnkas] {
    border-color: var(--primary);
    transform: translateY(-1px);
}

.kanban-card:active[b-e2ksbvnkas] {
    cursor: grabbing;
}

.kanban-card--dragging[b-e2ksbvnkas] {
    opacity: 0.5;
}
/* /Shared/Components/LoadingButton/LoadingButton.razor.rz.scp.css */
/* Spinning icon used by SpinIcon mode: the icon rotates in place instead of
   being swapped for a spinner, so the button keeps its width. */
.icon-spin[b-sbhy220jgq] {
    display: inline-block;
    animation: icon-spin-b-sbhy220jgq 0.8s linear infinite;
}

@keyframes icon-spin-b-sbhy220jgq {
    from {
        transform: rotate(0deg);
    }

    to {
        transform: rotate(360deg);
    }
}
/* /Shared/Components/RadioGroup/RadioGroup.razor.rz.scp.css */
.radio-group[b-f1envqk5cp] {
    display: flex;
    gap: 0.75rem;
}

.radio-group-horizontal[b-f1envqk5cp] {
    flex-direction: row;
    flex-wrap: wrap;
}

.radio-group-horizontal .radio-card[b-f1envqk5cp] {
    flex: 1 1 0;
    min-width: 0;
}

.radio-group-vertical[b-f1envqk5cp] {
    flex-direction: column;
}

/* Reset the button chrome — the card is drawn entirely via the rules below. */
.radio-card[b-f1envqk5cp] {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.25rem;
    padding: 1rem;
    text-align: left;
    background: var(--bs-card-bg);
    border: 1px solid var(--bs-border-color);
    border-radius: var(--bs-border-radius, 12px);
    color: var(--bs-body-color);
    cursor: pointer;
    transition: border-color 0.15s ease, box-shadow 0.15s ease, background-color 0.15s ease;
}

.radio-card:hover:not(:disabled)[b-f1envqk5cp] {
    border-color: var(--bs-primary);
}

.radio-card:focus-visible[b-f1envqk5cp] {
    outline: none;
    border-color: var(--bs-primary);
    box-shadow: 0 0 0 0.2rem rgba(var(--bs-primary-rgb), 0.25);
}

.radio-card:disabled[b-f1envqk5cp] {
    opacity: 0.6;
    cursor: not-allowed;
}

.radio-card.selected[b-f1envqk5cp] {
    border-color: var(--bs-primary);
    box-shadow: 0 0 0 1px var(--bs-primary);
}

.radio-card-icon[b-f1envqk5cp] {
    font-size: 1.5rem;
    line-height: 1;
    color: var(--bs-primary);
}

.radio-card-title[b-f1envqk5cp] {
    display: block;
    font-weight: 600;
}

.radio-card-description[b-f1envqk5cp] {
    display: block;
    font-size: 0.875rem;
    color: var(--bs-secondary-color);
}

/* Check badge, hidden until the card is selected. */
.radio-card-check[b-f1envqk5cp] {
    position: absolute;
    top: 0.5rem;
    right: 0.5rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.25rem;
    height: 1.25rem;
    border-radius: 50%;
    background: var(--bs-primary);
    color: var(--text-on-primary, #fff);
    font-size: 0.75rem;
    opacity: 0;
    transform: scale(0.6);
    transition: opacity 0.15s ease, transform 0.15s ease;
}

.radio-card.selected .radio-card-check[b-f1envqk5cp] {
    opacity: 1;
    transform: scale(1);
}
/* /Shared/Components/Sheet/Sheet.razor.rz.scp.css */
.page-sheet[b-m9n90c91js] {
    position: fixed;
    inset: 0;
    z-index: 1080;
    display: flex;
    flex-direction: column;
    background-color: var(--bg-body);
    overflow: hidden;
    transform: translateY(100%);
    transition: transform 0.35s cubic-bezier(0.22, 0.61, 0.36, 1);
    will-change: transform;
}

.page-sheet--open[b-m9n90c91js] {
    transform: translateY(0);
}

.page-sheet__topbar[b-m9n90c91js] {
    position: sticky;
    top: 0;
    z-index: 1;
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 1rem 1.25rem;
    background-color: var(--bg-body);
}

.page-sheet__title[b-m9n90c91js] {
    color: var(--text-primary);
}

.page-sheet__topbar .btn-close[b-m9n90c91js] {
    --bs-btn-close-color: var(--text-primary);
    filter: none;
}

@media (prefers-color-scheme: dark) {
    .page-sheet__topbar .btn-close[b-m9n90c91js] {
        filter: invert(1) grayscale(100%) brightness(200%);
    }
}

.page-sheet__body[b-m9n90c91js] {
    flex: 1 1 auto;
    overflow-y: auto;
}

@media (prefers-reduced-motion: reduce) {
    .page-sheet[b-m9n90c91js] {
        transition: none;
    }
}
/* /Shared/Components/SideNav/SideNav.razor.rz.scp.css */
.side-nav[b-uase4gz1or] {
    display: flex;
    flex-direction: column;
    width: 220px;
    flex-shrink: 0;
    background-color: var(--bg-surface);
    border-right: 1px solid var(--border-color);
    transition: width 0.2s ease;
}

.side-nav-collapsed[b-uase4gz1or] {
    width: 48px;
}

.side-nav-header[b-uase4gz1or] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0.75rem 1rem;
    min-height: 48px;
}

.side-nav-collapsed .side-nav-header[b-uase4gz1or] {
    justify-content: center;
    padding: 0.75rem 0;
}

.side-nav-title[b-uase4gz1or] {
    font-weight: 600;
    color: var(--text-primary);
    font-size: 0.95rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.side-nav-toggle[b-uase4gz1or] {
    background: transparent;
    border: none;
    color: var(--text-secondary);
    padding: 0.25rem 0.4rem;
    border-radius: 8px;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: background-color 0.15s, color 0.15s;
}

.side-nav-toggle:hover[b-uase4gz1or] {
    background-color: var(--bg-surface-alt);
    color: var(--text-primary);
}

.side-nav-body[b-uase4gz1or] {
    display: flex;
    flex-direction: column;
    padding: 0.5rem;
    gap: 0.25rem;
    overflow-y: auto;
}

[b-uase4gz1or] .side-nav-link {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.5rem 0.75rem;
    border-radius: 10px;
    color: var(--text-secondary);
    text-decoration: none;
    font-size: 0.95rem;
    transition: background-color 0.15s ease, color 0.15s ease;
}

[b-uase4gz1or] .side-nav-link:hover {
    background-color: var(--bg-surface-alt);
    color: var(--text-primary);
}

/* Active item is just coloured text — the sliding side bar injected on the
   body carries the selection, so no solid background block. */
[b-uase4gz1or] .side-nav-link.active {
    color: var(--accent);
    font-weight: 600;
}
/* /Shared/Components/Tabs/Tabs.razor.rz.scp.css */
/* Project-owned classes (not Bootstrap overrides): the header rule only applies
   to the Tabs style, and the content gets breathing room under the nav.
   The .nav-tabs/.nav-pills looks themselves stay global in app.css — they are
   Bootstrap overrides shared with SegmentedControl and with consumers that
   reach the header from their own scope (e.g. PipelineSettings). */
.tabs-header-bordered[b-9rrybbwfg7] {
    border-bottom: 1px solid var(--border-color);
}

/* Breathing room under a flat strip. A panelled set overrides this with padding of
   its own on every side. */
.tab-content[b-9rrybbwfg7] {
    padding-top: 1rem;
}

/* The open notebook sheet: the panel carries the active tab's own surface, so the
   selected tab and the content below it read as one continuous page. Both top
   corners stay square — the strip sits on that edge, and rounding either side
   would pinch the join into a waist. */
.tab-content-surface[b-9rrybbwfg7] {
    background-color: var(--bg-surface);
    border-radius: 0 0 var(--radius) var(--radius);
    padding: var(--tab-panel-padding);
}

/* A strip the user grows without limit (an estimate's options): the tabs stay on one
   line and travel sideways instead of wrapping onto a second row that would push the
   panel down the page.

   `flex: 0 1 auto` with `min-width: 0` is what makes the scroll happen: the list must be
   allowed to fall below its content's size (min-width: 0 is what lifts the automatic
   minimum that would otherwise keep a flex item as wide as its content), but it must NOT
   grow. Growing would stretch a two-tab strip across the whole header and strand "New
   option" at the far edge; sized to its tabs, the button trails the last one until the
   tabs actually overflow, and only then does the strip take the leftover width and the
   button settle at the edge.

   The clipping stays here, on the list itself (overflow-x). The header must never clip:
   a tab's action menu opens out of it, and an ancestor with overflow: hidden would cut
   the dropdown off inside the strip. */
.tabs-nav-scrollable[b-9rrybbwfg7] {
    flex: 0 1 auto;
    flex-wrap: nowrap;
    min-width: 0;
    overflow-x: auto;

    /* The sheets' rounded tops sit on this edge; a bar drawn under them would cut the
       open tab off from its panel, so the strip scrolls without one — the arrows beside
       it are what makes the overflow reachable. */
    scrollbar-width: none;
}

.tabs-nav-scrollable[b-9rrybbwfg7]::-webkit-scrollbar {
    display: none;
}

/* Each sheet keeps its own width: left to shrink, the tabs would squeeze into an
   unreadable row rather than overflow into the scroll. */
.tabs-nav-scrollable > .nav-item[b-9rrybbwfg7] {
    flex: 0 0 auto;
}

/* The fades overlay the strip's edges, so the header is their containing block. */
.tabs-header-scrollable[b-9rrybbwfg7] {
    position: relative;
}

/* What tells the eye the strip carries on: the tab at the edge dissolves into the
   header instead of being chopped off square.

   Each fade is a zero-width flex item sitting next to its arrow, painting outwards from
   there with a negative margin. Anchoring them to the header's own edges instead would
   put the end one over the "New option" button, whose width the CSS cannot know.
   Decorative only — pointer events pass through to the tabs underneath. */
.tabs-fade[b-9rrybbwfg7] {
    flex: 0 0 0;
    align-self: stretch;
    width: 0;
    pointer-events: none;
    position: relative;
    z-index: 1;

    /* Half of the header's gap-2 (0.5rem), pulled back on each side: the header's gap
       would otherwise show up twice around this zero-width item, pushing the arrow away
       from the strip it belongs to. */
    margin-inline: -0.25rem;
}

.tabs-fade[b-9rrybbwfg7]::before {
    content: '';
    position: absolute;
    top: 0;
    bottom: 0;
    width: 2rem;
}

.tabs-fade-start[b-9rrybbwfg7]::before {
    left: 0;
    background: linear-gradient(to right, var(--bg-surface-alt), transparent);
}

.tabs-fade-end[b-9rrybbwfg7]::before {
    right: 0;
    background: linear-gradient(to left, var(--bg-surface-alt), transparent);
}

/* The arrows that page the strip. Quiet by default — they are a way to get somewhere,
   not part of the selection — and only present while there is strip left on that side
   (Tabs.razor.js toggles d-none).

   Their own surface, separated from the tabs by a border: sitting flush against a strip
   that scrolls under them, a bare chevron gives no clue where the click target ends and
   the first tab begins. */
.tabs-scroll[b-9rrybbwfg7] {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;

    width: 2.25rem;
    align-self: stretch;
    padding: 0;

    border: 0;
    background-color: var(--bg-surface-alt);
    color: var(--text-secondary);

    transition: color 0.15s ease, background-color 0.15s ease;
}

/* The edge that faces the tabs, so the boundary the pointer must not cross is drawn. */
.tabs-scroll-start[b-9rrybbwfg7] {
    border-right: 1px solid var(--border-color);
}

.tabs-scroll-end[b-9rrybbwfg7] {
    border-left: 1px solid var(--border-color);
}

.tabs-scroll:hover:not(:disabled)[b-9rrybbwfg7] {
    background-color: var(--bg-surface);
    color: var(--text-primary);
}

.tabs-scroll:focus[b-9rrybbwfg7],
.tabs-scroll:focus-visible[b-9rrybbwfg7] {
    box-shadow: none;
    outline: none;
}

/* At its end: dimmed and inert, but still holding its place so the strip beside it
   keeps the same width. */
.tabs-scroll:disabled[b-9rrybbwfg7] {
    color: var(--text-secondary);
    opacity: 0.3;
    cursor: default;
}

/* The arrows sit inside the header's recess, so they take its rounded corner rather
   than cutting a square edge out of it. */
.tabs-header-panelled > .tabs-scroll-start[b-9rrybbwfg7] {
    border-radius: var(--radius) 0 0 0;
}

/* The action that grows the strip stays reachable however far the tabs have been
   scrolled: it never shrinks with them, and it keeps its own room from the strip and
   from the header's edge instead of being squeezed against them.

   It keeps trailing the last tab rather than being pushed to the far edge: the strip
   takes the leftover width (flex: 1 1 auto), so with few options the button sits right
   after them, and with many it ends up at the edge anyway — with the tabs scrolling
   under it instead of shoving it out of the header. */
.tabs-header-end-pinned[b-9rrybbwfg7] {
    flex: 0 0 auto;
    padding-inline: 0.5rem 1rem;
}

/* The space beside the tabs — the binding the sheets are bound into. Recessed, so
   the open tab still reads as lifted off it, and only on a panelled set: a flat
   strip has no page for the strip to belong to. */
.tabs-header-panelled[b-9rrybbwfg7] {
    background-color: var(--bg-surface-alt);
    border-radius: var(--radius) var(--radius) 0 0;
}
/* /Shared/Components/Toast/ToastItem.razor.rz.scp.css */
.app-toast[b-pxndktp3tk] {
    background-color: var(--bg-surface);
    color: var(--text-primary);
    border: 1px solid var(--border-color);
    border-left: 4px solid var(--border-color);
    border-radius: 12px;
    box-shadow: var(--card-shadow);
    overflow: hidden;
}

.app-toast .toast-header[b-pxndktp3tk] {
    background-color: transparent;
    color: var(--text-primary);
    border-bottom: 1px solid var(--border-color);
    font-weight: 600;
}

.app-toast .toast-body[b-pxndktp3tk] {
    color: var(--text-secondary);
}

.app-toast .btn-close[b-pxndktp3tk] {
    --bs-btn-close-color: var(--text-primary);
    filter: none;
}

/* Type accents (left border + header icon) */
.app-toast--success[b-pxndktp3tk] {
    border-left-color: var(--success);
}

.app-toast--success .app-toast__icon[b-pxndktp3tk] {
    color: var(--success);
}

.app-toast--warning[b-pxndktp3tk] {
    border-left-color: var(--warning);
}

.app-toast--warning .app-toast__icon[b-pxndktp3tk] {
    color: var(--warning);
}

.app-toast--danger[b-pxndktp3tk] {
    border-left-color: var(--danger);
}

.app-toast--danger .app-toast__icon[b-pxndktp3tk] {
    color: var(--danger);
}

.app-toast--info[b-pxndktp3tk] {
    border-left-color: var(--primary);
}

.app-toast--info .app-toast__icon[b-pxndktp3tk] {
    color: var(--primary);
}

/* Auto-hide countdown shown in the header (mm:ss) */
.app-toast__time[b-pxndktp3tk] {
    font-size: 0.75rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    color: var(--text-secondary);
}

/* Straight progress line below the header that depletes over the toast lifetime */
.app-toast__progress[b-pxndktp3tk] {
    height: 0.5px;
    background-color: var(--accent);
    transform-origin: right center;
    animation: app-toast-progress-b-pxndktp3tk linear forwards;
    animation-duration: var(--toast-duration, 5000ms);
}

@keyframes app-toast-progress-b-pxndktp3tk {
    from {
        transform: scaleX(1);
    }

    to {
        transform: scaleX(0);
    }
}

@media (prefers-color-scheme: dark) {
    .app-toast .btn-close[b-pxndktp3tk] {
        filter: invert(1) grayscale(100%) brightness(200%);
    }
}
/* /Shared/Layout/MainLayout.razor.rz.scp.css */
.page[b-g2sra1s6uz] {
    display: flex;
    flex-direction: column;
    height: 100vh;
    background-color: var(--bg);
    transition: background-color 0.2s;
}

main[b-g2sra1s6uz] {
    flex: 1;
    overflow-y: auto;
    background-color: var(--bg);
}

.content[b-g2sra1s6uz] {
    padding-top: 1rem;
}
/* /Shared/Layout/NavMenu.razor.rz.scp.css */
/* Top navbar — background/colors come from the global .navbar theme (white in
   light, dark in dark mode). Here we only handle layout and the toggler. */
.top-row[b-r8kwkn4sde] {
    min-height: 3.5rem;
}

/* The brand box is a fixed slot so the header layout never shifts with the
   company name length or the logo aspect ratio: a longer name is truncated
   with an ellipsis, a shorter one just leaves empty space, and any logo is
   scaled to fit inside the same box. */
.navbar-brand[b-r8kwkn4sde] {
    display: flex;
    align-items: center;
    width: 9rem;
    height: 2rem;
    font-size: 1.1rem;
    letter-spacing: 0.2px;
    overflow: hidden;
}

.navbar-brand .brand-name[b-r8kwkn4sde] {
    min-width: 0;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}

/* Company icon shown in place of the brand name when the company has one. */
.navbar-brand .brand-icon[b-r8kwkn4sde] {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: contain;
    object-position: left center;
    border-radius: 4px;
}

/* Organization selector slot — inline next to the brand on tablet/desktop. */
.org-slot[b-r8kwkn4sde] {
    display: flex;
    align-items: center;
    min-width: 0;
}

/* On phones the brand + selector don't fit on one line, so the selector drops
   to its own full-width row below the brand (the navbar grows to two rows). */
@media (max-width: 767.98px) {
    .org-slot[b-r8kwkn4sde] {
        flex: 0 0 100%;
        min-width: 100%;
    }
}

/* Hamburger toggler (small screens only) */
.nav-toggler[b-r8kwkn4sde] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.5rem;
    height: 2.5rem;
    padding: 0;
    border: 0;
    border-radius: 8px;
    color: var(--navbar-text);
    background-color: transparent;
    font-size: 1.4rem;
    line-height: 1;
    transition: background-color 0.15s ease;
}

.nav-toggler:hover[b-r8kwkn4sde],
.nav-toggler:focus-visible[b-r8kwkn4sde] {
    background-color: rgba(128, 128, 128, 0.15);
    outline: none;
}

/* Horizontal nav links — text only, quiet by default; the shared sliding
   underline (injected on the nav) marks the active item and glides between
   links. The global `.navbar .nav-link` rule forces the colour, hence the
   !important on the overrides. */
.top-row[b-r8kwkn4sde]  .nav-link {
    display: inline-flex;
    align-items: center;
    padding: 0.35rem 0.4rem;
    font-size: 0.95rem;
    font-weight: 500;
    color: var(--text-secondary) !important;
    transition: color 0.15s ease;
}

.top-row[b-r8kwkn4sde]  .nav-link:hover {
    color: var(--text-primary) !important;
}

.top-row[b-r8kwkn4sde]  .nav-link.active {
    color: var(--accent) !important;
    font-weight: 600;
}

/* Logout link in the top bar */
.top-row[b-r8kwkn4sde]  a[href="#"] {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    color: var(--accent);
    font-size: 0.95rem;
    font-weight: 500;
    transition: color 0.15s ease;
}

.top-row[b-r8kwkn4sde]  a[href="#"]:hover {
    color: var(--accent);
}

/* Left drawer (small screens) — neutral surface with the brand colour reserved
   for the active item, matching the minimalist light/dark chrome. */
.nav-drawer[b-r8kwkn4sde] {
    width: 280px;
    max-width: 85vw;
    background-color: var(--bg-surface);
    color: var(--text-primary);
    border-right: 1px solid var(--border-color);
}

.nav-drawer .offcanvas-header[b-r8kwkn4sde] {
    border-bottom: 1px solid var(--border-color);
}

.nav-drawer .navbar-brand[b-r8kwkn4sde] {
    color: var(--text-primary);
}

@media (prefers-color-scheme: dark) {
    .nav-drawer .btn-close[b-r8kwkn4sde] {
        filter: invert(1) grayscale(100%) brightness(200%);
    }
}

.nav-drawer-divider[b-r8kwkn4sde] {
    border-color: var(--border-color);
    opacity: 1;
}

.nav-drawer[b-r8kwkn4sde]  .nav-link {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    color: var(--text-secondary);
    border-radius: 8px;
    padding: 0.6rem 0.9rem;
    font-size: 0.95rem;
    font-weight: 500;
    transition: background-color 0.15s ease, color 0.15s ease;
}

.nav-drawer[b-r8kwkn4sde]  .nav-link .bi {
    font-size: 1.1rem;
}

.nav-drawer[b-r8kwkn4sde]  .nav-link:hover {
    color: var(--text-primary);
    background-color: var(--bg-surface-alt);
}

.nav-drawer[b-r8kwkn4sde]  .nav-link.active {
    color: var(--primary);
    background-color: color-mix(in srgb, var(--primary) 12%, transparent);
}

.nav-drawer[b-r8kwkn4sde]  a[href="#"] {
    display: inline-flex;
    align-items: center;
    gap: 0.6rem;
    color: var(--accent);
    font-size: 0.95rem;
    font-weight: 500;
}

.nav-drawer[b-r8kwkn4sde]  a[href="#"]:hover {
    color: var(--accent);
}
/* /Shared/Layout/OrganizationMenu.razor.rz.scp.css */
/* Inline organization selector that lives inside the top navbar (no separate
   band): a subtle, borderless trigger per level, neutral until hovered. */
.org-selector[b-wkilfcxw0u] {
    display: inline-flex;
    align-items: center;
    min-width: 0;
    font-size: 0.875rem;
}

.org-selector[b-wkilfcxw0u]  .breadcrumb {
    /* U+203A as a CSS escape, not a literal: the generated scoped-css bundle
       carries no @charset, so a raw multi-byte character renders as mojibake
       when the stylesheet is served without a charset in Content-Type. */
    --bs-breadcrumb-divider: '\203A';
    --bs-breadcrumb-divider-color: var(--text-secondary);
    margin-bottom: 0;
    flex-wrap: nowrap;
    align-items: center;
    gap: 0;
}

.org-selector[b-wkilfcxw0u]  .breadcrumb-item {
    display: inline-flex;
    align-items: center;
    min-width: 0;
}

.org-selector[b-wkilfcxw0u]  .breadcrumb-item + .breadcrumb-item::before {
    align-self: center;
    color: var(--text-secondary);
    font-size: 1.1em;
    line-height: 1;
    padding: 0 0.15rem;
}

/* Borderless trigger — transparent until hovered/open (Google-style). */
.org-selector[b-wkilfcxw0u]  .org-trigger {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    max-width: 100%;
    min-width: 0;
    padding: 0.3rem 0.55rem;
    border: 1px solid transparent;
    border-radius: 8px;
    background-color: transparent;
    font: inherit;
    font-weight: 500;
    line-height: 1.2;
    color: var(--text-primary);
    cursor: pointer;
    transition: background-color 0.15s ease, color 0.15s ease;
}

.org-selector[b-wkilfcxw0u]  .org-trigger:hover,
.org-selector[b-wkilfcxw0u]  .org-trigger[aria-expanded="true"] {
    background-color: var(--bg-surface-alt);
}

.org-selector[b-wkilfcxw0u]  .org-trigger:focus-visible {
    outline: none;
    border-color: var(--primary);
    box-shadow: 0 0 0 0.2rem color-mix(in srgb, var(--primary) 25%, transparent);
}

/* Level icon — a quiet glyph, no badge background. */
.org-selector[b-wkilfcxw0u]  .org-trigger-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    color: var(--text-secondary);
    font-size: 0.95em;
    transition: color 0.15s ease;
}

.org-selector[b-wkilfcxw0u]  .org-trigger:hover .org-trigger-icon,
.org-selector[b-wkilfcxw0u]  .org-trigger[aria-expanded="true"] .org-trigger-icon {
    color: var(--primary);
}

.org-selector[b-wkilfcxw0u]  .org-trigger-text {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-width: 0;
    max-width: 12rem;
}

/* Placeholder state (nothing selected yet) */
.org-selector[b-wkilfcxw0u]  .org-trigger-placeholder {
    color: var(--text-secondary);
    font-weight: 400;
}

.org-selector[b-wkilfcxw0u]  .org-trigger-caret {
    font-size: 0.7em;
    flex-shrink: 0;
    opacity: 0.6;
    transition: transform 0.15s ease;
}

.org-selector[b-wkilfcxw0u]  .org-trigger[aria-expanded="true"] .org-trigger-caret {
    transform: rotate(180deg);
    opacity: 1;
}

@media (max-width: 576px) {
    .org-selector[b-wkilfcxw0u] {
        font-size: 0.8rem;
    }

    .org-selector[b-wkilfcxw0u]  .org-trigger {
        padding: 0.25rem 0.4rem;
    }

    .org-selector[b-wkilfcxw0u]  .org-trigger-text {
        max-width: 7rem;
    }
}
