/* Placar Vivo — folha única.
 *
 * Tokens vêm do DESIGN.md da Oficina das Tintas. Os seis que a empresa pode
 * trocar (`--pv-primary`, `--pv-secondary`, `--pv-header`, `--pv-cta`,
 * `--pv-surface`, `--pv-ink`) chegam por `style` no <html>, escritos por
 * `TenantTheme.as_css_variables`. Os valores aqui são o fallback: uma empresa sem
 * tema salvo abre legível em vez de abrir sem cor.
 *
 * Poppins não é carregada de CDN de propósito. A TV da loja fica numa rede que
 * cai, e uma tela de vendas não pode depender do Google para ter tipografia. Os
 * arquivos moram em `static/web/fonts/` e são servidos pelo próprio app; a
 * declaração está logo abaixo dos tokens, na seção "fonte".
 *
 * Ordem do arquivo: tokens, fonte, reset, contenção, tipografia, shell, primitivos,
 * componentes de dado, TV, viewports. Mobile é o caso base; `min-width` é o
 * acréscimo. A folha nunca esconde no celular o que desenhou para o desktop.
 */

/* ---------------------------------------------------------------- tokens */

:root {
  --pv-primary: #1a3560;
  --pv-secondary: #f9be06;
  --pv-header: #1a3560;
  --pv-cta: #f9be06;
  --pv-surface: #f5f6fa;
  --pv-ink: #131523;

  --pv-white: #ffffff;
  --pv-border: #e6e9f4;
  --pv-muted: #5a607f;
  --pv-positive: #00700a;
  --pv-negative: #c40f27;
  --pv-warning: #8a5a00;
  --pv-warning-bg: #fff6e0;

  /* Derivados de marca. Existem para o gradiente de fundo e para os degraus do
   * mapa de calor não dependerem de hex solto no meio da folha. */
  --pv-primary-08: rgba(26, 53, 96, 0.08);
  --pv-primary-12: rgba(26, 53, 96, 0.12);
  --pv-primary-24: rgba(26, 53, 96, 0.24);
  --pv-secondary-10: rgba(249, 190, 6, 0.10);

  --pv-font: "Poppins", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;

  /* Escala tipográfica.
   *
   * O corpo fica em 16px e não nos 14px do protótipo: campo abaixo de 16px faz o
   * Safari do iPhone dar zoom sozinho no foco, e o anexo §11.12 exige 200% de
   * zoom sem perda. A densidade do protótipo vem de outro lugar, e é esse outro
   * lugar que a escala abaixo reproduz: rótulo miúdo em caixa alta, numeral
   * tabular com tracking apertado, texto de apoio em 13px. */
  --pv-t-micro: 0.6875rem;   /* 11px — rótulo de KPI, caixa alta */
  --pv-t-apoio: 0.8125rem;   /* 13px — contexto, legenda, intervalo */
  --pv-t-corpo: 0.9375rem;   /* 15px — tabela, botão, chip */
  --pv-t-base: 1rem;         /* 16px — corpo e campo */
  --pv-t-titulo: 1.0625rem;  /* 17px — h2 de card */
  --pv-t-tela: 1.375rem;     /* 22px — h1 */

  --pv-radius: 18px;
  --pv-radius-sm: 10px;
  --pv-pill: 999px;

  /* Elevação em duas camadas: a rasa desenha a borda ótica, a funda dá o
   * assentamento. Uma sombra só, larga, borra a beirada do card. */
  --pv-shadow: 0 1px 2px rgba(19, 21, 35, 0.05), 0 10px 30px rgba(12, 22, 40, 0.07);
  --pv-shadow-alta: 0 1px 2px rgba(19, 21, 35, 0.06), 0 18px 44px rgba(12, 22, 40, 0.12);
  --pv-shadow-topo: 0 8px 28px rgba(12, 22, 40, 0.22);

  --pv-1: 4px;
  --pv-2: 8px;
  --pv-3: 12px;
  --pv-4: 16px;
  --pv-5: 24px;
  --pv-6: 32px;
  --pv-7: 48px;

  --pv-largura: 1280px;
  /* Recorte do iPhone. Sem isto o rodapé do conteúdo fica embaixo da barra de
   * gestos e o último card parece cortado. */
  --pv-safe-b: env(safe-area-inset-bottom, 0px);

  /* Camada neutra.
   *
   * Os seis tokens de marca (`--pv-primary`, `--pv-secondary`, `--pv-header`,
   * `--pv-cta`, `--pv-surface`, `--pv-ink`) chegam por `style` no <html>, escritos
   * por `TenantTheme.as_css_variables`. Estilo inline ganha de qualquer folha,
   * então NÃO dá para trocá-los numa media query: a pele escura precisa de nomes
   * próprios.
   *
   * É para isso que servem os cinco abaixo. No claro eles apontam para a marca;
   * no escuro são recalculados a partir dela, e é por isso que o azul da Oficina
   * continua tingindo o fundo à noite em vez de virar cinza genérico. Toda
   * superfície e todo texto da folha falam com estes nomes, nunca com os seis. */
  --pv-fundo: var(--pv-surface);
  --pv-superficie: var(--pv-white);
  --pv-superficie-alta: var(--pv-white);
  --pv-texto: var(--pv-ink);
  --pv-linha: var(--pv-border);
  /* Fio de luz na beirada de cima do card. No claro é branco puro sobre a
   * superfície branca (o que desenha a borda ótica do vidro); no escuro é o
   * mesmo gesto invertido, um brilho fraco, senão vira contorno branco. */
  --pv-linha-vidro: rgba(255, 255, 255, 0.7);

  /* Véus.
   *
   * `--pv-primary-08/12/24` e `--pv-secondary-10` TAMBÉM chegam inline pelo tema
   * (`TenantTheme.as_css_variables` deriva os alphas da primária), então eles
   * caem na mesma armadilha dos seis: media query não os alcança. Estes quatro
   * aliases existem só para isso. No claro são véus de azul sobre branco; no
   * escuro viram véus de luz sobre azul-noite, senão hairline e hover somem.
   * Regra: hairline, hover e trilha de barra falam com `--pv-veu-*`. */
  /* A primária da marca é uma cor feita para ler SOBRE BRANCO. Usada como
   * `color:` sobre a superfície escura ela some (foi o que aconteceu com os
   * totais, os acumulados e os valores por vendedor na primeira pele escura).
   * Este token é a mesma marca, clareada o quanto for preciso para continuar
   * legível. Regra: fundo e traço falam com `--pv-primary`; texto fala com
   * `--pv-marca-texto`. */
  --pv-marca-texto: var(--pv-primary);

  /* Lavagem do fundo da página. Tokens próprios e não os véus: no claro os véus
   * são tinta de marca sobre branco e escurecem de leve, que é o efeito certo;
   * no escuro eles são luz sobre azul-noite e CLAREAVAM a página acima da
   * superfície dos cards, invertendo a hierarquia (a tela de login ficava com o
   * fundo mais claro que o próprio formulário). */
  --pv-lavagem-1: var(--pv-primary-12);
  --pv-lavagem-2: var(--pv-secondary-10);

  /* Rampa do mapa de calor, cinco passos.
   *
   * Vive em token porque a célula e a legenda precisam da MESMA cor, e antes a
   * legenda repetia os hex à mão dentro de `calor.html`: duas listas para manter
   * em sincronia, que é como uma delas fica para trás.
   *
   * No claro a intensidade cresce escurecendo (branco → navy da marca), que é a
   * leitura natural sobre papel. No escuro isso não pode ser reaproveitado: com a
   * rampa clara sobre fundo escuro, "sem venda" ficava navy e "máximo" ficava
   * navy também, quase a mesma cor, e um dia recordista lia igual a um dia
   * parado. A versão escura inverte o sentido e cresce clareando. */
  --pv-calor-0: #ffffff;
  --pv-calor-1: #dbe6f4;
  --pv-calor-2: #a8c4e4;
  --pv-calor-3: #587ba9;
  --pv-calor-4: var(--pv-primary);
  --pv-calor-txt-0: var(--pv-ink);
  --pv-calor-txt-1: var(--pv-ink);
  --pv-calor-txt-2: var(--pv-ink);
  --pv-calor-txt-3: #ffffff;
  --pv-calor-txt-4: #ffffff;

  --pv-veu-08: var(--pv-primary-08);
  --pv-veu-12: var(--pv-primary-12);
  --pv-veu-24: var(--pv-primary-24);
  --pv-brilho-10: var(--pv-secondary-10);
}

