/* ==========================================================================
   +JUNTOS 2026 - camada de override do projeto (dist/css/app.css)
   ==========================================================================

   COMO TRABALHAR AQUI
   -------------------
   Este projeto NAO tem build de front-end: nao existe Vite nem Mix rodando,
   e este arquivo e editado a mao e servido direto. O cache e furado pelo
   ?v={{ filemtime(...) }} nos dois head.blade.php, entao basta salvar.

   Ordem de carga (importa muito):
     plugins (@stack('styles')) -> adminlte.purged.css -> ESTE ARQUIVO
   Como este e o ultimo, para vencer AdminLTE, Bootstrap ou plugins basta
   igualar a especificidade deles. So use !important quando o concorrente
   tiver especificidade MAIOR, ou for style inline (do Blade ou escrito por
   JS de plugin, como o jquery-knob faz no input). Fora disso, e ruido.
   Regra pratica: antes de escrever !important, confira quem esta ganhando.

   As variantes mobile dos componentes NAO ficam junto do componente: estao
   agrupadas na secao 15, que por historico caiu no meio do arquivo. Mover
   isso mudaria a cascata, o que exige validar tela por tela no browser -
   por isso segue assim, e por isso a numeracao abaixo parece torta.

   INDICE (na ordem do arquivo)
   ----------------------------
   1.  Design tokens
   2.  Base, links e chrome do AdminLTE
       2.1 Preloader: a garrafa enchendo (reaproveita a peca da secao 9.1)
   3.  Login e telas de auth
   4.  Utilitarios de layout
   5.  Dash: KPIs, knob e cards
   6.  Dash: ranking
   7.  Dash: noticias e venda acumulada
   8.  Dash: comparativos
   9.  Dash: gatilho
       9.1 a garrafa que enche (SVG inline, animado so com transform)
   10. Dash: premiacao e relampago
   11. Dash: logindash
   12. Botoes, textos e formularios
   13. Plugins: Select2 e foco de campo
   14. Conteudo: premios, termo, PDF e links
   15. Ajustes por breakpoint (@supports e @media)
   16. Utilitarios diversos
   17. Listagens: tabela no desktop, cards no mobile
       + cor da paginacao (vermelho escuro do tema)
   18. Ajuste de metas: grade de KPIs por mes
       18.1 a linha do gatilho e o resumo do alvo/marcos
       18.2 aviso de ajuste sobrescrito (renderiza na tela de importacoes)
   19. Ranking: leaderboard por grupo
       19.1 grade larga. Usa @container, nao @media: a sidebar do AdminLTE muda
            a largura util do painel sem mudar a da janela. Por isso as
            variantes deste componente nao ficam na secao 15.
       19.2 abas geral/mes, scoreboard e grafico de evolucao (SVG, sem Chart.js)
       19.3 posicao dentro do card-rede (dash de admin e executivo)
       19.4 os grupos lado a lado (admin sem recorte de grupo)
       19.5 bloco de topo do dash: posicao + evolucao na mesma linha
       19.6 coluna lateral do dash encostando no rodape da linha
   20. Animacoes de entrada (IntersectionObserver, uma vez por peca)
       20.1 escalonamento  20.2 barras  20.3 tracos SVG
       20.4 entrada de blocos  20.5 knob
   21. Premios: simulacao de premiacao mensal
       Tabela no espaco largo, cards no estreito. Usa @container, como o 19.
   22. Importacoes: as etapas da carga
       22.1 acompanhamento da apuracao do ranking

   ==========================================================================
   1. DESIGN TOKENS
   --------------------------------------------------------------------------
   Fonte unica de verdade do tema. Para retematizar, altere so este bloco.
   Nota: Bootstrap 4.6 nao consome custom properties; estes tokens sao
   consumidos apenas por este arquivo.
   ========================================================================== */
:root {
    /* Marca */
    --brand: #ed1c24;
    --brand-rgb: 237, 28, 36;
    --brand-dark: #b00006;
    /* fim dos gradientes (preloader, sidebar mobile) */
    --brand-active: #b3211d;
    /* item ativo da sidebar */
    --accent: #ffcb00;
    /* estrelas, destaques */
    --ok: #1a9c53;
    /* meta batida em texto sobre fundo claro. O #1BEE78 do Functions::VERDE
       e feito para fundo escuro e some no branco */
    --brand-deep: #611e1e;
    /* textos pequenos sobre fundo claro */

    /* Textura de fundo da pagina. Vive num token porque e consumida em TRES
       lugares que precisam ser identicos (body::before, .modal-content e
       .preloader - vide secoes 2 e 2.1); trocar a arte e uma linha so.
       Sao DUAS artes: esta, mais discreta, e a do painel; o login troca o
       token pela arte cheia (secao 3). Ambas em webp (1920x1080), que aqui
       pesa menos da metade do jpg com a mesma imagem - os originais .jpg
       ficam na mesma pasta, fora do CSS. */
    --page-bg: url('/dist/theme/bg2026-content.jpg');

    /* Texto */
    --text: #333333;
    --text-muted: #6c757d;
    /* rotulos, legendas (cinza do Bootstrap 4) */

    /* Neutros de estrutura */
    --border: #dee2e6;
    /* borda de card e tabela */
    --divider: #f1f3f5;
    /* separador interno, mais leve que a borda */
    --surface: #fff;
    /* fundo de card sobre o bg da pagina */

    /* Forma */
    --radius: 10px;
    --radius-lg: 12px;
    --radius-sm: 0.25rem;
    /* botoes e pills */

    /* Sombras */
    --shadow-brand: 0 0 2px rgba(var(--brand-rgb), 0.3),
        0 1px 3px rgba(var(--brand-rgb), 0.5);
    --shadow-card: 0 1px 3px rgba(0, 0, 0, 0.08);
}


/* ==========================================================================
   2. BASE, LINKS E CHROME DO ADMINLTE
   ========================================================================== */
html,
body {
    font-family: 'Montserrat', sans-serif;
}

/* A cor de base fica no HTML, e o BODY precisa ser transparente. Nao e questao
   de gosto: o body::before abaixo tem z-index negativo, e camada negativa entra
   no contexto de empilhamento da RAIZ, nao do body. Nesse contexto a ordem e
   fundo do html -> camadas negativas -> fundo dos blocos em fluxo, e o body e
   um bloco em fluxo. Ou seja, qualquer cor no body e pintada DEPOIS da imagem e
   a tapa. O !important vence o .login-page do AdminLTE, que pinta #e9ecef aqui. */
html {
    background: #fff !important;
}

body {
    background: transparent !important;
}

/* A textura da pagina e uma CAMADA FIXA, nao um background-attachment: fixed.
   Motivo: no iOS o attachment fixed nao e fixo de verdade - o fundo e medido
   pela viewport, e a barra de URL que some e volta no scroll muda essa altura,
   entao a imagem redimensiona e pula enquanto a pessoa rola. Um ::before com
   position: fixed da o mesmo efeito parado, sem esse recalculo.

   O cover e obrigatorio: as artes sao 16:9, e com background-size: 100% (largura
   cheia, altura automatica) num celular de 390px a imagem vira uma faixa de
   ~220px no topo com branco embaixo.

   z-index: -1 poe a camada abaixo do conteudo. Nenhum ancestral pode criar
   contexto de empilhamento aqui (transform, filter, opacity < 1), senao ela
   some - por isso o fundo mora no body e nao no .wrapper. */
body::before {
    content: "";
    position: fixed;
    inset: 0;
    z-index: -1;
    background: var(--page-bg) no-repeat center center #fff;
    background-size: cover;
}

/* O modal e uma caixa menor que a tela: com attachment fixed ele mostrava um
   recorte deslocado da imagem, diferente a cada posicao de scroll. */
.modal-content {
    background: var(--page-bg) no-repeat center center #fff !important;
    background-size: cover !important;
}

.content-wrapper {
    padding: 10px;
}

.navbar-dark,
.sidebar-dark-primary {
    background: var(--brand);
    border: 0;
}

.navbar-dark .navbar-nav .nav-link {
    color: var(--brand);
}

.navbar-dark .nav-link:hover {
    color: #000 !important;
}

/* --------------------------------------------------------------------------
   2.1 Preloader: a garrafa enchendo
   --------------------------------------------------------------------------
   Markup em layouts/preloader.blade.php. A peca e a MESMA do card de gatilho
   (secao 9.1): mesmo vetor, mesma onda, mesmas bolhas, mesmo vidro. Aqui so
   troca o que era ligado ao dado.

   La:    .liq-nivel  = translateY calculado de --fill, o percentual real.
   Aqui:  .pre-nivel  = enche uma vez ate o gargalo e para.

   O mapa do viewBox e o mesmo dos dois lados - fundo do liquido y=1110,
   gargalo y=190 - senao as duas garrafas discordariam do mesmo desenho.

   Depois que enche, quem mantem a peca viva e o que ja era infinito na secao
   9.1: o respiro do .liq-balanco, a mare das ondas e as bolhas subindo.
   Por isso nao ha loop de enche-esvazia aqui: esvaziar a garrafa a cada 2s
   passaria a mensagem errada, e parada ela ficaria morta.

   O fundo e o mesmo da pagina (--page-bg, seja a arte do painel ou a do
   login). Assim a cortina nao troca de cor ao
   subir, so revela o conteudo - e a garrafa, que e vermelha, para de brigar
   com o degrade vermelho que havia aqui antes.
   -------------------------------------------------------------------------- */
/* Copia fiel da camada de fundo da pagina (body::before, secao 2), inclusive o
   position e o size: qualquer diferenca aqui vira um salto de imagem quando a
   cortina sobe, que e exatamente o que este fundo existe para evitar. O
   .preloader ja e position: fixed cobrindo a tela, entao basta repetir o
   enquadramento. */
.preloader {
    background: var(--page-bg) no-repeat center center #fff;
    background-size: cover;
}

.pre-garrafa {
    /* Mesmas cores do liquido do card de gatilho: a cola preta. */
    --liq-topo: #33211b;
    --liq-meio: #180e0a;
    --liq-fundo: #070403;

    /* Duracao da agitacao da superficie (secao 9.1). Aqui e a do preEnche, que
       nao tem atraso e dura menos que o gatilhoEnche do card - sem acertar isto
       a superficie continuaria batendo depois de a garrafa ter parado de subir. */
    --churn: 1.7s;

    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1.75rem;
}

/* Vence o width/height 100% de .garrafa (secao 9.1) por especificidade: la a
   garrafa preenche a coluna do card, aqui ela e que define o tamanho. */
.pre-garrafa .garrafa {
    width: auto;
    height: min(56vh, 380px);
}

.pre-marca {
    width: min(160px, 40vw);
    height: auto;
    fill: var(--brand);
    animation: preMarca 0.7s ease-out 0.55s both;
}

/* O 88% e uma passada do nivel final: liquido que sobe rapido bate no gargalo
   e volta um pouco. Sem isso a subida termina como uma barra de progresso.

   Para em 218, nao em 190 (o 100% do card de gatilho): la o cheio e um dado e
   precisa encostar no traco, aqui o gargalo cheio ate a tampa nao parece
   garrafa - falta o ar que toda garrafa tem embaixo da tampa. */
.pre-nivel {
    animation: preEnche 1.7s ease-out forwards;
}

@keyframes preEnche {
    0% {
        transform: translateY(1160px);
    }

    88% {
        transform: translateY(192px);
    }

    100% {
        transform: translateY(218px);
    }
}

@keyframes preMarca {
    from {
        opacity: 0;
        transform: translateY(10px);
    }

    to {
        opacity: 1;
        transform: none;
    }
}

/* Sem movimento: garrafa cheia, parada. As bolhas saem de cena porque sem a
   animacao elas ficariam paradas na linha d'agua, como sujeira no vidro. */
@media (prefers-reduced-motion: reduce) {
    .pre-nivel {
        transform: translateY(196px);
    }

    .pre-nivel,
    .pre-marca,
    .pre-garrafa .liq-balanco,
    .pre-garrafa .liq-onda {
        animation: none;
    }

    .pre-garrafa .liq-bolha-sobe {
        display: none;
    }
}

.sidebar {
    /* padding-left: 1rem !important; */
}

[class*="sidebar-dark-"] .sidebar a {
    color: #fff;
    font-size: 0.8rem !important;
}

.mouse {
    cursor: pointer;
}

.fa.fa-star {
    color: var(--accent);
}

a {
    color: var(--brand);
}

/* grid / table */
.table-transp-white th {
    background: var(--brand);
    color: #fff;
}


/* grid / table */

/* ==========================================================================
   3. LOGIN E TELAS DE AUTH
   ========================================================================== */
/* A arte cheia (lanternas e telhados) e so das telas de auth e de erro, que
   sao as que usam layouts/app.blade.php - ali o body ja vem com .login-page.
   O painel fica com a versao discreta do token (secao 1), que e fundo de
   trabalho e nao pode competir com os cards. Como o token e herdado, isto
   sozinho troca a arte nos tres consumidores: body::before, .modal-content e
   .preloader. */
body.login-page {
    --page-bg: url('/dist/theme/bg2026.jpg');
}

/* body.login-page e um flex column com align-items:center, entao o #app encolhe
   ate o conteudo (fit-content). Com a caixa em width:auto, a largura passava a
   depender de qual aba estava aberta - a aba do 1o acesso tem um paragrafo
   longo, entao a caixa esticava e a logo, que e uma % dela, crescia junto.
   Largura definida aqui: o layout para de reagir a troca de aba. */
body.login-page #app {
    width: 100%;
}

.login-box {
    width: 600px;
    max-width: calc(100% - 30px);
    margin-left: auto;
    margin-right: auto;
}

/* A tela do termo (auth/termo.blade.php) usa .card-box, nao .login-box: o PDF do
   regulamento pede mais largura que o formulario de login. Sem largura definida
   aqui a caixa ia de ponta a ponta do monitor (o #app e width:100%), e a caixa
   larga demais era metade do problema do regulamento parecer pequeno. */
.card-box {
    width: 1000px;
    max-width: calc(100% - 30px);
    margin-left: auto;
    margin-right: auto;
}

.login-box h1,
.card-box h1 {
    margin-top: 2rem;
    font-size: 1.2rem;
    color: var(--brand);
}

.login-box .brand {
    width: 40%;
    max-width: 240px;
}

.login-box .femsa {
    margin-top: 2.5rem !important;
}

.login-box-msg {
    color: var(--brand);
}

.login-box .nav-tabs {
    border: 0;
}

.login-box .nav-link {
    border: none !important;
}

/* Alerta das telas de auth. Fica fora do card (e fora das abas) porque a
   mensagem renderizada dentro de uma aba inativa nao aparece para quem
   acabou de submeter o formulario. */
.auth-alerta {
    max-width: 600px;
    margin: 0 auto 1rem auto;
}

