/* /Components/Layout/LandingLayout.razor.rz.scp.css */
.landing[b-pkh88qpluy] {
    background-color: #F7F9FC;
    min-height: 100vh;
    width: 100%;
    overflow-x: hidden;
}
/* /Components/Layout/MainLayout.razor.rz.scp.css */
/* Styles for the admin shell live in wwwroot/css/dashboard.css (global,
   so they can reach into MudBlazor's internal markup without ::deep). */
/* /Components/Layout/NavMenu.razor.rz.scp.css */
/* Styles for the nav menu live in wwwroot/css/dashboard.css (global,
   so they can reach into MudBlazor's internal markup without ::deep). */
/* /Components/Layout/ReconnectModal.razor.rz.scp.css */
.components-reconnect-first-attempt-visible[b-batn7vpbuq],
.components-reconnect-repeated-attempt-visible[b-batn7vpbuq],
.components-reconnect-failed-visible[b-batn7vpbuq],
.components-pause-visible[b-batn7vpbuq],
.components-resume-failed-visible[b-batn7vpbuq],
.components-rejoining-animation[b-batn7vpbuq] {
    display: none;
}

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


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

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

}

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

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

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

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

    100% {
        opacity: 1;
    }
}

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

    100% {
        opacity: 0;
    }
}

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

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

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

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

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

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

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

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

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

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

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

    100% {
        top: 0px;
        left: 0px;
        width: 80px;
        height: 80px;
        opacity: 0;
    }
}
/* /Components/Layout/Terminal/TerminalAppLayout.razor.rz.scp.css */
/* Shell fixo à viewport: cabeçalho e rodapé sempre visíveis, e SOMENTE o <main> rola. Altura
   (e não min-height) é o contrato — com min-height o conteúdo alto esticava a página e empurrava
   o rodapé para fora da tela. */
.terminal-app[b-9676d8rzd7] {
    height: 100vh; /* fallback para navegadores sem dvh */
    height: 100dvh;
    width: 100%;
    display: flex;
    flex-direction: column;
    background-color: #F7F9FC;
    overflow: hidden;
}

.terminal-app-content[b-9676d8rzd7] {
    flex: 1 1 auto;
    /* Sem isto o flex item nunca encolhe abaixo do conteúdo — e o rodapé sai da viewport. */
    min-height: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    overflow-y: auto;
    overflow-x: hidden;
    -webkit-overflow-scrolling: touch;
    /* O scroll não pode encadear para a página: em standalone o gesto viraria pull-to-refresh. */
    overscroll-behavior-y: contain;
    padding: 24px;
    /* Só as laterais: o topo é do cabeçalho e a base é do rodapé, que aplicam os próprios insets. */
    padding-left: calc(24px + env(safe-area-inset-left));
    padding-right: calc(24px + env(safe-area-inset-right));
    box-sizing: border-box;
}

.terminal-app-content-inner[b-9676d8rzd7] {
    width: 100%;
    max-width: 960px;
    /* Centraliza todas as divs da página como um conjunto. Quando o conteúdo excede a
       altura disponível, as margens automáticas zeram e o início continua acessível. */
    margin-block: auto;
    flex-shrink: 0;
}

