/* ============================================================
   Painel Universo88 — identidade visual

   Creme e rosa, os mesmos da loja, sem preto em superfície nenhuma (o texto
   usa o marrom da marca, #4F2815). A interface NÃO usa emoji: estado e
   hierarquia são feitos com cor, peso de fonte e barra lateral colorida.

   A regra que organiza a paleta: o rosa da marca é PREENCHIMENTO, nunca texto.
   Para rosa em texto existe --rosa-texto, escurecido até passar em contraste.

   As cores de série ficam em src/Theme.php, não aqui — elas são aplicadas
   inline nos gráficos e nas bolinhas, porque vêm do dado. Mexeu numa delas,
   rode `php ferramentas/validar-paleta.php`.
   ============================================================ */

:root {
    /* As QUATRO cores da marca:
         rosa #E593B1 · marrom #4F2815 · preto #1A1A1A · off white #FBF9F6
       Todo tom abaixo é MISTURA delas com o off white — nenhuma matiz nova.
       Precisa de um tom que não existe? Derive por mistura, não invente cor. */

    --branco: #FFFFFF;
    --fundo: #FBF9F6;          /* MARCA: off white */
    --fundo-2: #F2EFEB;        /* off white + 5% marrom  — faixa, hover, thead */
    --linha: #ECE6E2;          /* off white + 9% marrom  — grade */
    --borda: #E5DED9;          /* off white + 13% marrom */

    --tinta: #4F2815;          /* MARCA: marrom — texto principal, 12,13:1 */
    --preto: #1A1A1A;          /* MARCA: preto — ênfase máxima, 16,56:1 */
    --tinta-2: #785A4B;        /* off white + 76% marrom, 5,94:1 */
    --tinta-3: #A8958A;        /* off white + 48% marrom, 2,86:1 — SÓ eixo de gráfico */

    /* O rosa da marca é PREENCHIMENTO: 2,19:1 sobre o off white, ilegível como
       texto. Quando o rosa precisa VIRAR TEXTO, use --rosa-texto (5,30:1). */
    --rosa: #E593B1;           /* MARCA: rosa */
    --rosa-escuro: #B87382;    /* rosa + 30% marrom — hover e séries */
    --rosa-texto: #92585B;     /* rosa + 55% marrom — rosa legível em texto */
    --rosa-lavado: #F6E3E7;    /* off white + 22% rosa — menu ativo */

    /* ÚNICA exceção à paleta, e só nos indicadores de variação.
       O porquê está em src/Theme.php, na declaração de POSITIVO/NEGATIVO. */
    --positivo: #108474;
    --negativo: #C0392B;

    --menu: 250px;
    --menu-fechado: 72px;
    --raio: 20px;

    /* Sombra em duas camadas: um halo largo e difuso mais um contorno curto e
       escuro. Uma sombra só, larga, deixa o card "flutuando sem apoio"; a
       camada curta é o que dá a sensação de papel pousado sobre a mesa. */
    --sombra-card: 0 1px 2px rgba(79, 40, 21, .05), 0 6px 18px rgba(79, 40, 21, .05);
    --sombra-alta: 0 2px 4px rgba(79, 40, 21, .06), 0 14px 34px rgba(79, 40, 21, .10);
}

/* ------------------------------------------------ tipografia

   Duas famílias:
     Chunko Bold  títulos e números grandes — é a fonte de display da marca
     Poppins      todo o resto (corpo, rótulos, tabelas, eixos de gráfico)

   Auto-hospedadas, não puxadas do Google Fonts — mesma razão do fallback local
   do Plotly: a hospedagem não deve depender de um CDN para a página abrir
   certa. `swap` faz o texto aparecer na fonte de sistema enquanto a real
   carrega, em vez de deixar a tela em branco. Falta algum .woff2? A pilha de
   sistema assume e o painel continua legível — é degradação, não quebra.

   A Chunko tem UM peso só. O `font-weight: 400 900` declara que essa face
   cobre a faixa inteira, então um `font-weight: 700` num título usa o arquivo
   como está. Sem isso o navegador sintetizaria um negrito falso EM CIMA de uma
   fonte que já é bold, e os títulos sairiam borrados.

   A Chunko também não tem ▲ ▼, usados nos deltas. Não é problema: delta é
   texto de corpo, que é Poppins. Não use Chunko onde as setas aparecem.

   REGRA DE USO: Chunko só ACIMA DE 1rem. É uma fonte de display — os traços
   grossos e os contraformas fechados que dão personalidade ao número grande
   viram um borrão a 11 ou 15 px. Testado: em `.menu-sub` (.68rem, caixa alta,
   espaçada) e em `.painel-titulo` (.95rem) ela ficava ilegível. Abaixo de 1rem,
   use Poppins com peso 600/700. */
@font-face {
    font-family: 'Chunko Bold'; font-style: normal; font-weight: 400 900;
    font-display: swap; src: url('fonts/chunko-bold.woff2') format('woff2');
}
@font-face {
    font-family: 'Poppins'; font-style: normal; font-weight: 400;
    font-display: swap; src: url('fonts/poppins-400.woff2') format('woff2');
}
@font-face {
    font-family: 'Poppins'; font-style: normal; font-weight: 500;
    font-display: swap; src: url('fonts/poppins-500.woff2') format('woff2');
}
@font-face {
    font-family: 'Poppins'; font-style: normal; font-weight: 600;
    font-display: swap; src: url('fonts/poppins-600.woff2') format('woff2');
}
@font-face {
    font-family: 'Poppins'; font-style: normal; font-weight: 700;
    font-display: swap; src: url('fonts/poppins-700.woff2') format('woff2');
}

:root {
    --fonte-corpo: 'Poppins', -apple-system, BlinkMacSystemFont, 'Segoe UI',
                   'Helvetica Neue', sans-serif;
    --fonte-titulo: 'Chunko Bold', var(--fonte-corpo);
    /* Número nunca é Chunko: ela é fonte de display, com traço grosso e
       algarismo de largura variável — em 3,6rem o "R$ 0,00" fica pesado e
       treme durante a contagem. Número é Poppins 700 com tabular-nums. */
    --fonte-numero: var(--fonte-corpo);
}

* { box-sizing: border-box; }

html, body {
    margin: 0;
    padding: 0;
    background: var(--fundo);
    color: var(--tinta);
    font-family: var(--fonte-corpo);
    font-size: 16px;
    -webkit-font-smoothing: antialiased;
}

a { color: inherit; text-decoration: none; }

/* ------------------------------------------------ estrutura */
.app { display: flex; min-height: 100vh; }

/* ------------------------------------------------ trilho lateral

   Barra estreita e flutuante que cresce ao passar o mouse.

   Ela é `fixed` e cresce POR CIMA do conteúdo, em vez de empurrá-lo. Empurrar
   reflui a página inteira a cada passada de mouse — e, com Plotly na tela, cada
   reflow redesenha todos os gráficos. Sobreposto, o hover não custa nada.

   Abre também no `:focus-within`: quem navega por teclado chega aos itens pelo
   Tab, e um menu que só responde ao mouse deixaria essa pessoa às cegas. */

.menu {
    position: fixed;
    top: .8rem; left: .8rem; bottom: .8rem;
    z-index: 40;
    width: var(--menu-fechado);
    background: var(--branco);
    border: 1px solid var(--borda);
    border-radius: 22px;
    box-shadow: var(--sombra-card);
    padding: 1rem .7rem;
    overflow: hidden;
    display: flex; flex-direction: column;
    transition: width .22s cubic-bezier(.22, .8, .3, 1),
                box-shadow .22s ease;
}
.menu:hover, .menu:focus-within {
    width: var(--menu);
    box-shadow: var(--sombra-alta);
    overflow-y: auto;
}

/* Tudo que só faz sentido com o menu aberto. `visibility` junto da opacidade
   para o leitor de tela não anunciar rótulo invisível, e para o texto não
   receber clique enquanto está escondido. */
.menu-so-aberto {
    opacity: 0; visibility: hidden;
    transition: opacity .16s ease, visibility .16s ease;
}
.menu:hover .menu-so-aberto,
.menu:focus-within .menu-so-aberto {
    opacity: 1; visibility: visible;
    transition-delay: .06s;
}

/* o bloco de estado fica no rodapé do trilho */
.menu-fim { margin-top: auto; }

.conteudo {
    flex: 1;
    min-width: 0;
    /* deixa passagem para o trilho fechado; ele cresce por cima, sem refluir */
    margin-left: calc(var(--menu-fechado) + 1.6rem);
    padding: 1.4rem 1.6rem 3rem 1.6rem;
    max-width: 1480px;
}

/* ------------------------------------------------ menu lateral */
/* O logo da marca é um emblema QUADRADO (as cerejas), não um wordmark
   deitado — esticá-lo na largura do menu deixaria um selo gigante. Emblema
   pequeno + nome escrito ao lado, na Poppins da loja. */
.menu-logo a {
    display: flex; align-items: center; gap: .55rem;
}
.menu-logo img {
    width: 38px; height: 38px; flex: 0 0 38px;
    border-radius: 10px; display: block;
}
.menu-marca {
    font-family: var(--fonte-titulo);
    font-size: 1.02rem; font-weight: 700; color: var(--tinta);
    letter-spacing: -.02em; line-height: 1.1;
}
.menu-sub {
    font-size: .68rem; letter-spacing: .14em; color: var(--tinta-2);
    text-transform: uppercase; margin: .15rem 0 1.1rem 0; font-weight: 600;
}

.menu-item {
    display: flex; align-items: center; gap: .7rem;
    /* padding fixo e nowrap: o item não pode reposicionar o ícone enquanto o
       trilho abre, senão os ícones "andam" durante a animação */
    padding: .6rem .62rem;
    margin-bottom: .18rem;
    border-radius: 13px;
    font-size: .92rem;
    font-weight: 500;
    color: var(--tinta-2);
    white-space: nowrap;
    transition: background .14s ease, color .14s ease;
}
.menu-item-icone {
    width: 30px; height: 30px; flex: 0 0 30px;
    display: grid; place-items: center;
    border-radius: 10px;
    color: var(--tinta-2);
    transition: background .14s ease, color .14s ease;
}
.menu-item-icone svg { width: 19px; height: 19px; }
.menu-item:hover { background: var(--fundo-2); }
.menu-item.ativo { color: var(--tinta); font-weight: 650; }
/* No trilho fechado o item ativo é o BADGE, não a faixa: uma faixa de 56px de
   largura não se distingue de outra. O badge colorido é visível nos dois
   estados, que é o que mantém a orientação enquanto o menu está fechado. */
.menu-item.ativo .menu-item-icone {
    background: var(--rosa); color: var(--tinta);
}

.menu hr {
    border: none; border-top: 1px solid var(--linha); margin: 1rem 0 .9rem 0;
}

.menu-rotulo {
    font-size: .68rem; color: var(--tinta-3); text-transform: uppercase;
    letter-spacing: .06em; font-weight: 600;
}
.menu-valor {
    font-size: .92rem; font-weight: 650; color: var(--tinta); margin-bottom: .6rem;
}
.menu-dica { font-size: .72rem; color: var(--tinta-3); margin-top: .45rem; line-height: 1.45; }

.integra {
    display: flex; align-items: center; gap: .5rem;
    font-size: .8rem; padding: .28rem 0; color: var(--tinta-2);
}
.ponto-ok, .ponto-erro, .ponto-off {
    width: 8px; height: 8px; border-radius: 50%; flex: 0 0 auto;
}
.ponto-ok { background: var(--positivo); }
.ponto-erro { background: var(--negativo); }
.ponto-off { background: var(--tinta-3); }

.menu-aviso {
    background: var(--rosa-lavado); border-left: 3px solid var(--rosa);
    border-radius: 8px; padding: .6rem .7rem; margin-top: .8rem;
    font-size: .72rem; line-height: 1.5; color: var(--tinta-2);
}
.menu-aviso b { color: var(--rosa-texto); }
.menu-aviso code {
    background: var(--fundo); border-radius: 4px; padding: 0 .25rem;
    font-size: .7rem; color: var(--tinta);
}

/* ------------------------------------------------ botões */
.botao-primario, .botao-largo {
    display: block; width: 100%; text-align: center;
    background: var(--rosa); color: var(--tinta); border: none;
    border-radius: 10px; font-weight: 600; font-size: .86rem;
    padding: .55rem .8rem; cursor: pointer; font-family: inherit;
    transition: background .14s ease;
}
/* o hover escurece o fundo; o texto vira branco para não perder contraste */
.botao-primario:hover, .botao-largo:hover {
    background: var(--rosa-texto); color: var(--branco);
}

.botao-secundario {
    display: block; width: 100%; text-align: center;
    background: var(--branco); color: var(--tinta-2);
    border: 1px solid var(--borda); border-radius: 10px;
    font-weight: 550; font-size: .84rem; padding: .5rem .8rem;
    cursor: pointer; font-family: inherit; margin-top: .5rem;
}
.botao-secundario:hover { border-color: var(--rosa); color: var(--rosa-texto); }

/* ------------------------------------------------ cabeçalho da página */
.cabecalho {
    display: flex; align-items: flex-start; justify-content: space-between;
    gap: 1rem; margin-bottom: 1rem;
}
.cabecalho-direita { text-align: right; }
.pagina-titulo {
    font-family: var(--fonte-titulo);
    font-size: 1.75rem; font-weight: 700; letter-spacing: -.025em;
    color: var(--tinta); margin: 0; line-height: 1.15;
}
.pagina-sub { font-size: .9rem; color: var(--tinta-2); margin-top: .25rem; }

.aovivo {
    display: inline-flex; align-items: center; gap: .45rem;
    background: var(--rosa-lavado); color: var(--rosa-texto);
    border-radius: 999px; padding: .3rem .75rem;
    font-size: .74rem; font-weight: 700; letter-spacing: .04em;
}
.aovivo .ponto {
    width: 7px; height: 7px; border-radius: 50%; background: var(--rosa);
    animation: pulsa 1.8s ease-in-out infinite;
}
@keyframes pulsa {
    0%, 100% { opacity: 1; transform: scale(1); }
    50%      { opacity: .3; transform: scale(.72); }
}
/* quem pediu menos animação não deve ver um ponto pulsando sem parar */
@media (prefers-reduced-motion: reduce) {
    .aovivo .ponto { animation: none; }
}