.auth-alerta .alert {
    margin-bottom: 0.5rem;
    font-size: 0.9rem;
    text-align: left;
}

/* Texto de apoio dentro do card da marca (fundo vermelho, texto branco). */
.auth-ajuda {
    font-size: 0.8rem;
    line-height: 1.35rem;
    color: #fff;
    margin: 0 0 0.75rem 0;
    text-align: left;
}

.auth-requisitos {
    margin-top: -0.25rem;
}

.auth-ajuda-rodape {
    margin-top: 1rem;
}

/* Botao "ver senha": imita o input-group-text para nao brigar com o campo. */
.js-ver-senha {
    border: 1px solid #ced4da;
    border-left: 0;
    background: #e9ecef;
    color: var(--brand);
}

.js-ver-senha:focus {
    box-shadow: none;
}

/* ==========================================================================
   4. UTILITARIOS DE LAYOUT
   ========================================================================== */
table,
.dataTables_wrapper,
.text-black {
    color: var(--text) !important;
}

.content-header h1 {
    font-size: 1.4rem;
    color: var(--brand);
}

.nobackground {
    /* color: #fff !important; */
    background: none !important;
    border: 0 !important;
}

.noboxshadow {
    box-shadow: none !important;
}

.noborder {
    border: 0 !important;
}

.nopad {
    padding: 0 !important;
}

.logomenu {
    margin-top: 10px;
    margin-bottom: 10px;
    margin-left: 8px;
}

#whats {
    display: inline-block;
    position: fixed;
    width: 63px;
    height: 64px;
    right: 70px;
    bottom: 100px;
}

#whats img,
#whats a {
    width: 63px;
    height: 64px;
    display: block;
}

/* ==========================================================================
   5. DASH: KPIs, KNOB E CARDS
   ========================================================================== */
.bg-dash {
    /* color: var(--brand); */
    /* background: #f2f2f2; */
    /* background: linear-gradient(180deg,#730B20 0,#3A0000 67%) !important; */
}

.bg-kpi-bonus {
    background: #f2f2f2;
}

.bg-kpi-relampago {
    background: #fff;
    /* border: 1px solid var(--brand) !important; */
    box-sizing: border-box;
    box-shadow: var(--shadow-brand) !important;

}


.bg-redes {
    background: transparent !important;
}

.brand-link {
    border: none !important;
}

.sidebar-dark-primary .nav-sidebar>.nav-item>.nav-link.active,
.sidebar-light-primary .nav-sidebar>.nav-item>.nav-link.active,
.sidebar-dark-primary .nav-treeview>.nav-item>.nav-link.active,
.sidebar-light-primary .nav-treeview>.nav-item>.nav-link.active {
    color: #fff !important;
    background: var(--brand-active) !important;
    box-shadow: none;
}

.nav-pills .nav-link {
    border-radius: 2rem;
}

.main-header {
    margin: 0;
    padding: 0;
}

.knob {
    font-size: 18px !important;
    line-height: 18px !important;
    user-select: none;
    /* supported by Chrome and Opera */
    -webkit-user-select: none;
    /* Safari */
    -khtml-user-select: none;
    /* Konqueror HTML */
    -moz-user-select: none;
    /* Firefox */
    -ms-user-select: none;
    /* Internet Explorer/Edge */
}

.bg-dash .knob {
    z-index: 1 !important;
    margin-left: -5.5rem !important;
}

.bg-dash .knob-label {
    font-size: 1.1rem !important;
    /* display: block !important; */
    position: absolute !important;
    top: 2.51rem;
    right: 2.2rem !important;
}

.bg-kpirelampago .knob {
    z-index: 1 !important;
    /* margin-left: -5.5rem !important; */
}

.bg-kpirelampago .knob-label {
    font-size: 1.1rem !important;
    position: absolute !important;
    top: 3.76em;
    right: 39% !important;
}

.knob:focus,
.knob:focus {
    outline: none;
}


/* cards dash */
.card {
    /* border-radius: 0.35rem; */
    border-radius: 10px;
}

.bg-dash .card-title {
    font-size: 0.8rem !important;
    padding-top: 0.3rem;
    color: var(--brand);
    font-weight: 700;
}

.card-header {
    border: 0 !important;
}

/* --------------------------------------------------------------------------
   Resumo no header do card de rede (dash de admin, gerente e executivo, e a
   tela de metas)
   --------------------------------------------------------------------------
   Markup em painel/dash/rede-resumo-head.blade.php, incluido pelo header de
   painel/dash/card-rede.blade.php e pelo de painel/metas.blade.php.

   Esses cards nascem colapsados, entao o header e tudo que se ve de uma rede
   ate alguem abrir. Com so o nome ali, comparar trinta redes era abrir trinta
   cards; os dois numeros que decidem se vale abrir passam a vir junto.

   O header vira flex porque o AdminLTE posiciona .card-title e .card-tools com
   float, e float nao acomoda uma terceira peca. Em contexto flex os floats sao
   ignorados e os tres viram itens da mesma linha.

   O resumo fica sempre na SEGUNDA linha (flex-basis 100%), e nao encaixado
   entre o nome e o botao. Numa col-lg-4 o nome de uma rede real ("SUPERMERCADO
   SAO JOAO LTDA") ja come a linha inteira: tentar caber tudo junto ou cortaria
   o nome com reticencias - e o nome e o que identifica o card - ou deixaria a
   quebra a mercê do tamanho do nome, com cards vizinhos de alturas diferentes.
   Duas linhas sempre custa ~18px por card e e previsivel.
   -------------------------------------------------------------------------- */
.mj-rede-head {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.15rem 0.5rem;
}

.mj-rede-head .card-title {
    float: none;
    flex: 1 1 auto;
    min-width: 0;
}

.mj-rede-head .card-tools {
    float: none;
    flex: 0 0 auto;
}

.mj-rede-resumo {
    flex: 1 0 100%;
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.1rem 0.7rem;
    margin: 0;
    font-size: 0.68rem;
    color: var(--text-muted);
}

/* Verde so ao bater a meta; abaixo disso, neutro. Nao ha vermelho aqui de
   proposito: a meta e mensal e acumula ao longo do mes, entao no dia 10 QUASE
   TODA rede esta abaixo de 100% - pintar isso de vermelho alarmaria o mes
   inteiro e apagaria o unico limiar que significa alguma coisa em qualquer dia.
   A leitura fina (a escala de 4 cores do Functions::getColor) segue nos knobs e
   nas barras dentro do card. */
.mj-rede-chip b {
    font-size: 0.85rem;
    font-weight: 800;
    color: var(--text);
}

.mj-rede-chip.is-ok b {
    color: var(--ok);
}

.borderradius {
    border-radius: 10px;
}

/* Vive DENTRO de .card-body.p-0, nao e mais o proprio card-body.
   Motivo: o slideUp()/slideDown() do AdminLTE anima a altura do .card-body.
   Com min-height ali, a altura usada ficava travada em 300px durante toda a
   animacao e o collapse virava um salto seco no final. Com o min-height aqui,
   o wrapper anima livre e este bloco e clipado pelo overflow:hidden que o
   jQuery aplica. Bonus: background-size deixa de ser reamostrado por frame,
   porque a altura deste elemento nao muda. */
.card-kpi {
    position: relative;
    padding: 0 1.25rem 1.25rem;
    /* antes herdado de .card-body (1.25rem) */
    background-repeat: no-repeat;
    background-position: 1rem 6rem;
    background-size: auto 65%;
    min-height: 300px;
}

.card-kpi .card-title {
    color: var(--brand);
    padding-top: 0.3rem;
    font-size: 0.8rem;
}

.kpi h1,
.kpi h2,
.kpi h3 {
    margin: 0;
    margin-bottom: 0.35rem;
    padding: 0;
}

.kpi h1 {
    font-size: 0.8rem;
    font-weight: 400;
    text-transform: uppercase;
    color: var(--text);
}

.kpi h2 {
    font-size: 1.2rem;
    font-weight: bold;
    /* text-transform: uppercase; */
    color: var(--text);
}

.kpi h3,
.kpi-label {
    font-size: 0.65rem;
    font-weight: 200;
    text-transform: uppercase;
    color: var(--brand);
}

.kpi-label {
    line-height: 1.1rem;
}

.kpi .peso {
    font-size: 0.7rem;
}

.bold-red {
    color: var(--brand);
    font-weight: bold;
}

.bold-green {
    /* color: #00FF55; */
    font-weight: bold;
}

.bold-white {
    color: var(--brand);
    font-weight: bold;
}

.bold-orange {
    /* color: var(--accent); */
    font-weight: bold;
}

.card-danger:not(.card-outline)>.card-header {
    border-top-left-radius: 12px;
    border-top-right-radius: 12px;
}

.bg-card {
    /* background-color: var(--brand); */
    border: 1px solid var(--brand);
    border-radius: 12px;
}


/* ==========================================================================
   6. DASH: RANKING
   ========================================================================== */
.bg-ranking {
    /* background: url('/dist/theme/bg-dash.svg') repeat-x top center var(--brand-deep); */
    /* background: linear-gradient(180deg,var(--accent) 0,#DA6F7E 67%); */
    background: #fff !important;
    border-radius: 10px;
}

.ranking,
.bg-horizontal {
    /* padding: 1.5rem; */
    padding: 20px;
    margin: 0;
    background: url('/dist/theme/trofeu2.svg') no-repeat right bottom !important;
    min-height: 182px;
    /* background-size: contain; */
}

.bg-horizontal {
    /* background-position: 2rem 3.3rem */
}

.ranking h5,
.ranking h1,
.ranking h2 {
    font-size: 0.7rem;
    font-weight: bold;
    /* text-transform: uppercase; */
    color: var(--brand);

    padding: 0;
    margin: 0;
}

.ranking h1 {
    font-size: 3rem;
    /* line-height: 5rem; */
    font-weight: bold;
    margin-bottom: 2rem;
}

.ranking h2 {
    /* font-size: 1.6rem; */
    font-size: 3rem;
    font-weight: 100;
}

.card-ranking {
    /* height: 100%; */
    border-radius: 10px;
    /* background: #740002; */
    background: none !important;
    padding-bottom: 1rem;
}

.card-ranking .card-body {
    border-radius: 10px;
}



.card-ranking .nav-tabs .nav-item.show .nav-link,
.card-ranking .nav-tabs .nav-link.active {
    /* background: linear-gradient(180deg,#DA6F7E 0,var(--accent) 67%) !important; */
    /* background: var(--accent); */
    border: none;
}

.card-ranking:not(.card-outline)>.card-header a.active {
    font-weight: bold !important;
    color: var(--brand);
}

.backdrop-sidebar {
    background: var(--brand);
    /* background: linear-gradient(0deg,var(--brand) 0,var(--brand-dark) 50%) !important; */
    /* background-color: rgba(8, 8, 8, 0.7); */
    /* backdrop-filter: blur(16px) brightness(-13); */
}

/* ==========================================================================
   7. DASH: NOTICIAS E VENDA ACUMULADA
   ========================================================================== */
.font1 {
    font-size: 0.8rem !important;
    line-height: 1.9rem !important;
}

.news dt,
.news dt a {
    color: var(--brand);
    font-size: 1rem;
}

.news dd,
.news dd a {
    font-size: 0.8rem;
    font-weight: 200;
    color: #000;
}