.terminal-app-footer[b-9676d8rzd7] {
    /* Região fixa do shell: o rodapé nunca cede altura para o conteúdo. */
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px 12px;
    flex-wrap: wrap;
    padding: 10px 24px;
    /* Em standalone com viewport-fit=cover o rodapé encosta na barra de gestos do Android. */
    padding-bottom: calc(10px + env(safe-area-inset-bottom));
    padding-left: calc(24px + env(safe-area-inset-left));
    padding-right: calc(24px + env(safe-area-inset-right));
    border-top: 1px solid #D8DADD;
    background-color: #FFFFFF;
    font-size: 0.75rem;
    /* O literal dava 4,34:1 sobre o branco do rodapé. O token do canal (terminal.css) já foi
       escurecido até passar; o fallback acompanha para o caso de a folha global não carregar. */
    color: var(--tm-text-muted, #6A7076);
}

/* A versão quebra como bloco inteiro (nunca no meio do texto) e cede a vez ao status —
   Wake Lock e conexão são operacionais; a versão é só carimbo. */
.terminal-app-footer-version[b-9676d8rzd7] {
    white-space: nowrap;
    flex-shrink: 0;
}

.terminal-app-footer-status[b-9676d8rzd7] {
    display: flex;
    align-items: center;
    gap: 6px 16px;
    flex-wrap: wrap;
    justify-content: flex-end;
    /* Quando não couber tudo (ex.: falha do Wake Lock com texto + botão), o status quebra
       internamente em vez de estourar a largura do rodapé. */
    min-width: 0;
    flex: 1 1 auto;
}

.terminal-app-footer-connection[b-9676d8rzd7] {
    display: flex;
    align-items: center;
    gap: 6px;
}

.terminal-connection-dot[b-9676d8rzd7] {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background-color: #2E7D32;
    display: inline-block;
}

/* O ponto acompanha o TEXTO da disponibilidade operacional (TerminalPhysicalHealthTexts), nunca o
   contrário: a cor é reforço, o estado está escrito ao lado. Verde só com ativação validada no
   virtual ou resposta física recente com Ready=true. */
.terminal-app-footer-connection-negative .terminal-connection-dot[b-9676d8rzd7] {
    background-color: #B3261E;
}

.terminal-app-footer-connection-warning .terminal-connection-dot[b-9676d8rzd7] {
    background-color: #B26A00;
}

.terminal-app-footer-connection-neutral .terminal-connection-dot[b-9676d8rzd7] {
    background-color: #8A9096;
}

.terminal-app-loading[b-9676d8rzd7] {
    display: flex;
    justify-content: center;
    padding: 80px 0;
}

/* Celular ou pouca altura (paisagem em 1024×600, teclado aberto): o shell é fixo, então cada
   pixel de cabeçalho/rodapé sai do conteúdo — aqui os dois ficam compactos sem perder nada. */
@media (max-width: 600px), (max-height: 520px) {
    .terminal-app-content[b-9676d8rzd7] {
        padding: 16px;
        padding-left: calc(16px + env(safe-area-inset-left));
        padding-right: calc(16px + env(safe-area-inset-right));
    }

    .terminal-app-footer[b-9676d8rzd7] {
        padding: 6px 16px;
        padding-bottom: calc(6px + env(safe-area-inset-bottom));
        padding-left: calc(16px + env(safe-area-inset-left));
        padding-right: calc(16px + env(safe-area-inset-right));
        font-size: 0.7rem;
    }
}
/* /Components/Layout/Terminal/TerminalLayout.razor.rz.scp.css */
.terminal-bare[b-xojhb393i3] {
    min-height: 100vh; /* fallback para navegadores sem dvh */
    min-height: 100dvh;
    width: 100%;
    overflow-x: hidden;
    background-color: #F7F9FC;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px;
    /* viewport-fit=cover (TerminalPwaHead) faz o conteúdo passar por baixo das barras do sistema
       em telas com recorte; os insets devolvem a margem só onde o sistema pede. */
    padding-top: calc(24px + env(safe-area-inset-top));
    padding-bottom: calc(24px + env(safe-area-inset-bottom));
    padding-left: calc(24px + env(safe-area-inset-left));
    padding-right: calc(24px + env(safe-area-inset-right));
    box-sizing: border-box;
    position: relative;
}

/* Absoluto de propósito: o aviso de Wake Lock não pode entrar no fluxo flex e desalinhar o card
   de ativação que esta tela centraliza. Quando o Wake Lock está ativo o componente não renderiza
   nada e este contêiner fica vazio, sem ocupar espaço. */
.terminal-bare-wakelock[b-xojhb393i3] {
    position: absolute;
    left: 0;
    right: 0;
    bottom: calc(12px + env(safe-area-inset-bottom));
    display: flex;
    justify-content: center;
}
/* /Components/Shared/Dashboard/RecentMovements.razor.rz.scp.css */
/* Component-specific styling only — .panel-card/.panel-title/.panel-subtitle/.dash-table/
   .mono-tech/.empty-state/.state-page/.rounded-pill all come from the app's global stylesheets
   (wwwroot/css/dashboard.css) and are intentionally left untouched here. */

/* Spacing the dashboard's old .movements-card rule used to provide (wwwroot/css/dashboard.css). */
.recent-movements[b-kvs5nw9xul] {
    margin-bottom: 8px;
}

.recent-movements-header[b-kvs5nw9xul] {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
}

.recent-movements-link[b-kvs5nw9xul] {
    font-size: 13px;
    font-weight: 600;
    color: var(--tm-primary);
    white-space: nowrap;
}

/* On a phone the header stacks, and the link reads better aligned with the title than dangling
   on its own right edge. */
@media (max-width: 599px) {
    .recent-movements-header[b-kvs5nw9xul] {
        flex-direction: column;
        gap: 8px;
    }
}
/* /Components/Shared/Loading/GlobalLoadingOverlay.razor.rz.scp.css */
.global-loading-overlay[b-cynmg09znc] {
    position: fixed;
    inset: 0;
    z-index: 10000;

    display: flex;
    align-items: center;
    justify-content: center;

    background: rgba(245, 245, 246, 0.72);
    pointer-events: all;
}

.global-loading-overlay--blur[b-cynmg09znc] {
    backdrop-filter: blur(5px);
    -webkit-backdrop-filter: blur(5px);
}

/* Browsers without backdrop-filter support just get the flat semi-transparent background above
   — no separate fallback branch needed since the blur is an additive enhancement, not load-bearing. */

/* Horizontal, landscape-shaped card (logo | spinner | message in a row) rather than a tall
   stacked column — reads as a deliberate, symmetric panel instead of a narrow strip. */
.global-loading-content[b-cynmg09znc] {
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: center;
    gap: 20px;

    min-width: 340px;
    max-width: 90vw;
    text-align: left;

    background-color: var(--tm-surface);
    border: 1px solid var(--tm-border);
    border-radius: 12px;
    box-shadow: 0 12px 32px rgba(0, 0, 0, 0.18);
    padding: 28px 40px;
}

.global-loading-logo[b-cynmg09znc] {
    width: 56px;
    height: auto;
    object-fit: contain;
    flex-shrink: 0;
}

.global-loading-message.mud-typography[b-cynmg09znc] {
    color: var(--tm-text);
    font-weight: 600;
}

@media (max-width: 599px) {
    .global-loading-content[b-cynmg09znc] {
        min-width: 0;
        width: 100%;
        padding: 22px 24px;
        gap: 16px;
    }

    .global-loading-logo[b-cynmg09znc] {
        width: 44px;
    }
}

@media (prefers-reduced-motion: reduce) {
    .global-loading-logo[b-cynmg09znc] {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
    }

    [b-cynmg09znc] .global-loading-spinner svg {
        animation-duration: 0.01ms !important;
    }
}
/* /Components/Shared/ModelPager.razor.rz.scp.css */
.model-structure-pager[b-o6ipnfzspc] {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    align-items: center;
    gap: 4px;
    margin: 8px 0;
}

.model-structure-pager span[b-o6ipnfzspc] {
    flex-basis: 100%;
    order: -1;
    text-align: center;
    font-size: 12px;
}
/* /Components/Shared/Reports/ConsumptionTrendDialog.razor.rz.scp.css */
/* Component-specific styling only — .dialog-title/.dialog-subtitle come from the app's global
   dialog stylesheet. Nothing here is scoped to /relatorios or /dashboard. */

/* "Retiradas − Estornos = Consumo líquido" no topo do diálogo: é o que presta contas do número
   das barras, já que o tooltip do MudBlazor só carrega um valor por ponto. */
.consumption-trend-net-summary[b-5iyjiwh1gh] {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 12px;
    margin-bottom: 16px;
}

.consumption-trend-net-term[b-5iyjiwh1gh] {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.consumption-trend-net-label[b-5iyjiwh1gh] {
    font-size: 0.75rem;
    color: var(--tm-text-muted);
}

.consumption-trend-net-value[b-5iyjiwh1gh] {
    font-size: 1.125rem;
    font-weight: 600;
    line-height: 1.2;
}

.consumption-trend-net-term.is-total .consumption-trend-net-value[b-5iyjiwh1gh] {
    color: var(--tm-primary, #f15a24);
}

.consumption-trend-net-operator[b-5iyjiwh1gh] {
    font-size: 1.125rem;
    font-weight: 600;
    line-height: 1.2;
    color: var(--tm-text-muted);
}

.consumption-trend-dialog-axis-note[b-5iyjiwh1gh] {
    display: block;
    margin-top: 8px;
    color: var(--tm-text-muted);
}

/* Horizonte Total pode passar de 30 meses. O gráfico rola dentro deste container em vez de
   espremer os rótulos do eixo x; a largura mínima real vem inline, do MinChartWidthPx. */
.consumption-trend-chart-scroll[b-5iyjiwh1gh] {
    overflow-x: auto;
    overflow-y: hidden;
    max-width: 100%;
}

[b-5iyjiwh1gh] svg.mud-chart-bar,
[b-5iyjiwh1gh] svg.mud-chart-line {
    max-width: 100%;
    overflow: visible;
}

[b-5iyjiwh1gh] .mud-chart-legend {
    flex-wrap: wrap;
    row-gap: 4px;
}

@media (max-width: 600px) {
    [b-5iyjiwh1gh] svg.mud-chart-bar,
    [b-5iyjiwh1gh] svg.mud-chart-line {
        height: 280px;
    }
}
/* /Components/Shared/Reports/ConsumptionTrendReport.razor.rz.scp.css */
/* Component-specific styling only — .panel-card/.panel-title/.panel-subtitle/.dash-table/.mono-tech/
   .empty-state/.state-page/.rounded-pill/.table-actions/.table-action-btn/.actions-cell all come
   from the app's global stylesheets. Nothing here is scoped to /relatorios or /dashboard. */

.consumption-trend-search[b-86r3jvf2l1] {
    max-width: 360px;
    margin-bottom: 16px;
}

.consumption-trend-indicator[b-86r3jvf2l1] {
    display: flex;
    align-items: center;
    gap: 8px;
}

.consumption-trend-label[b-86r3jvf2l1] {
    font-size: 13px;
    font-weight: 600;
    color: var(--tm-text-muted);
}

@media (max-width: 599px) {
    .consumption-trend-search[b-86r3jvf2l1] {
        max-width: none;
    }
}
/* /Components/Shared/Reports/ParetoChart.razor.rz.scp.css */
/* A folha do DESENHO do Pareto. Ela viajou para cá junto com o SVG: isolamento de CSS do Blazor
   marca cada regra com o escopo do componente que a declara, então deixar estas regras na folha
   do painel as tornaria letra morta assim que o gráfico virou um componente próprio.

   A folha do painel (SkuConsumptionParetoPanel.razor.css) continua dona do que é dela: a grade de
   duas colunas, a tabela e as notas. */

.pareto-chart-frame[b-ix5g2c3b0p] {
    min-width: 0;
}

/* Quem LIMITA a largura é o host, na folha dele: é o que mantém o fator de escala do viewBox perto
   de 1 e, com ele, o corpo do texto estável em qualquer viewport. Ver o parâmetro Width. */

.pareto-chart[b-ix5g2c3b0p] {
    width: 100%;
    height: auto;
    overflow: visible;
}

.pareto-bar[b-ix5g2c3b0p] {
    fill: var(--tm-primary, #f15a24);
}

/* O bucket agregado é desenhado com hachura clara: distingue sem depender só de matiz, e
   sobretudo sem sugerir que ele é o mais barato. */
.pareto-bar.is-others[b-ix5g2c3b0p] {
    fill: var(--tm-primary, #f15a24);
    fill-opacity: 0.35;
    stroke: var(--tm-primary, #f15a24);
    stroke-dasharray: 3 2;
    stroke-width: 1;
}

/* Espessuras em unidades de viewBox, com o fator perto de 1: a linha do acumulado fica com ~1,6 px
   e continua legível sobre as barras sem virar o elemento mais pesado do desenho. */
.pareto-cumulative-line[b-ix5g2c3b0p] {
    fill: none;
    stroke: #303236;
    stroke-width: 1.6;
}

.pareto-cumulative-marker[b-ix5g2c3b0p] {
    fill: #303236;
}

.pareto-reference-80[b-ix5g2c3b0p] {
    stroke: var(--tm-text-muted, #6b7280);
    stroke-width: 1;
    stroke-dasharray: 6 4;
}

/* 10 unidades de viewBox com fator ~1 são ~10 px lidos — um degrau abaixo dos 12 px (0,75rem) da
   legenda logo abaixo, que é o corpo mais miúdo do projeto. É essa hierarquia que faz o gráfico
   parecer de uma peça só: o eixo é moldura, não conteúdo, e não pode ser lido antes das barras. */
.pareto-reference-label[b-ix5g2c3b0p],
.pareto-axis-label[b-ix5g2c3b0p],
.pareto-tick-label[b-ix5g2c3b0p] {
    font-size: 10px;
    fill: var(--tm-text-muted, #6b7280);
}

.pareto-gridline[b-ix5g2c3b0p] {
    stroke: var(--tm-border, #e5e7eb);
    stroke-width: 1;
}

.pareto-axis[b-ix5g2c3b0p] {
    stroke: var(--tm-border, #e5e7eb);
    stroke-width: 1;
}

.pareto-legend[b-ix5g2c3b0p] {
    display: flex;
    flex-wrap: wrap;
    gap: 16px;
    margin-top: 8px;
    font-size: 0.75rem;
    color: var(--tm-text-muted);
}

.pareto-legend-item[b-ix5g2c3b0p] {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

.pareto-legend-swatch[b-ix5g2c3b0p] {
    display: inline-block;
    width: 14px;
    height: 10px;
    border-radius: 2px;
}

.pareto-legend-swatch.is-bar[b-ix5g2c3b0p] {
    background-color: var(--tm-primary, #f15a24);
}

.pareto-legend-swatch.is-line[b-ix5g2c3b0p] {
    height: 2px;
    background-color: #303236;
}
/* /Components/Shared/Reports/SimplifiedStockPosition.razor.rz.scp.css */
/* Component-specific styling only — .panel-card/.panel-title/.panel-subtitle/.dash-table/.mono-tech/
   .stat-dot/.empty-state/.state-page/.rounded-pill all come from the app's global stylesheets
   (dashboard.css, skus.css) and are intentionally left untouched here. Nothing in this file is
   scoped to /relatorios or /dashboard — this component is meant to be dropped into either. */

.simplified-stock-position .stat-dot[b-ocfhfct4n2] {
    width: 10px;
    height: 10px;
}

.stock-position-status[b-ocfhfct4n2] {
    display: flex;
    align-items: center;
    gap: 8px;
}

.stock-position-status-label[b-ocfhfct4n2] {
    font-size: 13px;
    font-weight: 600;
    color: var(--tm-text-muted);
}

@media (max-width: 599px) {
    .stock-position-status-label[b-ocfhfct4n2] {
        white-space: nowrap;
    }
}

/* ---------- Compact mode (dashboard) ----------
   Presentation only: same columns, same rows, same order as the default /relatorios rendering. */

/* Spacing the dashboard's old .stock-position-card rule used to provide (wwwroot/css/dashboard.css)
   — scoped to compact so /relatorios, where this component is the last element on the page, keeps
   exactly the trailing spacing it had. */
.simplified-stock-position-compact[b-ocfhfct4n2] {
    margin-bottom: 32px;
}

.stock-position-header[b-ocfhfct4n2] {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
}

.stock-position-link[b-ocfhfct4n2] {
    font-size: 13px;
    font-weight: 600;
    color: var(--tm-primary);
    white-space: nowrap;
}

.stock-position-footer[b-ocfhfct4n2] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
    margin-top: 12px;
    padding-top: 12px;
    border-top: 1px solid var(--tm-border);
}

.stock-position-truncation[b-ocfhfct4n2] {
    color: var(--tm-text-muted);
}

.simplified-stock-position-compact[b-ocfhfct4n2]  .dash-table td,
.simplified-stock-position-compact[b-ocfhfct4n2]  .dash-table th {
    padding-top: 10px;
    padding-bottom: 10px;
}

.simplified-stock-position-compact .stock-position-status-label[b-ocfhfct4n2] {
    font-size: 12px;
}

@media (max-width: 599px) {
    .stock-position-header[b-ocfhfct4n2],
    .stock-position-footer[b-ocfhfct4n2] {
        flex-direction: column;
        align-items: flex-start;
        gap: 8px;
    }
}
/* /Components/Shared/Reports/SkuConsumptionComparisonReport.razor.rz.scp.css */
/* A folha da visão "Pareto comparativo". Nenhuma largura de container em pixel: a tabela tem doze
   colunas e é ela que estouraria 375px primeiro — abaixo de Md o MudTable já as empilha em
   cartões, e o que sobra aqui é rolagem contida. */

.comparison-header[b-a94cndj1ih] {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    justify-content: space-between;
    gap: 16px;
}

.comparison-window[b-a94cndj1ih] {
    display: block;
    margin-top: 4px;
    color: var(--tm-text-muted);
}

.comparison-kpis[b-a94cndj1ih] {
    margin-top: 16px;
}

.comparison-alert[b-a94cndj1ih] {
    margin-top: 16px;
}

/* O teto do gráfico NESTE host, e o par do Width=960 passado ao ParetoChart. Sem ele, um card de
   1800px esticaria o viewBox por 1,9 e o eixo sairia a ~19px — maior que qualquer texto da página.
   Onze barras também não ganham nada com 1800px de largura. */
.comparison-chart[b-a94cndj1ih] {
    margin-top: 24px;
    min-width: 0;
    max-width: 60rem;
}

.comparison-toolbar[b-a94cndj1ih] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 16px;
    margin-top: 24px;
}

.comparison-toolbar > :first-child[b-a94cndj1ih] {
    flex: 1 1 16rem;
    max-width: 100%;
}

.comparison-note[b-a94cndj1ih] {
    display: block;
    margin-top: 8px;
    color: var(--tm-text-muted);
}

.comparison-section-title[b-a94cndj1ih] {
    margin-top: 32px;
}

/* Doze colunas não cabem em tablet: a tabela rola DENTRO do card em vez de alargar a página. */
[b-a94cndj1ih] .comparison-table {
    max-width: 100%;
}

[b-a94cndj1ih] .comparison-table .mud-table-container {
    overflow-x: auto;
}

[b-a94cndj1ih] .numeric-cell {
    text-align: right;
    white-space: nowrap;
}

/* Código em cima, descrição embaixo: o código é a identidade que o operador procura, e a descrição
   é o que confirma que ele achou o item certo. */
[b-a94cndj1ih] .comparison-sku-code {
    display: block;
    font-weight: 600;
}

[b-a94cndj1ih] .comparison-sku-name {
    display: block;
    font-size: 0.75rem;
    color: var(--tm-text-muted);
}

/* "Outros" não é um SKU — é o resto. A ênfase discreta evita que alguém o leia como mais uma linha
   do ranking. */
[b-a94cndj1ih] .comparison-others-cell {
    font-style: italic;
    color: var(--tm-text-muted);
}

/* A busca DESTACA, e o destaque não é só cor: a borda à esquerda continua visível para quem não
   distingue matiz e para quem imprime a tabela. */
[b-a94cndj1ih] .comparison-highlight {
    background-color: rgba(241, 90, 36, 0.12);
    box-shadow: inset 3px 0 0 0 var(--tm-primary, #f15a24);
}

/* Sem nowrap: "Entrou no Top 20 (+11)" numa linha só era a célula mais larga da tabela, e era ela
   que trazia de volta a rolagem lateral que a redução de colunas tirou. O ícone continua colado no
   texto porque o gap é do flex, não um espaço. */
.comparison-status[b-a94cndj1ih] {
    display: inline-flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 2px 6px;
}

.comparison-delta-rank[b-a94cndj1ih] {
    font-size: 0.75rem;
    color: var(--tm-text-muted);
}

/* Em BLOCO, e não ao lado do número: o percentual embaixo do valor economiza a largura de
   "(+1.300,00%)" em toda linha da tabela, e continua lendo como um qualificador do número acima. */
.comparison-delta-percent[b-a94cndj1ih] {
    display: block;
    font-size: 0.75rem;
    color: var(--tm-text-muted);
}

/* No DETALHE a comparação com o período anterior fica ao lado, não embaixo: ali sobra largura. */
.comparison-detail-aside[b-a94cndj1ih] {
    margin-left: 4px;
    font-size: 0.75rem;
    color: var(--tm-text-muted);
}

[b-a94cndj1ih] .comparison-detail-row {
    background-color: var(--tm-surface-muted, rgba(0, 0, 0, 0.02));
}

.comparison-detail[b-a94cndj1ih] {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
    gap: 16px;
    padding: 8px 0;
}

.comparison-detail-label[b-a94cndj1ih] {
    display: block;
    color: var(--tm-text-muted);
}
/* /Components/Shared/Reports/SkuConsumptionParetoDialog.razor.rz.scp.css */
/* .dialog-title/.dialog-subtitle vêm da folha global de diálogos; aqui fica só o que é deste. */

.pareto-dialog-title[b-l5c3ixpoqu] {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    justify-content: space-between;
    gap: 12px;
    width: 100%;
}

.pareto-dialog-month-nav[b-l5c3ixpoqu] {
    display: inline-flex;
    align-items: center;
    gap: 4px;
}

.pareto-dialog-month-label[b-l5c3ixpoqu] {
    min-width: 72px;
    text-align: center;
    font-weight: 600;
}

.pareto-dialog-metric[b-l5c3ixpoqu] {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-bottom: 12px;
}

.pareto-dialog-metric-button[b-l5c3ixpoqu] {
    border-radius: 999px;
}

.pareto-dialog-tabs[b-l5c3ixpoqu] {
    margin-bottom: 8px;
}

.pareto-dialog-note[b-l5c3ixpoqu] {
    display: block;
    margin-top: 12px;
    color: var(--tm-text-muted);
}

/* Em 375px as abas não cabem lado a lado; o MudTabs já rola, e aqui só garantimos que ele role
   dentro do diálogo em vez de alargar a página. */
[b-l5c3ixpoqu] .mud-tabs-toolbar {
    max-width: 100%;
    overflow-x: auto;
}
/* /Components/Shared/Reports/SkuConsumptionParetoPanel.razor.rz.scp.css */
/* A composição da referência: tabela à esquerda, gráfico à direita; empilhados abaixo do
   MESMO breakpoint dos gráficos mensais (1199px). Dois breakpoints diferentes criariam uma faixa
   de larguras em que a página empilha e o diálogo não. */

.pareto-layout[b-iwf82zwf1w] {
    display: grid;
    grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
    gap: 24px;
    align-items: start;
}

@media (max-width: 1199px) {
    .pareto-layout[b-iwf82zwf1w] {
        grid-template-columns: minmax(0, 1fr);
    }
}

.pareto-table-side[b-iwf82zwf1w],
.pareto-chart-side[b-iwf82zwf1w] {
    min-width: 0;
}

/* O teto do gráfico NESTE host. O diálogo abre em MaxWidth.ExtraLarge, então em 1920px a coluna da
   direita passaria de 800px e escalaria o viewBox de 520 por 1,6 — o eixo sairia a ~16px, maior
   que a legenda. Em rem, e não em px, para acompanhar quem aumenta a fonte do navegador. */
.pareto-chart-side[b-iwf82zwf1w]  .pareto-chart-frame {
    max-width: 34rem;
}

[b-iwf82zwf1w] .pareto-table {
    /* Cinco colunas numéricas em 375px não cabem lado a lado; o MudTable já vira cartões no
       Breakpoint.Sm, e aqui só garantimos que a tabela nunca empurre o diálogo. */
    max-width: 100%;
}

[b-iwf82zwf1w] .numeric-cell {
    text-align: right;
}

/* Na CÉLULA, não na linha: abaixo de 960px o MudTable empilha as células em blocos e uma borda
   declarada no <tr> some justamente onde o total precisa se separar da última linha de dados. */
[b-iwf82zwf1w] .pareto-total-cell {
    font-weight: 600;
    border-top: 2px solid var(--tm-border);
}

/* "Outros" não é um SKU, uma OS, um centro nem um operador — é o resto. A ênfase discreta evita
   que alguém o leia como mais uma linha do ranking. */
[b-iwf82zwf1w] .pareto-others-cell {
    font-style: italic;
    color: var(--tm-text-muted);
}

.pareto-note[b-iwf82zwf1w] {
    display: block;
    margin-top: 8px;
    color: var(--tm-text-muted);
}
/* /Components/Shared/Reports/SkuConsumptionReport.razor.rz.scp.css */
/* Só o que esta visão tem de próprio. panel-card, panel-title, dash-table, empty-state e
   state-page vêm do tema; relatorios.css continua responsável apenas pelo layout da PÁGINA. */

.sku-consumption-report[b-5zob36y7bu] {
    display: flex;
    flex-direction: column;
    gap: 24px;
}

.sku-consumption-header[b-5zob36y7bu] {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    justify-content: space-between;
    gap: 8px;
    margin-bottom: 8px;
}

.sku-consumption-freshness[b-5zob36y7bu] {
    color: var(--tm-text-muted);
    white-space: nowrap;
}

/* Dinheiro e quantidade alinhados à direita: é o que deixa a coluna comparável de relance e o
   rodapé TOTAL alinhado com as parcelas de cima. */
[b-5zob36y7bu] .numeric-cell {
    text-align: right;
}

/* O rodapé vem PRONTO da RPC. A ênfase existe para que ninguém o confunda com mais um mês.
   A borda vai em cada CÉLULA, e não na linha: abaixo de 960px o MudTable empilha as células em
   blocos, e uma borda declarada no <tr> desapareceria justamente onde o total mais precisa se
   distinguir da última linha de dados. */
[b-5zob36y7bu] .sku-consumption-total-cell {
    font-weight: 600;
    border-top: 2px solid var(--tm-border);
}

.sku-consumption-unpriced[b-5zob36y7bu] {
    margin-top: 16px;
}

.sku-consumption-note[b-5zob36y7bu] {
    display: block;
    margin-top: 12px;
    color: var(--tm-text-muted);
}

/* Dois cards lado a lado no desktop; empilhados em tablet e celular. O corte em 1199px é
   deliberado: em 1024 (tablet deitado) duas colunas deixariam cada gráfico com menos de 470px,
   e 24 meses de barras rolariam nos DOIS cards ao mesmo tempo. */
.sku-consumption-charts[b-5zob36y7bu] {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 24px;
}

@media (max-width: 1199px) {
    .sku-consumption-charts[b-5zob36y7bu] {
        grid-template-columns: minmax(0, 1fr);
    }
}

.sku-consumption-chart-card[b-5zob36y7bu] {
    min-width: 0;
}

/* 18 e 24 meses passam da largura do card. Quem rola é ESTE container — nunca a página, e nunca
   às custas de espremer os rótulos do eixo x até virarem um borrão. */
.sku-consumption-chart-scroll[b-5zob36y7bu] {
    overflow-x: auto;
    overflow-y: hidden;
    max-width: 100%;
    margin-top: 12px;
}

[b-5zob36y7bu] svg.mud-chart-bar {
    max-width: 100%;
    overflow: visible;
}

@media (max-width: 599px) {
    [b-5zob36y7bu] svg.mud-chart-bar {
        height: 240px;
    }
}
/* /Components/Shared/Reports/StockBalanceHistoryChart.razor.rz.scp.css */
.balance-chart[b-mlbsofg6yg] {
    width: 100%;
}

.balance-chart-svg[b-mlbsofg6yg] {
    display: block;
    width: 100%;
    height: auto;
    overflow: visible;
}

.balance-gridline[b-mlbsofg6yg] {
    stroke: var(--tm-border, rgba(0, 0, 0, 0.08));
    stroke-width: 1;
}

.balance-axis[b-mlbsofg6yg] {
    stroke: var(--tm-border, rgba(0, 0, 0, 0.2));
    stroke-width: 1;
}

/* Em unidades de viewBox: com 1040 de largura esticados para ~1130 px na tela, o fator é ~1,09,
   então 11 aqui vira ~12 px lidos — o mesmo corpo da legenda logo abaixo. É essa igualdade que faz
   o gráfico parecer de uma peça só; com 14 os números do eixo ficavam maiores que a legenda e
   puxavam a atenção para a moldura em vez do dado. */
.balance-axis-label[b-mlbsofg6yg] {
    font-size: 11px;
    fill: var(--tm-text-muted, #8a8f98);
}

/* O zero é fronteira, não uma linha de grade a mais. */
.balance-zero-line[b-mlbsofg6yg] {
    stroke: var(--tm-text-muted, #8a8f98);
    stroke-width: 1.2;
}

/* Saldo: a mesma laranja do detalhe do otimizador — é o mesmo conceito, visto na aba nova. */
.balance-line[b-mlbsofg6yg] {
    fill: none;
    stroke: #F15A24;
    stroke-width: 1.8;
    stroke-linejoin: miter;
    stroke-linecap: butt;
}

.balance-marker[b-mlbsofg6yg] {
    fill: #F15A24;
}

/* PP e ES: traçados diferentes, e não só cores diferentes — quem não distingue as duas cores
   ainda distingue tracejado de pontilhado. */
.balance-reorder-line[b-mlbsofg6yg] {
    stroke: #303236;
    stroke-width: 1.4;
    stroke-dasharray: 7 4;
}

.balance-safety-line[b-mlbsofg6yg] {
    stroke: #8a8f98;
    stroke-width: 1.4;
    stroke-dasharray: 2 3;
}


/* Marca do intervalo que tocou o zero por dentro — a única evidência que o modo linha não pode
   perder quando a variação deixa de ser desenhada. */
.balance-stockout-mark[b-mlbsofg6yg] {
    fill: #b3261e;
}

/* VELAS.
   Direção pelo PREENCHIMENTO, nunca por verde/vermelho: cor por direção afirmaria que consumir é
   ruim e acumular é bom, e nenhuma das duas coisas é verdade em estoque — saldo caindo é a máquina
   trabalhando. O vermelho fica reservado para o intervalo que chegou a zero, que é o único estado
   inequivocamente ruim. ESSA parte não pode mudar.

   Qual dos dois preenchimentos significa qual direção é escolha de produto, e aqui ela é o
   INVERSO da convenção japonesa: laranja cheia sobe, vazada cai. Na paleta desta tela o laranja é
   a cor do estoque, então "mais laranja" lê-se como "mais saldo". */
.balance-candle-wick[b-mlbsofg6yg] {
    stroke: #F15A24;
    stroke-width: 1.2;
}

.balance-candle-body[b-mlbsofg6yg] {
    stroke: #F15A24;
    stroke-width: 1.2;
}

.balance-candle.is-up .balance-candle-body[b-mlbsofg6yg] {
    fill: #F15A24;
}

.balance-candle.is-down .balance-candle-body[b-mlbsofg6yg] {
    fill: var(--mud-palette-surface, #fff);
}

.balance-candle.is-stockout .balance-candle-wick[b-mlbsofg6yg],
.balance-candle.is-stockout .balance-candle-body[b-mlbsofg6yg] {
    stroke: #b3261e;
}

.balance-candle.is-stockout.is-up .balance-candle-body[b-mlbsofg6yg] {
    fill: #b3261e;
}

.balance-legend-candle[b-mlbsofg6yg] {
    display: inline-block;
    width: 9px;
    height: 14px;
    border: 1.5px solid #F15A24;
    box-sizing: border-box;
}

.balance-legend-candle.is-up[b-mlbsofg6yg] {
    background: #F15A24;
}

.balance-legend-candle.is-down[b-mlbsofg6yg] {
    background: transparent;
}

.balance-truncation[b-mlbsofg6yg] {
    stroke: #b3261e;
    stroke-width: 1.4;
    stroke-dasharray: 4 3;
}

.balance-truncation-label[b-mlbsofg6yg] {
    font-size: 10px;
    font-weight: 600;
    fill: #b3261e;
}

.balance-legend[b-mlbsofg6yg] {
    display: flex;
    flex-wrap: wrap;
    gap: 6px 16px;
    margin-top: 6px;
    font-size: 12px;
    color: var(--tm-text-muted, #8a8f98);
}

.balance-legend-item[b-mlbsofg6yg] {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

.balance-legend-swatch[b-mlbsofg6yg] {
    display: inline-block;
    width: 18px;
    height: 0;
    border-top-width: 2px;
    border-top-style: solid;
}

.balance-legend-swatch.is-balance[b-mlbsofg6yg] {
    border-top-color: #F15A24;
}

.balance-legend-swatch.is-reorder[b-mlbsofg6yg] {
    border-top-color: #303236;
    border-top-style: dashed;
}

.balance-legend-swatch.is-safety[b-mlbsofg6yg] {
    border-top-color: #8a8f98;
    border-top-style: dotted;
}


.balance-legend-dot[b-mlbsofg6yg] {
    display: inline-block;
    width: 8px;
    height: 8px;
    border-radius: 50%;
}

.balance-legend-dot.is-stockout[b-mlbsofg6yg] {
    background: #b3261e;
}
/* /Components/Shared/Reports/StockOccupancyDetailDialog.razor.rz.scp.css */
.occupancy-detail-grid[b-grmkj5ar40] {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
    gap: 10px;
    margin-bottom: 4px;
}

.occupancy-detail-card[b-grmkj5ar40] {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 8px 10px;
    border-radius: 8px;
    background: var(--tm-surface-muted, rgba(0, 0, 0, 0.03));
}

.occupancy-detail-label[b-grmkj5ar40] {
    font-size: 12px;
    color: var(--tm-text-muted);
}

.occupancy-detail-value[b-grmkj5ar40] {
    font-size: 16px;
    font-weight: 600;
}

.occupancy-detail-note[b-grmkj5ar40] {
    font-size: 11px;
    color: var(--tm-text-muted);
}



/* Uma tabela larga rola DENTRO do seu container: o diálogo em si nunca rola na horizontal. */
.occupancy-events-scroll[b-grmkj5ar40] {
    overflow-x: auto;
    margin-top: 6px;
}

.occupancy-events-table[b-grmkj5ar40] {
    width: 100%;
    border-collapse: collapse;
    font-size: 13px;
}

.occupancy-events-table th[b-grmkj5ar40],
.occupancy-events-table td[b-grmkj5ar40] {
    padding: 6px 8px;
    border-bottom: 1px solid var(--tm-border, rgba(0, 0, 0, 0.08));
    text-align: left;
    white-space: nowrap;
}

.occupancy-events-table th.numeric-cell[b-grmkj5ar40],
.occupancy-events-table td.numeric-cell[b-grmkj5ar40] {
    text-align: right;
}

/* A linha continua legível: o evento OCORREU. O que não é afirmável é o saldo acumulado nela. */
.occupancy-events-table tr.is-untrusted td[b-grmkj5ar40] {
    color: var(--tm-text-muted);
    font-style: italic;
}

.occupancy-events-pager[b-grmkj5ar40] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    margin-top: 8px;
}

/* Os controles NUNCA são comprimidos: quando a linha aperta, eles QUEBRAM para a linha de baixo,
   ainda alinhados à direita. Espremer um seletor até o rótulo truncar é o pior dos dois mundos. */
.occupancy-chart-header[b-grmkj5ar40] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 12px;
    margin-top: 12px;
    margin-bottom: 4px;
}

/* O título é o único que cede — e ele pode quebrar em duas linhas sem prejuízo. */
.occupancy-chart-title[b-grmkj5ar40] {
    flex: 1 1 240px;
    min-width: 0;
}

/* Largura FIXA e sem encolher. Duas coisas davam errado antes:

   1. A regra caía direto no <MudSelect>. Uma classe posta num COMPONENTE não recebe o atributo de
      escopo do CSS isolado, então `.occupancy-granularity-select[b-xxx]` nunca casava com o <div>
      que o MudSelect renderiza. As duas tentativas anteriores foram letra morta.
   2. Mesmo aplicada, base automática fazia a caixa mudar de tamanho a cada troca de opção.

   Agora a largura vive num <div> que ESTE componente emite — o escopo cola nele — e o ::deep leva
   o 100% para dentro do controle do MudBlazor. */
.occupancy-granularity[b-grmkj5ar40] {
    /* 235px é o que cabe o pior caso — "Automático (movimento)", 178px de texto medidos na fonte
       real do controle, mais o recuo interno e a seta. Abaixo disso o rótulo trunca; foi assim que
       a caixa voltou a cortar quando o valor passou a trazer o intervalo servido. */
    flex: 0 0 235px;
    width: 235px;
}

.occupancy-granularity[b-grmkj5ar40]  .mud-input-control {
    width: 100%;
}

@media (max-width: 600px) {
    .occupancy-granularity[b-grmkj5ar40] {
        flex: 1 1 100%;
        width: auto;
    }
}

.occupancy-chart-controls[b-grmkj5ar40] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
    flex: 0 0 auto;
    /* Mantém à direita mesmo quando quebra para uma linha só sua. */
    margin-left: auto;
}

.occupancy-style-toggle[b-grmkj5ar40] {
    display: flex;
    gap: 4px;
}

/* ::deep porque a classe cai num <MudButton>: o atributo de escopo iria parar numa classe que o
   MudBlazor renderiza, e a regra não casaria. O escopo fica no <div> que este componente emite. */
.occupancy-style-toggle[b-grmkj5ar40]  .occupancy-style-chip {
    border-radius: 999px;
    text-transform: none;
}
/* /Components/Shared/Reports/StockOccupancyReport.razor.rz.scp.css */
.occupancy-header[b-3crn0w8vre] {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    justify-content: space-between;
    gap: 12px;
}

.occupancy-kpis[b-3crn0w8vre] {
    margin-top: 12px;
}

.occupancy-toolbar[b-3crn0w8vre] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 12px;
    margin: 12px 0 4px;
}

/* ::deep porque a classe cai num <MudTextField>: sem atravessar a fronteira do componente, o
   atributo de escopo iria para uma classe que o MudBlazor renderiza e a regra não casaria. */
.occupancy-toolbar[b-3crn0w8vre]  .occupancy-search {
    flex: 1 1 280px;
    max-width: 380px;
}

.occupancy-situation-filters[b-3crn0w8vre] {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

.occupancy-situation-filters[b-3crn0w8vre]  .occupancy-situation-chip {
    border-radius: 999px;
    text-transform: none;
}


/* A tabela rola DENTRO do seu container. A página nunca rola na horizontal. */
.occupancy-table-scroll[b-3crn0w8vre] {
    overflow-x: auto;
    margin-top: 8px;
}

/* Recarga não pisca a tabela inteira: ela esmaece enquanto a resposta nova não chega. */
.occupancy-table-scroll.is-busy[b-3crn0w8vre] {
    opacity: 0.55;
    transition: opacity 120ms ease;
}

.occupancy-table[b-3crn0w8vre] {
    width: 100%;
    border-collapse: collapse;
    font-size: 13px;
}

.occupancy-table th[b-3crn0w8vre],
.occupancy-table td[b-3crn0w8vre] {
    padding: 8px;
    border-bottom: 1px solid var(--tm-border, rgba(0, 0, 0, 0.08));
    text-align: left;
    vertical-align: top;
    white-space: nowrap;
}

.occupancy-table th[b-3crn0w8vre] {
    font-weight: 600;
    color: var(--tm-text-muted);
}

.occupancy-table th.numeric-cell[b-3crn0w8vre],
.occupancy-table td.numeric-cell[b-3crn0w8vre] {
    text-align: right;
}

.occupancy-action-column[b-3crn0w8vre] {
    text-align: right;
}

.occupancy-two-line-cell[b-3crn0w8vre] {
    line-height: 1.35;
}

.occupancy-strong[b-3crn0w8vre] {
    font-weight: 600;
}

.occupancy-cell-meta[b-3crn0w8vre] {
    font-size: 11px;
    color: var(--tm-text-muted);
    max-width: 260px;
    overflow: hidden;
    text-overflow: ellipsis;
}

.occupancy-negative[b-3crn0w8vre] {
    color: #b3261e;
}

.occupancy-pager[b-3crn0w8vre] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    margin-top: 10px;
}

@media (max-width: 960px) {
    .occupancy-toolbar[b-3crn0w8vre]  .occupancy-search {
        max-width: none;
    }
}
/* /Components/Shared/Reports/StockOpportunityReport.razor.rz.scp.css */
/* A folha da visão "Capital em estoque". Nenhuma largura de container em pixel: os subtotais e a
   tabela precisam caber em 375px, e é o auto-fit com minmax que faz a grade encolher em vez de
   empurrar a página. */

.opportunity-header[b-9g9mdttvwk] {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    justify-content: space-between;
    gap: 16px;
}

.opportunity-window[b-9g9mdttvwk] {
    display: block;
    margin-top: 4px;
    color: var(--tm-text-muted);
}

.opportunity-kpis[b-9g9mdttvwk] {
    margin-top: 16px;
}

.opportunity-alert[b-9g9mdttvwk] {
    margin-top: 16px;
}

.opportunity-link[b-9g9mdttvwk] {
    display: block;
    margin-top: 4px;
}

/* Consumo, kit e durável lado a lado: três coisas diferentes, e é a separação que impede alguém
   de ler o custo de reposição de um durável como valor econômico líquido. */
.opportunity-breakdown[b-9g9mdttvwk] {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
    gap: 16px;
    margin-top: 24px;
}

.opportunity-breakdown-item[b-9g9mdttvwk] {
    min-width: 0;
    padding: 12px 16px;
    border: 1px solid var(--tm-border, #e5e7eb);
    border-radius: 8px;
}

.opportunity-breakdown-label[b-9g9mdttvwk] {
    display: block;
    color: var(--tm-text-muted);
}

.opportunity-toolbar[b-9g9mdttvwk] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 16px;
    margin-top: 24px;
}

.opportunity-toolbar > :first-child[b-9g9mdttvwk] {
    flex: 1 1 16rem;
    max-width: 100%;
}

.opportunity-note[b-9g9mdttvwk] {
    display: block;
    margin-top: 8px;
    color: var(--tm-text-muted);
}

.opportunity-pagination[b-9g9mdttvwk] {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
    margin-top: 16px;
}

[b-9g9mdttvwk] .opportunity-table {
    max-width: 100%;
}

[b-9g9mdttvwk] .opportunity-table .mud-table-container {
    overflow-x: auto;
}

[b-9g9mdttvwk] .numeric-cell {
    text-align: right;
    white-space: nowrap;
}

[b-9g9mdttvwk] .opportunity-sku-code {
    display: block;
    font-weight: 600;
}

[b-9g9mdttvwk] .opportunity-sku-name,
[b-9g9mdttvwk] .opportunity-sku-scope {
    display: block;
    font-size: 0.75rem;
    color: var(--tm-text-muted);
}

/* Ícone + texto, empilhados: um diagnóstico que dependa só de cor não é lido por quem imprime a
   tabela nem por quem não distingue matiz. */
[b-9g9mdttvwk] .opportunity-flag {
    display: flex;
    align-items: center;
    gap: 4px;
    font-size: 0.75rem;
    color: var(--tm-text-muted);
}

[b-9g9mdttvwk] .opportunity-flag-none {
    color: var(--tm-text-muted);
}
/* /Components/Shared/Reports/StockOptimizationApplyDialog.razor.rz.scp.css */
.so-apply-scroll[b-htn0t7yfzx] {
    overflow-x: auto;
    max-height: 50vh;
    overflow-y: auto;
}

.so-apply-table[b-htn0t7yfzx] {
    width: 100%;
    border-collapse: collapse;
    font-size: 13px;
}

.so-apply-table th[b-htn0t7yfzx],
.so-apply-table td[b-htn0t7yfzx] {
    padding: 6px 8px;
    border-bottom: 1px solid var(--tm-border, rgba(0, 0, 0, 0.08));
    text-align: left;
}

.so-apply-table th.numeric-cell[b-htn0t7yfzx],
.so-apply-table td.numeric-cell[b-htn0t7yfzx] {
    text-align: right;
    white-space: nowrap;
}
/* /Components/Shared/Reports/StockOptimizationDetailDialog.razor.rz.scp.css */
.so-detail-grid[b-na042551pj] {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: 10px;
    margin-bottom: 12px;
}

.so-detail-card[b-na042551pj] {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 8px 10px;
    border-radius: 8px;
    background: var(--tm-surface-muted, rgba(0, 0, 0, 0.03));
}

.so-detail-label[b-na042551pj] {
    font-size: 12px;
    color: var(--tm-text-muted);
}

.so-detail-value[b-na042551pj] {
    font-size: 16px;
    font-weight: 600;
}

.so-chart-scroll[b-na042551pj] {
    overflow-x: auto;
}

.so-chart[b-na042551pj] {
    position: relative;
    width: 100%;
    padding: 0 0 18px 22px;
    box-sizing: border-box;
}

.so-chart[b-na042551pj]  svg {
    display: block;
    width: 100%;
}

.so-axis-y[b-na042551pj] {
    position: absolute;
    left: 0;
    top: 50%;
    transform: rotate(-90deg) translateX(-50%);
    transform-origin: 0 0;
    font-size: 11px;
    color: var(--tm-text-muted);
    white-space: nowrap;
}

.so-axis-x[b-na042551pj] {
    display: block;
    text-align: center;
    font-size: 11px;
    color: var(--tm-text-muted);
    margin-top: 2px;
}

.so-chart-note[b-na042551pj] {
    display: block;
    margin-top: 4px;
    color: var(--tm-text-muted);
}

.so-cycles-table[b-na042551pj] {
    width: 100%;
    border-collapse: collapse;
    font-size: 13px;
}

.so-cycles-table th[b-na042551pj],
.so-cycles-table td[b-na042551pj] {
    padding: 6px 8px;
    border-bottom: 1px solid var(--tm-border, rgba(0, 0, 0, 0.08));
    text-align: left;
    white-space: nowrap;
}

.so-cycles-table th.numeric-cell[b-na042551pj],
.so-cycles-table td.numeric-cell[b-na042551pj] {
    text-align: right;
}

.so-binding[b-na042551pj] {
    font-weight: 600;
}
/* /Components/Shared/Reports/StockOptimizationEvaluationDialog.razor.rz.scp.css */
.so-eval-summary[b-in1yrzdpdr] {
    display: grid;
    grid-template-columns: max-content 1fr;
    gap: 4px 12px;
    margin: 12px 0;
    font-size: 13px;
}

.so-eval-summary dt[b-in1yrzdpdr] {
    color: var(--tm-text-muted);
}

.so-eval-summary dd[b-in1yrzdpdr] {
    margin: 0;
}
/* /Components/Shared/Reports/StockOptimizationReport.razor.rz.scp.css */
/* Component-specific styling only — .panel-card/.panel-title/.panel-subtitle/.empty-state/.state-page/
   .mono-tech/.numeric-cell/.actions-cell/.table-actions/.table-action-btn come from the app's global
   stylesheets. */

.so-header[b-jh1w5oz6w1] {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 16px;
    flex-wrap: wrap;
    margin-bottom: 12px;
}

.so-header-actions[b-jh1w5oz6w1] {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}

.so-evaluation-select[b-jh1w5oz6w1] {
    min-width: 280px;
}

.so-status-strip[b-jh1w5oz6w1] {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
    padding: 10px 12px;
    border-radius: 8px;
    background: var(--tm-surface-muted, rgba(0, 0, 0, 0.03));
    margin-bottom: 8px;
}

.so-status-text[b-jh1w5oz6w1],
.so-progress-text[b-jh1w5oz6w1] {
    font-size: 13px;
    color: var(--tm-text-muted);
}

.so-progress[b-jh1w5oz6w1] {
    flex-basis: 100%;
}

.so-guarantee-note[b-jh1w5oz6w1] {
    display: block;
    margin-bottom: 12px;
    color: var(--tm-text-muted);
}

.so-toolbar[b-jh1w5oz6w1] {
    display: flex;
    align-items: center;
    gap: 16px;
    flex-wrap: wrap;
    margin-bottom: 12px;
}

.so-search[b-jh1w5oz6w1] {
    flex: 1 1 280px;
    max-width: 420px;
}

.so-selection-bar[b-jh1w5oz6w1] {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-left: auto;
    flex-wrap: wrap;
}

.so-selection-count[b-jh1w5oz6w1] {
    font-size: 13px;
    font-weight: 600;
    color: var(--tm-text-muted);
}

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

.so-table[b-jh1w5oz6w1] {
    width: 100%;
    border-collapse: collapse;
    font-size: 14px;
}

.so-table th[b-jh1w5oz6w1],
.so-table td[b-jh1w5oz6w1] {
    padding: 8px 10px;
    text-align: left;
    border-bottom: 1px solid var(--tm-border, rgba(0, 0, 0, 0.08));
    vertical-align: middle;
}

.so-table th.numeric-cell[b-jh1w5oz6w1],
.so-table td.numeric-cell[b-jh1w5oz6w1] {
    text-align: right;
    white-space: nowrap;
}

.so-col-select[b-jh1w5oz6w1] {
    width: 44px;
}

.so-group-row[b-jh1w5oz6w1] {
    background: var(--tm-surface-muted, rgba(0, 0, 0, 0.03));
    font-weight: 600;
}

.so-item-row td:nth-child(2)[b-jh1w5oz6w1] {
    padding-left: 28px;
}

.so-group-meta[b-jh1w5oz6w1] {
    display: block;
    font-size: 12px;
    font-weight: 400;
    color: var(--tm-text-muted);
}

.so-equipment-label[b-jh1w5oz6w1] {
    font-weight: 500;
}

.so-badge[b-jh1w5oz6w1] {
    display: inline-block;
    margin-left: 6px;
    padding: 1px 6px;
    border-radius: 999px;
    font-size: 11px;
    font-weight: 600;
    background: var(--tm-surface-muted, rgba(0, 0, 0, 0.06));
    color: var(--tm-text-muted);
}

.so-badge-applied[b-jh1w5oz6w1] {
    background: rgba(46, 125, 50, 0.12);
    color: #1b5e20;
}

.so-badge-warn[b-jh1w5oz6w1] {
    background: rgba(237, 108, 2, 0.14);
    color: #8a4500;
}

.so-confidence[b-jh1w5oz6w1] {
    display: inline-block;
    padding: 2px 8px;
    border-radius: 999px;
    font-size: 12px;
    font-weight: 600;
}

.so-confidence-high[b-jh1w5oz6w1] { background: rgba(46, 125, 50, 0.12); color: #1b5e20; }
.so-confidence-medium[b-jh1w5oz6w1] { background: rgba(237, 108, 2, 0.14); color: #8a4500; }
.so-confidence-low[b-jh1w5oz6w1] { background: rgba(211, 47, 47, 0.12); color: #8e1c1c; }
.so-confidence-none[b-jh1w5oz6w1] { background: rgba(0, 0, 0, 0.06); color: var(--tm-text-muted); }

.so-status[b-jh1w5oz6w1] {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

.so-muted[b-jh1w5oz6w1] {
    color: var(--tm-text-muted);
    font-weight: 400;
    font-size: 12px;
}

.so-pager[b-jh1w5oz6w1] {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
    margin-top: 12px;
}

.visually-hidden[b-jh1w5oz6w1] {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
}

@media (max-width: 599px) {
    .so-evaluation-select[b-jh1w5oz6w1] {
        min-width: 100%;
    }

    .so-selection-bar[b-jh1w5oz6w1] {
        margin-left: 0;
    }
}
/* /Components/Shared/Terminal/TerminalActivationQrDialog.razor.rz.scp.css */
/* Layout da janela de QR Code de ativação.

   Isolado no componente porque nada disto é reaproveitável: é a moldura de UMA imagem que
   precisa continuar legível quando a pessoa amplia a tela para conferir, e quando a imprime. */

.terminal-qr[b-ieiudwdy8w] {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
}

/* Fundo branco FIXO, independente do tema. Um QR desenhado sobre a superfície escura do tema
   noturno tem contraste invertido, e leitor nenhum é obrigado a aceitar isso. */
.terminal-qr-frame[b-ieiudwdy8w] {
    background: #ffffff;
    border: 1px solid rgba(0, 0, 0, 0.12);
    border-radius: 8px;
    padding: 12px;
    line-height: 0;
}

.terminal-qr-image[b-ieiudwdy8w] {
    display: block;
    width: min(280px, 60vw);
    height: auto;
    /* Ampliação sem interpolação: um módulo continua sendo um quadrado de borda exata em
       qualquer zoom, que é a diferença entre um QR nítido e um QR borrado na tela do portal. */
    image-rendering: pixelated;
}

.terminal-qr-serial[b-ieiudwdy8w] {
    margin: 16px 0 0;
    font-size: 1.05rem;
    letter-spacing: 0.06em;
    word-break: break-all;
}

.terminal-qr-help[b-ieiudwdy8w] {
    margin-top: 12px;
    max-width: 42ch;
}
/* /Components/Shared/Terminal/TerminalIdleGuard.razor.rz.scp.css */
/* Camada de bloqueio por inatividade. OPACA e cobrindo a viewport inteira — cabeçalho, nome do
   operador, perfil, resultados e conteúdo operacional. Fail-closed: ela aparece ANTES do POST e
   permanece se a rede falhar, então em nenhum instante o dado de uma sessão vencida fica visível. */
.terminal-idle-lock[b-d3hxsm849f] {
    position: fixed;
    inset: 0;
    /* Acima de tudo o que o MudBlazor empilha (diálogo 1400, popover 1500, snackbar 1600): um
       diálogo aberto no momento do vencimento não pode aparecer por cima do bloqueio. */
    z-index: 30000;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px;
    /* Sem transparência e sem blur: um fundo translúcido deixaria nome e matrícula legíveis. */
    background-color: #F7F9FC;
    text-align: center;
}

/* `hidden` precisa vencer o `display: flex` acima — sem isto a camada ficaria visível sempre. */
.terminal-idle-lock[hidden][b-d3hxsm849f] {
    display: none;
}

.terminal-idle-lock-panel[b-d3hxsm849f] {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 12px;
    max-width: 420px;
}

.terminal-idle-lock-title[b-d3hxsm849f] {
    margin: 0;
    font-size: 1.25rem;
    font-weight: 600;
    color: #1F2933;
}

.terminal-idle-lock-text[b-d3hxsm849f] {
    margin: 0;
    font-size: 0.95rem;
    color: #565D64;
}

/* Só aparece quando o POST falha (offline, servidor fora). Botão nativo de propósito: precisa
   funcionar com o circuito Blazor morto, e quem o mostra/esconde é o módulo JS. */
.terminal-idle-lock-retry[b-d3hxsm849f] {
    margin-top: 8px;
    min-height: 44px;
    padding: 0 20px;
    border: 1px solid #F15A24;
    border-radius: 8px;
    background-color: #F15A24;
    color: #FFFFFF;
    font-size: 0.95rem;
    font-weight: 600;
    cursor: pointer;
}

.terminal-idle-lock-retry[hidden][b-d3hxsm849f] {
    display: none;
}

/* Existe só para carregar o token antiforgery do fetch — mesmo papel do formulário de bloqueio
   manual do TerminalAppLayout. */
.terminal-idle-lock-form[b-d3hxsm849f] {
    display: none;
}
/* /Components/Shared/Terminal/TerminalQrScannerDialog.razor.rz.scp.css */
/* Vídeo, moldura de enquadramento e estados da tela de leitura.

   O alvo é um tablet de chão de fábrica, segurado na mão, em retrato ou paisagem. O palco é
   quadrado para que a moldura signifique a mesma coisa nas duas orientações, e limitado por
   altura de viewport para que os botões Cancelar/Tentar novamente NUNCA saiam da tela — uma tela
   de câmera sem saída visível é o pior estado possível aqui. */

.terminal-scanner[b-l58vx8utfu] {
    display: flex;
    flex-direction: column;
    align-items: center;
}

.terminal-scanner-stage[b-l58vx8utfu] {
    position: relative;
    width: 100%;
    max-width: 420px;
    aspect-ratio: 1 / 1;
    max-height: 52vh;
    border-radius: 12px;
    overflow: hidden;
    background: #000000;
}

.terminal-scanner-video[b-l58vx8utfu] {
    width: 100%;
    height: 100%;
    /* cover, não contain: o corte preenche a moldura em qualquer proporção de câmera, e é sobre
       o que está DENTRO da moldura que a pessoa é instruída a mirar. */
    object-fit: cover;
    display: block;
}

/* Moldura puramente visual (aria-hidden no markup): ela guia o enquadramento, não comunica
   estado. O estado é o texto da região viva logo abaixo. */
.terminal-scanner-frame[b-l58vx8utfu] {
    position: absolute;
    inset: 12%;
    border: 3px solid rgba(255, 255, 255, 0.9);
    border-radius: 12px;
    box-shadow: 0 0 0 100vmax rgba(0, 0, 0, 0.35);
    pointer-events: none;
}

.terminal-scanner-loading[b-l58vx8utfu] {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(0, 0, 0, 0.55);
}

.terminal-scanner-instruction[b-l58vx8utfu] {
    margin-top: 16px;
    text-align: center;
}

.terminal-scanner-error[b-l58vx8utfu] {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 8px;
    padding: 24px 8px;
    max-width: 42ch;
}

.terminal-scanner-status[b-l58vx8utfu] {
    margin: 12px 0 0;
    min-height: 1.5em;
    text-align: center;
    font-size: 0.95rem;
}

.terminal-scanner-camera[b-l58vx8utfu] {
    margin-top: 16px;
    width: 100%;
    max-width: 420px;
}

/* Paisagem baixa (tablet deitado): o palco encolhe em vez de empurrar as ações para fora. */
@media (orientation: landscape) and (max-height: 560px) {
    .terminal-scanner-stage[b-l58vx8utfu] {
        max-height: 44vh;
    }

    .terminal-scanner-instruction[b-l58vx8utfu] {
        margin-top: 8px;
    }
}
/* /Components/Shared/Terminal/TerminalWakeLock.razor.rz.scp.css */
.terminal-wakelock[b-w7xiwk24sm] {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 0.75rem;
    line-height: 1.2;
    color: #747A80;
}

.terminal-wakelock-text[b-w7xiwk24sm] {
    white-space: nowrap;
}

.terminal-wakelock-active[b-w7xiwk24sm] {
    color: #2E7D32;
}

.terminal-wakelock-muted[b-w7xiwk24sm] {
    color: #9AA0A6;
}

.terminal-wakelock-warning[b-w7xiwk24sm] {
    color: #C77700;
}

/* O botão vive dentro de um rodapé de 0.75rem — o padding padrão do MudButton empurraria a
   altura do rodapé inteiro. Precisa de ::deep: o markup é do MudButton, não deste componente. */
.terminal-wakelock[b-w7xiwk24sm]  .terminal-wakelock-retry {
    font-size: 0.75rem;
    min-height: 0;
    padding: 0 6px;
}

@media (max-width: 600px) {
    .terminal-wakelock[b-w7xiwk24sm] {
        font-size: 0.7rem;
    }
}