/* A pele escura. Só redefine tokens; nenhuma regra de layout muda de lugar.
 *
 * Aqui não entram os seis da marca (ver acima) nem `--pv-white`, que continua
 * sendo branco de verdade: ele é a cor do texto sobre o cabeçalho e sobre a TV,
 * e essas duas superfícies são escuras nos dois modos.
 *
 * Positivo, negativo e alerta trocam de valor porque o par que passa em contraste
 * sobre branco (#00700a, #c40f27) some sobre um fundo #0e1320. */
@media (prefers-color-scheme: dark) {
  :root {
    color-scheme: dark;

    --pv-fundo: color-mix(in srgb, var(--pv-primary) 14%, #080b12);
    --pv-superficie: color-mix(in srgb, var(--pv-primary) 20%, #0d1220);
    --pv-texto: #eef1f8;
    --pv-linha: color-mix(in srgb, var(--pv-primary) 38%, #1b2233);

    --pv-muted: #9aa4bf;
    --pv-border: color-mix(in srgb, var(--pv-primary) 38%, #1b2233);
    --pv-positive: #4ade80;
    --pv-negative: #ff7085;
    --pv-warning: #fbbf24;
    --pv-warning-bg: rgba(251, 191, 36, 0.14);

    --pv-marca-texto: color-mix(in srgb, var(--pv-primary) 22%, #ffffff);

    /* No escuro a lavagem afunda em vez de levantar: o fundo da página fica
     * ABAIXO da superfície, e o card volta a ser a coisa mais clara da tela. */
    --pv-lavagem-1: rgba(0, 0, 0, 0.30);
    --pv-lavagem-2: rgba(249, 190, 6, 0.05);

    /* Cresce clareando. Ver a nota na rampa clara. */
    --pv-calor-0: color-mix(in srgb, var(--pv-primary) 18%, #0d1220);
    --pv-calor-1: color-mix(in srgb, var(--pv-primary) 72%, #0d1220);
    --pv-calor-2: #3a5f96;
    --pv-calor-3: #7d9fd0;
    --pv-calor-4: #cfe0f7;
    --pv-calor-txt-0: #eef1f8;
    --pv-calor-txt-1: #eef1f8;
    --pv-calor-txt-2: #eef1f8;
    --pv-calor-txt-3: #101725;
    --pv-calor-txt-4: #101725;

    --pv-veu-08: rgba(255, 255, 255, 0.06);
    --pv-veu-12: rgba(255, 255, 255, 0.10);
    --pv-veu-24: rgba(255, 255, 255, 0.20);
    --pv-brilho-10: rgba(249, 190, 6, 0.14);

    --pv-shadow: 0 1px 2px rgba(0, 0, 0, 0.45), 0 10px 30px rgba(0, 0, 0, 0.38);
    --pv-shadow-alta: 0 1px 2px rgba(0, 0, 0, 0.5), 0 18px 44px rgba(0, 0, 0, 0.5);
    --pv-linha-vidro: rgba(255, 255, 255, 0.07);

    /* Um degrau acima de `--pv-superficie`, e um degrau largo: é ela que faz a
     * gaveta se descolar da página e a pastilha do segmentado se descolar do
     * trilho. Perto demais da superfície, a seleção some. */
    --pv-superficie-alta: color-mix(in srgb, var(--pv-primary) 34%, #1b2436);

    --pv-shadow-topo: 0 8px 28px rgba(0, 0, 0, 0.55);
  }
}


/* ------------------------------------------------------------------ fonte */

/* Poppins servida pelo próprio app, nunca por CDN.
 *
 * O motivo é o mesmo de sempre: a TV da loja fica numa rede que cai, e tela de
 * vendas não perde tipografia porque o Google não respondeu. O que muda em
 * relação a antes é que agora existe fallback de verdade: os arquivos estão em
 * `static/web/fonts/` e saem do mesmo host do resto.
 *
 * `local()` vem primeiro de propósito. Quem já tem Poppins instalada (a máquina
 * de design, o Mac do escritório) não baixa nada; o download é o caminho de quem
 * não tem, que é o celular do balcão e a TV.
 *
 * Só 400/500/600, que são os pesos que o DESIGN.md declara, e só os subsets
 * latin e latin-ext. Devanagari é metade do peso da família e não desenha uma
 * letra desta tela. Licença em `fonts/OFL.txt`, ao lado dos arquivos. */
@font-face {
  font-family: "Poppins";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: local("Poppins Regular"), local("Poppins"),
       url("../fonts/poppins-400-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
                 U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Poppins";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: local("Poppins Regular"), local("Poppins"),
       url("../fonts/poppins-400-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
                 U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF,
                 U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Poppins";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: local("Poppins Medium"),
       url("../fonts/poppins-500-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
                 U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Poppins";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: local("Poppins Medium"),
       url("../fonts/poppins-500-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
                 U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF,
                 U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Poppins";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: local("Poppins SemiBold"),
       url("../fonts/poppins-600-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
                 U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Poppins";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: local("Poppins SemiBold"),
       url("../fonts/poppins-600-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
                 U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF,
                 U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ----------------------------------------------------------------- reset */

*,
*::before,
*::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  /* Contenção de largura na raiz. `clip` e não `hidden`: `hidden` cria contexto
   * de scroll e quebra `position: sticky` do cabeçalho. */
  overflow-x: clip;
}

body {
  margin: 0;
  font-family: var(--pv-font);
  font-size: var(--pv-t-base);
  line-height: 1.5;
  color: var(--pv-texto);
  overflow-x: clip;
  min-height: 100dvh;
  padding-bottom: var(--pv-safe-b);
  /* Fundo de marca em vez de cinza chapado: quatro manchas radiais fracas nas
   * cores da logo sobre a surface do tema. Custa uma pintura, não anima, e é o
   * que separa "painel" de "formulário" antes de qualquer card aparecer. */
  background:
    radial-gradient(1100px 520px at 8% -8%, var(--pv-lavagem-1), transparent 55%),
    radial-gradient(820px 440px at 96% 2%, var(--pv-lavagem-2), transparent 50%),
    var(--pv-fundo);
  background-attachment: fixed;
}

/* Todo descendente de grid e de flex nasce com `min-width: auto`, o que faz uma
 * tabela larga empurrar a coluna e vazar a página inteira. Esta é a regra que
 * impede o gráfico e a tabela de estourarem o 390px; as caixas de scroll abaixo
 * dependem dela para funcionar. */
.grid > *,
.conteudo > *,
.card > *,

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

h1, h2, h3 { margin: 0; font-weight: 600; line-height: 1.25; letter-spacing: -0.015em; }
h1 { font-size: var(--pv-t-tela); }
h2 { font-size: var(--pv-t-titulo); color: var(--pv-marca-texto); }
h3 { font-size: var(--pv-t-corpo); }
p { margin: 0 0 var(--pv-3); }

/* Marca como texto, não a marca: sobre a superfície escura o navy da logo é
 * quase o próprio fundo, e a lista de vendedores virava um bloco de links
 * invisíveis. Ver `--pv-marca-texto` no bloco de tokens. */
a { color: var(--pv-marca-texto); }

/* Rótulo miúdo em caixa alta. É o elemento que dá densidade de painel sem mexer
 * no tamanho do texto corrido. */
.rotulo {
  display: block;
  font-size: var(--pv-t-micro);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--pv-muted);
}

.intervalo,
.contexto { font-size: var(--pv-t-apoio); color: var(--pv-muted); }

/* Todo número que a pessoa compara com o de cima usa largura fixa de dígito. Sem
 * isto a coluna de dinheiro dança a cada atualização do poll. */
.numero,
.valor,
td.numero,
th.numero,
.serie,
.calor { font-variant-numeric: tabular-nums; }

/* Foco sempre visível, inclusive por teclado em elemento clicável (WCAG 2.4.7). */
:focus-visible {
  outline: 3px solid var(--pv-primary);
  outline-offset: 2px;
  border-radius: var(--pv-radius-sm);
}

.pular-para-conteudo {
  position: absolute;
  left: -9999px;
  top: var(--pv-2);
  padding: var(--pv-2) var(--pv-4);
  background: var(--pv-superficie);
  border-radius: var(--pv-radius-sm);
  z-index: 100;
}
.pular-para-conteudo:focus { left: var(--pv-2); }

.sr {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* ---------------------------------------------------------------- shell */

/* Cabeçalho fixo no topo. Numa tela que atualiza sozinha a cada cinco minutos, a
 * marca da empresa e o estado do contexto precisam continuar à vista depois do
 * scroll: é por eles que a pessoa sabe de qual loja é o número que está lendo. */
.shell-topo {
  position: sticky;
  top: 0;
  z-index: 40;
  color: var(--pv-white);
  /* Gradiente derivado do token da empresa, e não de hex solto.
   *
   * Era `rgba(15,30,55,.96) → var(--pv-header) → rgba(0,106,117,.92)`. Os dois
   * extremos eram cor da Oficina escrita à mão no meio da folha: o teal do fim
   * é o `#006A75` do site dela. Numa empresa de marca vermelha o cabeçalho
   * terminava em teal, e ninguém ia entender por quê.
   *
   * Agora as três paradas saem de `--pv-header`: escurecida na esquerda,
   * limpa no meio, e um passo em direção ao preto na direita. O fim ficou
   * bem mais escuro de propósito: a versão anterior clareava para o teal e
   * destoava da página, que é escura. Cabeçalho é moldura, não destaque. */
  background:
    linear-gradient(
      135deg,
      color-mix(in oklab, var(--pv-header) 78%, #05070d) 0%,
      var(--pv-header) 52%,
      color-mix(in oklab, var(--pv-header) 62%, #05070d) 100%
    ),
    var(--pv-header);
  backdrop-filter: blur(14px) saturate(1.2);
  -webkit-backdrop-filter: blur(14px) saturate(1.2);
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
  box-shadow: var(--pv-shadow-topo);
}

.shell-barra {
  display: flex;
  align-items: center;
  gap: var(--pv-3);
  max-width: var(--pv-largura);
  margin: 0 auto;
  padding: var(--pv-3) var(--pv-4);
}

/* Data e frescor na barra do topo, à direita do nome da empresa.
 *
 * 11px, e não a escala de apoio: é o tamanho que a JM usa e é o certo para
 * metadado que fica sempre na tela. O rótulo "sinc." é mais apagado que o
 * horário de propósito: quem lê rápido quer o número, não a palavra.
 *
 * `tabular-nums` porque o horário muda a cada sincronização e sem largura fixa
 * de dígito a barra inteira treme quando 20:52 vira 21:07. */
.shell-contexto {
  display: none;
  align-items: baseline;
  gap: var(--pv-3);
  /* Último filho da barra e sem `margin-left: auto`: `.shell-marca` tem
   * `flex: 1 1 auto` e come a folga antes, então a margem automática não
   * empurrava nada. A primeira tentativa deixou a data entre o nome da empresa e
   * a navegação, que é o pior lugar possível para metadado. */
  order: 99;
  font-size: var(--pv-t-micro);
  color: rgba(255, 255, 255, 0.6);
  white-space: nowrap;
}
.shell-sinc { color: rgba(255, 255, 255, 0.85); font-variant-numeric: tabular-nums; }
.shell-sinc .rotulo { color: rgba(255, 255, 255, 0.4); }
@media (min-width: 640px) { .shell-contexto { display: flex; } }
/* 900px: a data por extenso sai antes do horário. Numa barra que já tem marca,
 * navegação e sair, "Quarta-feira, 19 de Agosto" é a primeira coisa dispensável;
 * o frescor não é. Mesma decisão da JM, que esconde a data em `sm`. */
@media (max-width: 899px) { .shell-data { display: none; } }
/* A barra de quem opera tem um item a mais, e alguma coisa tem que sair.
 *
 * Medido em 1280px: as seis seções somam 566px, o item de operador 164 com o fio
 * e a margem, o perfil 90 e o "Sair" 63 — 919px numa faixa onde sobram 843. O
 * "Sair" caía para uma segunda linha e o cabeçalho ia de 56px para 110px, que é
 * o dobro do que a faixa de operador antiga custava.
 *
 * Sai a data por extenso, que é a mesma coisa que já sai abaixo de 900px e pelo
 * mesmo motivo: numa barra cheia ela é a primeira dispensável. O frescor fica,
 * porque saber de quando é o número não é dispensável nunca.
 *
 * Só na barra de operador: quem é cliente não perde nada, porque para ele a
 * barra nunca esteve apertada. */
@media (max-width: 1439px) {
  .shell-barra:has(.operador) .shell-data { display: none; }
}

.shell-marca { display: flex; align-items: center; gap: var(--pv-3); min-width: 0; flex: 1 1 auto; }
.shell-marca img {
  height: 32px;
  width: auto;
  display: block;
  /* Branco literal, não superfície: o chip do logo fica sobre o cabeçalho, que é
   * escuro nos dois modos, e logo de cliente costuma ser tinta escura. */
  background: var(--pv-white);
  border-radius: var(--pv-radius-sm);
  padding: 4px 8px;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.18);
}
.shell-marca .identidade { min-width: 0; }
.shell-marca .nome {
  display: flex;
  align-items: center;
  gap: var(--pv-2);
  font-weight: 600;
  font-size: var(--pv-t-corpo);
}
/* As reticências são do nome, nunca da linha inteira: o marcador de operador vem
 * depois dele e não pode ser a parte cortada. */
.shell-marca .nome-texto {
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.shell-marca .loja { color: rgba(255, 255, 255, 0.72); font-size: var(--pv-t-apoio); }

/* Menu de 390px (anexo §4.1): botão nomeado que abre a navegação, em vez de cinco
 * pílulas quebrando em três linhas e comendo a primeira dobra.
 *
 * `popover` nativo: teclado, Esc, clique fora e camada de topo sem JavaScript. E,
 * ao contrário de `<details>`, o estado fechado é um `display: none` do próprio
 * navegador que o CSS aqui consegue sobrepor — que é como o mesmo painel vira a
 * barra de navegação do desktop sem duplicar markup. */
.shell-menu-botao {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  gap: var(--pv-2);
  min-height: 40px;
  padding: var(--pv-2) var(--pv-4);
  border-radius: var(--pv-pill);
  border: 1px solid rgba(255, 255, 255, 0.22);
  background: rgba(255, 255, 255, 0.10);
  color: var(--pv-white);
  font: inherit;
  font-size: var(--pv-t-corpo);
  font-weight: 500;
  cursor: pointer;
}
.shell-menu-botao:hover { background: rgba(255, 255, 255, 0.2); }

.shell-menu-painel {
  /* O padrão do `popover` é centralizado na tela. Aqui ele desce do botão. */
  position: fixed;
  inset: auto;
  top: calc(var(--pv-topo-b, 56px) + var(--pv-2));
  right: var(--pv-3);
  margin: 0;
  min-width: 15rem;
  max-width: min(20rem, calc(100vw - var(--pv-5)));
  padding: var(--pv-2);
  border: 0;
  border-radius: var(--pv-radius);
  background: var(--pv-superficie-alta);
  box-shadow: var(--pv-shadow-alta);
  color: var(--pv-texto);
}
.shell-menu-painel::backdrop { background: rgba(12, 22, 40, 0.28); }

/* Empilhada no painel de 390px; volta a ser barra de pílulas em `min-width: 640px`. */
.shell-nav { display: flex; flex-direction: column; gap: 2px; }
.shell-nav a {
  color: var(--pv-texto);
  text-decoration: none;
  padding: var(--pv-2) var(--pv-3);
  border-radius: var(--pv-radius-sm);
  font-size: var(--pv-t-corpo);
  min-height: 44px;
  display: flex;
  align-items: center;
}
.shell-nav a:hover { background: var(--pv-fundo); }
.shell-nav a[aria-current="page"] { background: var(--pv-primary); color: var(--pv-white); font-weight: 600; }
.shell-nav .separador { height: 1px; background: var(--pv-border); margin: var(--pv-1) var(--pv-2); }
.shell-nav form { margin: 0; }
.shell-nav form button { width: 100%; justify-content: flex-start; min-height: 44px; }

/* Marcador de modo operador.
 *
 * Sucessor da faixa que ocupava a largura toda acima do cabeçalho. Ela era ouro
 * chapado, 15px, controles de 36px: ~52px que o app gastava, antes de qualquer
 * número, para dizer QUEM está olhando. Numa tela que deveria parecer a do
 * cliente, era o contrário disso.
 *
 * O aviso continua necessário — operar a Empresa errada é o erro caro deste app
 * — mas o que ele precisa é ser PERCEBIDO, não gritar. Aqui ele é uma palavra de
 * 11px em caixa alta colada no nome da Empresa: quem lê o nome lê a palavra
 * junto, e ela custa zero altura porque cabe na linha que já existia.
 *
 * O ouro sobrou onde de fato marca: o fio de baixo, 2px, na cor de destaque da
 * marca. Sobre o cabeçalho, que é escuro nos dois temas, ele lê nos dois. */
.marca-operador {
  flex: 0 0 auto;
  padding: 1px 5px;
  border-radius: 4px;
  vertical-align: 1px;
  font-size: var(--pv-t-micro);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--pv-secondary);
  background: color-mix(in srgb, var(--pv-secondary) 16%, transparent);
  box-shadow: inset 0 -2px 0 color-mix(in srgb, var(--pv-secondary) 55%, transparent);
}

/* Itens de operador no menu: trocar de Empresa e ir para a plataforma. Ficam
 * abaixo do separador, com o perfil e o sair, porque não são seções do produto.
 * Apagados em relação aos outros de propósito — o operador sabe que estão ali, e
 * quem não é operador nunca os vê.
 */
.shell-nav .operador {
  font-size: var(--pv-t-apoio);
  color: var(--pv-muted);
  gap: var(--pv-2);
  flex-wrap: wrap;
}
.shell-nav .operador:hover { color: var(--pv-texto); }
/* ------------------------------------------------- escolha de Empresa */

/* Uma linha por Empresa, alvo cheio. É a tela que substituiu o `<select>` da
 * faixa: com oito clientes, abrir a lista, achar o nome, fechar e confirmar são
 * quatro gestos para uma escolha que aqui é um toque. */
.lista-empresas { list-style: none; margin: var(--pv-3) 0 0; padding: 0; display: grid; gap: var(--pv-2); }
.lista-empresas form { margin: 0; }
.btn-empresa {
  width: 100%;
  display: flex;
  align-items: center;
  gap: var(--pv-3);
  min-height: 52px;
  padding: var(--pv-2) var(--pv-4);
  border-radius: var(--pv-radius-sm);
  border: 1px solid var(--pv-linha);
  background: var(--pv-superficie);
  color: var(--pv-texto);
  font: inherit;
  font-size: var(--pv-t-base);
  text-align: left;
  cursor: pointer;
}
.btn-empresa:hover { background: var(--pv-veu-08); border-color: var(--pv-primary); }
.btn-empresa:focus-visible { outline: 2px solid var(--pv-primary); outline-offset: 2px; }
.btn-empresa .nome { flex: 1 1 auto; min-width: 0; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* A Empresa em uso não some da lista e não vira item morto: ela continua
 * clicável. Reabrir a mesma é um jeito legítimo de voltar para o cockpit dela. */
.btn-empresa[aria-current="true"] { border-color: var(--pv-primary); box-shadow: inset 3px 0 0 var(--pv-primary); }
.etiqueta-atual {
  flex: 0 0 auto;
  font-size: var(--pv-t-micro);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--pv-marca-texto);
}
.escolher-saidas { display: flex; flex-wrap: wrap; gap: var(--pv-2); margin: var(--pv-4) 0 0; }
.escolher-saidas form { margin: 0; }

.conteudo {
  max-width: var(--pv-largura);
  margin: 0 auto;
  padding: var(--pv-4) var(--pv-3) var(--pv-6);
  display: flex;
  flex-direction: column;
  gap: var(--pv-4);
}

.cabecalho-tela {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--pv-3);
  flex-wrap: wrap;
}
.cabecalho-tela h1 + .intervalo { margin: var(--pv-1) 0 0; }

/* ---------------------------------------------------------------- botões */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--pv-2);
  min-height: 36px;
  padding: var(--pv-2) var(--pv-4);
  border-radius: var(--pv-pill);
  border: 1px solid transparent;
  font: inherit;
  font-size: var(--pv-t-corpo);
  font-weight: 500;
  cursor: pointer;
  text-decoration: none;
  background: transparent;
  color: var(--pv-marca-texto);
  transition: background 0.15s ease, box-shadow 0.15s ease, filter 0.15s ease;
}

/* O CTA ouro é de um submit por formulário. Estilizar `button[type=submit]`
 * como primário faria toda ação de linha virar chamada de marketing (§9.8). */
.btn-primary {
  background: var(--pv-cta);
  color: var(--pv-primary);
  font-weight: 600;
  min-height: 44px;
  padding: var(--pv-3) var(--pv-6);
  box-shadow: 0 8px 20px rgba(249, 190, 6, 0.3);
  /* Largura total abaixo de 640 px (§10.2). É um submit por formulário, então
   * isto não transforma ação de linha em faixa amarela. */
  width: 100%;
}
.btn-primary:hover { filter: brightness(0.94); }

.btn-secondary { background: var(--pv-primary); color: var(--pv-white); }
.btn-secondary:hover { filter: brightness(1.15); }

.btn-danger { background: var(--pv-negative); color: var(--pv-white); }

.btn-ghost {
  border-color: var(--pv-border);
  background: var(--pv-superficie);
  border-radius: var(--pv-radius-sm);
}
.btn-ghost:hover { background: var(--pv-fundo); }

.actions { display: flex; gap: var(--pv-2); flex-wrap: wrap; align-items: center; }
.table-actions { display: flex; gap: var(--pv-2); flex-wrap: wrap; align-items: center; }

/* ---------------------------------------------------------------- pessoas */

/* A lista é só leitura. O cadastro abre num `<dialog>` (`.modal`), e é por isso
 * que o nome é link: é o alvo do clique e continua funcionando sem JavaScript,
 * caindo na página própria da edição. */
.filtros-pessoas {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--pv-2) var(--pv-3);
  margin-bottom: var(--pv-4);
}
.filtros-pessoas .campo { margin: 0; }
.contagem-pessoas { margin: 0 0 var(--pv-3); }
.linha-pessoa th a { font-weight: 600; color: inherit; text-decoration: underline; text-underline-offset: 3px; }
.pessoa-email { display: block; color: var(--pv-muted); font-size: var(--pv-t-apoio); font-weight: 400; }

.modal {
  padding: 0;
  border: 0;
  /* O reset global zera a margem, e `<dialog>` modal só centraliza com
   * `margin: auto`. Sem isto ele abre grudado no canto superior esquerdo. */
  margin: auto;
  border-radius: var(--pv-radius);
  width: min(520px, calc(100vw - 2 * var(--pv-4)));
  max-height: calc(100dvh - 2 * var(--pv-4));
  background: var(--pv-superficie-alta, var(--pv-superficie));
  color: var(--pv-texto);
  box-shadow: var(--pv-shadow-alta, 0 20px 50px rgba(6, 9, 18, 0.35));
  overflow: auto;
  overscroll-behavior: contain;
}
.modal:not([open]) { display: none; }
.modal::backdrop { background: color-mix(in srgb, #060912 62%, transparent); }
.modal-painel { padding: var(--pv-4); outline: none; }
.modal-h {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--pv-3);
  margin-bottom: var(--pv-4);
}
.modal-h h2 { margin: 0; }
.modal-h .intervalo { margin: var(--pv-1) 0 0; }
.pessoa-bloco + .pessoa-bloco {
  margin-top: var(--pv-5, var(--pv-4));
  padding-top: var(--pv-4);
  border-top: 1px solid var(--pv-border);
}
.pessoa-bloco h3 { margin: 0 0 var(--pv-3); font-size: 1rem; }
.pessoa-pagina .modal-painel { padding: 0; }

/* ---------------------------------------------------------------- cards */

.card {
  background: var(--pv-superficie);
  border: 1px solid var(--pv-linha-vidro);
  border-radius: var(--pv-radius);
  box-shadow: var(--pv-shadow);
  padding: var(--pv-4);
  /* O card contém o próprio conteúdo largo. Sem isto uma tabela de cinco colunas
   * atravessa a beirada arredondada e vaza para fora da página. */
  overflow: hidden;
}

/* Cabeçalho interno do card: título, subtítulo e ação no mesmo lugar em toda
 * tela. Antes cada card montava o seu, e a variação acidental entre eles era
 * visível de longe. */
.card-h {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--pv-3);
  flex-wrap: wrap;
  margin-bottom: var(--pv-3);
}
.card-h .sub { margin: var(--pv-1) 0 0; font-size: var(--pv-t-apoio); color: var(--pv-muted); }

.grid { display: grid; gap: var(--pv-3); }
/* Dois KPIs por linha já no celular. O anexo §10.2 permite quando o valor segue
 * legível, e é o que coloca os quatro números da manhã na primeira dobra.
 *
 * `auto-fit` e não `repeat(2, 1fr)` travado: com duas colunas fixas, o zoom de
 * 200% em 390 px reduz a viewport a ~195 px e cada card sobra com 47 px de
 * conteúdo. Como o valor é `nowrap` e o card tem `overflow: hidden`, o número
 * seria cortado em silêncio em vez de quebrar, e §11.12 exige 200% sem perda de
 * conteúdo. Com o piso de 150 px a grade cai sozinha para uma coluna antes disso
 * e continua com duas na largura normal do celular. */
.grid-kpis { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }
.grid-2 { grid-template-columns: minmax(0, 1fr); }

/* ---------------------------------------------------------------- KPI */

.kpi { display: flex; flex-direction: column; gap: var(--pv-1); }
/* O valor acompanha a largura da tela em vez de quebrar.
 *
 * Em dois por linha a coluna tem cerca de 145 px em 390 px, e `R$ 452.789,00` em
 * 24 px não cabe: quebrava depois do `R$` e o número virava duas coisas. O
 * `clamp` desce para cerca de 18 px no celular e volta aos 28 px no desktop, e o
 * `nowrap` garante que a escolha seja essa e não a quebra. */
.kpi .valor {
  font-size: clamp(1.125rem, 4.6vw, 1.5rem);
  font-weight: 600;
  line-height: 1.15;
  letter-spacing: -0.025em;
  color: var(--pv-marca-texto);
  white-space: nowrap;
}
.kpi .contexto { font-size: var(--pv-t-apoio); color: var(--pv-muted); }
.kpi .ausente { color: var(--pv-muted); font-weight: 500; }
/* KPI de destaque: o "Vendas hoje" no Placar e no Meu desempenho. Um degrau de
 * escala, não uma cor diferente. */
.kpi.destaque { grid-column: 1 / -1; }
/* O piso desce até 1,25rem porque em 200% de zoom sobre 390 px a coluna fica com
 * 137 px, e um piso de 1,875rem cortaria `R$ 10.601,41` dentro do card. Continua
 * sendo o maior número da tela em qualquer largura. */
.kpi.destaque .valor { font-size: clamp(1.25rem, 7vw, 2.5rem); }

.delta { display: inline-flex; align-items: center; gap: var(--pv-1); font-size: var(--pv-t-apoio); font-weight: 600; }
.delta.positiva { color: var(--pv-positive); }
.delta.negativa { color: var(--pv-negative); }
.delta.neutra { color: var(--pv-muted); }

/* ---------------------------------------------------------- sincronização */

/* Indicador de sincronização.
 *
 * Deixou de ser pílula. `border-radius: 999px` numa caixa que pode ter duas
 * linhas de texto ("Não foi possível atualizar agora. Exibindo os últimos dados
 * válidos de 20:52.") vira uma cápsula alongada com as pontas vazias. Pílula é
 * forma de rótulo curto, e isto é uma frase.
 *
 * O marcador (● ◐ ▲ ○) ganhou caixa própria. Com `align-items: center` num
 * texto que quebra, ele centralizava contra o bloco inteiro e ficava na altura
 * do meio das duas linhas, fora da linha da primeira. Agora: alinhamento pelo
 * topo, caixa de altura fixa igual à da primeira linha, e o glifo centrado
 * dentro dela. Vale porque os quatro glifos têm métricas diferentes entre si, e
 * centrar um círculo pelo baseline nunca ia bater com centrar um triângulo. */
.sincronizacao {
  display: flex;
  align-items: flex-start;
  gap: var(--pv-2);
  font-size: var(--pv-t-apoio);
  line-height: 1.45;
  padding: var(--pv-2) var(--pv-3);
  border-radius: var(--pv-radius-sm);
  background: var(--pv-superficie);
  border: 1px solid var(--pv-border);
  color: var(--pv-muted);
  width: fit-content;
  max-width: 100%;
}
.sincronizacao .marcador {
  font-weight: 700;
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1em;
  height: calc(var(--pv-t-apoio) * 1.45);
  line-height: 1;
}
.sincronizacao details { flex: 0 0 auto; }
.sincronizacao.problema {
  background: var(--pv-warning-bg);
  border-color: color-mix(in srgb, var(--pv-warning) 42%, transparent);
  color: var(--pv-warning);
}
.sincronizacao.vazio { color: var(--pv-muted); }

.aviso {
  display: flex;
  gap: var(--pv-3);
  align-items: flex-start;
  padding: var(--pv-3) var(--pv-4);
  border-radius: var(--pv-radius-sm);
  background: var(--pv-warning-bg);
  border: 1px solid color-mix(in srgb, var(--pv-warning) 42%, transparent);
  color: var(--pv-warning);
  font-size: var(--pv-t-corpo);
}
.aviso button { margin-left: auto; flex: 0 0 auto; }

/* ------------------------------------------------------------------ ajuda */

/* Explicação sob demanda. Discreta fechada, legível aberta. Ela não pode
 * competir com o número que explica: quem já sabe a resposta precisa conseguir
 * ignorar a linha inteira sem esforço. */
.ajuda { margin: var(--pv-2) 0 0; }
.ajuda > summary {
  display: inline-flex;
  align-items: center;
  gap: var(--pv-2);
  cursor: pointer;
  font-size: var(--pv-t-apoio);
  color: var(--pv-muted);
  list-style: none;
  padding: var(--pv-1) 0;
  /* Alvo de toque de 44px sem ocupar 44px de layout: o pseudo-elemento estica a
   * área clicável para cima e para baixo do texto. */
  position: relative;
}
.ajuda > summary::-webkit-details-marker { display: none; }
.ajuda > summary::after {
  content: "";
  position: absolute;
  inset: -10px -8px;
}
.ajuda > summary:hover { color: var(--pv-marca-texto); }
.ajuda-marca {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  border: 1px solid currentColor;
  font-size: 11px;
  font-weight: 700;
  flex: 0 0 auto;
}
.ajuda-corpo {
  margin-top: var(--pv-2);
  padding: var(--pv-3);
  border-radius: var(--pv-radius);
  background: var(--pv-veu-08);
  font-size: var(--pv-t-apoio);
  line-height: 1.55;
  color: var(--pv-texto);
  max-width: 62ch;
}
.ajuda-corpo p { margin: 0 0 var(--pv-2); }
.ajuda-corpo p:last-child { margin: 0; }
.ajuda-corpo strong { font-weight: 600; }

/* ---------------------------------------------------------------- período */

/* A barra de período gruda embaixo do cabeçalho. Ela é o controle que a pessoa
 * mais usa e o único que muda o significado de todo número abaixo dela. */
.periodo {
  flex-wrap: wrap;
  flex: 0 0 auto;
  height: auto;
  min-height: 0;
  align-content: start;
  position: sticky;
  /* Embaixo do cabeçalho, não atrás dele. A altura do topo varia (banner de
   * operador, nome de loja em duas linhas), então quem mede é o `app.js` e
   * escreve em `--pv-topo-h`. Sem JavaScript a barra ainda funciona: gruda em
   * zero e some sob o cabeçalho, que é o comportamento antigo. */
  top: var(--pv-topo-h, 0px);
  z-index: 30;
  display: flex;
  gap: var(--pv-2);
  align-items: center;
  padding: var(--pv-2);
  border-radius: var(--pv-pill);
  background: color-mix(in srgb, var(--pv-superficie) 86%, transparent);
  backdrop-filter: blur(12px) saturate(1.1);
  -webkit-backdrop-filter: blur(12px) saturate(1.1);
  border: 1px solid var(--pv-linha-vidro);
  box-shadow: var(--pv-shadow);
  /* A rolagem horizontal mora em `.periodo-rolagem`, não aqui. `overflow-x`
   * nesta caixa recortava o painel do intervalo, que abre por baixo dela. */
  /* Em 390 px a barra sangra até a beirada da tela em vez de flutuar como
   * pílula. Pílula grudada deixa o conteúdo aparecer nas laterais enquanto rola
   * por baixo, e o resultado é um mapa de calor meio visível atrás do filtro.
   * Faixa inteira cobre a largura e o problema não existe. A pílula volta em
   * `min-width: 640px`, onde há gutter de sobra. */
  margin: 0 calc(var(--pv-3) * -1);
  padding: var(--pv-2) var(--pv-3);
  border-radius: 0;
  border-left: 0;
  border-right: 0;
  background: var(--pv-superficie);
}
.periodo > * { flex: 0 0 auto; }

/* Os atalhos passam de 390px e quebrar em três linhas empurraria o primeiro KPI
 * para fora da dobra, então eles rolam de lado. `min-width: 0` é o que deixa o
 * flex item encolher abaixo do conteúdo; sem ele a caixa cresce e não rola. */
.periodo-rolagem {
  display: flex;
  align-items: center;
  gap: var(--pv-2);
  flex: 1 1 280px;
  min-width: 0;
  overflow-x: auto;
  scrollbar-width: none;
}
.periodo-rolagem::-webkit-scrollbar { display: none; }
.periodo-rolagem > * { flex: 0 0 auto; }

.periodo .chip {
  padding: var(--pv-2) var(--pv-3);
  border-radius: var(--pv-pill);
  border: 1px solid transparent;
  background: transparent;
  text-decoration: none;
  font-size: var(--pv-t-corpo);
  font-weight: 500;
  min-height: 36px;
  display: inline-flex;
  align-items: center;
  color: var(--pv-muted);
  white-space: nowrap;
  cursor: pointer;
}
.periodo .chip:hover { background: var(--pv-veu-08); color: var(--pv-marca-texto); }
.periodo .chip[aria-current="true"] {
  background: var(--pv-primary);
  color: var(--pv-white);
  font-weight: 600;
}
.periodo .seta { min-width: 36px; justify-content: center; }
.periodo .intervalo { white-space: nowrap; padding: 0 var(--pv-1); }
/* Contexto (visão da loja x meu desempenho) usa a mesma pílula, mas não é
 * navegação de período e não gruda no topo. */
.segmentado {
  display: flex;
  gap: var(--pv-1);
  padding: var(--pv-1);
  border-radius: var(--pv-pill);
  background: var(--pv-veu-08);
  /* Em 390px "Visão da loja | Meu desempenho" passa da largura do cabeçalho.
   * Rola dentro de si em vez de cortar o segundo rótulo na beirada. */
  max-width: 100%;
  overflow-x: auto;
  scrollbar-width: none;
}
.segmentado::-webkit-scrollbar { display: none; }
.segmentado > * { flex: 0 0 auto; }
.segmentado .chip {
  padding: var(--pv-2) var(--pv-3);
  border-radius: var(--pv-pill);
  font-size: var(--pv-t-corpo);
  font-weight: 500;
  min-height: 36px;
  display: inline-flex;
  align-items: center;
  text-decoration: none;
  color: var(--pv-marca-texto);
  white-space: nowrap;
}
/* O selecionado é uma pastilha sobre o trilho. No claro ela é branca sobre o véu
 * azul; no escuro precisa ser MAIS clara que o trilho, e `--pv-superficie` ali é
 * quase a mesma cor do trilho, o que apagava a seleção. */
.segmentado .chip[aria-current="true"] {
  background: var(--pv-superficie-alta);
  color: var(--pv-texto);
  font-weight: 600;
  box-shadow: var(--pv-shadow);
}

/* --------------------------------------------------------- caixa de scroll */

/* Gráfico e tabela largos rolam dentro da própria caixa, nunca na página. Sem
 * isto um intervalo customizado de noventa dias faz o documento inteiro rolar
 * para o lado, que é o que o anexo §10.1 proíbe.
 *
 * `overscroll-behavior-inline: contain` impede o gesto lateral de vazar para o
 * histórico do navegador quando chega no fim da caixa. */
.rolagem {
  overflow-x: auto;
  overscroll-behavior-inline: contain;
  -webkit-overflow-scrolling: touch;
}
.rolagem:focus-visible { outline-offset: 4px; }

/* ---------------------------------------------------------------- série */

.serie {
  display: flex;
  align-items: flex-end;
  gap: 2px;
  height: 160px;
  padding-top: var(--pv-4);
  /* Cada coluna tem largura mínima de toque. Abaixo disso a barra vira risco e
   * o alvo some; passando do que a caixa comporta, quem rola é `.rolagem`. */
  min-width: 100%;
}
/* A coluna é um `button`: o valor do dia precisa existir no toque e no teclado, e
 * não só no hover (§9.3, §10.2).
 *
 * A largura mínima é 8px e não os 24px do alvo mínimo do WCAG 2.5.8. A conta
 * manda: o padrão da tela é o mês corrente, e 31 dias a 24px pediriam 800px
 * dentro de uma caixa de ~334px, o que faria a visão default exigir arrastar para
 * o lado no celular. A 8px o mês inteiro cabe, e um intervalo customizado de
 * noventa dias continua estourando e rolando dentro da caixa, como projetado.
 *
 * A exceção de "equivalente" do 2.5.8 é o que autoriza: o mesmo dia tem célula de
 * 38px no mapa de calor logo abaixo e linha própria na tabela alternativa, e as
 * duas abrem exatamente o mesmo detalhe. */
.serie .col {
  flex: 1 0 8px;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  height: 100%;
  padding: 0;
  border: 0;
  background: transparent;
  font: inherit;
  cursor: pointer;
  border-radius: 3px;
}
.serie .col:hover .barra { filter: brightness(1.15); }
.serie .col:focus-visible { outline-offset: 1px; }
.serie .barra {
  display: block;
  width: 100%;
  background: linear-gradient(180deg, color-mix(in srgb, var(--pv-primary) 76%, white), var(--pv-primary));
  border-radius: 3px 3px 0 0;
  min-height: 2px;
}
.serie .col.aberto .barra {
  background: repeating-linear-gradient(
    45deg,
    var(--pv-primary),
    var(--pv-primary) 4px,
    color-mix(in srgb, var(--pv-primary) 66%, white) 4px,
    color-mix(in srgb, var(--pv-primary) 66%, white) 8px
  );
}
.serie .col.vazio .barra { background: var(--pv-border); min-height: 2px; }

.legenda {
  display: flex;
  gap: var(--pv-3);
  flex-wrap: wrap;
  font-size: var(--pv-t-apoio);
  color: var(--pv-muted);
  margin-top: var(--pv-3);
}
.legenda span { display: inline-flex; align-items: center; gap: var(--pv-1); }
.legenda i { width: 14px; height: 14px; border-radius: 3px; border: 1px solid var(--pv-border); display: inline-block; }

.tabela-alternativa { margin-top: var(--pv-4); }
.tabela-alternativa summary { cursor: pointer; font-size: var(--pv-t-apoio); color: var(--pv-muted); min-height: 36px; display: flex; align-items: center; }

/* ---------------------------------------------------------------- calor */

.calor { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: var(--pv-1); }
.calor .rotulo-dia {
  font-size: var(--pv-t-micro);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--pv-muted);
  text-align: center;
  padding-bottom: var(--pv-1);
}
.calor .celula {
  aspect-ratio: 1;
  min-height: 38px;
  border-radius: var(--pv-radius-sm);
  border: 1px solid var(--pv-border);
  background: var(--pv-superficie);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  color: var(--pv-texto);
  font: inherit;
  font-size: var(--pv-t-apoio);
  font-weight: 500;
}
/* O contorno de foco de 3px encostava na célula vizinha numa grade de 38px. Aqui
 * ele vira anel por sombra, que não ocupa espaço de layout. */
.calor .celula:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px var(--pv-superficie), 0 0 0 6px var(--pv-primary);
  position: relative;
  z-index: 1;
}
/* Cada passo tem contraste próprio e a célula também traz o número do dia:
 * a cor reforça, não informa sozinha (UX-P08). */
.calor .celula[data-passo="0"] { background: var(--pv-calor-0); color: var(--pv-calor-txt-0); }
.calor .celula[data-passo="1"] { background: var(--pv-calor-1); color: var(--pv-calor-txt-1); }
.calor .celula[data-passo="2"] { background: var(--pv-calor-2); color: var(--pv-calor-txt-2); }
.calor .celula[data-passo="3"] { background: var(--pv-calor-3); color: var(--pv-calor-txt-3); }
.calor .celula[data-passo="4"] { background: var(--pv-calor-4); color: var(--pv-calor-txt-4); }
.calor .celula.aberto { border: 2px dashed var(--pv-secondary); }
.calor .celula.fora { visibility: hidden; }

/* ---------------------------------------------------------------- tabelas */

table { width: 100%; border-collapse: collapse; font-size: var(--pv-t-corpo); }
th, td { text-align: left; padding: var(--pv-3) var(--pv-2); border-bottom: 1px solid var(--pv-border); }
/* Cabeçalho de coluna quebra linha. Com `nowrap` um rótulo como "Dias na
 * amostra" sozinho fazia uma tabela de três colunas precisar rolar em 390 px. */
th {
  font-weight: 700;
  color: var(--pv-muted);
  font-size: var(--pv-t-micro);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  vertical-align: bottom;
}
/* Dinheiro não quebra no meio. `R$ 141.901,94` partido em duas linhas deixa de
 * ser um número e vira dois. Quem rola é a caixa, não o valor.
 *
 * O `nowrap` é só do dado. O cabeçalho `.numero` continua podendo quebrar: com
 * ele travado, "Dias na amostra" sozinho fazia uma tabela de três colunas
 * precisar rolar em 390 px. */
td.numero, th.numero { text-align: right; }
td.numero { white-space: nowrap; }
tbody tr:last-child td { border-bottom: none; }
tbody th[scope="row"] { font-size: var(--pv-t-corpo); font-weight: 600; color: var(--pv-texto); text-transform: none; letter-spacing: normal; }

/* Identificador preso na primeira coluna quando a tabela rola de lado. O anexo
 * §9.6 permite scroll horizontal "apenas se o primeiro identificador permanecer
 * visível", e sem isto o nome do vendedor some junto com o resto. */
.tabela-fixa th[scope="row"],
.tabela-fixa thead th:first-child {
  position: sticky;
  left: 0;
  z-index: 2;
  background: var(--pv-superficie);
  /* Beirada desenhada por sombra: uma borda entraria no cálculo de largura da
   * célula grudada e desalinharia do cabeçalho. */
  box-shadow: 1px 0 0 var(--pv-border);
}
.tabela-fixa .linha-agregada th[scope="row"] { background: var(--pv-fundo); }
/* A coluna grudada tem piso de largura. Sem ele, em 390 px o navegador espremia
 * o nome até quebrar em três linhas ("LUIZ / FELIPE · / 5519") para dar espaço a
 * colunas que estão fora da vista de qualquer jeito. */
.tabela-fixa th[scope="row"] { min-width: 8.5rem; }

/* Código do ERP embaixo do nome, não colado nele. Ele existe para desempatar
 * homônimo, então precisa ser legível e não pode competir com o nome. */
.codigo {
  display: block;
  font-size: var(--pv-t-micro);
  font-weight: 500;
  letter-spacing: 0.04em;
  color: var(--pv-muted);
}

.etiqueta {
  display: inline-block;
  padding: 2px var(--pv-2);
  border-radius: var(--pv-pill);
  background: var(--pv-veu-12);
  color: var(--pv-marca-texto);
  font-size: var(--pv-t-micro);
  font-weight: 600;
  white-space: nowrap;
}
.etiqueta.alerta { background: var(--pv-warning-bg); color: var(--pv-warning); }
/* `ok` era usado no template (`<c-etiqueta tom="ok">novo</c-etiqueta>`) e não
 * tinha regra nenhuma: a etiqueta de primeira compra saía idêntica à de cliente
 * recorrente, o que anulava a única coisa que ela existia para dizer. */
.etiqueta.ok {
  background: color-mix(in srgb, var(--pv-positive) 16%, transparent);
  color: var(--pv-positive);
}
.etiqueta.verde {
  background: color-mix(in srgb, var(--pv-positive) 16%, transparent);
  color: var(--pv-positive);
}
.etiqueta.ambar {
  background: var(--pv-warning-bg);
  color: var(--pv-warning);
}
.etiqueta.vermelho {
  background: color-mix(in srgb, var(--pv-negative) 14%, transparent);
  color: var(--pv-negative);
}

.resumo-metas-card {
  padding: var(--pv-5);
  margin-bottom: var(--pv-5);
}
.resumo-metas {
  display: grid;
  gap: var(--pv-5);
}
.resumo-metas-celula {
  display: flex;
  flex-direction: column;
  gap: var(--pv-2);
  min-width: 0;
}
.resumo-metas-celula .rotulo {
  margin: 0;
}
.resumo-metas-celula .valor {
  display: block;
  font-size: 1.5rem;
  font-weight: 700;
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
  line-height: 1.15;
  margin: 0;
}
.resumo-metas-celula .contexto {
  margin: 0;
  color: var(--pv-muted);
  font-size: var(--pv-t-apoio);
  line-height: 1.35;
}
.resumo-metas-celula .semaforo { margin-top: 2px; }
@media (min-width: 720px) {
  .resumo-metas {
    grid-template-columns: 1.15fr 1fr 0.9fr;
    gap: var(--pv-6);
    align-items: start;
  }
}
.meta-vendedor { margin: var(--pv-4) 0 var(--pv-5); }

.linha-agregada td { background: var(--pv-fundo); font-weight: 500; }

/* ------------------------------------------------- escolha de empresa */

/* Lista de alvos grandes, um por empresa. O `<select>` da faixa do topo resolve
 * a TROCA, quando já se está dentro de uma empresa e o nome dela está na tela;
 * aqui não há contexto nenhum e o que a pessoa precisa é ler os nomes todos de
 * uma vez e acertar num toque. */
.lista-empresas {
  list-style: none;
  margin: var(--pv-4) 0 0;
  padding: 0;
  display: grid;
  gap: var(--pv-2);
}
.lista-empresas form { margin: 0; }
.btn-empresa {
  width: 100%;
  min-height: 52px;
  display: flex;
  align-items: center;
  gap: var(--pv-3);
  padding: var(--pv-3) var(--pv-4);
  border: 1px solid var(--pv-linha);
  border-radius: var(--pv-radius-sm);
  background: var(--pv-superficie-alta);
  color: var(--pv-texto);
  font: inherit;
  font-size: var(--pv-t-base);
  font-weight: 600;
  text-align: left;
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease;
}
.btn-empresa:hover { background: var(--pv-veu-08); border-color: var(--pv-primary); }
.btn-empresa .nome { flex: 1; min-width: 0; }
.etiqueta-suspensa {
  font-size: var(--pv-t-micro);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-weight: 700;
  color: var(--pv-warning);
  background: var(--pv-warning-bg);
  padding: 2px var(--pv-2);
  border-radius: var(--pv-pill);
}

/* ---------------------------------------------------------------- vazios */

.vazio {
  text-align: center;
  padding: var(--pv-6) var(--pv-4);
  color: var(--pv-muted);
}
.vazio h2 { color: var(--pv-texto); margin-bottom: var(--pv-2); }

/* ---------------------------------------------------------------- forms */

.campo { display: block; margin-bottom: var(--pv-4); }
.campo > span { display: block; font-size: var(--pv-t-apoio); font-weight: 600; margin-bottom: var(--pv-1); }
/* Caixa de marcar na linha do texto: o `span` do campo vira rótulo ao lado. */
.campo-caixa { display: flex; align-items: center; gap: var(--pv-2); }
.campo-caixa > span { display: inline; margin-bottom: 0; font-weight: 500; }
input[type="text"], input[type="search"], input[type="email"], input[type="password"], input[type="date"], select {
  width: 100%;
  padding: var(--pv-3);
  border: 1px solid var(--pv-border);
  border-radius: var(--pv-radius-sm);
  font: inherit;
  /* 16px em campo não é escolha estética: abaixo disso o Safari do iPhone dá
   * zoom sozinho no foco e a pessoa perde o enquadramento da tela. */
  font-size: var(--pv-t-base);
  background: var(--pv-superficie);
  color: var(--pv-texto);
  min-height: 44px;
}
.erro-form {
  padding: var(--pv-3);
  border-radius: var(--pv-radius-sm);
  background: color-mix(in srgb, var(--pv-negative) 10%, var(--pv-superficie));
  border: 1px solid color-mix(in srgb, var(--pv-negative) 36%, transparent);
  color: var(--pv-negative);
  margin-bottom: var(--pv-4);
}

/* A tela de entrada NÃO acompanha `prefers-color-scheme`, pelo mesmo motivo da
 * TV: ela já é uma superfície de marca, com fundo navy próprio e as duas radiais
 * da logo, e não os tokens neutros. Deixar o card seguir a pele escura punha um
 * retângulo quase preto no meio de um azul médio, o que lê como buraco e não
 * como cartão. Ela abre igual às oito da manhã e às onze da noite. */
.entrar-tela {
  --pv-superficie: #ffffff;
  --pv-superficie-alta: #ffffff;
  --pv-texto: var(--pv-ink);
  --pv-linha: var(--pv-border);
  --pv-linha-vidro: rgba(255, 255, 255, 0.7);
  --pv-marca-texto: var(--pv-primary);
  --pv-muted: #5a607f;

  min-height: 100dvh;
  display: grid;
  place-items: center;
  padding: var(--pv-4);
  background:
    radial-gradient(900px 500px at 20% 0%, rgba(0, 147, 209, 0.35), transparent 55%),
    radial-gradient(700px 420px at 95% 100%, rgba(249, 190, 6, 0.22), transparent 50%),
    var(--pv-primary);
}
.entrar-caixa { width: 100%; max-width: 420px; }

/* -------------------------------------------------------------- cockpit */

/* O cockpit tem folha própria: `web/css/cockpit.css`, carregada só na tela dele.
 * Até 2026-09-01 as mesmas 88 classes viviam aqui TAMBÉM, com valores diferentes
 * (o herói era `flex` aqui e `grid` lá, o painel tinha raio 16 aqui e 18 lá).
 * Como `cockpit.css` entra depois no `<head>`, ela sempre vencia, e este bloco
 * era código morto que só servia para confundir quem viesse ajustar espaçamento.
 * Se algum dia uma classe do cockpit precisar valer fora dele, ela sobe para a
 * seção de primitivos acima, não volta para cá. */

/* ------------------------------------------------------------ viewports */

/* Acima de 640px: o cabeçalho abre a navegação em pílulas, os KPIs ganham
 * colunas e o par calor/semana fica lado a lado. Nada aparece aqui que já não
 * existisse empilhado no celular. */
@media (min-width: 640px) {
  .conteudo { padding: var(--pv-5) var(--pv-4) var(--pv-7); gap: var(--pv-5); }
  .card { padding: var(--pv-5); }
  h1 { font-size: 1.75rem; }
  .btn-primary { width: auto; }

  .shell-barra { gap: var(--pv-4); padding: var(--pv-3) var(--pv-4); }
  .shell-menu { position: static; }
  .shell-menu > summary { display: none; }
  .shell-marca { flex: 0 1 auto; }
  .shell-menu-botao { display: none; }
  /* Fora da camada de topo e sem `display: none`: o painel volta a ser um filho
   * comum da barra e vira a navegação em pílulas. */
  .shell-menu-painel {
    display: flex;
    position: static;
    inset: auto;
    flex: 1 1 auto;
    min-width: 0;
    max-width: none;
    background: transparent;
    box-shadow: none;
    padding: 0;
    color: inherit;
  }
  .shell-nav { flex: 1 1 auto; flex-direction: row; flex-wrap: wrap; align-items: center; gap: var(--pv-1); }
  /* Padding lateral menor que o do painel de 390px, e é medida, não gosto.
   *
   * Com `var(--pv-3)` de cada lado as seis seções somavam 614px numa barra que,
   * depois do nome da Empresa e da data, sobra 852px. Somado o item de operador
   * (148px), o perfil e o "Sair", passava de 900px e a linha quebrava: o "Sair"
   * caía sozinho para uma segunda faixa e o cabeçalho crescia 48px.
   *
   * O alvo continua em 40px de altura, que é o que a mão exige; o que encolhe é
   * o ar em volta do texto, que numa barra escura já vem do próprio contraste. */
  .shell-nav a {
    color: rgba(255, 255, 255, 0.86);
    border-radius: var(--pv-pill);
    min-height: 40px;
    padding-inline: var(--pv-2);
  }
  .shell-nav a:hover { background: rgba(255, 255, 255, 0.14); color: var(--pv-white); }
  .shell-nav a[aria-current="page"] { background: var(--pv-white); color: var(--pv-primary); }
  .shell-nav .separador { display: none; }
  .shell-nav .pessoa { margin-left: auto; }

  /* No desktop o item de operador fica logo depois das seções, atrás de um fio.
   * Mesma leitura do popover de 390px, onde ele mora abaixo do separador: à
   * esquerda o produto, depois do fio o chrome de quem opera.
   *
   * Sem `margin-left: auto` aqui, e essa é a correção de um defeito medido: com
   * `auto` neste item E no perfil, o primeiro comia toda a folga e o par
   * perfil/sair não cabia mais na linha — o "Sair" caía para uma segunda faixa e
   * o cabeçalho crescia 48px. Um `auto` por barra, e ele é do perfil.
   *
   * Cinza de chrome não existe sobre o cabeçalho escuro: `--pv-muted` some ali.
   * Branco rebaixado é o mesmo gesto na paleta certa. */
  .shell-nav .operador {
    margin-left: var(--pv-2);
    padding-left: var(--pv-3);
    border-left: 1px solid rgba(255, 255, 255, 0.18);
    border-radius: 0;
    color: rgba(255, 255, 255, 0.62);
    white-space: nowrap;
  }
  .shell-nav .operador:hover { background: transparent; color: var(--pv-white); }
  .shell-nav .operador[aria-current="page"] { background: transparent; color: var(--pv-white); font-weight: 600; }
  /* No painel branco de 390px o "Sair" é um botão ghost normal. No cabeçalho
   * escuro ele virava a pílula branca mais forte da tela, hierarquia que a ação
   * de sair não merece. Aqui ele se alinha aos itens de navegação. */
  .shell-nav form button {
    min-height: 40px;
    border-radius: var(--pv-pill);
    border-color: rgba(255, 255, 255, 0.22);
    background: transparent;
    color: rgba(255, 255, 255, 0.86);
    justify-content: center;
    width: auto;
  }
  .shell-nav form button:hover { background: rgba(255, 255, 255, 0.14); color: var(--pv-white); }

  .periodo {
    margin: 0;
    padding: var(--pv-2);
    border-radius: 16px;
    border: 1px solid var(--pv-linha);
    background: color-mix(in srgb, var(--pv-superficie) 86%, transparent);
  }

  .grid-kpis { grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }
  .grid-2 { grid-template-columns: repeat(auto-fit, minmax(340px, 1fr)); }
  .filtros-pessoas { grid-template-columns: minmax(0, 2fr) minmax(0, 1fr) minmax(0, 1fr); }
  .kpi.destaque { grid-column: auto; }
  .kpi.destaque .valor { font-size: 2rem; }
  .kpi .valor { font-size: clamp(1.375rem, 2.2vw, 1.75rem); }
  .serie { height: 200px; }

}

/* Barra cheia volta ao botão Menu até 1280px.
 *
 * Com a tela Fabricantes (ADENDO-09) a conta de admin passou a ter oito seções.
 * Em pílulas, abaixo de ~1240px, o "Sair" caía sozinho para uma segunda faixa e o
 * cabeçalho crescia 48px, o mesmo defeito já medido duas vezes acima. Em vez de
 * apertar mais o padding, a barra cheia (oito seções + perfil = nove links)
 * continua no popover de 390px nessa faixa. Vendedor e financeiro, com menos
 * seções, seguem em pílulas a partir de 640px como antes. */
@media (min-width: 640px) and (max-width: 1279px) {
  .shell-barra:has(.shell-nav > a:nth-of-type(9)) .shell-menu-botao { display: inline-flex; }
  .shell-barra:has(.shell-nav > a:nth-of-type(9)) .shell-menu-painel {
    position: fixed;
    inset: auto;
    top: calc(var(--pv-topo-b, 56px) + var(--pv-2));
    right: var(--pv-3);
    flex: none;
    min-width: 15rem;
    max-width: min(20rem, calc(100vw - var(--pv-5)));
    padding: var(--pv-2);
    background: var(--pv-superficie-alta);
    box-shadow: var(--pv-shadow-alta);
    color: var(--pv-texto);
  }
  .shell-barra:has(.shell-nav > a:nth-of-type(9)) .shell-menu-painel:not(:popover-open) { display: none; }
  .shell-barra:has(.shell-nav > a:nth-of-type(9)) .shell-menu-painel:popover-open { display: block; }
  .shell-barra:has(.shell-nav > a:nth-of-type(9)) .shell-nav { flex-direction: column; align-items: stretch; gap: 2px; }
  .shell-barra:has(.shell-nav > a:nth-of-type(9)) .shell-nav a,
  .shell-barra:has(.shell-nav > a:nth-of-type(9)) .shell-nav .operador {
    color: var(--pv-texto);
    border: 0;
    border-radius: var(--pv-radius-sm);
    margin: 0;
    padding: var(--pv-2) var(--pv-3);
    min-height: 44px;
  }
  .shell-barra:has(.shell-nav > a:nth-of-type(9)) .shell-nav a:hover { background: var(--pv-fundo); color: var(--pv-texto); }
  .shell-barra:has(.shell-nav > a:nth-of-type(9)) .shell-nav a[aria-current="page"] { background: var(--pv-primary); color: var(--pv-white); }
  .shell-barra:has(.shell-nav > a:nth-of-type(9)) .shell-nav .separador { display: block; }
  .shell-barra:has(.shell-nav > a:nth-of-type(9)) .shell-nav .pessoa { margin-left: 0; }
  .shell-barra:has(.shell-nav > a:nth-of-type(9)) .shell-nav form button {
    width: 100%;
    justify-content: flex-start;
    min-height: 44px;
    border-radius: var(--pv-radius-sm);
    border-color: var(--pv-border);
    background: var(--pv-superficie);
    color: var(--pv-marca-texto);
  }
}

@media (min-width: 1600px) {
}

/* Quem pediu menos transparência ao sistema recebe superfície opaca. O vidro é
 * acabamento; a legibilidade não é. */
@media (prefers-reduced-transparency: reduce) {
  .shell-topo, .periodo {
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }
  .periodo { background: var(--pv-superficie); }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}

@media print {
  .shell-topo, .periodo, .actions { display: none; }
  body { background: none; }
  .card { box-shadow: none; border: 1px solid var(--pv-border); }
}

.sincronizacao[hidden] { display: none; }