/* No dash a novidade e um resumo: 3 linhas por item para o card nao crescer */
.news-resumo dd {
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.vendaacumulado {
    color: var(--brand);
    background: #ececec;
    border-radius: 10px;
    /* background: linear-gradient(180deg,#C73333 0,#391E29 67%) !important; */
}

.vendaacumulado b {
    font-weight: 2rem;
}

.vendaacumulado h1,
.vendaacumulado h2 {
    font-size: 0.8rem;
    /* line-height: 1rem; */
    /* text-transform: uppercase; */
    width: 80%;
    margin-bottom: 2rem;
}

.vendaacumulado h2 {
    margin-bottom: 0rem;
    line-height: 1rem;
}

.vendaacumulado h3 {
    font-size: 1rem;
}

.vendaacumulado h1 {
    margin-top: 30px;
    font-size: 1.2rem;
    font-weight: bold;
    line-height: normal;
}

.vendaacumulado p {
    font-size: 1rem;
    color: var(--accent);
}

/* ==========================================================================
   8. DASH: COMPARATIVOS
   ========================================================================== */
.comparativos {
    padding: 0 !important;
}

.comparativos,
.bg-card-comparativos {
    color: #000;
    background-color: #fff;
    /* padding: 0 !important; */
    /* background: linear-gradient(180deg,#191821 0,#353536 67%) !important; */
}

.comparativos .card-danger:not(.card-outline)>.card-header,
.card-danger:not(.card-outline)>.card-header a {
    color: #000;
}

.card-comparativos .nav-tabs .nav-item.show .nav-link,
.card-comparativos .nav-tabs .nav-link.active {
    background: none !important;
    border: none;
}

.bg-header-comparativos {
    background: #fff !important;
}

.card-comparativos:not(.card-outline)>.card-header {
    color: #E08A8B;
    font-size: 0.8rem;
}

.card-comparativos:not(.card-outline)>.card-header a.active {
    font-weight: bold !important;
    color: #FF5455;
}

.card-comparativos {
    box-shadow: none !important;
}

.small1,
.smallbonus {
    font-size: 0.7rem;
    /* font-weight: bold; */
    padding-bottom: 0.50rem;
}

.small2 {
    font-size: 0.7rem;
}

.smallbonus {
    font-weight: normal;
    text-transform: uppercase;
}

/* ==========================================================================
   9. DASH: GATILHO
   ========================================================================== */
.roundbar {
    border-radius: 6px !important;
    margin-bottom: 0.8rem;
    /* background-color: #e6e9ec; */
    /* background-color: #56606D; */
}

.gatilhobar-horizontal {
    height: 2rem !important;
}

.bgbarhorizontal {
    padding-top: 2rem;
    /* background: url('/dist/theme/graficos/horizontal.svg') no-repeat top left  !important; */
    /* background-size: contain !important */
}

.card-outline,
.card-outline .card-header {
    color: #000;
}

/* --------------------------------------------------------------------------
   9.1 Gatilho: a garrafa que enche
   --------------------------------------------------------------------------
   O contorno vem do mesmo vetor de dist/theme/garrafa.svg, inline no Blade
   para virar clipPath. O card passa o dado numa unica variavel:

       .card-gatilho { --fill: 0..100 }

   Dentro do recorte ha tres transforms ANINHADOS, um por grupo, justamente
   para nao se sobrescreverem (transform nao acumula no mesmo elemento):

       .liq-nivel   sobe/desce conforme --fill      <- unica ligada ao dado
         .liq-balanco   respiro vertical lento
           .liq-onda        mare: a superficie incha e assenta, na vertical

   Mapa do viewBox (296 20 348 1108): fundo do liquido y=1110, gargalo y=190.
   Logo o curso util e 920 unidades.
   -------------------------------------------------------------------------- */
.graficoGatilho {
    height: 422px;
    text-align: center !important;
}

.garrafa {
    width: 100%;
    height: 100%;
}

/* A cola: preta, com um fio de marrom quente no topo so para o liquido ter
   volume - sem ele o gradiente vira um bloco chapado e a superficie desaparece.
   Quem carrega a marca aqui e o vidro (contorno, tampa e friso), nao o
   conteudo. Mexeu nestas tres? Reveja tambem .liq-superficie e .garrafa-brilho:
   os dois foram calibrados contra liquido escuro. */
.card-gatilho {
    --liq-topo: #33211b;
    --liq-meio: #180e0a;
    --liq-fundo: #070403;
}

/* O h1 herda width:80% de .vendaacumulado; aqui a coluna ja e estreita. */
.card-gatilho h1 {
    width: 100%;
}

.liq-nivel {
    transform: translateY(calc(1110px - 920px * var(--fill) / 100));
    animation: gatilhoEnche 1.9s cubic-bezier(0.22, 1, 0.36, 1) 0.25s both;
}

/* So o from: o to e o transform acima, congelado pelo fill-mode both. */
@keyframes gatilhoEnche {
    from {
        transform: translateY(1160px);
    }
}

/* --churn: quanto dura a agitacao da superficie enquanto o nivel sobe. Aqui e o
   0.25s de atraso + 1.9s do gatilhoEnche; no preloader o enche e outro (1.7s),
   por isso o valor mora no card e nao na regra da onda. */
.card-gatilho {
    --churn: 2.15s;
}

/* --------------------------------------------------------------------------
   Quem dispara a subida e o observador da secao 20, nao o render.

   O motivo esta no comentario do anima.blade.php: aquele observador so comeca
   a olhar DEPOIS que a cortina do preloader cai, exatamente para nao gastar
   animacao atras dela. A subida da garrafa ficava de fora desse acordo -
   comecava no render, e como o preloader so sai 900ms depois do load, numa
   tela lenta a garrafa terminava de encher escondida. A cortina subia e o
   usuario via um bloco vermelho parado.

   O :not(.anima-on) e obrigatorio nos dois seletores. Se o estado vazio valesse
   tambem com o card aceso, o translateY(1160px) daqui venceria por
   especificidade o nivel real la de cima - e como o `to` do gatilhoEnche e
   implicito (sai do transform do elemento), a animacao encheria de 1160 ate
   1160, ou seja, nada.

   Sem JS, sem IntersectionObserver ou com movimento reduzido nao existe
   html.anima-pronta: nada aqui casa, e a garrafa nasce cheia no nivel certo.
   -------------------------------------------------------------------------- */
html.anima-pronta [data-anima~="gatilho"]:not(.anima-on) .liq-nivel {
    transform: translateY(1160px);
    animation: none;
}

/* A agitacao da superficie tem de recomecar junto com o nivel, senao ela roda
   atras da cortina e o liquido sobe com a superficie ja assentada.

   As bolhas ficam de fora de proposito: elas moram dentro do .liq-nivel, que
   enquanto vazio esta em 1160px, fora do recorte da garrafa. Nao ha nada para
   esconder, e zerar a animacao delas so as deixaria paradas na linha d'agua. */
html.anima-pronta [data-anima~="gatilho"]:not(.anima-on) .liq-onda-tras,
html.anima-pronta [data-anima~="gatilho"]:not(.anima-on) .liq-onda-frente {
    animation: none;
}

.liq-balanco {
    animation: gatilhoBalanco 2.9s ease-in-out infinite alternate;
}

@keyframes gatilhoBalanco {
    from {
        transform: translateY(-8px);
    }

    to {
        transform: translateY(8px);
    }
}

/* MARE, nao correnteza: as duas camadas se movem so na VERTICAL, porque o resto
   da peca (o nivel enchendo, o respiro, as bolhas) tambem sobe - uma onda
   correndo de lado era o unico movimento remando contra o desenho.

   O que mantem a superficie viva sem o deslize lateral:

   1. Fase fixa em X. Sem translateX as duas senoides ficariam com as cristas
      eternamente alinhadas, e a de tras viraria um halo escuro parado. O
      -44.375px e um QUARTO de periodo (177.5 / 4) - meio periodo poe a crista
      escura bem no vale da clara e sobra vermelho escuro demais no topo, que
      e o mesmo motivo de as amplitudes verticais abaixo serem curtas. Vai no
      mesmo translate() do Y: transform nao acumula.
   2. Periodos que nao fecham entre si (5.2s x 3.7s). Como nao ha divisor
      comum curto, o encontro das duas cristas demora a se repetir e o olho
      nao acha o loop.
   3. Keyframes IRREGULARES, quatro por camada, e nao um sobe-desce simetrico.
      A onda passa por um pico principal e um secundario, em tempos que nao se
      dividem - assim ela nunca fica dois ciclos iguais nem para nos extremos.
   4. Amplitudes diferentes entre as camadas, e a da frente bem maior. E o
      cruzamento das duas em ritmos distintos que muda a SILHUETA da superficie;
      sem isso o desenho apenas sobe e desce inteiro, rigido.

   Historico, porque estes numeros ja foram ajustados duas vezes na direcao
   errada: com 9.5s/6.2s e amplitude baixa a superficie parecia TRAVADA, e
   encurtar so o periodo (4.8s/3.4s) trocou o travado por um TREMOR - movimento
   curto e rapido demais para ler como onda. O que faltava era amplitude junto
   com mudanca de forma. Periodo e amplitude andam juntos aqui: encurtar um sem
   abrir o outro sempre cai num dos dois defeitos.

   A de tras vai opaca: qualquer transparencia aqui deixa o vidro branco
   atravessar a crista e vira uma faixa clara sobre o liquido.

   Sao DUAS animacoes por camada, em sequencia: a agitacao de enchimento e
   depois a mare. Elas nao se somam - as duas escrevem transform, e quem esta
   depois na lista vence enquanto estiver ativa. A mare entra com delay de
   var(--churn) e, sem fill-mode, nao pinta nada durante esse atraso; e por isso
   que a primeira aparece antes e some na hora certa. O ultimo keyframe da
   agitacao repete o 0% da mare de proposito: e o que torna a troca invisivel. */
.liq-onda-tras {
    animation: gatilhoEnchendoTras var(--churn, 2.15s) ease-in-out both,
        gatilhoMareTras 5.2s ease-in-out var(--churn, 2.15s) infinite;
}

.liq-onda-frente {
    animation: gatilhoEnchendoFrente var(--churn, 2.15s) ease-in-out both,
        gatilhoMareFrente 3.7s ease-in-out var(--churn, 2.15s) infinite;
}

/* Enquanto enche a superficie e batida, e as duas camadas vao em sentidos
   opostos: e o cruzamento delas que da a leitura de liquido entrando. A
   amplitude decai a cada passada - a agua se acalma sozinha, e chegar na mare
   com a superficie ja quase parada evita o degrau na troca. */
@keyframes gatilhoEnchendoTras {
    0% {
        transform: translate(-44.375px, -26px);
    }

    30% {
        transform: translate(-44.375px, 22px);
    }

    55% {
        transform: translate(-44.375px, -15px);
    }

    78% {
        transform: translate(-44.375px, 14px);
    }

    100% {
        transform: translate(-44.375px, 12px);
    }
}

@keyframes gatilhoEnchendoFrente {
    0% {
        transform: translateY(34px);
    }

    30% {
        transform: translateY(-28px);
    }

    55% {
        transform: translateY(21px);
    }

    78% {
        transform: translateY(-24px);
    }

    100% {
        transform: translateY(-20px);
    }
}

/* 0% e 100% identicos: o loop fecha sem salto. Os tempos do meio (36/64 e
   28/52/76) sao os que quebram a simetria - ver o item 3 do comentario acima. */
@keyframes gatilhoMareTras {
    0% {
        transform: translate(-44.375px, 12px);
    }

    36% {
        transform: translate(-44.375px, -14px);
    }

    64% {
        transform: translate(-44.375px, 4px);
    }

    100% {
        transform: translate(-44.375px, 12px);
    }
}

@keyframes gatilhoMareFrente {
    0% {
        transform: translateY(-20px);
    }

    28% {
        transform: translateY(14px);
    }

    52% {
        transform: translateY(22px);
    }

    76% {
        transform: translateY(-6px);
    }

    100% {
        transform: translateY(-20px);
    }
}

/* Linha d'agua. Com o liquido preto a sombra escura que havia aqui sumia
   dentro da propria cola, entao ela inverteu: um fio claro, na intensidade de
   um menisco, que e o unico jeito de a superficie se ler contra o vidro. */
.liq-superficie {
    fill: none;
    stroke: rgba(255, 255, 255, 0.30);
    stroke-width: 5;
}

.liq-bolha-sobe {
    animation: gatilhoSobe var(--dur) linear var(--atraso) infinite;
}

@keyframes gatilhoSobe {
    from {
        transform: translateY(760px);
    }

    to {
        transform: translateY(24px);
    }
}

.liq-bolha {
    fill: rgba(255, 255, 255, 0.72);
    transform-box: fill-box;
    transform-origin: center;
    animation: gatilhoBolha var(--dur) ease-in var(--atraso) infinite;
}

@keyframes gatilhoBolha {
    0% {
        opacity: 0;
        transform: translateX(0) scale(0.45);
    }

    12% {
        opacity: 0.8;
    }

    50% {
        transform: translateX(9px) scale(1);
    }

    88% {
        opacity: 0.65;
    }

    100% {
        opacity: 0;
        transform: translateX(0) scale(1.15);
    }
}

.garrafa-contorno {
    fill: none;
    stroke: var(--brand);
    stroke-width: 7;
    stroke-miterlimit: 10;
}

.garrafa-tampa {
    fill: var(--brand);
}

.garrafa-tampa-friso {
    fill: var(--accent);
    opacity: 0.9;
}

/* Reflexos de vidro. Ficam sobre o liquido, e contra a cola preta cada ponto
   de opacidade aparece o dobro - subir isto acinzenta o liquido inteiro. */
.garrafa-brilho {
    fill: rgba(255, 255, 255, 0.28);
}

/* --------------------------------------------------------------------------
   Marcos: metas parciais e alvo final, em unidades do viewBox (348 de largura).
   O rotulo em 30 da ~12px na largura que a coluna lateral entrega - ficar
   maior que isso invade a tampa, que termina em y=133.

   Os dois estados nunca dividem o mesmo fundo: marco pendente esta, por
   definicao, acima do nivel (vidro claro) e marco atingido esta submerso (cola
   preta). Por isso escuro x branco, e nao uma cor unica de compromisso -
   dourado sobre o vidro claro dava contraste de 3,4:1 e sumia.
   -------------------------------------------------------------------------- */
.gatilho-marco line {
    stroke: var(--brand-deep);
    stroke-width: 4;
    stroke-dasharray: 14 12;
    opacity: 0.55;
}

.gatilho-marco text {
    fill: var(--brand-deep);
    font-size: 30px;
    font-weight: bold;
    letter-spacing: 0.04em;
}

/* Atingido: submerso no vermelho, inverte para continuar legivel. */
.gatilho-marco.is-atingido line {
    stroke: rgba(255, 255, 255, 0.85);
    opacity: 1;
}

.gatilho-marco.is-atingido text {
    fill: #fff;
}

.gatilho-aura {
    animation: gatilhoPulsa 2.6s ease-in-out 1.5s infinite;
}

@keyframes gatilhoPulsa {

    0%,
    100% {
        opacity: 0.85;
    }

    50% {
        opacity: 0.35;
    }
}

.gatilho-selo {
    display: inline-block;
    margin-top: 0.25rem;
    padding: 0.3rem 0.7rem;
    border-radius: 999px;
    background: var(--accent);
    color: #5a3800;
    font-size: 0.62rem;
    font-weight: bold;
    letter-spacing: 0.1em;
    text-transform: uppercase;
}

@media (prefers-reduced-motion: reduce) {

    .liq-nivel,
    .liq-balanco,
    .liq-onda-tras,
    .liq-onda-frente,
    .liq-bolha-sobe,
    .liq-bolha,
    .gatilho-aura {
        animation: none;
    }

    .liq-bolha {
        opacity: 0.5;
    }
}


.boxGatilho {
    border: 1px solid #fff;
    border-radius: 1rem;
    padding: 1rem;
    margin-bottom: 20px;

}

/* ==========================================================================
   10. DASH: PREMIACAO E RELAMPAGO
   ========================================================================== */
.premiacao {
    padding: 0 !important;
}

.premiacao,
.bg-card-premiacao {
    color: #ffffff;
    padding: 0 !important;
    text-align: center;
    background: linear-gradient(0deg, #192437 0, var(--brand) 67%) !important;
}

.bg-card-premiacao {
    padding: 0.25rem !important;
}

.card-premiacao .nav-tabs .nav-item.show .nav-link,
.card-premiacao .nav-tabs .nav-link.active {
    background: none !important;
    border: none;
}

.card-premiacao .nav-tabs .nav-link {
    border-radius: 0.30rem !important;
}

.bg-header-premiacao {
    background: var(--brand) !important;
}

.card-premiacao:not(.card-outline)>.card-header {
    color: #000;
    font-size: 0.8rem;
}

.card-premiacao:not(.card-outline)>.card-header a.active {
    font-weight: bold !important;
    color: #000;
}


.swiper-button-next:after,
.swiper-rtl .swiper-button-prev:after,
.swiper-button-prev:after,
.swiper-rtl .swiper-button-next:after {
    color: #CB6868;
}

.card-nopad {
    margin-bottom: 0 !important;
    padding-bottom: 0 !important;
    padding-top: 1.5rem !important;
}

.card-premiacao {
    box-shadow: none !important;
}

.card-kpirelampago {
    padding-top: 0.50rem;
    background-repeat: no-repeat;
    background-position: center bottom;
}

.bgrelampago2 {
    background-repeat: no-repeat;
    background-position: center bottom;
    background-size: auto 30%;
    min-height: 495px;
}

.mySwiper {
    min-height: 457px;
}

.bg-kpirelampago {
    background: linear-gradient(0deg, #2D2634 0, #581530 67%) !important;
}

.kpirelampago h1,
.kpirelampago h2,
.kpirelampago h3,
.kpirelampago h4 {
    margin: 0;
    margin-bottom: 0.35rem;
    padding: 0;
}

.kpirelampago h1 {
    font-size: 0.8rem;
    font-weight: 400;
    text-transform: uppercase;
    color: #ffffff;
    margin-bottom: 3rem;
}

.kpirelampago h2 {
    font-size: 1.1rem;
    font-weight: bold;
    text-transform: uppercase;
    color: #ffffff;
}

.kpirelampago h3,
.kpirelampago-label {
    font-size: 0.9rem;
    font-weight: 200;
    text-transform: uppercase;
}

.kpirelampago h4 {
    font-size: 1.1rem;
    font-weight: bold;
    text-transform: uppercase;
    color: #F688A9;
}

.padding-labels {
    padding: 0.9rem 0;
    margin-bottom: 5.5rem;
}

/* ==========================================================================
   11. DASH: LOGINDASH
   ========================================================================== */
.logindash {
    padding: 0 !important;
}

.logindash,
.bg-card-logindash {
    color: #fff;
    /* padding: 0 !important; */
    /* background: linear-gradient(180deg,#191821 0,#353536 67%) !important; */
}

.bg-card-logindash {
    background: var(--brand);
    border-radius: 10px;
}

.card-logindash .nav-tabs {
    padding-left: 25%;
    height: 55px;
}

.card-logindash .nav-tabs .nav-item:nth-child(2) {
    margin-left: 10px;
}

.card-logindash .nav-tabs .nav-item.show .nav-link,
.card-logindash .nav-tabs .nav-link.active,
.card-logindash {
    background: none !important;
    border: none;
}

.bg-header-logindash {
    background: none !important;

}

.card-logindash:not(.card-outline)>.card-header {
    color: var(--brand);
    font-size: 0.7rem;
}

.card-logindash:not(.card-outline)>.card-header a {
    color: var(--brand);
    border: 1px solid var(--brand) !important;
    border-radius: 1rem;
    padding: 5px 20px;
}

.card-logindash:not(.card-outline)>.card-header a.active {
    font-weight: bold !important;
    color: #fff;
    background: var(--brand) !important;
    border-radius: 1rem;
    position: relative;
    /* necessário para a seta */
}

/* seta centralizada */
.card-logindash:not(.card-outline)>.card-header a.active::after {
    content: "";
    position: absolute;
    bottom: -10px;
    /* joga a seta pra fora do botão */
    left: 50%;
    transform: translateX(-50%);
    width: 0;
    height: 0;
    border-left: 10px solid transparent;
    border-right: 10px solid transparent;
    border-top: 10px solid var(--brand);
    /* mesma cor do fundo */
}

.card-logindash {
    box-shadow: none !important;
}

.smallLogin {
    font-size: 0.8rem;
    color: #fff;
    text-align: left;
    margin: 0;
    padding: 0;
}


/* ==========================================================================
   12. BOTOES, TEXTOS E FORMULARIOS
   ========================================================================== */
.icheck-danger>input:first-child:checked+input[type="hidden"]+label::before,
.icheck-danger>input:first-child:checked+label::before {
    background-color: var(--brand);
    color: #fff;
}

.btn-danger {
    background-color: var(--brand);
}

.btn-default {
    background-color: #fff;
    color: var(--brand);
}

.txtFooter {
    margin-top: 1rem;
    color: var(--brand);
    font-weight: 100;
    font-size: 0.75rem;
}

.txtFooter a {
    color: var(--brand);
}

.subtitulo {
    color: var(--brand);
    margin-top: 0.35rem;
    font-size: 0.9rem;
}

.descricao {
    color: #000;
    font-size: 0.8rem;
    width: 80%;
}

/* Selects nativos com o mesmo raio do Select2 (secao 13), para nao ficarem
   dois cantos diferentes lado a lado no mesmo filtro. Prefixar com o elemento
   ja vence o .form-control / .custom-select do Bootstrap, sem !important.
   Cobre tambem o "Mostrar _MENU_ registros" do DataTables, que sai como
   select.custom-select.custom-select-sm.form-control.form-control-sm. */
select.form-control,
select.form-control-sm,
select.custom-select,
select.custom-select-sm {
    border-radius: var(--radius);
}

/* select2 */
.select2-container--bootstrap4 .select2-selection,
/* ==========================================================================
   13. PLUGINS: SELECT2 E FOCO DE CAMPO
   ========================================================================== */
.select2-container--bootstrap4 .select2-selection--multiple .select2-search__field {
    background: none;
    color: var(--brand);
    border-radius: 10px;
}

.select2-container--bootstrap4 .select2-results__option--highlighted,
.select2-container--bootstrap4 .select2-results__option--highlighted.select2-results__option[aria-selected="true"] {
    background: var(--brand);
    color: #fff;
}

.select2-container--bootstrap4 .select2-selection--multiple .select2-selection__choice,
.select2-container--bootstrap4 .select2-selection--single .select2-selection__rendered {
    color: var(--brand);
}

.select2-search__field::placeholder {
    color: rgb(255, 255, 255);
    opacity: 1;
    /* Firefox */
}

.select2-container--bootstrap4 .select2-selection--single .select2-selection__arrow b {
    border-color: #FFF transparent transparent transparent;

}

.select2-container--bootstrap4.select2-container--focus .select2-selection {
    border-color: var(--brand);
    border-radius: 10px;
}

/* Aberto, o tema arredonda so o lado livre do par campo+dropdown; o padrao
   dele e 0.25rem e aqui o campo e 10px. */
.select2-container--bootstrap4 .select2-dropdown.select2-dropdown--below {
    border-bottom-right-radius: var(--radius);
    border-bottom-left-radius: var(--radius);
}

.select2-container--bootstrap4 .select2-dropdown.select2-dropdown--above {
    border-top-left-radius: var(--radius);
    border-top-right-radius: var(--radius);
}

/* Foco da marca nos campos (o AdminLTE deixa azul do Bootstrap).
   Sem !important: mesma especificidade do AdminLTE e este arquivo carrega
   depois dele nos dois head.blade.php. */
.form-control:focus {
    border-color: var(--brand);
    box-shadow: 0 0 0 0.2rem rgba(var(--brand-rgb), 0.25);
}



/* ==========================================================================
   14. CONTEUDO: PREMIOS, TERMO, PDF E LINKS
   ========================================================================== */
.subG {
    font-size: 1.4rem;
}

.subX {
    font-size: 1.2rem;
    font-weight: bold;
}

.white {
    color: #ffffff;
}

.h-premios {
    background: #fff !important;
    min-height: 470px;
}

.h-premios ul li {
    padding: 2px;
}

/* Os quatro meses lado a lado, terminando na mesma linha.
   O .row do Bootstrap ja da a mesma altura as colunas (align-items: stretch);
   o que faltava era o card esticar dentro da coluna e a lista de premios
   crescer para ocupar a sobra. Sem isso o bloco branco de cada mes para onde
   o texto daquele mes acaba, e dezembro (lista mais longa) desalinha os
   outros tres. Nao da para resolver so com o min-height do .h-premios: ele e
   um piso, nao um teto. */
.premios-mes {
    display: flex;
}

.premios-mes>.card {
    width: 100%;
}

.premios-mes .card-body {
    display: flex;
    flex-direction: column;
}

.premios-mes .h-premios {
    flex: 1 1 auto;
}

/* Premios do mes agrupados por categoria (LIFESTYLE, TECNOLOGIA, +JUNTOS,
   EDUCACAO). O rotulo e um <b> dentro do proprio <li>: vira linha propria,
   para o nome do premio nao emendar na categoria. */
.premios-categorias li + li {
    margin-top: 0.5rem;
}

.premios-categorias li b {
    display: block;
    color: var(--brand);
    font-size: 0.75rem;
    letter-spacing: 0.05em;
}

.bgcolor {
    /* background-color: #BF0D0D; */
    min-height: 470px
}

.bgcolor ul li {
    padding: 5px;

}

.descricaoT {
    font-size: 1rem;
    font-weight: 200;
}

.m10 {
    margin: 10px 0;
}

.ml20 {
    margin-left: 20px;
}

.linkblank {
    color: var(--brand) !important;
    text-decoration: underline;
}

.linkblank:hover,
.linkblank:active,
.linkblank:active {
    color: var(--brand) !important;
    font-weight: bold;
}

/* .os-content-glue, .sidebar,  { */
.sidebar-dark-primary {
    /* background-color: transparent !important; */
    /* background-color: rgba(0, 0, 0, 0.2) !important; */
}

.sidebar-collapse .sidebar-dark-primary {
    /* background-color: transparent !important; */
    /* background-color: rgba(78, 13, 13, 1) !important; */
}

.sidebar-collapse .sidebar-dark-primary:hover,
.sidebar-collapse .sidebar-dark-primary:active {
    background-color: var(--brand);
    /* background-color: rgba(0, 0, 0, 0.8) !important; */
}

.pdfview {
    width: 100%;
    height: 100%;
}

/* Visualizador do Adobe na tela do termo. Altura em vh porque a caixa fixa de
   500px ficava baixa em monitor grande; o teto evita estourar o viewport em tela
   alta e o piso mantem leitura no celular. */
.pdfview-termo {
    width: 100%;
    height: min(78vh, 900px);
    min-height: 420px;
}

.labelpdf {
    font-size: 0.8rem;
    word-break: break-word;
    font-weight: normal;
    /* O texto do aceite fica FORA do card vermelho, mas herdava o color:#fff do
       .logindash (resto do tema escuro antigo). Na arte clara de 2026 ele sumia
       no fundo. */
    color: var(--brand-deep);
}

.termo {
    width: 80% !important;
    max-width: none !important;
}

.pad5 {
    padding: 0.5rem 2rem;
}

/* ==========================================================================
   15. AJUSTES POR BREAKPOINT (@supports e @media)
   ========================================================================== */
@supports (-webkit-backdrop-filter: none) or (backdrop-filter: none) {


    .logindash,
    .bg-card-logindash {
        -webkit-backdrop-filter: blur(30px) brightness(-7);
        backdrop-filter: blur(16px) brightness(-7);
    }
}

/* slightly transparent fallback for Firefox (not supporting backdrop-filter) */
@supports not ((-webkit-backdrop-filter: none) or (backdrop-filter: none)) {}


@media (max-width: 992px) {

    /* O cover que ficava aqui virou regra unica na secao 2 (body::before):
       o enquadramento agora e o mesmo em toda largura, e o preloader e o modal
       - que este override nao alcancava - deixam de destoar no celular. */

    .brand-link {
        display: none !important
    }

    .backdrop-sidebar,
    .sidebar-dark-primary {
        /* background-color: rgba(0, 0, 0, 0.9) !important; */
        background: linear-gradient(0deg, var(--brand) 0, var(--brand-dark) 50%) !important;
    }
}

@media (max-width: 428px) {
    .bg-horizontal {
        background: none !important;
    }

    .ranking {
        background-size: 30% !important;
    }

    .login-box {
        width: 320px;
    }

    .login-box .brand {
        width: 50%;
        /* margin-left: -2.5rem !important; */
    }

    .card-logindash .nav-tabs {
        padding-left: 6%;
    }

    /* Termo no celular: a moldura vermelha (1.25rem do card-body) mais o respiro
       da coluna e do .pad5 comiam uns 70px dos ~390px de tela, e o Adobe em
       FIT_WIDTH desenhava o regulamento em ~270px. Estreitando o respiro so
       aqui, o documento recupera a largura. O escopo em .card-box existe porque
       .bg-card-logindash e .pad5 tambem servem login, reset e formularios. */
    .card-box .bg-card-logindash {
        padding: 0.5rem;
    }

    .card-box .pad5 {
        padding: 0.5rem 0.75rem;
    }

    .pdfview-termo {
        height: 68vh;
        min-height: 300px;
    }

    #whats {
        display: inline-block;
        position: fixed;
        width: 43px;
        height: 34px;
        right: 10px;
        bottom: 100px;
    }

    #whats img,
    #whats a {
        width: 43px;
        height: 44px;
        display: block;
    }

    .card-kpi {
        padding-top: 0rem;
        background-size: auto 55%;
    }

    .kpi h3,
    .kpi-label {
        font-size: 0.6rem;
    }

    .col-6.col-sm-12.col-md-6.kpi-label.text-left {
        margin: 0 !important;
        padding: 0 !important;
        text-align: right !important;
    }
}

/* Celular deitado: a consulta de largura acima nao pega (a tela tem 800px+ de
   largura), e ali 68vh/78vh dao ~280px - o piso de altura do visualizador e que
   passava a mandar, estourando a tela. Por isso este corte e por ALTURA. */
@media (max-height: 500px) {
    .pdfview-termo {
        height: 78vh;
        min-height: 240px;
    }
}

/* Grade de KPIs em duas colunas antes de 1720px.
   Os cards de KPI tem knob, imagem e tres linhas de numero: em tres colunas
   eles so respiram numa tela bem larga, por isso abaixo de 1720px caem para
   duas. A regra vale SO para a grade de KPIs (o [data-anima="lista"] do dash e
   do metas), e nao para todo .col-xl-4 da aplicacao: quando era global, ela
   engordava tambem a coluna da posicao no bloco de topo, que e col-xl-4 ao
   lado de um col-xl-8. Somando 50% + 66,6% a linha estourava e o grafico de
   evolucao caia para baixo do scoreboard em qualquer tela menor que 1720px. */
@media screen and (max-width: 1720px) {
    [data-anima="lista"]>.col-xl-4 {
        flex: 0 0 50%;
        max-width: 50%;
    }
}

/* ==========================================================================
   16. UTILITARIOS DIVERSOS
   ========================================================================== */
.img-fluid {
    /* margin-top: 50px; */
}

.gridUser {
    text-align: center;
    margin-right: 5px;
    margin-top: 5px;
}

.gridUser div>p {
    margin: 0;
    padding: 0;
    font-size: 0.8rem;
}

.btn-ir {
    font-size: 0.9rem;
}


.bg-success {
    background-color: var(--brand) !important;
}


.embed-container {
    position: relative;
    padding-bottom: 50%;
    height: 0;
    overflow: hidden;
    max-width: 100%;
}

.embed-container iframe,
.embed-container object,
.embed-container embed {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
}


.minimenuheader {
    position: absolute;
    right: 0;
}

.smalltitle {
    font-size: 11px !important;
}

.invalid-feedback {
    color: #620901 !important;
}

.mB10 {
    margin-bottom: 15px;
}

/* ==========================================================================
   17. LISTAGENS: TABELA NO DESKTOP, CARDS NO MOBILE
   --------------------------------------------------------------------------
   Uso na view:
     <table class="table ... mj-cards">        -> ativa os cards em < 768px
       <td class="mj-card-actions">            -> vai para o canto sup. direito
       <td class="mj-card-title">              -> titulo do card (sem rotulo)
       <td class="mj-card-sub">                -> subtitulo (sem rotulo)
       <td data-label="Fone">                  -> linha "rotulo -> valor"

   As celulas rotuladas seguem a ordem das colunas (itens flex de mesmo
   `order` mantem a ordem do DOM), entao nao precisa classe por coluna.

   Requisitos: o DataTable precisa de "responsive": false, senao o plugin
   Responsive move as celulas para child rows e desmonta o card. Para nao
   perder a leitura no desktop, envolva a tabela em .mj-table-scroll depois
   do init (ver painel/usuarios/index).

   Cores vem dos tokens da secao 1 (--surface, --border, --divider,
   --text-muted, --radius, --shadow-card).
   ========================================================================== */
@media (min-width: 768px) {
    .mj-table-scroll {
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
    }
}

@media (max-width: 767.98px) {

    .mj-cards thead,
    .mj-cards tfoot {
        display: none;
    }

    .mj-cards,
    .mj-cards tbody,
    .mj-cards tbody tr,
    .mj-cards tbody td {
        display: block;
        width: 100%;
    }

    .mj-cards {
        border: 0;
    }

    /* Cada registro e um card. O :nth-of-type vence o .table-striped */
    .mj-cards tbody tr,
    .mj-cards.table-striped tbody tr:nth-of-type(odd) {
        position: relative;
        display: flex;
        flex-direction: column;
        background-color: var(--surface);
        border: 1px solid var(--border);
        border-radius: var(--radius);
        box-shadow: var(--shadow-card);
        padding: 0.75rem;
        margin-bottom: 0.75rem;
    }

    /* .sorting_1 e a coluna ordenada, que o DataTables pinta de cinza */
    .mj-cards tbody td,
    .mj-cards tbody td.sorting_1 {
        background-color: transparent;
        border: 0;
        padding: 0.35rem 0;
        white-space: normal;
        word-break: break-word;
    }

    .mj-cards tbody td[data-label] {
        display: flex;
        justify-content: space-between;
        align-items: baseline;
        gap: 0.75rem;
        border-top: 1px solid var(--divider);
        font-size: 0.875rem;
    }

    .mj-cards tbody td[data-label]::before {
        content: attr(data-label);
        flex: 0 0 auto;
        font-weight: 600;
        color: var(--text-muted);
    }

    /* Cabecalho do card: o padding a direita reserva espaco para as acoes */
    .mj-cards tbody td.mj-card-title {
        order: -2;
        padding: 0 2.5rem 0.15rem 0;
        font-size: 1rem;
        font-weight: 700;
        line-height: 1.3;
        color: var(--text);
    }

    .mj-cards tbody td.mj-card-sub {
        order: -1;
        padding: 0 2.5rem 0.35rem 0;
        font-size: 0.8125rem;
        color: var(--text-muted);
    }

    .mj-cards tbody td.mj-card-actions {
        position: absolute;
        top: 0.5rem;
        right: 0.5rem;
        width: auto;
        padding: 0;
    }

    /* ----------------------------------------------------------------------
       Paginacao do DataTables no mobile (vale para qualquer listagem, nao so
       as .mj-cards). O dataTables.bootstrap4.css usa white-space: nowrap no
       .dataTables_paginate e na ul.pagination, entao com muitas paginas
       ("Anterior 1 2 3 4 5 ... 36 Proximo") a barra estoura a largura da tela
       sem poder quebrar linha. Aqui a barra quebra em pills centralizadas.
       Os seletores repetem o `div.` do plugin de proposito: o dele e
       (0,3,3) e venceria por especificidade, mesmo este arquivo vindo depois.
       ---------------------------------------------------------------------- */
    div.dataTables_wrapper div.dataTables_paginate,
    div.dataTables_wrapper div.dataTables_paginate ul.pagination {
        white-space: normal;
    }

    div.dataTables_wrapper div.dataTables_paginate ul.pagination {
        flex-wrap: wrap;
        justify-content: center;
        margin: 0;
    }

    div.dataTables_wrapper div.dataTables_paginate .page-item {
        margin: 2px;
    }

    div.dataTables_wrapper div.dataTables_paginate .page-link {
        margin-left: 0;
        /* anula o -1px que junta as bordas na barra */
        padding: 0.35rem 0.6rem;
        font-size: 0.8125rem;
        border-radius: var(--radius-sm);
    }
}

/* --------------------------------------------------------------------------
   Cor da paginacao (Anterior 1 2 3 Proximo). O Bootstrap 4 pinta os links de
   azul (#007bff); aqui trocamos pelo vermelho escuro do tema. Vale para o
   DataTables e para o paginate padrao do Laravel. Sem !important: estes
   seletores igualam a especificidade do Bootstrap e este arquivo vem depois.
   -------------------------------------------------------------------------- */
.page-link {
    color: var(--brand-dark);
}

.page-link:hover {
    color: #fff;
    background-color: var(--brand-dark);
    border-color: var(--brand-dark);
}

.page-link:focus {
    box-shadow: 0 0 0 0.2rem rgba(176, 0, 6, 0.25);
}

.page-item.active .page-link {
    color: #fff;
    background-color: var(--brand-dark);
    border-color: var(--brand-dark);
}

/* ==========================================================================
   18. AJUSTE DE METAS: GRADE DE KPIS POR MES
   --------------------------------------------------------------------------
   Tela painel/ajuste-metas: tabela com um input por mes. No desktop e uma
   tabela normal; no mobile cada KPI vira card (mesma ideia da secao 17, mas
   com inputs no lugar de texto). Os campos alterados ganham destaque amarelo
   ate salvar. Cores vem dos tokens da secao 1.
   ========================================================================== */

/* Remove as setinhas do input numerico (o campo e type=text, mas fica a
   prova de mudanca futura para type=number) */
.input-meta::-webkit-outer-spin-button,
.input-meta::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
}