/* ------------------------------------------------ cards de KPI */
.grade-kpi {
    display: grid;
    grid-template-columns: repeat(var(--colunas, 4), minmax(0, 1fr));
    gap: .7rem;
    margin-bottom: .8rem;
}
@media (max-width: 1200px) { .grade-kpi { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 860px)  { .grade-kpi { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

.kpi {
    background: var(--branco); border: 1px solid var(--borda); border-radius: var(--raio);
    padding: 1.05rem 1.15rem .8rem 1.15rem;
    display: flex; flex-direction: column;
    box-shadow: var(--sombra-card);
    transition: box-shadow .16s ease, transform .16s ease;
}
.kpi:hover { box-shadow: var(--sombra-alta); transform: translateY(-2px); }
.kpi-destaque { border-color: var(--rosa); box-shadow: 0 2px 10px rgba(225, 74, 129, .16); }
.kpi-label {
    font-size: .72rem; font-weight: 650; letter-spacing: .06em;
    text-transform: uppercase; color: var(--tinta-3);
}
.kpi-valor {
    font-family: var(--fonte-numero);
    /* 1,75rem e não 1,95: a fonte de display ocupa bem mais largura que a
       anterior no mesmo corpo, e seis KPIs numa linha deixam ~155px por card */
    font-size: 1.75rem; font-weight: 700; color: var(--tinta);
    line-height: 1.12; letter-spacing: -.02em; margin-top: .3rem;
    /* rede de segurança: se um valor passar do limiar do Theme::cardKpi mesmo
       assim, ele é cortado com reticências em vez de vazar por cima do card
       vizinho — um número truncado se vê, um número vazado engana */
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
    font-variant-numeric: tabular-nums;
    font-weight: 700; letter-spacing: -.02em;
}
.kpi-valor-longo { font-size: 1.32rem; }
.kpi-rodape { font-size: .78rem; margin-top: .3rem; }
/* o espaço da faísca só existe quando há faísca: reservado à toa, ele deixava
   um card 40px mais alto que o conteúdo dele numa fileira em que os vizinhos
   tinham gráfico */
.kpi-faisca:empty { display: none; }
.kpi-faisca { margin-top: .55rem; }
.kpi-faisca svg { max-width: 100%; height: auto; }

.d-pos { color: var(--positivo); font-weight: 700; }
.d-neg { color: var(--negativo); font-weight: 700; }
.d-neutro { color: var(--tinta-3); font-weight: 600; }
.d-ref { color: var(--tinta-3); }

.legenda-caption {
    color: var(--tinta-3); font-size: .78rem; line-height: 1.5;
    margin: -.2rem 0 1rem 0;
}

/* ------------------------------------------------ painéis */
.painel {
    background: var(--branco); border: 1px solid var(--borda);
    border-radius: var(--raio); padding: 1.05rem 1.25rem;
    margin-bottom: .9rem;
    box-shadow: var(--sombra-card);
    box-shadow: 0 1px 2px rgba(79, 40, 21, .04);
}
.painel-titulo {
    font-size: .95rem; font-weight: 700; color: var(--tinta);
    margin-bottom: .15rem; letter-spacing: -.01em;
}
.painel-sub { font-size: .78rem; color: var(--tinta-3); margin-bottom: .5rem; }
.vazio { text-align: center; padding: 1.6rem 1rem; font-size: .9rem; color: var(--tinta-2); }

/* colunas lado a lado */
.colunas { display: grid; gap: .7rem; margin-bottom: .7rem; }
.col-2-1 { grid-template-columns: 2fr 1fr; }
.col-185-1 { grid-template-columns: 1.85fr 1fr; }
.col-21-1 { grid-template-columns: 2.1fr 1fr; }
.col-1-1 { grid-template-columns: 1fr 1fr; }
@media (max-width: 1100px) {
    .colunas { grid-template-columns: 1fr !important; }
}
.colunas > * { min-width: 0; }

/* Painéis lado a lado terminam na mesma linha: todos esticam até a altura da
   fileira, para as bordas de baixo casarem. Quem tem gráfico elástico dentro
   ainda vira coluna flex, e aí o gráfico cresce junto em vez de deixar um vão
   branco — é a diferença entre esticar o card e esticar o conteúdo.
   Navegador sem `:has()` só perde o segundo efeito. */
.colunas > * > .painel:only-child { height: 100%; }
.colunas > * > .painel:only-child:has(.grafico-elastico) {
    display: flex;
    flex-direction: column;
}
.grafico-elastico { flex: 1 1 auto; }

/* ------------------------------------------------ lista de cortes */
.linha {
    display: flex; align-items: center; gap: .65rem;
    padding: .6rem 0; border-bottom: 1px solid var(--linha);
}
.linha:last-child { border-bottom: none; }
.bolinha { width: 9px; height: 9px; border-radius: 3px; flex: 0 0 auto; }
.linha-nome { font-size: .88rem; color: var(--tinta); font-weight: 500; flex: 1; min-width: 0; }
.linha-aux { font-size: .76rem; color: var(--tinta-3); white-space: nowrap; }
.linha-valor {
    font-size: .9rem; color: var(--tinta); font-weight: 700;
    min-width: 84px; text-align: right;
}
/* barra de proporção embaixo do nome do canal */
.trilho {
    display: block; height: 4px; background: var(--linha); border-radius: 99px;
    margin-top: .3rem; overflow: hidden;
}
.trilho span { display: block; height: 100%; border-radius: 99px; }

/* ------------------------------------------------ avisos */
.aviso {
    background: var(--branco); border: 1px solid var(--borda); border-radius: 14px;
    padding: .85rem 1.1rem; margin-bottom: .9rem;
    font-size: .84rem; line-height: 1.6; color: var(--tinta-2);
}
.aviso code {
    background: var(--fundo); border: 1px solid var(--linha); border-radius: 5px;
    padding: .05rem .3rem; font-size: .8rem; color: var(--tinta);
    word-break: break-all;
}
.aviso b { color: var(--tinta); }
.aviso-ok { border-left: 3px solid var(--positivo); }
.aviso-alerta { border-left: 3px solid var(--negativo); }

/* legenda das classes ABC */
.legenda-classes { display: flex; gap: .9rem; flex-wrap: wrap; margin: 0 0 .4rem 0; }
.tag-classe {
    display: inline-flex; align-items: center; gap: .35rem;
    font-size: .74rem; color: var(--tinta-3); font-weight: 550;
}

/* ------------------------------------------------ integrações */
.integra-card {
    display: flex; align-items: center; gap: 1rem;
    padding: .95rem 1.2rem; margin-bottom: .6rem;
}
.integra-card .nome { font-weight: 650; color: var(--tinta); font-size: .94rem; }
.integra-card .detalhe { font-size: .79rem; color: var(--tinta-2); margin-top: .15rem; }
.selo {
    border-radius: 999px; padding: .22rem .65rem;
    font-size: .68rem; font-weight: 700; letter-spacing: .03em;
    background: var(--rosa-lavado); color: var(--tinta);
    white-space: nowrap;
}

/* ------------------------------------------------ filtros */
.faixa-filtros { padding: .85rem 1.25rem .95rem 1.25rem; }
.filtros-grade { display: flex; gap: 1rem; flex-wrap: wrap; align-items: flex-end; }
.filtro { flex: 1 1 220px; min-width: 200px; }

.rotulo-filtro {
    font-size: .68rem; font-weight: 650; letter-spacing: .07em;
    text-transform: uppercase; color: var(--tinta-3); margin-bottom: .3rem;
}

/* popover feito com <details>: abre sem JS e fecha com Esc */
.pop { position: relative; }
.pop-botao {
    list-style: none; cursor: pointer;
    background: var(--branco); color: var(--tinta);
    border: 1px solid var(--borda); border-radius: 10px;
    font-weight: 550; font-size: .88rem;
    padding: .5rem .8rem; display: flex; align-items: baseline; gap: .5rem;
    transition: border-color .14s ease;
}
.pop-botao::-webkit-details-marker { display: none; }
.pop-botao:hover { border-color: var(--rosa); color: var(--rosa-texto); }
.pop-resumo { font-size: .78rem; color: var(--tinta-3); margin-left: auto; white-space: nowrap; }
.pop[open] .pop-botao { border-color: var(--rosa); }

.pop-corpo {
    position: absolute; z-index: 40; top: calc(100% + 6px); left: 0;
    background: var(--branco); border: 1px solid var(--borda);
    border-radius: 12px; padding: .8rem .9rem;
    box-shadow: 0 10px 30px rgba(79, 40, 21, .13);
    min-width: 260px;
}
.pop-periodo { display: flex; gap: 1.4rem; min-width: 520px; }
.pop-coluna { flex: 1; min-width: 0; }
@media (max-width: 760px) {
    .pop-periodo { flex-direction: column; min-width: 260px; }
    .pop-corpo { left: auto; right: 0; }
}

.atalho {
    display: block; padding: .35rem .55rem; border-radius: 8px;
    font-size: .86rem; color: var(--tinta-2); font-weight: 500;
}
.atalho:hover { background: var(--rosa-lavado); color: var(--rosa-texto); }
.atalho.ativo { background: var(--rosa-lavado); color: var(--rosa-texto); font-weight: 650; }

.pop-acoes { display: flex; gap: .5rem; }
.pop-acoes a {
    flex: 1; text-align: center; padding: .35rem .5rem; border-radius: 8px;
    font-size: .82rem; color: var(--tinta-2); border: 1px solid var(--borda);
}
.pop-acoes a:hover { border-color: var(--rosa); color: var(--rosa-texto); }
.pop-corpo hr { border: none; border-top: 1px solid var(--linha); margin: .6rem 0; }
.pop-dica { font-size: .74rem; color: var(--tinta-3); margin-top: .5rem; line-height: 1.45; }

.form-selecao { max-height: 320px; overflow-y: auto; }
.opcao {
    display: flex; align-items: center; gap: .5rem;
    padding: .3rem .2rem; font-size: .86rem; color: var(--tinta); cursor: pointer;
}
.opcao input { accent-color: var(--rosa); }
.form-selecao .botao-primario { margin-top: .6rem; position: sticky; bottom: 0; }

.form-calendario label {
    display: block; font-size: .78rem; color: var(--tinta-2); margin-bottom: .5rem;
}
.form-calendario input[type="date"], .form-select select {
    display: block; width: 100%; margin-top: .2rem;
    border: 1px solid var(--borda); border-radius: 10px;
    padding: .45rem .6rem; font-size: .88rem; font-family: inherit;
    color: var(--tinta); background: var(--branco);
}
.form-select select { margin-top: 0; cursor: pointer; }

/* ------------------------------------------------ tabelas */
.tabela-caixa {
    overflow: auto; border: 1px solid var(--borda); border-radius: 12px;
    margin-top: .4rem;
}
.tabela { width: 100%; border-collapse: collapse; font-size: .84rem; }
.tabela thead th {
    position: sticky; top: 0; z-index: 1;
    background: var(--fundo-2); color: var(--tinta-2);
    font-size: .72rem; font-weight: 650; text-transform: uppercase;
    letter-spacing: .04em; text-align: center;
    padding: .55rem .7rem; border-bottom: 1px solid var(--borda);
    cursor: pointer; white-space: nowrap; user-select: none;
}
.tabela thead th:hover { color: var(--rosa-texto); }
.tabela thead th.ord-asc span::after  { content: " ▲"; font-size: .7em; }
.tabela thead th.ord-desc span::after { content: " ▼"; font-size: .7em; }
/* A regra do preto: DADO DENSO em preto, prosa em marrom.
   A célula de tabela é o lugar onde se compara número com número, dezenas de
   linhas de cada vez — o contraste máximo (16,56:1) ajuda a varredura. Título,
   legenda e texto corrido continuam no marrom da marca, que é mais quente e
   menos cansativo para leitura contínua. */
.tabela td {
    padding: .48rem .7rem; border-bottom: 1px solid var(--linha);
    color: var(--preto); white-space: nowrap;
}
/* ------------------------------------------------ alinhamento das colunas

   Cabeçalho centralizado com valor à direita era o que fazia a coluna parecer
   deslocada: dois eixos diferentes na mesma faixa vertical. Agora os dois
   centralizam, e a PRIMEIRA coluna — que é sempre o nome de alguma coisa, não
   um número — fica à esquerda nos dois.

   O preço disso é que a vírgula decimal deixa de ficar empilhada quando os
   valores têm tamanhos muito diferentes. `tabular-nums` segura a maior parte
   do estrago: todo algarismo tem a mesma largura, então números do mesmo
   comprimento continuam alinhados perfeitamente entre si. */
.tabela td.num { text-align: center; font-variant-numeric: tabular-nums; }

/* Estas regras vêm DEPOIS de `.tabela td.num` de propósito: as duas têm a
   mesma especificidade, então quem ganha é a última. A primeira coluna é
   sempre o nome de alguma coisa — produto, campanha, dia — e nome se lê da
   esquerda, mesmo quando a célula é montada em HTML e por isso carrega a
   classe `num`. */
.tabela thead th:first-child,
.tabela td:first-child,
.tabela td.num:first-child { text-align: left; }
.tabela tbody tr:last-child td { border-bottom: none; }
.tabela tbody tr:hover td { background: var(--fundo); }

/* ------------------------------------------------ células de duas linhas

   Uma célula que carrega o número E o que aconteceu com ele. Foi o que tirou
   três colunas da tabela de campanhas: a variação, a participação no gasto e o
   volume de cliques passaram a morar embaixo do número a que se referem, em
   vez de virarem colunas próprias que o olho tinha que reassociar. */

.cel-num {
    text-align: center; font-variant-numeric: tabular-nums;
    font-weight: 650; color: var(--preto); font-size: .84rem; line-height: 1.25;
}
.cel-num-alerta { color: var(--negativo); }

.cel-nota, .cel-delta {
    display: block; text-align: center;
    font-size: .66rem; line-height: 1.3; font-variant-numeric: tabular-nums;
}
.cel-nota  { color: var(--tinta-3); }
.cel-delta { font-weight: 650; color: var(--tinta-2); }
.cel-delta.bom  { color: var(--positivo); }
.cel-delta.ruim { color: var(--negativo); }

/* Participação no gasto: a barra faz "esta campanha come 73% do orçamento"
   ser VISTO, e não calculado a partir de uma coluna de reais. */
/* A célula herda `text-align: right` de `td.num` — o nome da campanha volta
   para a esquerda aqui, sem mexer no componente de tabela (outras telas usam
   célula em HTML e contam com o alinhamento à direita). */
.cel-campanha { min-width: 190px; text-align: left; }
.cel-campanha-topo {
    display: flex; align-items: baseline; justify-content: space-between; gap: .5rem;
}
.cel-campanha-nome {
    font-weight: 600; color: var(--tinta); font-size: .82rem;
    overflow: hidden; text-overflow: ellipsis;
}
.cel-campanha-parte {
    font-size: .68rem; color: var(--tinta-3); font-variant-numeric: tabular-nums;
}
.cel-barra {
    height: 5px; background: var(--fundo-2); border-radius: 3px;
    margin-top: .3rem; overflow: hidden;
}
.cel-barra i { display: block; height: 100%; border-radius: 3px; }

/* ------------------------------------------------ gráficos */
.grafico { width: 100%; }

/* ------------------------------------------------ login */
.login-tela {
    min-height: 100vh; display: flex; align-items: flex-start;
    justify-content: center; padding-top: 12vh; background: var(--fundo);
}
.login-caixa {
    width: 100%; max-width: 400px; background: var(--branco);
    border: 1px solid var(--borda); border-radius: var(--raio);
    padding: 1.6rem 1.5rem; box-shadow: 0 1px 2px rgba(79, 40, 21, .04);
}
.login-caixa img { width: 150px; margin-bottom: 1rem; }
.login-caixa p { font-size: .9rem; color: var(--tinta-2); margin: 0 0 .9rem 0; }
.login-caixa input[type="password"] {
    width: 100%; border: 1px solid var(--borda); border-radius: 10px;
    padding: .6rem .8rem; font-size: .95rem; font-family: inherit;
    margin-bottom: .7rem; color: var(--tinta);
}
.login-erro {
    background: var(--rosa-lavado); color: var(--rosa-texto);
    border-radius: 8px; padding: .55rem .7rem; font-size: .84rem;
    margin-bottom: .7rem; font-weight: 550;
}

/* ------------------------------------------------ erro */
.erro-caixa {
    background: var(--branco); border: 1px solid var(--borda);
    border-left: 3px solid var(--negativo); border-radius: 14px;
    padding: 1.2rem 1.4rem; margin: 2rem auto; max-width: 720px;
}
.erro-caixa h1 { font-size: 1.1rem; margin: 0 0 .5rem 0; color: var(--tinta); }
.erro-caixa pre {
    background: var(--fundo); border: 1px solid var(--linha); border-radius: 8px;
    padding: .7rem .8rem; font-size: .8rem; overflow-x: auto;
    color: var(--tinta-2); white-space: pre-wrap;
}

/* Marcar todos / Limpar: botões que agem nas caixas do próprio popover.
   Como <button>, e não <a>, para não navegar — quem aplica é o "Aplicar". */
.pop-acoes button {
    flex: 1; text-align: center; padding: .35rem .5rem; border-radius: 8px;
    font-size: .82rem; color: var(--tinta-2); background: var(--branco);
    border: 1px solid var(--borda); cursor: pointer; font-family: inherit;
}
.pop-acoes button:hover { border-color: var(--rosa); color: var(--rosa-texto); }

/* ============================================================
   CELULAR
   ============================================================
   O desktop tem barra lateral fixa e filtros no topo. No telefone isso não
   funciona: o menu empurraria o conteúdo para baixo da dobra, e o filtro ficaria
   longe do polegar. Então a navegação e os filtros descem para a base da tela,
   no padrão de aplicativo — barra de abas fixa, e tudo que abre vira folha
   deslizante a partir de baixo.

   Os dois menus existem no HTML ao mesmo tempo; quem escolhe é o CSS. Custa
   alguns bytes e evita depender de JS para navegar.
   ============================================================ */

.topo-mobile, .tabbar, .folha { display: none; }

@media (max-width: 900px) {

    /* ---------------------------------------- estrutura */
    .app { flex-direction: column; }
    .menu { display: none; }               /* a barra lateral dá lugar às abas */

    .conteudo {
        margin-left: 0;
        padding: .85rem .85rem 0 .85rem;
        max-width: 100%;
        /* espaço para a barra de abas + a faixa de filtros não taparem o fim
           do conteúdo. A variável é redefinida quando a tela tem filtros. */
        /* as alturas reais da barra de abas e da faixa de filtros são medidas em
           JS e viram variáveis — chutar um valor fixo deixava uma fresta em que
           o conteúdo aparecia entre as duas barras */
        padding-bottom: calc(var(--altura-abas, 76px) + var(--altura-filtros, 0px) + .8rem);
    }

    /* ---------------------------------------- topo compacto */
    .topo-mobile {
        display: flex; align-items: center; justify-content: space-between;
        gap: .8rem; padding: .7rem .85rem;
        background: var(--branco); border-bottom: 1px solid var(--borda);
        position: sticky; top: 0; z-index: 20;
    }
    .topo-mobile img { width: 30px; height: 30px; border-radius: 8px; display: block; }
    .topo-mobile-estado {
        display: flex; flex-direction: column; align-items: flex-end; line-height: 1.25;
    }
    .topo-mobile-estado span:last-child {
        font-size: .8rem; font-weight: 650; color: var(--tinta);
    }
    /* o topo vem antes do conteúdo na ordem visual, embora esteja depois no HTML */
    .app { display: flex; }
    .topo-mobile { order: -1; }

    /* ---------------------------------------- barra de abas */
    .tabbar {
        /* minmax(0,...) e não 1fr puro: `1fr` equivale a minmax(auto,1fr) e a
           célula se recusa a encolher abaixo do texto, estourando a barra */
        display: grid; grid-template-columns: repeat(5, minmax(0, 1fr));
        position: fixed; left: 0; right: 0; bottom: 0; z-index: 60;
        background: var(--branco);
        border-top: 1px solid var(--borda);
        padding-bottom: env(safe-area-inset-bottom);
        box-shadow: 0 -2px 12px rgba(79, 40, 21, .06);
    }
    .tab {
        display: flex; flex-direction: column; align-items: center; justify-content: center;
        gap: .18rem; padding: .5rem .2rem .55rem .2rem;
        background: none; border: none; font-family: inherit; cursor: pointer;
        color: var(--tinta-3); font-size: .66rem; font-weight: 600;
        letter-spacing: .01em; -webkit-tap-highlight-color: transparent;
        position: relative;
    }
    .tab svg { width: 22px; height: 22px; }
    .tab span {
        max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    }
    .tab.ativo { color: var(--rosa-texto); }
    /* traço no topo da aba ativa: a cor sozinha não basta para quem não a distingue */
    .tab.ativo::before {
        content: ''; position: absolute; top: 0; left: 22%; right: 22%; height: 2.5px;
        background: var(--rosa); border-radius: 0 0 3px 3px;
    }

    /* ---------------------------------------- faixa de filtros na base */
    .faixa-filtros {
        position: fixed; left: 0; right: 0;
        /* acima da barra de abas no empilhamento: a folha do filtro é filha
           desta faixa e não consegue escapar do contexto criado por ela, então
           um z-index menor que o das abas deixava o "Aplicar" atrás delas */
        z-index: 65;
        bottom: var(--altura-abas, 76px);
        margin: 0; border-radius: 0;
        border-left: none; border-right: none; border-bottom: none;
        padding: .5rem .7rem;
        box-shadow: 0 -1px 8px rgba(79, 40, 21, .05);
    }
    .filtros-grade {
        gap: .45rem; flex-wrap: nowrap;
        overflow-x: auto; scrollbar-width: none; padding-bottom: 1px;
    }
    .filtros-grade::-webkit-scrollbar { display: none; }
    .filtro { flex: 0 0 auto; min-width: 0; }
    /* o rótulo em cima dobraria a altura da faixa; o próprio texto do botão já diz
       o que está filtrado ("Últimos 30 dias", "2 de 7 canais") */
    .faixa-filtros .rotulo-filtro { display: none; }

    .pop-botao {
        padding: .42rem .7rem; font-size: .82rem; border-radius: 999px;
        white-space: nowrap; gap: .35rem;
    }
    .pop-resumo { display: none; }         /* o intervalo aparece dentro da folha */

    /* ---------------------------------------- popover vira folha */
    .pop-corpo {
        position: fixed; left: 0; right: 0; bottom: 0; top: auto;
        min-width: 0; width: 100%;
        max-height: 76vh; overflow-y: auto;
        border-radius: 18px 18px 0 0;
        border-left: none; border-right: none; border-bottom: none;
        padding: .9rem 1rem calc(1rem + env(safe-area-inset-bottom)) 1rem;
        box-shadow: 0 -8px 40px rgba(79, 40, 21, .22);
        z-index: 70;
        animation: sobe .18s ease-out;
    }
    /* alça de arrastar: sinaliza "isto sobe de baixo" sem precisar de texto */
    .pop-corpo::before {
        content: ''; display: block; width: 36px; height: 4px; border-radius: 99px;
        background: var(--borda); margin: -.2rem auto .8rem auto;
    }
    .pop-periodo { flex-direction: column; min-width: 0; gap: .9rem; }
    .pop-titulo-mobile { display: block; }
    /* fundo escurecido: o alvo do toque é o próprio <details>, e o JS fecha por isso */
    details.pop[open]::before {
        content: ''; position: fixed; inset: 0; z-index: 65;
        background: rgba(79, 40, 21, .38);
        animation: aparece .18s ease-out;
    }
    .atalho { padding: .55rem .6rem; font-size: .92rem; }
    .opcao { padding: .5rem .2rem; font-size: .92rem; }
    .form-selecao { max-height: 44vh; }

    @keyframes sobe    { from { transform: translateY(18px); opacity: .6; } }
    @keyframes aparece { from { opacity: 0; } }

    /* ---------------------------------------- folha "Mais" */
    .folha { display: block; position: fixed; inset: 0; z-index: 90; }
    .folha[hidden] { display: none; }
    .folha-fundo {
        position: absolute; inset: 0; background: rgba(79, 40, 21, .38);
        animation: aparece .18s ease-out;
    }
    .folha-corpo {
        position: absolute; left: 0; right: 0; bottom: 0;
        background: var(--branco); border-radius: 18px 18px 0 0;
        padding: .7rem 1.1rem calc(1.1rem + env(safe-area-inset-bottom)) 1.1rem;
        max-height: 86vh; overflow-y: auto;
        box-shadow: 0 -8px 40px rgba(79, 40, 21, .22);
        animation: sobe .2s ease-out;
    }
    .folha-alca {
        width: 36px; height: 4px; border-radius: 99px;
        background: var(--borda); margin: 0 auto .9rem auto;
    }
    .folha-telas { display: grid; grid-template-columns: repeat(2, 1fr); gap: .5rem; }
    .folha-tela {
        display: flex; align-items: center; gap: .6rem;
        padding: .8rem .8rem; border-radius: 12px;
        border: 1px solid var(--borda); color: var(--tinta-2);
        font-size: .88rem; font-weight: 550;
    }
    .folha-tela svg { width: 20px; height: 20px; flex: 0 0 auto; }
    .folha-tela.ativo {
        background: var(--rosa-lavado); border-color: var(--rosa);
        color: var(--rosa-texto); font-weight: 650;
    }

    /* ---------------------------------------- conteúdo */
    .cabecalho { flex-direction: column; align-items: flex-start; gap: .5rem; }
    .cabecalho-direita { text-align: left; }
    .pagina-titulo { font-size: 1.4rem; }
    .pagina-sub { font-size: .85rem; }

    .grade-kpi { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .5rem; }
    .kpi { padding: .8rem .85rem .65rem .85rem; border-radius: 14px; }
    .kpi-valor { font-size: 1.4rem; }
    .kpi-valor-longo { font-size: 1.15rem; }
    .kpi-label { font-size: .64rem; letter-spacing: .04em; }
    .kpi-rodape { font-size: .72rem; }
    /* a faísca some: em 160px de largura ela vira um borrão e só rouba altura */
    .kpi-faisca { display: none; }
    .kpi:hover { transform: none; box-shadow: 0 1px 2px rgba(79, 40, 21, .04); }

    .painel { padding: .85rem .9rem; border-radius: 14px; }
    .colunas { gap: .55rem; margin-bottom: .55rem; }

    .linha { gap: .5rem; padding: .55rem 0; }
    .linha-nome { font-size: .84rem; }
    .linha-valor { font-size: .85rem; min-width: 68px; }
    .linha-aux { font-size: .72rem; }

    /* tabela: rola na horizontal, com a primeira coluna fixa para não se perder
       a referência da linha ao arrastar */
    .tabela-caixa { -webkit-overflow-scrolling: touch; }
    .tabela { font-size: .78rem; }
    .tabela td, .tabela thead th { padding: .42rem .55rem; }
    .tabela thead th:first-child, .tabela td:first-child {
        position: sticky; left: 0; z-index: 2;
        background: var(--branco);
        box-shadow: 1px 0 0 var(--linha);
    }
    .tabela thead th:first-child { z-index: 3; background: var(--fundo); }
    .tabela tbody tr:hover td:first-child { background: var(--fundo); }

    .integra-card { padding: .8rem .9rem; }
    .aviso { padding: .75rem .9rem; font-size: .8rem; border-radius: 12px; }
    .legenda-caption { font-size: .74rem; }
    .form-calendario input[type="date"] { font-size: 1rem; }  /* < 16px o iOS dá zoom */
}

/* telefones estreitos: KPI em coluna única fica mais legível que dois cards
   espremidos com o número quebrando em duas linhas */
@media (max-width: 380px) {
    .grade-kpi { grid-template-columns: 1fr; }
    .kpi-valor { font-size: 1.6rem; }
    .kpi-faisca { display: block; }
    .folha-telas { grid-template-columns: 1fr; }
}

@media (prefers-reduced-motion: reduce) {
    .pop-corpo, .folha-corpo, .folha-fundo, details.pop[open]::before { animation: none; }
}

/* Título dentro da folha do filtro: no celular o resumo do intervalo sai do
   botão (não caberia), então ele reaparece aqui como contexto. */
.pop-titulo-mobile { display: none; }
.pop-titulo-mobile b { color: var(--tinta); font-weight: 700; }
@media (max-width: 900px) {
    .pop-titulo-mobile {
        display: block; font-size: .8rem; color: var(--tinta-3);
        margin: -.2rem 0 .7rem 0; padding-bottom: .6rem;
        border-bottom: 1px solid var(--linha);
    }
}

/* ============================================================
   TELA "HOJE (AO VIVO)"
   ============================================================
   Uma faixa de marca, o número do dia grande e centrado sobre ela, e blocos
   de leitura rápida embaixo. É a tela que fica aberta o dia inteiro, então ela
   precisa dizer duas coisas de longe: quanto já vendeu e se o dia está acima
   ou abaixo do ritmo normal.

   A faixa é o degradê rosa da marca e o número mora num card branco sobreposto
   — é o que dá a sensação de painel vivo sem escurecer nenhuma superfície
   (a regra do tema: nada de fundo preto). */

.vivo-faixa {
    position: relative;
    /* margem negativa = a faixa vaza o padding do .conteudo e encosta nas
       bordas laterais, em vez de flutuar como mais um card. */
    margin: -1.4rem -1.6rem 0 -1.6rem;
    padding: 1.5rem 1.6rem 4.6rem 1.6rem;
    background: linear-gradient(160deg, var(--rosa) 0%, var(--rosa-escuro) 100%);
    overflow: hidden;
}
/* onda inferior: a faixa termina numa curva, não numa aresta — combina com o
   traço arredondado da loja. SVG embutido no background para não pedir mais um
   arquivo à hospedagem. */
.vivo-faixa::after {
    content: ''; position: absolute; left: 0; right: 0; bottom: -1px; height: 46px;
    background: var(--fundo);
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1200 46' preserveAspectRatio='none'%3E%3Cpath d='M0 46V18c180 22 420-14 600-8s420 34 600 6v30z' fill='%23000'/%3E%3C/svg%3E") no-repeat center/100% 100%;
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1200 46' preserveAspectRatio='none'%3E%3Cpath d='M0 46V18c180 22 420-14 600-8s420 34 600 6v30z' fill='%23000'/%3E%3C/svg%3E") no-repeat center/100% 100%;
}

.vivo-relogio {
    position: relative; z-index: 1;
    display: inline-flex; align-items: center; gap: .5rem;
    margin: 0 auto; padding: .38rem .95rem;
    border-radius: 99px;
    background: rgba(255, 255, 255, .18);
    color: var(--branco);
    font-size: .84rem; font-weight: 600;
    font-variant-numeric: tabular-nums;
}
.vivo-relogio .ponto {
    width: 8px; height: 8px; border-radius: 50%;
    background: var(--branco);
    animation: pulso-vivo 1.6s ease-in-out infinite;
}
@keyframes pulso-vivo {
    0%, 100% { opacity: 1; transform: scale(1); }
    50%      { opacity: .35; transform: scale(.82); }
}
.vivo-faixa-topo {
    display: flex; flex-direction: column; align-items: center; gap: .55rem;
}
.vivo-faixa-titulo {
    position: relative; z-index: 1;
    font-family: var(--fonte-titulo);
    color: var(--branco); font-size: 1.32rem; font-weight: 700;
    letter-spacing: -.02em; text-align: center;
}

/* O card do número, sobreposto à onda. O -3.4rem de margem é o que o faz
   "flutuar" sobre a faixa em vez de ficar abaixo dela. */
.vivo-heroi {
    position: relative; z-index: 2;
    margin: -3.4rem 1.5rem 0 1.5rem;
    background: var(--branco);
    border: 1px solid var(--borda);
    border-radius: var(--raio);
    box-shadow: 0 10px 34px rgba(79, 40, 21, .12);
    padding: 1.5rem 1.6rem 1.35rem 1.6rem;
    text-align: center;
}
.vivo-heroi-rotulo {
    font-size: .74rem; font-weight: 700; letter-spacing: .09em;
    text-transform: uppercase; color: var(--tinta-3);
}
.vivo-heroi-valor {
    font-family: var(--fonte-numero);
    font-size: 3.6rem; font-weight: 700; color: var(--tinta);
    letter-spacing: -.045em; line-height: 1.04; margin-top: .3rem;
    font-variant-numeric: tabular-nums;
}
.vivo-heroi-delta { font-size: .92rem; margin-top: .4rem; }

/* Ritmo do dia: a barra que o ML não tem. Compara o acumulado de agora com o
   que costuma ter entrado ATÉ ESTA HORA nos últimos dias — sem isso, "R$ 700
   às 9h" não diz se o dia está bom ou ruim. */
.vivo-ritmo {
    margin-top: 1.15rem; padding-top: 1.05rem;
    border-top: 1px solid var(--linha);
    display: grid; grid-template-columns: 1fr auto; gap: .5rem 1.2rem;
    align-items: end; text-align: left;
}
.vivo-ritmo-texto { font-size: .82rem; color: var(--tinta-2); line-height: 1.5; }
.vivo-ritmo-texto b { color: var(--tinta); font-weight: 700; }
.vivo-ritmo-projecao { text-align: right; white-space: nowrap; }
.vivo-ritmo-projecao .n {
    font-size: 1.42rem; font-weight: 700; color: var(--tinta);
    letter-spacing: -.03em; font-variant-numeric: tabular-nums;
}
.vivo-trilho {
    grid-column: 1 / -1;
    height: 9px; border-radius: 99px; background: var(--linha);
    overflow: hidden; position: relative;
}
.vivo-trilho span {
    display: block; height: 100%; border-radius: 99px;
    background: linear-gradient(90deg, var(--rosa-escuro), var(--rosa));
}
/* marca dos 100% = o ritmo normal do dia; passar dela é dia acima da média */
.vivo-trilho i {
    position: absolute; top: -3px; bottom: -3px; width: 2px;
    background: var(--tinta-3); border-radius: 2px;
}

/* ---------------------------------------------- métricas-chave (grade de ícones) */
.vivo-metricas {
    display: grid; grid-template-columns: repeat(5, 1fr);
    gap: .7rem; margin: .7rem 0;
}
.vivo-metrica {
    background: var(--branco); border: 1px solid var(--borda);
    border-radius: var(--raio); padding: .95rem 1rem;
    display: flex; flex-direction: column; gap: .1rem;
}
.vivo-metrica-topo { display: flex; align-items: center; gap: .5rem; }
.vivo-metrica-icone {
    width: 26px; height: 26px; border-radius: 8px; flex: 0 0 auto;
    display: grid; place-items: center;
}
.vivo-metrica-icone svg { width: 15px; height: 15px; display: block; }
.vivo-metrica-label {
    font-size: .72rem; font-weight: 700; letter-spacing: .05em;
    text-transform: uppercase; color: var(--tinta-3);
}
.vivo-metrica-valor {
    font-size: 1.62rem; font-weight: 700; color: var(--tinta);
    letter-spacing: -.03em; line-height: 1.15; margin-top: .35rem;
    font-variant-numeric: tabular-nums;
}
.vivo-metrica-rodape { font-size: .76rem; margin-top: .1rem; }

/* ---------------------------------------------- campeões do dia */
.vivo-campeao {
    display: flex; align-items: center; gap: .75rem;
    padding: .62rem 0; border-bottom: 1px solid var(--linha);
}
.vivo-campeao:last-child { border-bottom: none; }
.vivo-campeao-pos {
    width: 24px; height: 24px; border-radius: 8px; flex: 0 0 auto;
    display: grid; place-items: center;
    font-size: .78rem; font-weight: 800;
    background: var(--fundo); color: var(--tinta-2);
}
/* o primeiro colocado ganha o rosa da marca */
.vivo-campeao:first-child .vivo-campeao-pos {
    background: var(--rosa-lavado); color: var(--rosa-texto);
}
.vivo-campeao-corpo { flex: 1; min-width: 0; }
.vivo-campeao-nome {
    font-size: .88rem; font-weight: 600; color: var(--tinta);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.vivo-campeao-aux {
    font-size: .74rem; color: var(--tinta-3); margin-top: .12rem;
    display: flex; align-items: center; gap: .4rem; flex-wrap: wrap;
}
.vivo-campeao-valor {
    text-align: right; white-space: nowrap;
    font-size: .92rem; font-weight: 700; color: var(--tinta);
    font-variant-numeric: tabular-nums;
}
.vivo-campeao-valor small {
    display: block; font-size: .72rem; font-weight: 500; color: var(--tinta-3);
}
/* ---------------------------------------------- fluxo de pedidos */
.vivo-pedido {
    display: flex; align-items: center; gap: .7rem;
    padding: .6rem 0; border-bottom: 1px solid var(--linha);
}
.vivo-pedido:last-child { border-bottom: none; }
.vivo-pedido-hora {
    font-size: .78rem; font-weight: 700; color: var(--tinta-2);
    font-variant-numeric: tabular-nums; width: 42px; flex: 0 0 auto;
}
/* pedido de um dia anterior: hora esmaecida e a data embaixo, senão um pedido
   das 23h aparece no topo da lista e parece do futuro */
.vivo-pedido-hora-antes { color: var(--tinta-3); font-weight: 600; }
.vivo-pedido-hora small {
    display: block; font-size: .66rem; font-weight: 600; color: var(--tinta-3);
    margin-top: .05rem;
}

.vivo-pedido-corpo { flex: 1; min-width: 0; }
.vivo-pedido-nome {
    font-size: .85rem; color: var(--tinta); font-weight: 500;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.vivo-pedido-aux { font-size: .73rem; color: var(--tinta-3); margin-top: .1rem; }
.vivo-pedido-valor {
    font-size: .88rem; font-weight: 700; color: var(--tinta);
    font-variant-numeric: tabular-nums; white-space: nowrap;
}

@media (max-width: 1100px) {
    .vivo-metricas { grid-template-columns: repeat(3, 1fr); }
}
@media (max-width: 900px) {
    /* a margem negativa tem de casar EXATAMENTE com o padding do .conteudo
       nesta faixa (.85rem), senão a faixa estoura a largura e a página inteira
       ganha rolagem horizontal */
    .vivo-faixa { padding: 1.15rem .85rem 4.2rem .85rem; margin: -.85rem -.85rem 0 -.85rem; }
    .vivo-heroi { margin: -3.2rem .2rem 0 .2rem; padding: 1.2rem 1rem 1.1rem 1rem; }
    .vivo-heroi-valor { font-size: 2.6rem; }
    .vivo-ritmo { grid-template-columns: 1fr; }
    .vivo-ritmo-projecao { text-align: left; }
    .vivo-metricas { grid-template-columns: repeat(2, 1fr); }
    .vivo-metrica-valor { font-size: 1.4rem; }
}
@media (max-width: 380px) {
    .vivo-metricas { grid-template-columns: 1fr; }
}
@media (prefers-reduced-motion: reduce) {
    .vivo-relogio .ponto { animation: none; }
}

/* ============================================================
   BLOCOS DE CANAL E DE MÍDIA (tela ao vivo)
   ============================================================
   Substituem as listas de "nome — barra — valor". A lista respondia DE ONDE
   veio o faturamento; estes blocos respondem O QUE FAZER, que é outra coisa:
   64% da loja própria tanto pode ser a loja indo bem quanto o marketplace
   parado. Cada canal só se explica contra o próprio normal daquela hora, e é
   essa comparação que ganhou espaço aqui. */

.bloco-corte {
    padding: .8rem 0;
    border-bottom: 1px solid var(--linha);
}
.bloco-corte:first-of-type { padding-top: .2rem; }
.bloco-corte:last-of-type { border-bottom: none; padding-bottom: .1rem; }

.bloco-corte-topo {
    display: flex; align-items: center; gap: .45rem;
    margin-bottom: .3rem;
}
.bloco-corte-nome {
    font-size: .86rem; font-weight: 600; color: var(--tinta);
    flex: 1; min-width: 0;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.bloco-corte-fatia {
    font-size: .74rem; font-weight: 700; color: var(--tinta-3);
    font-variant-numeric: tabular-nums;
}
.bloco-corte-valor {
    font-size: 1.32rem; font-weight: 700; color: var(--tinta);
    letter-spacing: -.03em; line-height: 1.15;
    font-variant-numeric: tabular-nums;
}
.bloco-corte-barra {
    height: 6px; border-radius: 99px; background: var(--linha);
    margin: .45rem 0 .4rem 0; overflow: hidden; position: relative;
}
.bloco-corte-barra span { display: block; height: 100%; border-radius: 99px; }
/* o traço marca onde este canal costuma estar a esta hora — é o que
   transforma a barra de "fatia do bolo" em "adiantado ou atrasado" */
.bloco-corte-barra i {
    position: absolute; top: -2px; bottom: -2px; width: 2px;
    background: var(--tinta-2); border-radius: 2px;
}
.bloco-corte-pe {
    display: flex; align-items: baseline; justify-content: space-between;
    gap: .5rem; font-size: .75rem; color: var(--tinta-3);
}
.bloco-corte-pe .aux { white-space: nowrap; }

/* canal que ainda não vendeu hoje mas costuma ter vendido: o silêncio é a
   informação, então ele continua na lista em vez de sumir */
.bloco-corte-mudo .bloco-corte-valor { color: var(--tinta-3); font-weight: 600; }
.bloco-corte-mudo .bloco-corte-nome { color: var(--tinta-2); }

/* legenda dentro de um painel encosta no eixo do gráfico sem este respiro */
.painel > .legenda-caption { margin-top: .6rem; }

/* rodapé de fechamento de conta, comum aos dois painéis */
.painel-conta {
    margin-top: .9rem; padding-top: .85rem;
    border-top: 1px solid var(--linha);
    display: grid; grid-template-columns: 1fr 1fr; gap: .7rem;
}
.painel-conta-item .n {
    font-size: 1.3rem; font-weight: 700; color: var(--tinta);
    letter-spacing: -.03em; line-height: 1.15;
    font-variant-numeric: tabular-nums;
}
.painel-conta-item .r { font-size: .72rem; color: var(--tinta-3); margin-top: .1rem; }

@media (max-width: 900px) {
    .painel-conta { grid-template-columns: 1fr; }
}

/* barra dentro da célula da tabela — o valor continua escrito ao lado, a barra
   só faz a coluna virar leitura de relance */
.tab-barra {
    display: inline-block; vertical-align: middle;
    width: 68px; height: 5px; border-radius: 99px;
    background: var(--linha); overflow: hidden; margin-right: .45rem;
}
.tab-barra > span {
    display: block; height: 100%; border-radius: 99px;
    background: var(--rosa-escuro);
}
.tab-barra-valor { font-variant-numeric: tabular-nums; }

/* quatro destaques numa grade 2×2 dentro do painel */
.painel-conta-4 { grid-template-columns: 1fr 1fr; gap: .9rem .7rem; }
.painel-conta-4 .n { font-size: 1.16rem; }
@media (max-width: 900px) {
    .painel-conta-4 { grid-template-columns: 1fr 1fr; }
}


/* ------------------------------------------------ a conta do faturamento

   Uma conta, não uma tabela: rótulo à esquerda, valor alinhado à direita e a
   variação em terceira coluna, com as duas linhas de subtotal marcadas por
   filete e peso. É a mesma leitura do extrato de banco, que é o formato em que
   as pessoas já sabem conferir número. */

.conta { margin-top: .2rem; }
.conta-linha {
    display: grid;
    grid-template-columns: 1fr auto minmax(96px, auto);
    align-items: baseline; gap: .5rem 1rem;
    padding: .5rem 0;
    border-bottom: 1px solid var(--linha);
}
.conta-linha:last-child { border-bottom: none; }
.conta-rotulo { font-size: .88rem; color: var(--tinta-2); }
.conta-valor {
    font-size: .95rem; font-weight: 600; color: var(--tinta);
    font-variant-numeric: tabular-nums; white-space: nowrap;
}
.conta-delta { font-size: .76rem; text-align: right; white-space: nowrap; }

/* dedução: o valor fica em tom secundário para o olho descer a coluna pelos
   números que somam */
.conta-menos .conta-valor { color: var(--tinta-2); font-weight: 500; }
.conta-neutro .conta-rotulo, .conta-neutro .conta-valor { color: var(--tinta-3); }

/* subtotal: o filete acima é o que transforma a lista em conta */
.conta-total {
    border-top: 2px solid var(--tinta);
    border-bottom: none;
    margin-top: .15rem; padding-top: .6rem;
}
.conta-total + .conta-linha { border-top: 1px solid var(--linha); }
.conta-total .conta-rotulo {
    color: var(--tinta); font-weight: 700; font-size: .92rem;
}
.conta-total .conta-valor { font-size: 1.14rem; font-weight: 700; }

/* ------------------------------------------------ ranking de produto com o período anterior

   Duas barras na MESMA escala, a de baixo mais clara: é a leitura de "cresceu
   ou encolheu" sem precisar ler dois números e subtrair. O percentual continua
   escrito ao lado porque barra não se lê no centavo. */

.rank-prod {
    display: flex; align-items: flex-start; gap: .7rem;
    padding: .65rem 0; border-bottom: 1px solid var(--linha);
}
.rank-prod:last-of-type { border-bottom: none; }
.rank-prod .mini, .rank-prod .mini-vazia { width: 40px; height: 40px; flex: 0 0 auto; }
.rank-prod-corpo { flex: 1; min-width: 0; }
.rank-prod-topo {
    display: flex; align-items: baseline; justify-content: space-between; gap: .7rem;
}
.rank-prod-nome {
    font-size: .86rem; font-weight: 600; color: var(--tinta);
    min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.rank-prod-valor {
    font-size: .9rem; font-weight: 700; color: var(--tinta);
    font-variant-numeric: tabular-nums; white-space: nowrap;
}
.rank-prod-barra {
    height: 7px; border-radius: 99px; background: var(--linha);
    margin-top: .3rem; overflow: hidden;
}
.rank-prod-barra > span {
    display: block; height: 100%; border-radius: 99px; background: var(--rosa-escuro);
}
/* a barra do período anterior não tem trilho: com o fundo cinza atrás, um
   produto que não existia antes desenhava uma barra vazia de ponta a ponta e
   parecia ter vendido o período inteiro */
.rank-prod-barra-antes {
    height: 5px; margin-top: .15rem; background: transparent;
}
.rank-prod-barra-antes > span { background: var(--rosa-lavado); }
.rank-prod-pe {
    display: flex; align-items: center; gap: .45rem;
    margin-top: .35rem; font-size: .74rem; color: var(--tinta-3);
}
.rank-prod-pe .aux { white-space: nowrap; }
.rank-prod-delta { margin-left: auto; white-space: nowrap; }

@media (max-width: 760px) {
    .conta-linha { grid-template-columns: 1fr auto; }
    /* na largura de celular a variação desce para a própria linha, alinhada ao
       valor — espremê-la em terceira coluna quebraria o número no meio */
    .conta-delta { grid-column: 2; text-align: right; }
}

/* ============================================================
   TELA "VENDAS"
   ============================================================
   A tela abria com sete painéis brancos idênticos empilhados: nada dizia o que
   era mais importante, e o mesmo eixo de datas se repetia três vezes. A faixa
   abaixo resolve as duas coisas — dá cara de marca à tela e coloca o número que
   importa acima de todos os outros. */

.faixa-periodo {
    position: relative;
    /* margem negativa: a faixa vaza o padding do .conteudo e encosta nas
       bordas, em vez de flutuar como mais um card */
    margin: -1.4rem -1.6rem 1.2rem -1.6rem;
    padding: 1.5rem 1.6rem 3.4rem 1.6rem;
    background: linear-gradient(150deg, var(--rosa) 0%, var(--rosa-escuro) 100%);
    overflow: hidden;
}
/* a mesma onda da tela Hoje, para as duas faixas serem reconhecidamente a
   mesma peça de marca */
/* A faixa recorta o que vaza (é o que mantém a onda e o gradiente dentro das
   bordas), mas o calendário é mais alto que ela e era cortado no meio. Enquanto
   o popover estiver aberto a faixa para de recortar; fechado, tudo volta ao
   que era. */
.faixa-periodo:has(.pop[open]) { overflow: visible; }

.faixa-periodo::after {
    content: ''; position: absolute; left: 0; right: 0; bottom: -1px; height: 40px;
    background: var(--fundo);
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1200 46' preserveAspectRatio='none'%3E%3Cpath d='M0 46V18c180 22 420-14 600-8s420 34 600 6v30z' fill='%23000'/%3E%3C/svg%3E") no-repeat center/100% 100%;
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1200 46' preserveAspectRatio='none'%3E%3Cpath d='M0 46V18c180 22 420-14 600-8s420 34 600 6v30z' fill='%23000'/%3E%3C/svg%3E") no-repeat center/100% 100%;
}
/* z-index 3, e não 1: o `.faixa-periodo-caixa` logo abaixo também cria contexto
   de empilhamento e vem DEPOIS no HTML — com os dois em z-index 1, o card do
   faturamento ganhava por ordem de documento e cobria o calendário aberto. O
   z-index 40 do `.pop-corpo` não resolvia sozinho: ele só vale DENTRO do
   contexto criado aqui, e é este contexto que precisava subir. */
.faixa-periodo-topo {
    position: relative; z-index: 3;
    display: flex; align-items: baseline; justify-content: space-between;
    gap: 1rem; flex-wrap: wrap;
}
.faixa-periodo-titulo {
    font-family: var(--fonte-titulo);
    color: var(--branco); font-size: 1.26rem; letter-spacing: -.01em;
}
.faixa-periodo-datas {
    color: var(--branco); font-size: .84rem; opacity: .9;
    font-variant-numeric: tabular-nums;
}
.faixa-periodo-caixa {
    position: relative; z-index: 1;
    margin-top: 1rem; background: var(--branco);
    border-radius: var(--raio); padding: 1.3rem 1.5rem;
    box-shadow: 0 6px 22px rgba(79, 40, 21, .10);
    display: flex; align-items: flex-end; justify-content: space-between;
    gap: 1.2rem; flex-wrap: wrap;
}
.faixa-periodo-rotulo {
    font-size: .72rem; font-weight: 650; letter-spacing: .08em;
    text-transform: uppercase; color: var(--tinta-3);
}
.faixa-periodo-valor {
    font-family: var(--fonte-numero);
    font-size: 2.9rem; color: var(--tinta);
    line-height: 1.04; letter-spacing: -.02em; margin-top: .2rem;
    font-variant-numeric: tabular-nums;
}
.faixa-periodo-delta { font-size: .9rem; margin-top: .35rem; }
/* as três contas que compõem o número grande, à direita dele */
.faixa-periodo-conta {
    display: flex; gap: 1.6rem; flex-wrap: wrap;
    padding-bottom: .3rem;
}
.faixa-periodo-conta div { text-align: right; }
.faixa-periodo-conta .r {
    font-size: .7rem; font-weight: 650; letter-spacing: .05em;
    text-transform: uppercase; color: var(--tinta-3);
}
.faixa-periodo-conta .n {
    font-size: 1.02rem; font-weight: 700; color: var(--tinta-2);
    font-variant-numeric: tabular-nums; margin-top: .1rem;
}


/* ---- as três lentes, dentro da faixa

   Elas moravam numa tira própria abaixo da faixa: 90px de altura para três
   links, longe do título que eles mudam. Aqui são lidas junto com ele. O
   contraste vem do fundo translúcido — texto branco sobre o rosa da marca —, e
   a aba ativa inverte para fundo branco e tinta, que é a leitura mais forte
   que existe nesta paleta. */
.faixa-periodo-abas { position: relative; z-index: 2; }
.faixa-periodo-abas .abas-visao {
    margin: 0; background: rgba(255, 255, 255, .16);
    border-color: rgba(255, 255, 255, .34);
}
.faixa-periodo-abas .aba-visao { color: var(--branco); }
.faixa-periodo-abas .aba-visao:hover { background: rgba(255, 255, 255, .14); }
.faixa-periodo-abas .aba-visao.ativo {
    background: var(--branco); color: var(--tinta);
}

/* ---- a faísca no meio da caixa

   O vão que existia entre o número e as parcelas não era respiro: era espaço
   sem função, e num card de 1.300px ele chegava a 600. A série do período
   ocupa esse meio dizendo o que nem a capa nem a variação diziam — o formato.
   Ela some antes de espremer as duas pontas. */
.faixa-periodo-faisca {
    flex: 1 1 240px; min-width: 0;
    display: flex; align-items: flex-end; justify-content: center;
    padding-bottom: .45rem; opacity: .85;
}
.faixa-periodo-faisca svg { max-width: 100%; height: auto; }

/* a régua que substitui a faísca quando o período é curto demais para ter
   formato: o valor absoluto do período comparado, que a variação em cima
   pressupõe e não mostra */
.faixa-periodo-regua {
    flex-direction: column; align-items: center; justify-content: flex-end;
    gap: .1rem; text-align: center; opacity: 1;
}
.faixa-periodo-regua .r {
    font-size: .7rem; font-weight: 650; letter-spacing: .05em;
    text-transform: uppercase; color: var(--tinta-3);
}
.faixa-periodo-regua .n {
    font-size: 1.14rem; font-weight: 700; color: var(--tinta-2);
    font-variant-numeric: tabular-nums;
}
@media (max-width: 1150px) { .faixa-periodo-faisca { display: none; } }

/* ---- o ritmo do mês, no rodapé da caixa

   Era um painel inteiro chamado "setembro de 2026" — que repetia o período do
   cabeçalho — para dizer duas frases e desenhar uma barra. Embaixo do número
   que elas qualificam, as mesmas duas frases não custam dobra nenhuma. */
.faixa-periodo-ritmo {
    flex: 1 1 100%;
    margin-top: .95rem; padding-top: .85rem;
    border-top: 1px solid var(--linha);
}
.faixa-periodo-ritmo-topo {
    display: flex; justify-content: space-between; gap: .6rem; flex-wrap: wrap;
    font-size: .8rem; color: var(--tinta-2); margin-bottom: .4rem;
}
.faixa-periodo-ritmo-topo b { color: var(--tinta); }

@media (max-width: 760px) {
    .faixa-periodo { margin: -1rem -1rem 1rem -1rem; padding: 1.1rem 1rem 3rem 1rem; }
    .faixa-periodo-valor { font-size: 2.1rem; }
    .faixa-periodo-caixa { padding: 1rem 1.1rem; }
    .faixa-periodo-conta { gap: 1.1rem; }
}

/* ------------------------------------------------ entrada em cascata

   Os painéis sobem 10px e aparecem conforme chegam à dobra. É curto (380ms) e
   o conteúdo final já está no HTML — quem tem JS desligado vê tudo de pé, e o
   `.visivel` é aplicado sem animação para quem pediu menos movimento. */
[data-entra] {
    opacity: 0; transform: translateY(10px);
    transition: opacity .38s ease, transform .38s cubic-bezier(.22, .8, .3, 1);
}
[data-entra].visivel { opacity: 1; transform: none; }

/* barra de proporção crescendo da esquerda */
.trilho > span.cresce,
.bloco-corte-barra > span.cresce {
    transition: width .62s cubic-bezier(.22, .8, .3, 1);
}

@media (prefers-reduced-motion: reduce) {
    [data-entra] { opacity: 1; transform: none; transition: none; }
    .trilho > span.cresce,
    .bloco-corte-barra > span.cresce { transition: none; }
}

/* ============================================================
   LINHAS DE PRODUTO — as três da loja
   ============================================================
   Quadro, personalizado e arte digital. Três negócios com margem, logística e
   tempo de produção diferentes, e o painel precisa separá-los em toda tela onde
   o produto aparece.

   O card tem badge de ícone colorido, valor grande, barra de participação e
   rodapé com unidades. A cor é a mesma nas três telas — ela É a identidade da
   linha, não decoração do card. */

.grade-classes {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: .9rem;
    margin-bottom: 1.1rem;
}

.card-classe {
    background: var(--branco);
    border: 1px solid var(--borda);
    border-radius: var(--raio);
    padding: 1.05rem 1.15rem 1rem 1.15rem;
    box-shadow: var(--sombra-card);
    transition: box-shadow .18s ease, transform .18s ease;
}
.card-classe:hover {
    box-shadow: var(--sombra-alta);
    transform: translateY(-2px);
}

.card-classe-topo {
    display: flex; align-items: center; gap: .6rem; margin-bottom: .75rem;
}
/* badge quadrado arredondado com o ícone dentro, na cor da linha */
.card-classe-icone {
    width: 34px; height: 34px; flex: 0 0 34px;
    border-radius: 11px;
    display: grid; place-items: center;
    color: var(--branco);
}
.card-classe-icone svg { width: 18px; height: 18px; }
.card-classe-nome {
    font-size: .82rem; font-weight: 650; color: var(--tinta-2);
    letter-spacing: .01em;
}
.card-classe-valor {
    font-family: var(--fonte-numero);
    font-size: 1.55rem; color: var(--tinta);
    line-height: 1.1; letter-spacing: -.02em;
    font-variant-numeric: tabular-nums;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.card-classe-barra {
    height: 7px; border-radius: 99px; background: var(--linha);
    overflow: hidden; margin: .7rem 0 .5rem 0;
}
.card-classe-barra > span { display: block; height: 100%; border-radius: 99px; }
.card-classe-pe {
    display: flex; align-items: baseline; justify-content: space-between; gap: .5rem;
}
.card-classe-fatia {
    font-size: .88rem; font-weight: 700; color: var(--tinta);
    font-variant-numeric: tabular-nums;
}
.card-classe-pe .aux {
    font-size: .72rem; color: var(--tinta-3);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

@media (max-width: 860px) {
    .grade-classes { grid-template-columns: 1fr; gap: .7rem; }
    .card-classe-valor { font-size: 1.35rem; }
}

@media (prefers-reduced-motion: reduce) {
    .card-classe, .card-classe:hover { transition: none; transform: none; }
}

/* variante empilhada das linhas de produto, para coluna estreita (tela Hoje) */
.classe-linha {
    display: flex; align-items: flex-start; gap: .7rem;
    padding: .75rem 0; border-bottom: 1px solid var(--linha);
}
.classe-linha:last-child { border-bottom: none; padding-bottom: .2rem; }
.classe-linha-corpo { flex: 1; min-width: 0; }
.classe-linha-topo {
    display: flex; align-items: baseline; justify-content: space-between;
    gap: .6rem; margin-bottom: .1rem;
}
.classe-linha-nome {
    font-size: .86rem; font-weight: 650; color: var(--tinta);
}
.classe-linha-valor {
    font-size: .92rem; font-weight: 700; color: var(--tinta);
    font-variant-numeric: tabular-nums; white-space: nowrap;
}
.classe-linha .card-classe-barra { margin: .4rem 0 .3rem 0; height: 6px; }


/* a faixa de topo precisa saber do trilho para vazar até a borda certa */
.faixa-periodo, .vivo-faixa {
    margin-left: -1.6rem; margin-right: -1.6rem;
}

@media (prefers-reduced-motion: reduce) {
    .menu, .menu-so-aberto { transition: none; }
}

/* ------------------------------------------------ KPI com badge de ícone */
.kpi-topo { display: flex; align-items: center; gap: .55rem; margin-bottom: .1rem; }
.kpi-icone {
    width: 30px; height: 30px; flex: 0 0 30px;
    border-radius: 10px; display: grid; place-items: center;
    color: var(--branco);
}
.kpi-icone svg { width: 17px; height: 17px; }

/* ------------------------------------------------ abas de gráfico

   Um painel com várias visualizações da mesma linha do tempo. Substituiu quatro
   painéis empilhados que repetiam o mesmo eixo de datas. */
.grafico-abas-barra {
    display: flex; gap: .3rem; flex-wrap: wrap;
    background: var(--fundo-2);
    border-radius: 13px; padding: .25rem;
    margin: .2rem 0 .9rem 0;
    width: fit-content; max-width: 100%;
}
.grafico-aba {
    border: none; background: transparent; cursor: pointer;
    font-family: inherit; font-size: .82rem; font-weight: 600;
    color: var(--tinta-2);
    padding: .42rem .85rem; border-radius: 10px;
    white-space: nowrap;
    transition: background .14s ease, color .14s ease;
}
.grafico-aba:hover { color: var(--tinta); }
.grafico-aba.ativo {
    background: var(--branco); color: var(--tinta);
    box-shadow: 0 1px 3px rgba(79, 40, 21, .10);
}
.grafico-aba-painel { display: none; }
.grafico-aba-painel.ativo { display: block; }

@media (prefers-reduced-motion: reduce) {
    .grafico-aba { transition: none; }
}

/* ------------------------------------------------ abas de visão

   Trocam a LENTE da tela inteira (diária ↔ mensal), não o conteúdo de um
   painel. São links e recarregam a página — o estado mora na URL, então o
   botão "voltar" funciona e a visão pode ser mandada por link. */
.abas-visao {
    display: flex; gap: .35rem;
    background: var(--fundo-2);
    border-radius: 15px; padding: .3rem;
    margin: 0 0 1rem 0;
    width: fit-content; max-width: 100%;
}
.aba-visao {
    font-family: var(--fonte-numero);
    font-size: .92rem; color: var(--tinta-2);
    padding: .55rem 1.35rem; border-radius: 12px;
    white-space: nowrap;
    transition: background .16s ease, color .16s ease;
}
.aba-visao:hover { color: var(--tinta); }
.aba-visao.ativo {
    background: var(--branco); color: var(--tinta);
    box-shadow: 0 1px 4px rgba(79, 40, 21, .12);
}

/* ------------------------------------------------ cards de mês */
/* Três colunas fixas, não auto-fit: são sempre seis cards, e o auto-fit
   encaixava cinco numa linha e deixava o sexto órfão. 3×2 é a grade que os
   seis meses sempre preenchem. */
.grade-meses {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: .9rem; margin-bottom: 1rem;
}
@media (max-width: 1100px) { .grade-meses { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 700px)  { .grade-meses { grid-template-columns: 1fr; } }
.card-mes {
    background: var(--branco); border: 1px solid var(--borda);
    border-radius: var(--raio); padding: 1rem 1.1rem .85rem 1.1rem;
    box-shadow: var(--sombra-card);
    transition: box-shadow .18s ease, transform .18s ease;
}
.card-mes:hover { box-shadow: var(--sombra-alta); transform: translateY(-2px); }
/* o mês em curso é o único incompleto: a borda avisa antes de a pessoa
   comparar um mês de 12 dias com um de 31 e achar que despencou */
.card-mes-atual { border-color: var(--rosa); }
.card-mes-rotulo {
    font-size: .74rem; font-weight: 650; letter-spacing: .04em;
    text-transform: uppercase; color: var(--tinta-3);
    display: flex; align-items: center; gap: .4rem; flex-wrap: wrap;
}
.chip-atual {
    background: var(--rosa-lavado); color: var(--rosa-texto);
    border-radius: 99px; padding: .1rem .45rem;
    font-size: .62rem; letter-spacing: .02em;
}
.card-mes-valor {
    font-family: var(--fonte-numero);
    font-size: 1.6rem; color: var(--tinta);
    line-height: 1.1; letter-spacing: -.02em; margin-top: .3rem;
    font-variant-numeric: tabular-nums;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.card-mes-delta { font-size: .78rem; margin-top: .25rem; }
.card-mes-pe {
    display: flex; justify-content: space-between; gap: .5rem;
    font-size: .73rem; color: var(--tinta-3);
    margin-top: .5rem; padding-top: .5rem;
    border-top: 1px solid var(--linha);
    font-variant-numeric: tabular-nums;
}
.card-mes-faisca { margin-top: .4rem; }

@media (prefers-reduced-motion: reduce) {
    .aba-visao, .card-mes, .card-mes:hover { transition: none; transform: none; }
}

/* ------------------------------------------------ miniaturas de produto

   A imagem vem do CDN da Shopify com `width=` na URL — o redimensionamento
   acontece lá, não aqui. Ver Theme::miniatura. */
.mini {
    border-radius: 10px; object-fit: cover; flex: 0 0 auto;
    background: var(--fundo-2);
    border: 1px solid var(--borda);
    display: block;
}
/* produto sem foto: quadrado com a inicial, para a lista não desalinhar */
.mini-vazia {
    display: grid; place-items: center;
    border-radius: 10px; flex: 0 0 auto;
    background: var(--rosa-lavado); color: var(--rosa-texto);
    font-family: var(--fonte-numero); font-size: .95rem;
    border: 1px solid var(--borda);
}

/* miniatura dentro de célula de tabela */
.cel-produto { display: flex; align-items: center; gap: .6rem; }
.cel-produto .mini, .cel-produto .mini-vazia { width: 34px; height: 34px; }

/* lista de produtos com foto */
.lista-produtos { margin-bottom: .9rem; }
.produto-linha {
    display: flex; align-items: center; gap: .75rem;
    padding: .6rem 0; border-bottom: 1px solid var(--linha);
}
.produto-linha:last-child { border-bottom: none; }
.produto-pos {
    width: 22px; flex: 0 0 22px; text-align: center;
    font-size: .78rem; font-weight: 800; color: var(--tinta-3);
    font-variant-numeric: tabular-nums;
}
.produto-corpo { flex: 1; min-width: 0; }
.produto-nome {
    font-size: .88rem; font-weight: 600; color: var(--tinta);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.produto-aux {
    font-size: .74rem; color: var(--tinta-3); margin-top: .2rem;
    display: flex; align-items: center; gap: .4rem; flex-wrap: wrap;
}
.produto-valor {
    font-size: .95rem; font-weight: 700; color: var(--tinta);
    font-variant-numeric: tabular-nums; white-space: nowrap;
}

/* nos campeões da tela Hoje a miniatura entra entre a posição e o nome */
.vivo-campeao .mini, .vivo-campeao .mini-vazia { width: 44px; height: 44px; }

/* ============================================================
   TELA "HOJE" — três pilhas
   ============================================================
   Métricas-chave | tendência por hora | mais vendidos. É o arranjo do painel ao
   vivo do Mercado Livre, e ele funciona pela mesma razão aqui: a tela fica
   aberta o dia inteiro e é lida de relance, de longe. Três blocos fixos, sempre
   nos mesmos lugares, evitam procurar.

   Cada coluna é uma PILHA de painéis, não um painel só. Com um painel por
   coluna e mais dois numa fileira abaixo, as alturas nunca fechavam — a grade
   de métricas ocupa o dobro da lista de campeões, e num dia de poucas vendas a
   terceira coluna virava um retângulo quase vazio ao lado de um cheio. O painel
   de baixo de cada pilha ocupa essa sobra.

   O que ainda sobrar é absorvido pelo ÚLTIMO painel da pilha (`flex: 1`): as
   três terminam na mesma linha, e o desencontro fica dentro do card, onde é
   respiro, em vez de virar degrau entre eles. */

.vivo-colunas {
    display: grid;
    grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.3fr) minmax(0, 1fr);
    gap: .9rem; align-items: stretch;
    margin-bottom: .9rem;
}
.vivo-col {
    display: flex; flex-direction: column; gap: .9rem;
    min-width: 0;
}
.vivo-col > .painel { margin-bottom: 0; display: flex; flex-direction: column; }

/* A sobra vai para o painel que sabe CRESCER, não para o último da pilha.
   Esticar o card sem esticar o que tem dentro só muda o lugar do vão: ele sai
   de entre os cards e vira um retângulo branco no pé de um deles — que foi
   exatamente o que aconteceu com "Linhas de produto", duas barras no topo de
   meio metro de card vazio.

   Onde há gráfico, é ele quem recebe a folga: um gráfico mais alto é mais
   legível, então o espaço vira informação. Sem gráfico, fica com o último
   painel, e aí quem se espalha é o conteúdo dele (regras abaixo). */
.vivo-col > .painel:last-child { flex: 1; }
.vivo-col > .painel:has(.grafico-elastico) { flex: 1; }
.vivo-col > .painel:has(.grafico-elastico) ~ .painel:last-child { flex: 0 0 auto; }
.vivo-col > .painel > .grafico-elastico { flex: 1 1 auto; min-height: 0; }

/* A grade de métricas divide a folga entre as LINHAS: os separadores chegam
   até a base e a grade fecha o card, em vez de terminar no meio dele. O
   conteúdo de cada célula centra na vertical para não ficar pendurado no topo
   de uma célula alta. */
.vivo-col > .painel > .vivo-metricas { flex: 1 1 auto; grid-auto-rows: 1fr; }
.vivo-col > .painel > .vivo-metricas .vivo-metrica {
    display: flex; flex-direction: column; justify-content: center;
}

/* Listas (campeões, últimos pedidos) fazem o mesmo quando é a pilha delas que
   sobra: as linhas se espalham até a base. O teto existe porque num dia de
   duas vendas a linha cresceria até virar um cartaz — passado ele, é melhor
   deixar o respiro no pé do card do que uma lista deformada. */
.vivo-col > .painel:last-child > .vivo-campeao,
.vivo-col > .painel:last-child > .vivo-pedido {
    flex: 1 1 auto; max-height: 7rem;
}

@media (max-width: 1250px) {
    .vivo-colunas { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
    /* a tendência é o painel mais largo: a pilha dela ocupa a linha inteira
       quando sobra, e as outras duas dividem a de baixo */
    .vivo-colunas > .vivo-col:nth-child(2) { grid-column: 1 / -1; order: -1; }
}
@media (max-width: 860px) {
    .vivo-colunas { grid-template-columns: 1fr; }
    .vivo-colunas > .vivo-col:nth-child(2) { grid-column: auto; order: 0; }
}

/* métricas-chave em grade de dois, cada uma com ícone em círculo */
.vivo-metricas {
    display: grid; grid-template-columns: 1fr 1fr; gap: .1rem;
}
.vivo-metrica {
    padding: .8rem .6rem;
    border-right: 1px solid var(--linha);
    border-bottom: 1px solid var(--linha);
}
/* a grade tem duas colunas: as ímpares não levam borda à direita */
.vivo-metrica:nth-child(2n) { border-right: none; }
.vivo-metrica:nth-last-child(-n+2) { border-bottom: none; }
.vivo-metrica-icone {
    width: 30px; height: 30px; border-radius: 50%;
    display: grid; place-items: center;
    background: var(--rosa-lavado); color: var(--rosa-texto);
    margin-bottom: .45rem;
}
.vivo-metrica-icone svg { width: 16px; height: 16px; }
.vivo-metrica-label {
    font-size: .74rem; color: var(--tinta-3); font-weight: 600;
}
.vivo-metrica-valor {
    font-family: var(--fonte-numero); font-weight: 700;
    font-size: 1.32rem; color: var(--tinta); line-height: 1.15;
    letter-spacing: -.02em; margin-top: .1rem;
    font-variant-numeric: tabular-nums;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.vivo-metrica-rodape { font-size: .7rem; margin-top: .15rem; color: var(--tinta-3); }

/* campeões: o primeiro colocado ganha destaque, como no painel do ML */
.vivo-campeao-topo {
    background: var(--rosa-lavado);
    border-radius: 14px;
    margin: 0 -.5rem; padding-left: .5rem; padding-right: .5rem;
}
.vivo-campeao-topo .vivo-campeao-pos { background: var(--rosa); color: var(--tinta); }
.vivo-campeao-estoque { margin-top: .2rem; font-size: .73rem; }
/* estoque no fim é urgente e precisa saltar — vender bem algo que vai acabar
   hoje é aviso, não elogio */
.selo-alerta {
    background: var(--negativo); color: var(--branco);
    border-radius: 99px; padding: .1rem .45rem;
    font-size: .66rem; font-weight: 700; white-space: nowrap;
}

/* ------------------------------------------------ filtro dentro da faixa

   O seletor de período mora no canto da faixa, não numa barra abaixo: é o
   controle que muda tudo na tela, e no meio dos painéis ele desaparecia. */
.faixa-periodo-filtro { position: relative; z-index: 2; }
/* O filtro mora no canto DIREITO da faixa, e o popover tem 520px: ancorado à
   esquerda ele saía pela borda da janela. Alinhado à direita, cresce para
   dentro da tela. Enquanto a faixa recortava, isto passava despercebido. */
.faixa-periodo-filtro .pop-corpo { left: auto; right: 0; }
.faixa-periodo-filtro .filtro { margin: 0; }
.faixa-periodo-filtro .rotulo-filtro { display: none; }
.faixa-periodo-filtro .pop-botao {
    background: rgba(255, 255, 255, .18);
    border-color: rgba(255, 255, 255, .45);
    color: var(--branco);
    backdrop-filter: blur(4px);
}
.faixa-periodo-filtro .pop-botao:hover {
    background: rgba(255, 255, 255, .3); border-color: var(--branco); color: var(--branco);
}
.faixa-periodo-filtro .pop-resumo { color: rgba(255, 255, 255, .8); }
.faixa-periodo-filtro .pop[open] .pop-botao { border-color: var(--branco); }

/* abas de visão centralizadas */
/* .abas-centro saiu junto com a tira de abas da tela Vendas: as lentes moram
   dentro da faixa agora (ver .faixa-periodo-abas). */

/* barra de progresso do mês */
.mes-progresso { margin-bottom: 1rem; }
.mes-progresso-topo {
    display: flex; justify-content: space-between; gap: .6rem;
    font-size: .82rem; color: var(--tinta-2); margin-bottom: .4rem;
}

/* a conta do bruto até o que entrou, embaixo do número do dia */
.vivo-heroi-conta {
    font-size: .8rem; color: var(--tinta-3); margin-top: .35rem;
}

/* ------------------------------------------------ linha de tabela clicável */
tr.linha-clicavel { cursor: pointer; transition: background .12s ease; }
tr.linha-clicavel:hover { background: var(--rosa-lavado); }
tr.linha-clicavel:focus-visible {
    outline: 2px solid var(--rosa-texto); outline-offset: -2px; background: var(--rosa-lavado);
}
/* seta discreta na última célula, para a linha se anunciar como navegável */
tr.linha-clicavel td:last-child { position: relative; }
tr.linha-clicavel td:last-child::after {
    content: '›'; position: absolute; right: .45rem; top: 50%;
    transform: translateY(-50%);
    color: var(--tinta-3); font-size: 1.1rem; opacity: 0;
    transition: opacity .12s ease;
}
tr.linha-clicavel:hover td:last-child::after { opacity: 1; }

/* volta da tela de detalhe */
.volta-dia { margin-bottom: .8rem; }
.volta-dia a {
    font-size: .86rem; font-weight: 600; color: var(--tinta-2);
    display: inline-flex; align-items: center; gap: .3rem;
    padding: .4rem .8rem; border-radius: 10px;
    background: var(--branco); border: 1px solid var(--borda);
    box-shadow: var(--sombra-card);
}
.volta-dia a:hover { color: var(--tinta); border-color: var(--rosa); }

/* Painéis lado a lado com a MESMA altura, e o conteúdo distribuído.
   Antes o painel mais curto deixava um vão branco embaixo; agora ele estica
   e o conteúdo se espalha até a base. */
.colunas > .painel { display: flex; flex-direction: column; }
.colunas > .painel > .grafico,
.colunas > .painel > .grafico-elastico { flex: 1 1 auto; min-height: 0; }

@media (prefers-reduced-motion: reduce) {
    tr.linha-clicavel, tr.linha-clicavel td:last-child::after { transition: none; }
}

/* ------------------------------------------------ linha de tabela expansível

   O detalhe do dia abre EMBAIXO da linha, sem sair da página. O conteúdo já
   está no HTML; o clique só revela. */
tr.linha-expansivel { cursor: pointer; transition: background .12s ease; }
tr.linha-expansivel:hover { background: var(--fundo-2); }
tr.linha-expansivel.aberta { background: var(--rosa-lavado); }
tr.linha-expansivel.aberta td { border-bottom-color: transparent; }
tr.linha-expansivel:focus-visible {
    outline: 2px solid var(--rosa-texto); outline-offset: -2px;
}
.col-abrir { width: 34px; text-align: center; }
.seta-abrir {
    display: inline-block; color: var(--tinta-3); font-size: 1rem;
    transition: transform .16s ease, color .16s ease;
}
tr.linha-expansivel:hover .seta-abrir { color: var(--tinta); }
tr.linha-expansivel.aberta .seta-abrir { transform: rotate(180deg); color: var(--rosa-texto); }

.linha-detalhe > td { padding: 0 !important; background: var(--rosa-lavado); }
.detalhe-corpo { padding: .3rem .6rem 1rem .6rem; }

.detalhe-grade {
    display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: .7rem;
}
@media (max-width: 1000px) { .detalhe-grade { grid-template-columns: 1fr; } }

/* Uma coluna só: o detalhe de campanha é uma tabela larga, não três painéis
   lado a lado. Reaproveita o painel e a moldura, muda só a grade. */
.detalhe-grade-larga { grid-template-columns: 1fr; }
.detalhe-grade-duas  { grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (max-width: 900px) { .detalhe-grade-duas { grid-template-columns: 1fr; } }

/* Tabela dentro de um painel de detalhe.

   Não reaproveita `.tabela`: aquela tem cabeçalho grudento, altura máxima e
   ordenação — três coisas que dentro de uma linha expansível brigam com o
   acordeão em vez de ajudar. Esta é só uma grade de leitura. */
.tabela-mini {
    width: 100%; border-collapse: collapse; margin-top: .5rem;
    font-size: .78rem;
}
.tabela-mini th {
    text-align: left; font-weight: 600; color: var(--tinta-3);
    font-size: .66rem; letter-spacing: .06em; text-transform: uppercase;
    padding: .3rem .5rem .35rem; border-bottom: 1px solid var(--linha);
    white-space: nowrap;
}
.tabela-mini td {
    padding: .34rem .5rem; border-bottom: 1px solid var(--linha);
    color: var(--tinta); white-space: nowrap;
}
.tabela-mini tr:last-child td { border-bottom: 0; }
.tabela-mini th.num, .tabela-mini td.num {
    text-align: center; font-variant-numeric: tabular-nums;
}
.tabela-mini th:first-child, .tabela-mini td:first-child { text-align: left; }
.tabela-mini tr:hover td { background: var(--fundo-2); }

/* Em tela estreita a tabela rola dentro do painel — a página nunca rola na
   horizontal. */
.detalhe-grade-larga .detalhe-painel { overflow-x: auto; }

.detalhe-painel {
    background: var(--branco); border: 1px solid var(--borda);
    border-radius: 14px; padding: .85rem 1rem;
}
.detalhe-titulo {
    font-size: .7rem; font-weight: 700; letter-spacing: .07em;
    text-transform: uppercase; color: var(--tinta-3); margin-bottom: .6rem;
}
.detalhe-linha, .detalhe-produto {
    display: flex; align-items: center; gap: .55rem;
    padding: .4rem 0; border-bottom: 1px solid var(--linha);
    white-space: normal;
}
.detalhe-painel > :last-child { border-bottom: none; }
.detalhe-nome {
    flex: 1; min-width: 0; font-size: .82rem; color: var(--tinta);
    overflow: hidden; text-overflow: ellipsis;
}
.detalhe-valor {
    text-align: right; white-space: nowrap;
    font-size: .86rem; font-weight: 700; color: var(--tinta);
    font-variant-numeric: tabular-nums;
}
.detalhe-valor small {
    display: block; font-size: .68rem; font-weight: 500; color: var(--tinta-3);
}
.detalhe-conta { font-size: .82rem; color: var(--tinta-2); justify-content: space-between; }
.detalhe-produto .mini, .detalhe-produto .mini-vazia { width: 38px; height: 38px; }
.detalhe-link {
    display: inline-block; margin-top: .7rem;
    font-size: .78rem; font-weight: 650; color: var(--rosa-texto);
}
.detalhe-link:hover { text-decoration: underline; }

.visualmente-oculto {
    position: absolute; width: 1px; height: 1px; overflow: hidden;
    clip: rect(0 0 0 0); white-space: nowrap;
}

@media (prefers-reduced-motion: reduce) {
    tr.linha-expansivel, .seta-abrir { transition: none; }
}

/* ------------------------------------------------ funil da campanha

   Duas metades que precisam ficar alinhadas linha a linha: a silhueta em SVG
   e a coluna de texto. O alinhamento não é feito por altura fixa em px — é
   feito pelo próprio SVG, que tem viewBox de 100 × (nº de etapas) e
   preserveAspectRatio="none", então cada faixa ocupa exatamente 1/N da altura
   que a coluna de texto determinar. Muda o número de etapas, continua casando. */
/* Enquanto um detalhe está aberto, a caixa da tabela solta a altura máxima:
   quem rola passa a ser a página, e o painel aparece inteiro. Ver app.js. */
.tabela-caixa.com-detalhe { max-height: none !important; }

.funil {
    display: grid; grid-template-columns: minmax(96px, 24%) 1fr;
    gap: 1.1rem; align-items: stretch;
}
.funil-desenho { display: flex; }
.funil-silhueta {
    width: 100%; height: 100%; display: block; min-height: 150px;
}

.funil-etapas { display: grid; }
.funil-linha {
    display: flex; flex-direction: column; justify-content: center;
    padding: .2rem 0 .2rem .1rem;
    border-bottom: 1px solid var(--linha);
}
.funil-linha:last-child { border-bottom: 0; }

.funil-linha-topo {
    display: flex; align-items: baseline; justify-content: space-between; gap: .5rem;
}
.funil-linha-nome {
    font-size: .78rem; font-weight: 650; color: var(--tinta);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.funil-linha-valor {
    font-size: 1.02rem; font-weight: 700; color: var(--tinta);
    font-variant-numeric: tabular-nums; letter-spacing: -.02em; white-space: nowrap;
}
.funil-linha-baixo {
    display: flex; align-items: baseline; justify-content: space-between;
    gap: .5rem; font-size: .68rem; color: var(--tinta-3); margin-top: .05rem;
}
.funil-linha-custo {
    color: var(--rosa-texto); font-weight: 600; white-space: nowrap;
    font-variant-numeric: tabular-nums;
}

.funil-perda {
    margin-top: .7rem; padding: .55rem .75rem;
    background: var(--rosa-lavado); border-radius: 10px;
    font-size: .72rem; color: var(--tinta); line-height: 1.45;
}
.funil-perda b { font-weight: 700; }

@media (max-width: 620px) {
    .funil { grid-template-columns: 64px 1fr; gap: .7rem; }
}

/* ------------------------------------------------ mapa do Brasil

   Mapa e lista dividem o painel: o mapa responde "onde estamos" de relance, a
   lista responde "quanto" com o número escrito. Um sem o outro deixaria a
   pergunta pela metade — mapa não se lê com precisão, lista não se lê com
   geografia. */
.geo {
    display: grid; grid-template-columns: minmax(160px, 46%) 1fr;
    gap: 1rem; align-items: center;
}
.mapa-br svg { width: 100%; height: auto; display: block; }
.mapa-uf {
    stroke: var(--branco); stroke-width: 2.5;
    stroke-linejoin: round;
    transition: opacity .12s ease;
}
/* Escurecer no hover mudaria a cor, que aqui CODIFICA valor. A opacidade
   destaca sem mentir sobre o número. */
.mapa-br:hover .mapa-uf { opacity: .45; }
.mapa-br .mapa-uf:hover { opacity: 1; }

@media (max-width: 720px) {
    .geo { grid-template-columns: 1fr; gap: .8rem; }
    .mapa-br { max-width: 260px; margin: 0 auto; }
}

/* Marca de "voltou e comprou" na lista de checkouts abandonados. Verde porque
   é a única boa notícia possível ali — e rara o bastante para merecer cor. */
.marca-voltou {
    display: inline-block; margin-left: .35rem;
    padding: .05rem .35rem; border-radius: 6px;
    background: rgba(16, 132, 116, .12); color: var(--positivo);
    font-size: .6rem; font-weight: 700; letter-spacing: .02em;
    text-transform: uppercase; vertical-align: middle;
}

/* ------------------------------------------------ curva ABC

   Os três cartões embaixo do gráfico de Pareto. Cada um diz o que a letra
   significa em dinheiro — sem isso, "Curva A" é jargão que o leitor precisa
   traduzir sozinho toda vez. */
.grade-curvas {
    display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
    gap: .7rem; margin-top: 1rem;
}
.card-curva {
    background: var(--fundo); border: 1px solid var(--borda);
    border-radius: 14px; padding: .8rem .9rem;
}
.card-curva-topo {
    display: flex; align-items: center; justify-content: space-between;
    gap: .5rem; margin-bottom: .45rem;
}
.card-curva-valor {
    font-weight: 700; font-size: 1.05rem; color: var(--tinta);
    font-variant-numeric: tabular-nums; letter-spacing: -.02em;
}
.card-curva-linha { font-size: .74rem; color: var(--tinta-2); }
.card-curva-nota {
    font-size: .68rem; color: var(--tinta-3); line-height: 1.4; margin-top: .35rem;
}

.chip-curva {
    display: inline-block; padding: .12rem .5rem; border-radius: 7px;
    color: var(--branco); font-size: .66rem; font-weight: 700;
    letter-spacing: .04em; text-transform: uppercase;
}
/* A mesma marca em miniatura, para caber ao lado do nome numa lista. */
.chip-curva-mini {
    display: inline-block; width: 15px; height: 15px; border-radius: 5px;
    color: var(--branco); font-size: .6rem; font-weight: 700;
    line-height: 15px; text-align: center; vertical-align: middle;
}

/* Direção nas listas de movimento. Aqui a cor é legítima: subir receita é bom
   e cair é ruim, sem ambiguidade — diferente de investimento em mídia, onde
   subir não é nem uma coisa nem outra. */
.linha-aux.sobe  { color: var(--positivo); font-weight: 650; }
.linha-aux.desce { color: var(--negativo); font-weight: 650; }

/* ==========================================================================
   RFM — matriz, segmentos e o detalhe do cliente
   ==========================================================================
   A matriz é um mapa de calor clicável: cada célula é um link que troca o
   recorte da lista logo abaixo. A cor sai de Theme::corRampa (a mesma rampa
   dos outros mapas do painel), então nada aqui fixa cor de dado — o CSS só
   cuida de forma, foco e legibilidade do texto sobre o preenchimento.
   -------------------------------------------------------------------------- */

.rfm-caixa { overflow-x: auto; padding-bottom: 4px; }

.rfm-matriz {
    border-collapse: separate;
    border-spacing: 4px;
    min-width: 640px;
    margin: 0 auto;
}

.rfm-eixo-x {
    caption-side: top;
    padding-bottom: 8px;
    font-size: .72rem;
    letter-spacing: .06em;
    text-transform: uppercase;
    font-weight: 600;
    color: var(--tinta-3);
    text-align: center;
}
.rfm-eixo-y {
    margin: 6px 0 0;
    font-size: .72rem;
    letter-spacing: .06em;
    text-transform: uppercase;
    font-weight: 600;
    color: var(--tinta-3);
}

.rfm-matriz th {
    font-size: .78rem;
    font-weight: 600;
    color: var(--tinta-2);
    padding: 0;
}
.rfm-matriz thead th { vertical-align: bottom; padding-bottom: 4px; }
.rfm-matriz tbody th { text-align: right; padding-right: 10px; white-space: nowrap; }
.rfm-matriz th span {
    display: block;
    font-size: .68rem;
    font-weight: 400;
    color: var(--tinta-3);
}
.rfm-canto { width: 1px; }

.rfm-cel {
    width: 116px;
    height: 74px;
    border-radius: 10px;
    padding: 0;
    position: relative;
}
.rfm-cel a {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 1px;
    width: 100%;
    height: 100%;
    border-radius: inherit;
    text-decoration: none;
    color: var(--tinta);
    transition: transform .1s ease;
}
.rfm-cel a:hover { transform: scale(1.05); }
.rfm-cel a:focus-visible { outline: 2px solid var(--tinta); outline-offset: 1px; }
.rfm-cel b {
    font-size: 1.06rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    line-height: 1.15;
}
.rfm-cel span {
    font-size: .68rem;
    font-variant-numeric: tabular-nums;
    opacity: .78;
}

/* O contador de recorrentes: fica no canto porque é uma terceira informação
   na mesma célula, e competir com o número principal a tornaria ilegível. */
.rfm-rec {
    position: absolute;
    top: 4px;
    right: 6px;
    font-size: .62rem;
    font-style: normal;
    font-weight: 700;
    opacity: .6;
    font-variant-numeric: tabular-nums;
}

/* Nos dois degraus mais escuros da rampa o marrom do texto some no fundo. */
.rfm-escura a, .rfm-escura .rfm-rec { color: var(--branco); }

.rfm-ativa { box-shadow: 0 0 0 3px var(--tinta); }
.rfm-vazia { background: var(--fundo-2); border-radius: 10px; }

.rfm-seg {
    color: var(--tinta);
    text-decoration: none;
    font-weight: 600;
    border-bottom: 1px solid transparent;
}
.rfm-seg:hover { border-bottom-color: var(--rosa-escuro); }
.rfm-seg.ativo { color: var(--rosa-texto); border-bottom-color: var(--rosa-escuro); }

.rfm-limpar { margin: 0 0 12px; font-size: .84rem; }
.rfm-limpar a { color: var(--rosa-texto); text-decoration: none; font-weight: 600; }
.rfm-limpar a:hover { text-decoration: underline; }

.barra-mini {
    display: block;
    height: 8px;
    border-radius: 0 4px 4px 0;
    margin-bottom: 3px;
    min-width: 2px;
}

/* -------------------------------------------------- detalhe expandido do cliente */

.det-cliente {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 24px;
}
.det-bloco h4 {
    margin: 0 0 8px;
    font-size: .74rem;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--tinta-3);
    font-weight: 600;
}
.det-tab {
    width: 100%;
    border-collapse: collapse;
    font-size: .84rem;
}
.det-tab th {
    text-align: left;
    font-weight: 600;
    font-size: .7rem;
    text-transform: uppercase;
    letter-spacing: .05em;
    color: var(--tinta-3);
    padding: 0 8px 5px 0;
    border-bottom: 1px solid var(--borda);
}
.det-tab td {
    padding: 5px 8px 5px 0;
    border-bottom: 1px solid var(--linha);
}
.det-tab tr:last-child td { border-bottom: 0; }
.det-tab .num { text-align: right; font-variant-numeric: tabular-nums; padding-right: 0; }

.det-fatos {
    display: flex;
    flex-wrap: wrap;
    gap: 10px 22px;
    margin: 14px 0 0;
    padding-top: 12px;
    border-top: 1px solid var(--borda);
}
.det-fatos div { display: flex; flex-direction: column; gap: 1px; }
.det-fatos dt {
    font-size: .68rem;
    text-transform: uppercase;
    letter-spacing: .05em;
    color: var(--tinta-3);
    font-weight: 600;
}
.det-fatos dd {
    margin: 0;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

@media (max-width: 760px) {
    .det-cliente { grid-template-columns: 1fr; gap: 18px; }
}

/* O quadradinho que amarra a linha da tabela ao bloco do mapa de segmentos:
   mesma cor, mesmo grupo. Sem ele as duas leituras ficam soltas uma da outra. */
.rfm-ponto {
    display: inline-block;
    width: 9px;
    height: 9px;
    border-radius: 3px;
    margin-right: 7px;
    vertical-align: baseline;
}

/* Alvo de âncora. Sem a margem o navegador encosta o elemento no topo absoluto
   da janela e o título do painel fica colado na borda, parecendo cortado. */
.ancora {
    display: block;
    height: 0;
    scroll-margin-top: 18px;
}

/* ==========================================================================
   Pódio dos campeões — tela Produtos
   ==========================================================================
   Seis cards com foto. O primeiro ocupa duas colunas porque a distância entre
   o campeão e o segundo colocado nesta loja é grande, e dar a ele o mesmo
   retângulo dos outros achataria justamente o que a tela quer mostrar.
   -------------------------------------------------------------------------- */

/* Quatro colunas FIXAS, e sete produtos, porque as duas coisas se encaixam: o
   primeiro ocupa duas colunas e os outros seis ocupam uma, o que dá 8 células —
   exatamente duas linhas cheias. Com `auto-fill` a contagem de colunas mudava
   com a largura e sobrava um card sozinho numa linha vazia. Os degraus vão de 4
   para 2 direto: em 3 colunas as 8 células deixariam um buraco de novo. */
.podio {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 14px;
}
@media (max-width: 1000px) { .podio { grid-template-columns: repeat(2, 1fr); } }

.podio-card {
    display: flex;
    flex-direction: column;
    background: var(--branco);
    border: 1px solid var(--borda);
    border-radius: 14px;
    overflow: hidden;
    transition: box-shadow .14s ease, transform .14s ease;
}
.podio-card:hover { box-shadow: var(--sombra-card); transform: translateY(-2px); }

/* O campeão ocupa 2 colunas POR 2 LINHAS. Ocupando só duas colunas numa linha
   ele ditava a altura da linha inteira, e os cards ao lado ganhavam um vão
   morto de 200px embaixo do texto. Espalhado por duas linhas, a altura dele é a
   soma de duas linhas normais e ninguém estica à toa. São 9 produtos porque é a
   conta que fecha: 4 colunas × 3 linhas = 12 células, o campeão toma 4 e os
   outros 8 tomam uma cada. */
.podio-primeiro { grid-column: span 2; grid-row: span 2; }
/* Sem proporção fixa aqui: a foto do campeão é quem absorve a altura das duas
   linhas, então ela cresce com o card em vez de recortar. */
.podio-primeiro .podio-foto { aspect-ratio: auto; flex: 1; min-height: 240px; }
/* Só a FOTO cresce. Com `flex: 1` também no corpo, os dois dividiam a sobra das
   duas linhas e o texto ficava boiando no meio de um vão. O corpo passa a ter a
   altura do seu conteúdo e a foto absorve o resto. */
.podio-primeiro .podio-corpo { flex: none; }

@media (max-width: 1000px) {
    .podio-primeiro { grid-row: span 1; }
    .podio-primeiro .podio-foto { aspect-ratio: 4 / 3; flex: none; }
}
@media (max-width: 560px) {
    .podio { grid-template-columns: 1fr; }
    .podio-primeiro { grid-column: span 1; }
}

/* `contain` e não `cover`: o catálogo é de quadro e pôster, quase tudo em
   retrato. Recortado para caber num retângulo deitado, o primeiro colocado
   aparecia com metade da arte cortada — numa loja que vende a imagem, esconder
   a imagem é o oposto do que o painel deve fazer. O fundo neutro faz as sobras
   laterais parecerem moldura, e não falha. */
.podio-foto {
    position: relative;
    aspect-ratio: 4 / 3;
    background: var(--fundo-2);
    border-bottom: 1px solid var(--linha);
    overflow: hidden;
}
.podio-foto img {
    width: 100%; height: 100%;
    object-fit: contain;
    padding: 10px;
    display: block;
}
.podio-semfoto {
    display: grid; place-items: center;
    width: 100%; height: 100%;
    font-family: var(--fonte-titulo);
    font-size: 2.2rem;
    color: var(--branco);
}
/* O número da posição sobre a foto. O fundo escuro semitransparente existe
   porque a foto é do cliente e pode ser clara, escura ou listrada — sem ele o
   "1" some em metade dos produtos. */
.podio-posicao {
    position: absolute; top: 8px; left: 8px;
    display: grid; place-items: center;
    min-width: 26px; height: 26px;
    padding: 0 7px;
    border-radius: 99px;
    background: rgba(26, 16, 10, .62);
    backdrop-filter: blur(3px);
    color: var(--branco);
    font-size: .8rem; font-weight: 700;
    font-variant-numeric: tabular-nums;
}

.podio-corpo {
    display: flex; flex-direction: column; gap: 5px;
    padding: 12px 14px 14px;
    flex: 1;
}
.podio-corpo h4 {
    margin: 0;
    font-size: .88rem; font-weight: 600; line-height: 1.3;
    color: var(--tinta);
}
.podio-primeiro .podio-corpo h4 { font-size: 1.02rem; }
.podio-valor {
    font-family: var(--fonte-titulo);
    font-size: 1.24rem; letter-spacing: -.01em;
    color: var(--tinta);
    font-variant-numeric: tabular-nums;
}
.podio-primeiro .podio-valor { font-size: 1.62rem; }
.podio-linha {
    display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
}
.podio-barra {
    height: 5px; border-radius: 99px;
    background: var(--linha);
    overflow: hidden;
    margin-top: 3px;
}
.podio-barra span {
    display: block; height: 100%;
    background: var(--rosa);
    border-radius: 99px;
}
.podio-primeiro .podio-barra span { background: var(--rosa-escuro); }

/* ---------------------------------------- listas com foto (Produtos)

   Duas listas, mesma peça de foto: "A porta de entrada" (um produto por linha)
   e "Levam junto" (dois produtos por linha). A miniatura é quadrada e recortada
   por object-fit porque as fotos da loja têm proporções diferentes entre si —
   sem o recorte, as linhas ficariam com alturas distintas. */

/* A .mini cuida da foto; a .mini-vazia recebe o tamanho aqui porque ela não
   tem width/height inline como a <img> tem. */
.lista-foto .mini-vazia { width: 46px; height: 46px; }
.lista-par  .mini-vazia { width: 40px; height: 40px; }

.lista-foto, .lista-par { list-style: none; margin: 0; padding: 0; }

.lista-foto li {
    display: flex; align-items: center; gap: 12px;
    padding: 9px 0;
    border-bottom: 1px solid var(--linha);
}
.lista-foto li:last-child { border-bottom: 0; }
.lf-corpo { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 6px; }
.lf-corpo b {
    font-size: .88rem; font-weight: 600; color: var(--tinta);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.lf-barra { display: block; height: 6px; border-radius: 99px; background: var(--linha); overflow: hidden; }
.lf-barra span { display: block; height: 100%; border-radius: 99px; }
.lf-valor {
    flex: none; text-align: right;
    font-weight: 700; font-size: 1.02rem;
    font-variant-numeric: tabular-nums;
    display: flex; flex-direction: column; line-height: 1.2;
}
.lf-valor .aux { font-weight: 400; font-size: .68rem; }

.lista-par li {
    display: flex; align-items: center; gap: 10px;
    padding: 9px 0;
    border-bottom: 1px solid var(--linha);
}
.lista-par li:last-child { border-bottom: 0; }
.lp-item { display: flex; align-items: center; gap: 9px; flex: 1; min-width: 0; }
.lp-item b {
    font-size: .84rem; font-weight: 600; color: var(--tinta);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.lp-mais { flex: none; color: var(--tinta-3); font-weight: 700; font-size: 1.05rem; }
.lp-conta {
    flex: none; text-align: right;
    font-weight: 700; font-size: 1.02rem;
    font-variant-numeric: tabular-nums;
    display: flex; flex-direction: column; line-height: 1.2;
}
.lp-conta .aux { font-weight: 400; font-size: .68rem; }

@media (max-width: 620px) {
    .lista-par li { flex-wrap: wrap; }
    .lp-item { flex: 1 1 100%; }
    .lp-mais { display: none; }
    .lp-conta { margin-left: auto; }
}

/* Chips das tabelas de palavra e termo (tela Mídia, aba Google).
   Tom de fundo baixo de propósito: são etiquetas de contexto ao lado do dado,
   não o dado. Chip forte aqui competiria com os números da própria linha. */
.chip-corresp, .chip-situacao {
    display: inline-block;
    padding: .12rem .5rem;
    border-radius: 99px;
    font-size: .7rem;
    font-weight: 600;
    white-space: nowrap;
    background: var(--fundo-2);
    color: var(--tinta-2);
    border: 1px solid var(--borda);
}
/* "Solto" é o único que pede atenção: é o termo sobre o qual ninguém decidiu
   nada ainda, e é onde mora a ação. Os outros dois são assunto encerrado. */
.chip-situacao.sit-none     { background: var(--rosa-lavado); color: var(--rosa-texto);
                              border-color: var(--rosa); }
.chip-situacao.sit-excluded { opacity: .62; }