.input-meta {
    -moz-appearance: textfield;
}

/* Campo com valor diferente do original: destaque ate salvar */
.input-meta.meta-alterada {
    background-color: #fff3cd;
    border-color: var(--accent);
}

@media (max-width: 767.98px) {
    .metas-table thead {
        display: none;
    }

    .metas-table,
    .metas-table tbody,
    .metas-table tbody tr,
    .metas-table tbody td {
        display: block;
        width: 100%;
    }

    .metas-table {
        border: 0;
    }

    /* Cada KPI e um card. O :nth-of-type vence o .table-striped */
    .metas-table tbody tr,
    .metas-table.table-striped tbody tr:nth-of-type(odd) {
        position: relative;
        display: flex;
        flex-direction: column;
        background-color: var(--surface);
        border: 1px solid var(--border);
        border-radius: var(--radius);
        box-shadow: var(--shadow-card);
        padding: 0.75rem;
        margin-bottom: 0.75rem;
    }

    .metas-table tbody td {
        background-color: transparent;
        border: 0;
        padding: 0.35rem 0;
    }

    /* Nome do KPI: titulo do card */
    .metas-table tbody td.td-kpi-nome {
        order: -2;
        font-size: 1rem;
        font-weight: 700;
        padding-bottom: 0.15rem;
    }

    /* Badge do tipo: logo abaixo do titulo */
    .metas-table tbody td.td-kpi-tipo {
        order: -1;
        padding-bottom: 0.5rem;
    }

    /* Linhas de mes: rotulo -> input */
    .metas-table tbody td[data-label] {
        display: flex;
        justify-content: space-between;
        align-items: center;
        gap: 0.75rem;
        border-top: 1px solid var(--divider);
        padding: 0.5rem 0;
    }

    .metas-table tbody td[data-label]::before {
        content: attr(data-label);
        flex: 0 0 auto;
        font-weight: 600;
        color: var(--text-muted);
        font-size: 0.875rem;
    }

    .metas-table tbody td[data-label] .input-meta {
        max-width: 180px;
    }
}

/* --------------------------------------------------------------------------
   18.1 A linha do gatilho
   --------------------------------------------------------------------------
   O gatilho fica na mesma grade dos KPIs, mas nao e um deles: e outra tabela no
   banco (`gatilho`) e alimenta os marcos da garrafa do dash. O filete da marca e
   o fundo mais quente existem para separar as duas coisas sem tirar a linha da
   tabela - fora dela, ela perderia o colar do Excel e o "salvar so o que mudou".

   O :nth-of-type vence o .table-striped do Bootstrap, que pinta as linhas
   impares e passaria por cima do destaque.
   -------------------------------------------------------------------------- */
.metas-table tbody tr.linha-gatilho,
.metas-table.table-striped tbody tr.linha-gatilho:nth-of-type(odd) {
    background-color: #fffaf0;
}

/* O filete so no desktop: la a linha e uma faixa horizontal e o traco separa as
   duas partes da grade. No mobile cada td vira bloco, e o mesmo traco em todos
   eles seria uma cerca dentro do card - ali a marca vai na borda esquerda, e o
   separador entre os meses continua sendo o do td[data-label] da secao 18. */
@media (min-width: 768px) {
    .metas-table tbody tr.linha-gatilho > td {
        border-top: 3px solid var(--brand);
    }
}

@media (max-width: 767.98px) {
    .metas-table tbody tr.linha-gatilho,
    .metas-table.table-striped tbody tr.linha-gatilho:nth-of-type(odd) {
        border-left: 4px solid var(--brand);
    }
}

/* Resumo do gatilho: o alvo derivado e os marcos que a garrafa vai desenhar.
   Nao ha input para o alvo de proposito - meses e total editaveis podiam
   discordar, e os marcos (acumulado / total) nunca fechariam em 100%. */
.gatilho-resumo {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.35rem 1.25rem;
    margin-top: 0.75rem;
    padding: 0.6rem 0.9rem;
    border: 1px solid var(--border);
    border-left: 4px solid var(--brand);
    border-radius: var(--radius-sm);
    background-color: #fffaf0;
    color: var(--text);
    font-size: 0.875rem;
}

.gatilho-resumo-titulo {
    font-weight: 700;
    color: var(--brand-deep);
    text-transform: uppercase;
    letter-spacing: 0.03em;
    font-size: 0.75rem;
}

/* Os marcos sao o dado que se olha antes de salvar: monoespacado para os
   percentuais nao dancarem de largura a cada digito digitado. */
#gatilhoMarcos {
    font-variant-numeric: tabular-nums;
}

/* --------------------------------------------------------------------------
   18.2 Aviso de ajuste sobrescrito
   --------------------------------------------------------------------------
   Renderiza na tela de IMPORTACOES, nao aqui - mora nesta secao porque o
   assunto e o mesmo: o ajuste manual de meta. A planilha de metas apaga e
   reescreve os meses que traz, e este aviso lista o que ela derrubou, com o
   valor antigo a vista para dar de repor.

   O amarelo forte vem do .alert-warning do AdminLTE (#ffc107 com texto
   #1f2d3d, ~9:1 de contraste), que e o padrao do painel - nao se mexe nele
   aqui. O que falta e a tabela DENTRO do alerta: as bordas do Bootstrap
   assumem fundo claro e desaparecem sobre esse amarelo.
   -------------------------------------------------------------------------- */
.tabela-ajustes-sobrescritos {
    color: inherit;
}

.tabela-ajustes-sobrescritos th,
.tabela-ajustes-sobrescritos td {
    border-top-color: rgba(0, 0, 0, 0.12);
}

.tabela-ajustes-sobrescritos thead th {
    border-bottom-color: rgba(0, 0, 0, 0.25);
}

/* Os volumes existem para serem comparados coluna a coluna. */
.tabela-ajustes-sobrescritos td.text-right,
.tabela-ajustes-sobrescritos th.text-right {
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}


/* ==========================================================================
   19. RANKING: LEADERBOARD POR GRUPO
   --------------------------------------------------------------------------
   Uso na view:
     @include('painel.dash.ranking.leaderboard', ['lista' => $lista])

   Lista, nao tabela: o mesmo markup serve celular e desktop, sem rolagem
   horizontal e sem virar card. O que muda e a grade.

   Os breakpoints aqui sao @container, nao @media, e por um motivo pratico: a
   sidebar do AdminLTE abre e fecha e muda a largura util do painel sem mudar a
   largura da janela. Medindo o container, a lista responde ao espaco que
   realmente tem. Por isso as variantes deste componente NAO estao na secao 15
   com as outras - elas nao sao por breakpoint de tela.

   O contorno do container e o .mj-rank; quem mede e ele.
   ========================================================================== */
.mj-rank {
    container-type: inline-size;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-card);
    overflow: hidden;
}

/* Cabecalho de colunas: so existe quando existem colunas */
.mj-rank-cols {
    display: none;
    gap: 0.1rem 0.7rem;
    padding: 0.45rem 0.9rem 0.45rem 0;
    border-bottom: 1px solid var(--border);
    font-size: 0.625rem;
    font-weight: 700;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.mj-rank-cols .r {
    text-align: right;
}

.mj-rank-list {
    display: flex;
    flex-direction: column;
}

/* ---------- faixas de contexto ---------- */
.mj-rank-band {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.45rem 1rem;
    background: linear-gradient(90deg, rgba(255, 203, 0, 0.22), rgba(255, 203, 0, 0));
    border-bottom: 1px solid var(--divider);
    font-size: 0.65rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--brand-deep);
}

.mj-rank-band::before {
    content: "";
    width: 3px;
    height: 12px;
    background: var(--accent);
    border-radius: 2px;
}

.mj-rank-band.is-cut {
    background: none;
    color: var(--text-muted);
    border-top: 1px solid var(--border);
}

.mj-rank-band.is-cut::before {
    background: var(--border);
}

/* Separador da janela de vizinhos: conta quantas ficaram fora, sem nomear nem
   posicionar nenhuma delas. */
.mj-rank-band.is-gap {
    background: none;
    color: var(--text-muted);
    border-top: 1px solid var(--border);
    text-transform: none;
    letter-spacing: 0.02em;
    font-weight: 600;
}

.mj-rank-band.is-gap::before {
    content: "\22EF";
    width: auto;
    height: auto;
    background: none;
    color: var(--text-muted);
    font-size: 0.85rem;
    line-height: 1;
}

/* ---------- a linha ---------- */
.mj-rank-row {
    display: grid;
    grid-template-columns: 3.1rem 1fr auto;
    align-items: center;
    gap: 0.1rem 0.7rem;
    width: 100%;
    text-align: left;
    appearance: none;
    border: 0;
    border-bottom: 1px solid var(--divider);
    background: var(--surface);
    font: inherit;
    color: var(--text);
    padding: 0.6rem 0.9rem 0.6rem 0;
}

/* Zona de premiacao: um bloco continuo, nao uma medalha. O corte pode ser top 5
   ou top 10; medalha e coisa das tres primeiras. Fica so um veu quente, porque o
   trilho da esquerda ja esta ocupado codificando o movimento. Vem antes do hover
   e do destaque de proposito: os dois tem que vencer este fundo. */
.mj-rank-row[data-premiacao="1"] {
    background: linear-gradient(90deg, rgba(255, 203, 0, 0.09), rgba(255, 203, 0, 0));
}

button.mj-rank-row {
    cursor: pointer;
}

button.mj-rank-row:hover {
    background: var(--divider);
}

button.mj-rank-row:focus-visible {
    outline: 2px solid var(--brand);
    outline-offset: -2px;
}

.mj-rank-row[data-destaque="1"] {
    background: var(--divider);
}

/* Trilho da posicao: a faixa de 3px codifica o movimento desde a ultima
   analise, e o numero fica em coluna fixa para as posicoes alinharem na
   varredura vertical. */
.mj-rank-rail {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    align-self: stretch;
}

.mj-rank-rail::before {
    content: "";
    width: 3px;
    align-self: stretch;
    background: var(--border);
    border-radius: 0 2px 2px 0;
}

.mj-rank-row[data-mv="up"] .mj-rank-rail::before {
    background: var(--verde, #28a745);
}

.mj-rank-row[data-mv="down"] .mj-rank-rail::before {
    background: #9b2c3f;
}

.mj-rank-pos {
    font-size: 1.1rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    letter-spacing: -0.02em;
    color: var(--text-muted);
    min-width: 2ch;
}

/* O disco vale para a zona de premiacao inteira: com corte em top 5, deixar o
   4o e o 5o sem disco fazia eles parecerem fora do bloco em que estao. O que
   distingue o podio nao e a forma, e o metal. */
.mj-rank-row[data-medalha] .mj-rank-pos,
.mj-rank-row[data-premiacao="1"] .mj-rank-pos {
    display: grid;
    place-items: center;
    width: 1.85rem;
    height: 1.85rem;
    min-width: 0;
    border-radius: 50%;
    color: var(--brand-deep);
    font-size: 0.95rem;
}

/* metal: so as tres primeiras */
.mj-rank-row[data-medalha="1"] .mj-rank-pos {
    background: var(--accent);
}

.mj-rank-row[data-medalha="2"] .mj-rank-pos {
    background: #b0aeb4;
}

.mj-rank-row[data-medalha="3"] .mj-rank-pos {
    background: #c2865c;
}

/* premiacao fora do podio: mesmo disco, ouro lavado com aro. Le como "do mesmo
   grupo que os tres de cima, mas nao e medalha". */
.mj-rank-row[data-premiacao="1"]:not([data-medalha]) .mj-rank-pos {
    background: rgba(255, 203, 0, 0.2);
    box-shadow: inset 0 0 0 1.5px rgba(255, 203, 0, 0.8);
}

.mj-rank-main {
    min-width: 0;
}

.mj-rank-name {
    display: block;
    font-size: 0.9rem;
    font-weight: 600;
    letter-spacing: -0.01em;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Linha anonima: o rotulo e a propria posicao, nao um apelido. Apelido estavel
   ao longo da campanha permitiria montar o historico do concorrente. */
.mj-rank-name.is-anon {
    color: var(--text-muted);
    font-weight: 500;
    font-variant-numeric: tabular-nums;
}

/* Sem colocacao: a rede existe no mes, mas ainda nao pontuou. O travessao no
   lugar do numero e a cor apagada dizem "ainda nao comecou", nao "ultimo lugar".
   Ver AnaliseService::gravarPosicao, que e quem grava a posicao zero. */
.mj-rank-row[data-sem-posicao="1"] .mj-rank-pos {
    color: var(--text-muted);
    font-weight: 500;
}

/* trilho codifica subida e queda: sem posicao nao ha movimento */
.mj-rank-row[data-sem-posicao="1"] .mj-rank-rail::before {
    display: none;
}

/* Linha velada: a campanha decidiu nao expor concorrente, entao sobra a posicao.
   O peso menor e o que evita a leitura de "faltou carregar": a linha nao esta
   incompleta, ela e assim de proposito. As colunas da direita continuam no
   markup, vazias, segurando a grade das outras linhas no lugar. */
.mj-rank-row[data-velada="1"] {
    color: var(--text-muted);
}

.mj-rank-row[data-velada="1"] .mj-rank-name {
    opacity: 0.75;
}

/* sem numero nenhum, o trilho de movimento nao tem o que codificar */
.mj-rank-row[data-velada="1"] .mj-rank-rail::before {
    opacity: 0.35;
}

.mj-rank-you {
    display: inline-block;
    margin-left: 0.4rem;
    padding: 0.05rem 0.35rem;
    border-radius: 3px;
    background: var(--brand);
    color: #fff;
    font-size: 0.6rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    vertical-align: 1px;
}

.mj-rank-sub {
    display: block;
    font-size: 0.72rem;
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
}

.mj-rank-sub b {
    color: var(--text);
    font-weight: 600;
}

.mj-rank-aside {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 0.15rem;
}

.mj-rank-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.2rem;
    font-size: 0.72rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    color: var(--text-muted);
    white-space: nowrap;
}

.mj-rank-chip[data-mv="up"] {
    color: #157f3d;
}

.mj-rank-chip[data-mv="down"] {
    color: #9b2c3f;
}

.mj-spark {
    display: block;
}

/* Colunas que so existem no desktop: no celular a mesma informacao esta na
   linha .mj-rank-sub embaixo do nome. */
.mj-rank-pts,
.mj-rank-meta {
    display: none;
}

.mj-rank-foot {
    padding: 0.6rem 1rem 0.7rem;
    border-top: 1px solid var(--border);
    font-size: 0.72rem;
    color: var(--text-muted);
}

.mj-rank-foot b {
    color: var(--text);
    font-weight: 600;
}

.mj-rank-empty {
    padding: 1.5rem 1rem;
    text-align: center;
    color: var(--text-muted);
    font-size: 0.85rem;
}

/* ==========================================================================
   19.1 Leaderboard: grade larga (medida no painel, nao na janela)
   ========================================================================== */
@container (min-width: 600px) {
    .mj-rank-cols {
        display: grid;
        grid-template-columns: 3.1rem minmax(0, 1fr) 6.4rem 5.2rem 5.4rem;
    }

    .mj-rank-row {
        grid-template-columns: 3.1rem minmax(0, 1fr) 6.4rem 5.2rem 5.4rem;
        padding-top: 0.5rem;
        padding-bottom: 0.5rem;
    }

    .mj-rank-sub {
        display: none;
    }

    .mj-rank-pts,
    .mj-rank-meta {
        display: flex;
        flex-direction: column;
        align-items: flex-end;
        font-variant-numeric: tabular-nums;
    }

    .mj-rank-pts .v {
        font-size: 0.875rem;
        font-weight: 700;
    }

    .mj-rank-pts .u,
    .mj-rank-meta .u {
        font-size: 0.65rem;
        color: var(--text-muted);
    }

    /* %meta e a unica medida com alvo conhecido (100%), entao ganha forma alem
       do numero: uma barra curta que enche ate o alvo. */
    .mj-rank-meta .v {
        font-size: 0.85rem;
        font-weight: 600;
    }

    .mj-rank-meta .bar {
        width: 3.4rem;
        height: 3px;
        border-radius: 2px;
        background: var(--divider);
        overflow: hidden;
    }

    .mj-rank-meta .bar i {
        display: block;
        height: 100%;
        border-radius: 2px;
        background: var(--text-muted);
    }

    .mj-rank-meta[data-bateu="1"] .bar i {
        background: #157f3d;
    }

    .mj-rank-meta[data-bateu="1"] .v {
        color: #157f3d;
    }

    .mj-rank-aside {
        justify-content: center;
    }

    .mj-rank-aside .mj-spark {
        order: -1;
    }
}

/* ==========================================================================
   19.2 Ranking: abas geral/mes, scoreboard e evolucao
   --------------------------------------------------------------------------
   O scoreboard e a evolucao tambem sao containers proprios: no dash da rede
   eles vivem lado a lado num card estreito, e na tela de ranking ocupam a
   largura toda. Medir o container e nao a janela deixa os dois casos certos com
   o mesmo markup.
   ========================================================================== */
/* Barra de navegacao do ranking: o mes da campanha e o tipo de ranking, lado a
   lado. Os dois grupos sao submits do mesmo form de filtros. */
.mj-rank-nav {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.5rem 1.25rem;
    margin-bottom: 0.75rem;
    padding: 0.5rem 0.75rem;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-card);
}

.mj-rank-nav-grupo {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    min-width: 0;
}

.mj-rank-nav-lbl {
    font-size: 0.6rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--text-muted);
    white-space: nowrap;
}

.mj-rank-seg {
    display: flex;
    gap: 2px;
    padding: 3px;
    background: var(--divider);
    border-radius: var(--radius-sm);
}

.mj-rank-nav-note {
    margin-left: auto;
    font-size: 0.68rem;
    color: var(--text-muted);
}

.mj-rank-mes {
    appearance: none;
    border: 0;
    background: transparent;
    font: inherit;
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    color: var(--text-muted);
    padding: 0.3rem 0.62rem;
    border-radius: 4px;
    cursor: pointer;
}

.mj-rank-mes:hover {
    color: var(--text);
}

.mj-rank-mes.is-active {
    background: var(--brand);
    color: #fff;
}

.mj-rank-mes:focus-visible {
    outline: 2px solid var(--brand);
    outline-offset: 2px;
}

.mj-rank-tab {
    appearance: none;
    border: 0;
    background: transparent;
    font: inherit;
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    color: var(--text-muted);
    padding: 0.3rem 0.7rem;
    border-radius: 4px;
    cursor: pointer;
    white-space: nowrap;
}

.mj-rank-tab:hover {
    color: var(--text);
}

.mj-rank-tab.is-active {
    background: var(--brand);
    color: #fff;
}

.mj-rank-tab:focus-visible {
    outline: 2px solid var(--brand);
    outline-offset: 2px;
}

/* ---------- scoreboard ---------- */
.mj-score {
    container-type: inline-size;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-card);
    overflow: hidden;
}

.mj-score-head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.2rem 0.6rem;
    padding: 0.7rem 1rem 0.5rem;
    border-bottom: 1px solid var(--divider);
}

.mj-score-head .who {
    font-size: 0.95rem;
    font-weight: 700;
    letter-spacing: -0.01em;
    color: var(--text);
}

.mj-score-head .tag {
    font-size: 0.68rem;
    color: var(--text-muted);
}

.mj-score-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 1px;
    background: var(--divider);
}

.mj-score-tile {
    background: var(--surface);
    padding: 0.9rem 1rem 1rem;
    display: grid;
    grid-template-columns: 1fr auto;
    align-items: end;
    column-gap: 0.75rem;
    row-gap: 0.1rem;
}

.mj-score-tile .lbl {
    grid-column: 1 / -1;
    font-size: 0.65rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.mj-score-tile .big {
    font-size: 2.4rem;
    font-weight: 700;
    letter-spacing: -0.04em;
    line-height: 1;
    font-variant-numeric: tabular-nums;
    color: var(--brand);
}

.mj-score-tile .big i {
    font-size: 1rem;
    font-style: normal;
    font-weight: 600;
    letter-spacing: 0;
    color: var(--text-muted);
}

.mj-score-tile .mj-spark {
    grid-column: 2;
    grid-row: 2 / 4;
    align-self: center;
}

.mj-score-tile .foot {
    grid-column: 1;
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.45rem;
    font-size: 0.8rem;
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
}

.mj-score-tile .foot b {
    color: var(--text);
    font-weight: 700;
}

@container (min-width: 460px) {
    .mj-score-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

/* ---------- evolucao ---------- */
.mj-evo {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-card);
    padding: 1rem 1rem 1.1rem;
    display: flex;
    flex-direction: column;
    gap: 0.55rem;
    color: var(--text);
}

.mj-evo-head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.35rem 0.75rem;
}

.mj-evo-head .t {
    font-size: 0.65rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.mj-evo-head .w {
    font-size: 0.8rem;
    font-weight: 700;
    color: var(--text);
}

.mj-evo-legend {
    display: flex;
    gap: 0.9rem;
    font-size: 0.72rem;
    color: var(--text-muted);
}

.mj-evo-legend i {
    display: inline-block;
    width: 14px;
    height: 0;
    margin-right: 0.3rem;
    vertical-align: 3px;
    border-top: 2px solid var(--brand);
}

.mj-evo-legend i.is-dash {
    border-top-style: dashed;
    border-color: var(--text-muted);
}

/* O grafico tem ALTURA fixa e largura vinda do viewBox (que cresce com a
   quantidade de analises). Antes era width:100%/height:auto, e num container
   largo o SVG inteiro escalava junto - inclusive os textos de 9px, que viravam
   20px. Fixando a altura, o desenho nunca fica desproporcional; quando o mes
   tem muitas analises, o excesso vira rolagem horizontal aqui. */
.mj-evo-plot {
    overflow-x: auto;
    overflow-y: hidden;
    -webkit-overflow-scrolling: touch;
    margin: 0 -0.25rem;
    padding: 0 0.25rem;
}

/* A altura cresce por breakpoint, dentro de limites. A largura acompanha pela
   proporcao do viewBox, entao o desenho fica maior na tela grande sem voltar ao
   problema antigo (escalar sem teto e inflar os textos de 9px). O excesso vira
   rolagem no wrapper. */
.mj-evo-plot svg {
    display: block;
    height: 148px;
    width: auto;
    max-width: none;
}

@media (min-width: 992px) {
    .mj-evo-plot svg {
        height: 186px;
    }
}

/* Nao ha terceiro degrau de proposito: a altura multiplica a largura pela
   proporcao do viewBox, e crescer mais faria o desenho voltar a estourar a
   coluna numa tela grande - trocando um problema pelo outro. */

/* ---------- pontos interativos ---------- */
.mj-evo-pt {
    cursor: pointer;
}

.mj-evo-pt:focus {
    outline: none;
}

.mj-evo-pt:focus-visible {
    outline: 2px solid var(--brand);
    outline-offset: 1px;
}

/* a marca visivel cresce quando o alvo invisivel ao lado recebe o ponteiro */
.mj-evo-pt:hover+.mj-evo-marca,
.mj-evo-pt:focus-visible+.mj-evo-marca {
    r: 5.5;
}

.mj-evo-tip {
    position: fixed;
    z-index: 1080;
    max-width: 15rem;
    padding: 0.35rem 0.55rem;
    border-radius: var(--radius-sm);
    background: var(--brand-deep);
    color: #fff;
    font-size: 0.72rem;
    line-height: 1.35;
    box-shadow: 0 4px 14px -4px rgba(0, 0, 0, 0.4);
    pointer-events: none;
}

.mj-evo-tip[hidden] {
    display: none;
}

.mj-evo-cap {
    font-size: 0.68rem;
    color: var(--text-muted);
    line-height: 1.5;
}

/* ==========================================================================
   19.3 Ranking: posicao dentro do card-rede (dash de admin e executivo)
   ========================================================================== */
.mj-rede-pos {
    align-items: center;
    margin-bottom: 0.15rem;
}

.mj-rede-pos .mj-spark {
    display: inline-block;
    vertical-align: middle;
    margin-left: 0.3rem;
}

.mj-rede-de {
    font-size: 0.68rem;
    color: var(--text-muted);
    margin-right: 0.2rem;
}

/* ==========================================================================
   19.4 Ranking: os grupos lado a lado (admin sem recorte de grupo)
   --------------------------------------------------------------------------
   Substitui os 121 cards por rede que a tela antiga empilhava. Uma coluna por
   grupo; o grupo inteiro fica a um clique.
   ========================================================================== */
.mj-grupos {
    container-type: inline-size;
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 1px;
    background: var(--border);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-card);
    overflow: hidden;
}

@container (min-width: 560px) {
    .mj-grupos {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@container (min-width: 900px) {
    .mj-grupos {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }
}

@container (min-width: 1180px) {
    .mj-grupos {
        grid-template-columns: repeat(5, minmax(0, 1fr));
    }
}

.mj-grupo {
    background: var(--surface);
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.mj-grupo-head {
    display: flex;
    justify-content: space-between;
    gap: 0.4rem;
    margin: 0;
    padding: 0.6rem 0.75rem 0.5rem;
    border-bottom: 1px solid var(--divider);
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--brand);
}

.mj-grupo-head em {
    font-style: normal;
    font-size: 0.62rem;
    font-weight: 400;
    letter-spacing: 0;
    text-transform: none;
    color: var(--text-muted);
}

.mj-grupo-row {
    display: grid;
    grid-template-columns: 1.7rem minmax(0, 1fr) auto;
    align-items: center;
    gap: 0.45rem;
    padding: 0.4rem 0.75rem;
    border-bottom: 1px solid var(--divider);
    color: var(--text);
    text-decoration: none;
}

.mj-grupo-row:hover {
    background: var(--divider);
    color: var(--text);
    text-decoration: none;
}

.mj-grupo-row .p {
    font-size: 0.78rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    color: var(--text-muted);
}

/* na coluna compacta nao cabe disco, mas a zona de premiacao inteira ganha a
   cor da marca na posicao - mesmo critério do leaderboard */
.mj-grupo-row[data-medalha] .p,
.mj-grupo-row[data-premiacao="1"] .p {
    color: var(--brand);
}

.mj-grupo-row[data-medalha] .p {
    font-weight: 700;
}

.mj-grupo-row[data-premiacao="1"] {
    background: linear-gradient(90deg, rgba(255, 203, 0, 0.09), rgba(255, 203, 0, 0));
}

.mj-grupo-row[data-premiacao="1"]:hover {
    background: var(--divider);
}

.mj-grupo-row .nm {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.mj-grupo-row .nm b {
    font-size: 0.78rem;
    font-weight: 600;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.mj-grupo-row .nm .pt {
    font-size: 0.65rem;
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
}

.mj-grupo-more {
    margin-top: auto;
    padding: 0.5rem 0.75rem 0.65rem;
    font-size: 0.65rem;
    color: var(--text-muted);
}

.mj-grupo-more:hover {
    color: var(--brand);
}

/* ==========================================================================
   19.5 Ranking: bloco de topo do dash (posicao + evolucao lado a lado)
   --------------------------------------------------------------------------
   No dash da rede e em metas, o scoreboard e o grafico ficam na mesma linha.
   Como as duas alturas naturais nao batem (dois numeros grandes de um lado, um
   grafico do outro), o card estica para acompanhar a linha. So vale quando as
   colunas estao lado a lado: empilhadas no celular, cada um volta a ter a
   altura do proprio conteudo.
   ========================================================================== */
/* respiro entre o topo e a secao dos KPIs */
.mj-topo {
    margin-bottom: 1rem;
}

@media (min-width: 1200px) {

    .mj-topo>[class*="col-"]>.mj-score,
    .mj-topo>[class*="col-"]>.mj-evo {
        height: 100%;
    }

    /* o grafico fica ancorado embaixo, para a legenda nao flutuar no meio */
    .mj-topo>[class*="col-"]>.mj-evo .mj-evo-plot {
        margin-top: auto;
    }

    /* Aqui os dois tiles EMPILHAM em vez de ficar lado a lado, e cada um estica
       para dividir a altura. Antes ficavam curtos no topo e sobrava um vazio
       grande embaixo do card - o esticar criava o vao em vez de usar o espaco.
       Vence o @container de 460px do proprio .mj-score-grid por especificidade. */
    .mj-topo .mj-score {
        display: flex;
        flex-direction: column;
    }

    .mj-topo .mj-score-grid {
        flex: 1;
        grid-template-columns: minmax(0, 1fr);
        grid-auto-rows: 1fr;
    }

    /* rotulo no alto, numero e pontuacao embaixo: o tile mais alto distribui em
       vez de acumular folga no meio */
    .mj-topo .mj-score-tile {
        align-content: space-between;
        row-gap: 0.5rem;
    }

    /* com mais altura, o numero da posicao pode crescer */
    .mj-topo .mj-score-tile .big {
        font-size: 3rem;
    }

    .mj-topo .mj-score-tile .big i {
        font-size: 1.1rem;
    }
}

/* ==========================================================================
   19.6 Dash: coluna lateral encostando no rodape da linha
   --------------------------------------------------------------------------
   A coluna do gatilho + comparativo terminava bem antes da grade de KPIs, que
   e mais alta, e sobrava um vazio grande embaixo dela. Aqui o comparativo
   absorve a altura que sobra e encosta no rodape, entao o unico buraco que
   resta e o slot vago da grade de KPIs - que le como "falta um KPI", nao como
   layout quebrado. Quantos KPIs a rede tem varia, entao esse slot e inerente.

   Sao varios niveis de flex porque o card-comparativo e aninhado: card >
   card-body > row > col > card interno > card-body colorido. O fundo colorido
   so desce ate embaixo se a cadeia toda esticar.

   So no PC: empilhado no celular cada card volta a ter a altura do conteudo.
   ========================================================================== */
@media (min-width: 1200px) {
    .mj-lateral {
        display: flex;
        flex-direction: column;
    }

    /* Sem zerar a margem: os cards de KPI da coluna vizinha terminam com o
       margin-bottom de 1rem do .card do AdminLTE, e a coluna toda mede isso. Se
       este card zerar a dele, ele desce 1rem alem da ultima linha de KPIs - era
       a linha passando um pouco. Mantendo a margem, o flex desconta ela da
       altura e as duas colunas fecham no mesmo ponto, seja qual for o valor que
       o tema use. */
    .mj-lateral>.card:last-child {
        flex: 1;
    }

    .mj-lateral>.card:last-child,
    .mj-lateral>.card:last-child>.card-body,
    .mj-lateral>.card:last-child>.card-body>.row,
    .mj-lateral>.card:last-child>.card-body>.row>.col-12,
    .mj-lateral .card-comparativos,
    .mj-lateral .card-comparativos>.card-body {
        display: flex;
        flex-direction: column;
        min-height: 0;
    }

    .mj-lateral>.card:last-child>.card-body,
    .mj-lateral>.card:last-child>.card-body>.row,
    .mj-lateral>.card:last-child>.card-body>.row>.col-12,
    .mj-lateral .card-comparativos,
    .mj-lateral .card-comparativos>.card-body,
    .mj-lateral .card-comparativos .tab-content {
        flex: 1;
    }

    .mj-lateral .card-comparativos .tab-content {
        display: flex;
        flex-direction: column;
        min-height: 0;
    }

    /* Esticar a caixa por fora nao resolvia nada: a lista continuava amontoada no
       topo com branco embaixo. Aqui as linhas se distribuem na altura ganha.
       Precisa ser .tab-pane.active e nao .tab-pane: o Bootstrap esconde as abas
       inativas com display:none, e um display:flex aqui as traria de volta.
       Este seletor tem especificidade (0,4,0) contra a (0,2,0) do plugin. */
    .mj-lateral .card-comparativos .tab-content>.tab-pane.active {
        display: flex;
        flex-direction: column;
        justify-content: space-between;
        flex: 1;
        min-height: 0;
    }
}

/* Placar da aba: quantos KPIs ja estao na meta. O percentual de cada um a tela
   ja mostrava; o total, nao. */
.mj-comp-placar {
    padding-bottom: 0.5rem;
    margin-bottom: 0.35rem;
    border-bottom: 1px solid var(--border);
    font-size: 0.72rem;
    color: var(--text-muted);
}

.mj-comp-placar b {
    font-size: 1.05rem;
    font-weight: 700;
    color: var(--brand);
}

/* ==========================================================================
   20. ANIMACOES DE ENTRADA
   --------------------------------------------------------------------------
   Ligadas por resources/views/painel/dash/anima.blade.php.

   ESTRUTURA: o IntersectionObserver marca CONTAINERES, nao pecas. Um
   .mj-rank-list recebe data-anima e acende as 30 linhas, as 30 barras e os 30
   sparklines de dentro dele de uma vez. Observar peca a peca daria centenas de
   observers numa tela de admin (121 redes). Por isso os seletores abaixo sao
   sempre "container aceso -> filho anima".

   TODO estado inicial daqui esta preso a html.anima-pronta, classe que o head
   so poe quando ha JS, ha IntersectionObserver e o usuario nao pediu movimento
   reduzido. Sem ela nada abaixo se aplica e a tela renderiza no estado final.
   Isso nao e detalhe de acessibilidade: barra escondida que nunca anima e dado
   perdido, entao o padrao tem que ser "visivel".

   Animar sempre transform / opacity / clip-path. width e stroke-width em
   elemento grande custam layout a cada frame, e esta tela chega a ~1450 barras.

   ESCALONAMENTO: a peca publica --i (seu indice na lista) e cada transicao
   calcula o proprio atraso. O teto de 12 existe para a 30a linha de um ranking
   nao esperar 1,4s so para comecar.

   INDICE
     20.1 barras       20.2 tracos SVG
     20.3 listas       20.4 knob
   ========================================================================== */

/* --------------------------------------------------------------------------
   20.1 Barras
   clip-path e nao width nem scaleX: width faz layout a cada frame, e scaleX
   numa barra de 3px com border-radius esmaga o raio durante a animacao.
   -------------------------------------------------------------------------- */
html.anima-pronta [data-anima~="barras"] .mj-anima-barra {
    clip-path: inset(0 100% 0 0);
}

html.anima-pronta [data-anima~="barras"].anima-on .mj-anima-barra {
    clip-path: inset(0 0 0 0);
    transition: clip-path 1.1s cubic-bezier(0.22, 1, 0.36, 1) calc(min(var(--i, 0), 12) * 45ms);
}

/* --------------------------------------------------------------------------
   20.2 Tracos SVG
   Depende de pathLength="1" na polyline: normaliza o comprimento do traco, e
   com isso o dasharray funciona sem ninguem medir o path em JS.
   -------------------------------------------------------------------------- */
html.anima-pronta [data-anima~="tracos"] .mj-traco {
    stroke-dasharray: 1;
    stroke-dashoffset: 1;
}

html.anima-pronta [data-anima~="tracos"].anima-on .mj-traco {
    stroke-dashoffset: 0;
    transition: stroke-dashoffset 1.1s ease-out calc(min(var(--i, 0), 12) * 45ms);
}

/* Area e marcas entram DEPOIS do traco. Na ordem inversa a marca final ficaria
   flutuando sozinha antes de a linha chegar nela. */
html.anima-pronta [data-anima~="tracos"] .mj-traco-area,
html.anima-pronta [data-anima~="tracos"] .mj-traco-marca {
    opacity: 0;
}

/* A area do sparkline nasce com opacity .1 no proprio SVG: e para esse valor
   que ela volta, nao para 1. */
html.anima-pronta [data-anima~="tracos"].anima-on .mj-traco-area {
    opacity: 0.1;
    transition: opacity 0.5s ease-out calc(min(var(--i, 0), 12) * 45ms + 0.7s);
}

html.anima-pronta [data-anima~="tracos"].anima-on .mj-traco-marca {
    opacity: 1;
    transition: opacity 0.4s ease-out calc(min(var(--i, 0), 12) * 45ms + 0.85s);
}

/* --------------------------------------------------------------------------
   20.3 Listas: os filhos diretos sobem em cascata
   -------------------------------------------------------------------------- */
html.anima-pronta [data-anima~="lista"]>* {
    opacity: 0;
    transform: translateY(10px);
}

html.anima-pronta [data-anima~="lista"].anima-on>* {
    opacity: 1;
    transform: none;
    transition: opacity 0.45s ease-out calc(min(var(--i, 0), 12) * 45ms),
        transform 0.45s cubic-bezier(0.22, 1, 0.36, 1) calc(min(var(--i, 0), 12) * 45ms);
}

/* --------------------------------------------------------------------------
   20.4 Knob
   O valor quem anima e o partial do plugin: e canvas, so da para redesenhar em
   JS. Aqui fica so o fade, para o gauge nao aparecer cravado em zero antes de
   o observador mandar contar.
   -------------------------------------------------------------------------- */
html.anima-pronta .knob-anima {
    opacity: 0;
}

html.anima-pronta .knob-anima.anima-on {
    opacity: 1;
    transition: opacity 0.4s ease-out;
}

/* ==========================================================================
   21. PREMIOS: SIMULACAO DE PREMIACAO MENSAL
   --------------------------------------------------------------------------
   Uso na view:
     @include('painel.premios.tabela-simulacao', ['simulacao' => $simulacao])

   Substitui a imagem tabela@2x.png, que era ilegivel no celular e por isso
   ficava escondida abaixo de 428px - o que tirava a explicacao da conta
   justamente de quem mais acessa por telefone.

   O markup traz o mesmo conteudo duas vezes, e aqui decidimos qual aparece:
   ate 819px de container sao os cards, dali para cima e a tabela. Sao 27
   colunas com cabecalho de tres niveis; nenhum reflow em CSS mantem isso
   legivel num celular, entao a versao estreita e outro desenho, nao a mesma
   tabela espremida.

   O breakpoint e @container e nao @media pelo mesmo motivo da secao 19: a
   sidebar do AdminLTE abre e fecha e muda a largura util do painel sem mudar
   a da janela. Navegador sem @container fica nos cards, que funcionam em
   qualquer largura.

   Cores vem dos tokens da secao 1 (--brand, --ok, --surface, --border,
   --divider, --text-muted, --radius, --shadow-card).
   ========================================================================== */
.mj-simul {
    container-type: inline-size;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-card);
    padding: 0.9rem;
    color: var(--text);
}

.mj-simul-legenda p {
    margin: 0 0 0.8rem;
    font-size: 0.82rem;
    line-height: 1.5;
    color: var(--text-muted);
}

.mj-simul-legenda b {
    color: var(--text);
}

/* Cada dica descreve um dos dois layouts: a da tabela so aparece com ela, no
   @container la embaixo. */
.mj-simul-dica,
.mj-simul-dica-cards {
    margin: 0 0 0.5rem;
    font-size: 0.72rem;
    color: var(--text-muted);
}

.mj-simul-dica {
    display: none;
}

/* --------------------------------------------------------------------------
   21.1 Estreito: um card por cliente, um indicador por linha
   -------------------------------------------------------------------------- */
.mj-simul-scroll {
    display: none;
}

.mj-simul-cards {
    display: grid;
    gap: 0.75rem;
}

.mj-simul-card {
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 0.7rem 0.8rem 0.8rem;
}

.mj-simul-card.is-fora {
    border-color: rgba(var(--brand-rgb), 0.35);
}

.mj-simul-card-topo {
    display: flex;
    align-items: baseline;
    gap: 0.5rem;
    padding-bottom: 0.45rem;
    border-bottom: 2px solid var(--divider);
}

.mj-simul-card-pos {
    flex: 0 0 auto;
    padding: 0.1rem 0.5rem;
    border-radius: 999px;
    background: var(--brand);
    color: #fff;
    font-size: 0.8rem;
    font-weight: 800;
}

.mj-simul-card-nome {
    flex: 1 1 auto;
    font-size: 1rem;
    font-weight: 700;
}

.mj-simul-card-total {
    flex: 0 0 auto;
    text-align: right;
}

.mj-simul-card-total b {
    font-size: 1.2rem;
    color: var(--ok);
}

.mj-simul-card.is-fora .mj-simul-card-total b {
    color: var(--brand);
}

.mj-simul-card-total small {
    display: block;
    font-size: 0.62rem;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.mj-simul-card-status {
    margin: 0.5rem 0 0;
    font-size: 0.76rem;
    font-weight: 600;
    color: var(--ok);
}

.mj-simul-card.is-fora .mj-simul-card-status {
    color: var(--brand);
}

.mj-simul-card-grupo {
    margin: 0.85rem 0 0.1rem;
    font-size: 0.66rem;
    font-weight: 700;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.mj-simul-card-grupo.is-bonus {
    color: var(--brand);
}

.mj-simul-card-lista {
    margin: 0;
    padding: 0;
    list-style: none;
}

.mj-simul-card-item {
    position: relative;
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.6rem;
    padding: 0.45rem 0 0.55rem;
    border-top: 1px solid var(--divider);
}

.mj-simul-card-kpi {
    font-size: 0.76rem;
    line-height: 1.25;
}

.mj-simul-card-kpi small {
    display: block;
    font-size: 0.64rem;
    color: var(--text-muted);
}

.mj-simul-card-valor {
    flex: 0 0 auto;
    text-align: right;
}

.mj-simul-card-valor b {
    font-size: 0.95rem;
}

.mj-simul-card-item.is-ok .mj-simul-card-valor b {
    color: var(--ok);
}

.mj-simul-card-item.is-baixo .mj-simul-card-valor b {
    color: var(--brand);
}

.mj-simul-card-valor small {
    display: block;
    font-size: 0.66rem;
    color: var(--text-muted);
}

/* A barra e a leitura rapida do card: escala 0 a 130%, com um risco no 100%
   (= 76.92% da escala) para separar quem bateu a meta de quem passou dela.
   O preenchimento vem do --pct calculado na view. */
.mj-simul-card-barra {
    position: absolute;
    right: 0;
    bottom: 0;
    left: 0;
    height: 3px;
    border-radius: 2px;
    background: var(--divider);
}

.mj-simul-card-barra::before {
    content: "";
    display: block;
    width: var(--pct, 0%);
    height: 100%;
    border-radius: 2px;
    background: var(--ok);
}

.mj-simul-card-item.is-baixo .mj-simul-card-barra::before {
    background: var(--brand);
}

.mj-simul-card-barra::after {
    content: "";
    position: absolute;
    top: -2px;
    bottom: -2px;
    left: 76.92%;
    width: 1px;
    background: var(--text-muted);
    opacity: 0.55;
}

/* --------------------------------------------------------------------------
   21.2 Largo: a tabela, com a coluna do cliente fixa na rolagem
   -------------------------------------------------------------------------- */
@container (min-width: 820px) {

    .mj-simul-cards {
        display: none;
    }

    .mj-simul-dica {
        display: block;
    }

    .mj-simul-dica-cards {
        display: none;
    }

    .mj-simul-scroll {
        display: block;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
    }

    /* separate, e nao collapse: com collapse as bordas da celula sticky ficam
       para tras e somem por baixo das colunas que rolam */
    /* max-content + min-width: 100% e o que faz o `width` das colunas fixas
       valer. Com `width: 100%` o Chrome usa a largura do container como base e
       espreme as celulas abaixo da medida pedida - e ai os offsets `right` das
       colunas fixas, que sao a soma dessas larguras, saem do lugar. */
    .mj-simul-tabela {
        width: max-content;
        min-width: 100%;
        border-collapse: separate;
        border-spacing: 0;
        font-size: 0.78rem;
    }

    .mj-simul-tabela thead th {
        padding: 0.4rem 0.45rem;
        background: var(--brand);
        border-right: 1px solid rgba(255, 255, 255, 0.25);
        border-bottom: 1px solid rgba(255, 255, 255, 0.25);
        color: #fff;
        font-weight: 700;
        text-align: center;
        vertical-align: middle;
    }

    .mj-simul-tabela thead th.is-bonus {
        background: var(--brand-dark);
    }

    /* O rotulo do grupo e centrado na faixa inteira, entao numa tabela rolada
       ele acaba embaixo das colunas fixas. Sticky dentro do proprio th, com as
       bordas nas larguras dessas colunas (90 e 76+72+58), mantem o texto na
       parte visivel da faixa sem sair dela. */
    .mj-simul-grupo {
        display: inline-block;
        position: sticky;
        left: 90px;
        right: 206px;
    }

    .mj-simul-kpi-nome {
        display: block;
        max-width: 11rem;
        font-size: 0.66rem;
        line-height: 1.2;
        text-transform: uppercase;
    }

    .mj-simul-kpi-peso {
        display: block;
        margin-top: 0.2rem;
        font-size: 0.72rem;
        font-weight: 800;
        color: var(--accent);
    }

    .mj-simul-sub {
        font-size: 0.64rem;
        font-weight: 600;
    }

    .mj-simul-tabela tbody th,
    .mj-simul-tabela tbody td {
        padding: 0.45rem 0.5rem;
        background: var(--surface);
        border-bottom: 1px solid var(--divider);
        text-align: center;
        white-space: nowrap;
    }

    .mj-simul-tabela tbody td.is-bonus {
        background: #fdf3f3;
    }

    .mj-simul-pct {
        font-weight: 700;
    }

    .mj-simul-pct.is-ok {
        color: var(--ok);
    }

    .mj-simul-pct.is-baixo {
        color: var(--brand);
    }

    /* Colunas fixas na rolagem: o cliente na esquerda e o resultado na direita.
       Sem isso, 27 colunas fazem o leitor perder de vista de quem e a linha e
       em quantos pontos ela deu - justamente as duas pontas que interessam.

       Os `right` sao a soma das larguras das colunas a direita de cada uma, e
       por isso as tres tem `width` fixo. Os valores cabem folgados (o mais
       largo e "Ranking", no cabecalho), entao o layout auto respeita a medida.
       Mexeu numa largura, refaca as somas.

       O box-shadow faz a borda de separacao: em celula sticky a `border` fica
       para tras e some por baixo das colunas que rolam. */
    .mj-simul-col-cliente,
    .mj-simul-col-total,
    .mj-simul-col-rank,
    .mj-simul-col-status {
        position: sticky;
        z-index: 2;
    }

    .mj-simul-tabela thead .mj-simul-col-cliente,
    .mj-simul-tabela thead .mj-simul-col-total,
    .mj-simul-tabela thead .mj-simul-col-rank,
    .mj-simul-tabela thead .mj-simul-col-status {
        z-index: 3;
    }

    .mj-simul-col-cliente {
        left: 0;
        width: 90px;
        text-align: left;
    }

    .mj-simul-col-status {
        right: 0;
        width: 58px;
    }

    .mj-simul-col-rank {
        right: 58px;
        width: 72px;
    }

    .mj-simul-col-total {
        right: 130px;
        width: 76px;
    }

    .mj-simul-tabela tbody th.mj-simul-col-cliente {
        box-shadow: 1px 0 0 var(--border);
        font-weight: 700;
        text-align: left;
    }

    .mj-simul-tabela tbody .mj-simul-col-total {
        box-shadow: -1px 0 0 var(--border);
    }

    .mj-simul-tabela tbody .mj-simul-col-total {
        font-size: 0.9rem;
        font-weight: 800;
        color: var(--ok);
    }

    .mj-simul-tabela tbody .mj-simul-col-rank {
        font-weight: 700;
        color: var(--ok);
    }

    .mj-simul-tabela tbody tr.is-fora .mj-simul-col-total,
    .mj-simul-tabela tbody tr.is-fora .mj-simul-col-rank {
        color: var(--brand);
    }

    .mj-simul-col-status .fa-thumbs-up {
        color: var(--ok);
    }

    .mj-simul-col-status .fa-thumbs-down {
        color: var(--brand);
    }
}

/* ==========================================================================
   22. IMPORTACOES: AS ETAPAS DA CARGA
   --------------------------------------------------------------------------
   Uso: resources/views/painel/importacoes/inserir.blade.php

   A tela era um select de tipo, um campo de arquivo e um botao "Executar".
   Nada dizia a ORDEM (metas e volumes encontram a rede pelo codigo, entao a
   base de redes vem primeiro ou o resto e descartado em silencio), nem quantos
   arquivos cada base tem (volume sao 13, o resto e 1), e o campo de arquivo
   aparecia inclusive para a Analise, que nao usa arquivo.

   Agora e um card por etapa, numerado. O numero nao e enfeite: e a unica coisa
   na tela que comunica a sequencia.
   ========================================================================== */

.etapas-importacao {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.etapa-importacao {
    margin-bottom: 0;
}

.etapa-importacao .card-body {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 1rem;
}

.etapa-cabecalho {
    display: flex;
    align-items: flex-start;
    gap: 0.85rem;
    /* Cresce e encolhe, para o bloco do formulario ficar com o que precisa e
       nao mais que isso. */
    flex: 1 1 20rem;
    min-width: 0;
}

.etapa-numero {
    flex: 0 0 auto;
    width: 2rem;
    height: 2rem;
    border-radius: 50%;
    background: var(--brand);
    color: #fff;
    font-weight: 700;
    display: flex;
    align-items: center;
    justify-content: center;
    /* line-height 1 porque o flex centraliza: a altura de linha herdada
       empurrava o numero para baixo do circulo. */
    line-height: 1;
}

.etapa-texto {
    min-width: 0;
}

.etapa-titulo {
    margin: 0 0 0.15rem;
    font-size: 1.05rem;
    font-weight: 700;
    color: var(--text);
}

.etapa-descricao {
    margin: 0 0 0.25rem;
    font-size: 0.85rem;
    color: var(--text-muted);
}

/* O que ja existe no banco. Derivado dos dados, porque nao ha log de
   importacao: a tabela `importacoes` esta vazia e so tem timestamps. */
.etapa-estado {
    margin: 0;
    font-size: 0.8rem;
    color: var(--text);
}

.etapa-estado i {
    color: var(--brand);
}

.etapa-separador {
    color: var(--border);
    margin: 0 0.15rem;
}

.etapa-form {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    flex-wrap: wrap;
    /* Nao cresce: o texto da etapa fica com a sobra. */
    flex: 0 1 auto;
    margin: 0;
}

.etapa-arquivo {
    font-size: 0.85rem;
    max-width: 15rem;
}

.etapa-botao {
    white-space: nowrap;
}

/* Ate tablet os dois blocos empilham, e o formulario passa a ocupar a linha
   inteira: com o campo de arquivo ao lado do texto em tela estreita, o nome do
   arquivo selecionado nao caberia em nenhum dos dois. */
@media (max-width: 767.98px) {
    .etapa-importacao .card-body {
        flex-direction: column;
        align-items: stretch;
    }

    .etapa-form {
        flex: 1 1 auto;
        justify-content: space-between;
    }

    .etapa-arquivo {
        max-width: none;
    }
}

/* --------------------------------------------------------------------------
   22.1 Importacoes: acompanhamento da apuracao do ranking
   --------------------------------------------------------------------------
   A apuracao roda em fila, entao a tela pergunta o andamento de tres em tres
   segundos (o JS esta na propria view). Aqui e so a barra.

   Duas variantes, porque as fases sao de dois tipos: as que tem total conhecido
   (uma escrita por rede) rendem percentual, e as outras nao. Barra que inventa
   numero mente sobre o que falta, entao nessas a barra fica listrada e animada,
   sem afirmar posicao.
   -------------------------------------------------------------------------- */

.analise-progresso {
    /* Ocupa a linha inteira abaixo do botao, dentro do card da etapa. */
    flex: 1 1 100%;
    margin-top: 0.5rem;
}

.analise-progresso-topo {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 0.5rem;
    margin-bottom: 0.25rem;
    font-size: 0.8rem;
}

.analise-etapa {
    color: var(--text);
    font-weight: 600;
}

.analise-contagem {
    color: var(--text-muted);
    /* Nao encolhe: o percentual e o dado que o olho procura primeiro. */
    flex: 0 0 auto;
}

.analise-barra {
    height: 0.5rem;
    border-radius: 999px;
    background: var(--divider);
    overflow: hidden;
}

.analise-barra-preenchida {
    height: 100%;
    width: 0;
    border-radius: 999px;
    background: var(--brand);
    transition: width 0.4s ease;
}

/* Fase sem total: a listra andando diz "trabalhando" sem afirmar quanto falta. */
.analise-barra-preenchida.indeterminada {
    background-image: linear-gradient(
        90deg,
        rgba(255, 255, 255, 0.45) 25%,
        transparent 25%,
        transparent 50%,
        rgba(255, 255, 255, 0.45) 50%,
        rgba(255, 255, 255, 0.45) 75%,
        transparent 75%
    );
    background-size: 1rem 1rem;
    animation: analise-listra 0.9s linear infinite;
}

@keyframes analise-listra {
    from { background-position: 0 0; }
    to { background-position: 1rem 0; }
}

/* Terminou: verde, porque o vermelho da marca aqui parece erro. */
.analise-progresso[data-estado="concluido"] .analise-barra-preenchida {
    background: var(--ok);
    animation: none;
}

.analise-progresso[data-estado="erro"] .analise-barra-preenchida {
    background: var(--brand-dark);
    animation: none;
}

.analise-aviso {
    margin: 0.4rem 0 0;
    font-size: 0.8rem;
    color: var(--brand-dark);
}

.analise-aviso code {
    /* O comando fica selecionavel e legivel: e para ser copiado. */
    background: var(--divider);
    color: var(--text);
    padding: 0 0.25rem;
    border-radius: var(--radius-sm);
    user-select: all;
}

@media (prefers-reduced-motion: reduce) {
    .analise-barra-preenchida {
        transition: none;
    }

    .analise-barra-preenchida.indeterminada {
        animation: none;
    }
}
