/* ==========================================================================
   Pulso NPS — sistema visual "Policromo"
   Claro, colorido e macio. Uma família de texto só (Manrope); monoespaçada
   fica reservada a identificador que se lê caractere a caractere.

   Ordem do arquivo: tokens, base, controles, login, shell, componentes e,
   NO FIM, todo o responsivo. Media query no meio do arquivo perde para a
   regra que vem depois — foi assim que o painel do login deixou de sumir
   no celular na versão anterior.
   ========================================================================== */

:root {
  color-scheme: light;

  /* superfícies */
  --bg:          #F5F5F9;
  --surface:     #FFFFFF;
  --surface-2:   #FBFBFD;
  --surface-3:   #F1F1F6;

  /* tinta */
  --ink:         #131322;
  --ink-2:       #41415C;
  --muted:       #63637E;
  /* O mesmo de --muted. #737394 passava só sobre branco puro (4,56) e reprovava
     justamente onde ele aparece: sobre neu-soft (4,14), det-soft (3,89), prom-soft
     (4,05), accent-soft (3,90) e surface-3 (4,05). Com #63637E o pior caso é o
     det-soft, com 4,95. O nome fica, porque as regras que o usam dizem "texto
     secundário de segunda ordem", e isso pode voltar a ter outro valor. */
  --muted-2:     #63637E;

  /* linhas */
  --rule:        #E8E8EF;
  --rule-2:      #D6D6E2;
  --rule-3:      #BFBFD0;
  --field-line:  #8A8AA3;   /* borda de campo: 3,36 sobre branco. --rule-2 dava 1,44 e
                               reprovava o mínimo de 3:1 exigido de componente de interface. */

  /* acento */
  --accent:      #3D3DF5;
  --accent-2:    #5757FF;
  --accent-3:    #8A6BFF;
  --accent-ink:  #2B2BB8;   /* tinta sobre --accent-soft: 8,41 */
  --accent-soft: #ECECFE;
  --accent-line: #C9C9FB;
  --accent-grad: linear-gradient(135deg, #3D3DF5, #8A6BFF 45%, #FF3D71 105%);

  /* semântica: o tom vivo pinta MARCA (barra, ponto, medidor);
     o tom -ink pinta TEXTO, porque o vivo não passa em contraste. */
  --prom:        #00A170;  --prom-ink: #007544;  --prom-soft: #E0F7EC;  --prom-line: #A8E8C9;
  --neu:         #F0A202;  --neu-ink:  #8A5B00;  --neu-soft:  #FEF3DC;  --neu-line:  #F5DFA8;
  --det:         #F42D5E;  --det-ink:  #C7134A;  --det-soft:  #FFE7EE;  --det-line:  #FFC2D5;
  /* O verde girou de #00A25C para #00A170 e o rosa de #FF3D71 para #F42D5E: no par
     antigo, promotor e detrator viravam quase a MESMA cor em deuteranopia. Com o giro,
     a distância percebida triplica. Quem não distingue verde de vermelho é ~8% dos
     homens — numa rede de 400 lojas, isso é gente de verdade lendo o ranking. */
  --prom-ink-2:  #05673D;   /* fundo do aviso de sucesso */
  --det-ink-2:   #A80F3E;   /* fundo do aviso de erro e hover do botão de perigo */
  /* A MARCA amarela (barra, ponto). O --neu vivo dá 2,1:1 sobre branco e some ao
     sol: a barra de neutro do histograma e o ponto de "atenção" precisam de 3:1,
     que é o mínimo de componente gráfico. O fundo amarelo claro não muda. */
  --neu-mark:    #B87A00;

  /* tipografia — uma família de texto, uma de identificador */
  --f-ui: "Manrope", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  --f-id: "JetBrains Mono", ui-monospace, "Cascadia Mono", Consolas, monospace;

  /* Escala de tamanhos. Eram 17 valores soltos, com texto útil em 10,5 e 11px; agora
     o piso é 12px, sem exceção: o rótulo em caixa-alta (thead, .rot) ficava em 11,5px
     e era o único texto abaixo do piso (lote 11). Ele subiu para 12px com um pouco
     menos de espaçamento entre as letras, para a coluna não alargar. */
  --t-xs:   12px;   /* tag, rótulo e nota de KPI, legenda miúda  */
  --t-sm:   13px;   /* corpo de tabela, .sub                      */
  --t-md:   14px;   /* corpo e campos (16px em toque)             */
  --t-lg:   16px;   /* título de cartão                           */
  --t-xl:   20px;   /* título da tela                             */
  --t-2xl:  28px;   /* número de KPI                              */
  --t-hero: 44px;   /* o NPS em destaque                          */

  /* raio: cresce com o tamanho do objeto */
  --r-xs: 8px;    /* tag, badge           */
  --r-sm: 10px;   /* campo, botão         */
  --r-md: 12px;   /* seletor, aviso       */
  --r-lg: 16px;   /* cartão, régua de KPI */
  --r-xl: 22px;   /* modal, gaveta        */
  --r-full: 999px;

  /* elevação — sombra azulada, para casar com o acento */
  --sh-1: 0 1px 2px rgba(19, 19, 34, .05);
  --sh-2: 0 2px 8px rgba(19, 19, 34, .06), 0 1px 2px rgba(19, 19, 34, .04);
  --sh-3: 0 16px 40px rgba(31, 31, 90, .16), 0 3px 8px rgba(19, 19, 34, .06);
  --anel: 0 0 0 3px rgba(61, 61, 245, .16);
  --scrim: rgba(19, 19, 34, .38);

  /* ritmo */
  --s1: 4px; --s2: 8px; --s3: 12px; --s4: 16px; --s5: 20px; --s6: 24px; --s8: 32px;

  --content-max: 1440px;    /* teto de medida: em 2560px a coluna de texto vira ilegível */
  --side-w: 236px;
  --top-h: 62px;
  --pad-x: 24px;
}

/* ==========================================================================
   Base
   ========================================================================== */

* { box-sizing: border-box; }
html, body { height: 100%; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--f-ui);
  font-size: var(--t-md);
  line-height: 1.55;
  font-variant-numeric: lining-nums;
  overflow-wrap: break-word;      /* nome de loja e de categoria em pt-BR são longos */
}

h1, h2, h3, h4 { margin: 0; font-weight: 700; line-height: 1.22; letter-spacing: -.018em; }
p { margin: 0; }
a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }
[hidden] { display: none !important; }
img, svg, canvas { max-width: 100%; }

/* Algarismo alinhado em coluna SEM fonte de máquina de escrever. */
.num { font-variant-numeric: tabular-nums lining-nums; font-feature-settings: "tnum" 1; }

/* Identificador que se copia e se confere caractere a caractere. Só aqui. */
.id { font-family: var(--f-id); font-size: max(var(--t-xs), .92em); letter-spacing: -.01em; }

.eyebrow {
  font-size: var(--t-xs); font-weight: 800; letter-spacing: .08em; line-height: 1.45;
  text-transform: uppercase; color: var(--muted);
}

/* Texto secundário solto no corpo (legenda de bloco, "Carregando…", o "até" entre
   duas datas). Existia só dentro do topo, do cartão e da gaveta, e o resto do app
   usava a classe sem regra nenhuma: saía em 14px e na cor do texto principal. */
.sub { font-size: var(--t-sm); color: var(--muted); }

/* Sem border-radius aqui: :focus-visible tem especificidade maior que a do seletor
   de elemento do campo, e o campo encolhia de 10px para 8px ao receber foco. */
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ==========================================================================
   Controles
   ========================================================================== */

input, select, textarea {
  font: inherit; width: 100%; min-width: 0;
  color: var(--ink); background: var(--surface);
  border: 1.5px solid var(--field-line); border-radius: var(--r-sm);
  padding: 9px 12px;
  transition: border-color .13s, box-shadow .13s;
}
input::placeholder, textarea::placeholder { color: var(--muted-2); }
input:hover, select:hover, textarea:hover { border-color: var(--rule-3); }
input:focus, select:focus, textarea:focus {
  outline: none; border-color: var(--accent); box-shadow: var(--anel);
}
/* O anel de 16% some ao sol (1,29:1). Com teclado, um contorno cheio por fora,
   e a borda de acento continua: um não substitui o outro. */
input:focus-visible, select:focus-visible, textarea:focus-visible, button:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 1px;
}
select {
  appearance: none; padding-right: 32px; cursor: pointer;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5 11 1.5' fill='none' stroke='%2363637E' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 11px center;
}
textarea { resize: vertical; min-height: 84px; }

.btn {
  font: inherit; font-weight: 700; font-size: 13.5px; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  min-height: 38px; padding: 9px 17px; border-radius: var(--r-sm);
  border: 1.5px solid transparent; background: var(--accent); color: #fff;
  transition: background .13s, border-color .13s, box-shadow .13s, transform .07s;
  white-space: nowrap;
}
.btn:hover { background: var(--accent-2); }
.btn:active { transform: translateY(1px); }
.btn:disabled { opacity: .48; cursor: default; transform: none; }
.btn.ghost { background: var(--surface); color: var(--ink-2); border-color: var(--rule-2); }
.btn.ghost:hover { background: var(--surface-3); border-color: var(--rule-3); color: var(--ink); }
.btn.quiet { background: transparent; border-color: transparent; color: var(--muted); padding: 8px 10px; min-height: 36px; }
.btn.quiet:hover { background: var(--surface-3); color: var(--ink); }
.btn.danger { background: var(--det-ink); }
.btn.danger:hover { background: var(--det-ink-2); }
/* Destrutivo, mas não é o caminho principal do diálogo: "Desativar" fica no
   rodapé ao lado de "Salvar", e um botão vermelho sólido ali disputaria o olho
   com a ação que a pessoa veio fazer. */
.btn.danger.ghost { background: var(--surface); color: var(--det-ink); border-color: var(--det-line); }
.btn.danger.ghost:hover { background: var(--det-soft); border-color: var(--det-ink); }
.btn.sm { min-height: 32px; padding: 6px 13px; font-size: 12.5px; border-radius: var(--r-xs); }
.btn.block { width: 100%; }

/* Uma fita, dois usos: o recorte de período no topo das telas (.seg) e as abas
   da gaveta da tratativa (.tabs). Mesma pergunta ao operador — escolha um destes —
   então mesma resposta visual. As abas ENTRAM nestes seletores em vez de ganharem
   uma cópia: duas fitas parecidas e não iguais é o jeito mais barato de uma tela
   parecer montada de pedaços, e a cópia só diverge da original com o tempo. */
/* Sem rolagem lateral. A fita rolava com a barra escondida, e nada dizia que havia
   mais opções: no celular o topo mostrava "Hoje 7 dias 30 d" e escondia 60 e 90, e
   a aba ativa podia estar fora da tela. Agora ela quebra linha quando não cabe, e
   no celular vira colunas iguais (ver o @media 720). */
.seg, .tabs {
  display: inline-flex; flex-wrap: wrap; background: var(--surface-3); border: 1px solid var(--rule);
  border-radius: var(--r-md); padding: 3px; gap: 2px; max-width: 100%;
}
.seg button, .tabs .tab {
  font: inherit; font-size: var(--t-sm); font-weight: 600; border: 0; background: transparent;
  color: var(--muted); padding: 6px 13px; border-radius: var(--r-xs); cursor: pointer;
  white-space: nowrap; min-height: 30px;
}
.seg button:hover, .tabs .tab:hover { color: var(--ink); }
.seg button.on, .tabs .tab.on {
  background: var(--surface); color: var(--accent); font-weight: 800; box-shadow: var(--sh-1);
}

/* Chips de filtro com contagem (status da fila, filtros de convites). A exceção da
   regra de colunas iguais: a 360, "Dispensadas" e "Atrasadas 204" não cabem num
   quinto da largura. Cada chip tem a largura do próprio texto e a fileira quebra. */
.seg.chips { display: flex; flex-wrap: wrap; gap: 6px; background: none; border: 0; padding: 0; }
.seg.chips button {
  background: var(--surface); border: 1px solid var(--rule-2); border-radius: var(--r-full);
  padding: 5px 13px;
}
.seg.chips button.on {
  background: var(--accent-soft); border-color: var(--accent-line); color: var(--accent-ink);
  box-shadow: none;
}

/* A fita das abas fica DENTRO de uma linha da tabela, colada no que vem depois.
   O respiro é dela, não do conteúdo da aba — que muda de forma a cada aba. */
.tabs { margin-bottom: var(--s3); }

/* Rótulo de grupo dentro de um formulário longo ("Conteúdo", "Cooldown", "Envio").
   Sem isto o <h4> sai com o tamanho do navegador — 1.33em e negrito, maior que o
   título do cartão que o contém. É o mesmo rótulo miúdo do cabeçalho de tabela,
   porque é a mesma coisa: o nome de um grupo de colunas. */
.rot {
  font-size: var(--t-xs); font-weight: 800; letter-spacing: .045em; text-transform: uppercase;
  color: var(--muted);
}

/* ==========================================================================
   Login
   ========================================================================== */

/* svh e não dvh: dvh remede a cada colapso da barra de URL no celular e faz a
   página inteira refluir enquanto o dedo rola. */
.login { display: grid; grid-template-columns: 1.12fr .88fr; min-height: 100svh; background: var(--surface); }

.login-art {
  position: relative; overflow: hidden;
  background: radial-gradient(120% 90% at 10% 6%, #FFFFFF 0%, #F3F3FB 42%, #E7E7FC 100%);
  border-right: 1px solid var(--rule);
  display: flex; flex-direction: column; justify-content: space-between;
  padding: clamp(28px, 4vw, 52px);
}
.art-top, .art-bottom { position: relative; z-index: 1; }

.wordmark { display: flex; align-items: center; gap: 11px; min-width: 0; }
.wordmark .mark {
  width: 32px; height: 32px; border-radius: var(--r-sm); flex: none;
  background: var(--accent-grad); display: grid; place-items: center;
  box-shadow: 0 3px 10px rgba(61, 61, 245, .32);
}
.wordmark .mark svg { display: block; }
.wordmark .txt { font-size: 17px; font-weight: 700; letter-spacing: -.03em; color: var(--ink); white-space: nowrap; }
.wordmark .txt b {
  font-weight: 800; background: var(--accent-grad);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}

.art-bottom .art-h {
  font-size: clamp(28px, 3.4vw, 44px); font-weight: 800; letter-spacing: -.035em;
  line-height: 1.08; max-width: 15ch; margin-bottom: var(--s3); color: var(--ink);
}
.art-bottom p:not(.art-h) { color: var(--ink-2); max-width: 42ch; font-size: 15px; }
.art-stats {
  display: flex; flex-wrap: wrap; gap: var(--s5) var(--s8);
  margin-top: var(--s6); padding-top: var(--s5); border-top: 1.5px solid var(--accent-line);
}
.art-stats div { display: flex; flex-direction: column; gap: 1px; }
.art-stats .v { font-size: 20px; font-weight: 800; letter-spacing: -.03em; color: var(--accent); }
.art-stats .k { font-size: var(--t-xs); color: var(--muted); }

.login-form { display: grid; place-items: center; padding: clamp(24px, 5vw, 44px) clamp(18px, 5vw, 32px); }
.login-inner { width: min(380px, 100%); display: flex; flex-direction: column; gap: var(--s5); }
.login-inner .hd h1 { font-size: clamp(22px, 3vw, 26px); letter-spacing: -.03em; }
/* A marca repetida em cima do "Entrar" só existe sem o painel ilustrado (ver @940). */
.so-celular { display: none; }
/* "Mostrar" dentro do campo Senha, à direita. O campo reserva o lugar dele para o
   texto digitado não correr por baixo do botão. */
.campo-senha { position: relative; }
.campo-senha input { padding-right: 88px; }
.ver-senha {
  position: absolute; right: 4px; top: 50%; transform: translateY(-50%);
  min-height: 34px; padding: 0 12px; border: 0; border-radius: var(--r-xs);
  background: transparent; color: var(--accent-ink); font: inherit; font-size: var(--t-sm);
  font-weight: 700; cursor: pointer;
}
.ver-senha:hover { background: var(--accent-soft); }
/* A orientação de quem esqueceu a senha, colada no botão Entrar. */
.login-ajuda { font-size: var(--t-sm); color: var(--muted); margin-top: calc(-1 * var(--s2)); }
.login-inner .hd p { color: var(--muted); margin-top: 5px; }
.field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
/* O rótulo do campo e o .rotulo-campo (o de um grupo, como os rádios, ou o de um valor
   só de leitura, como a "Senha" de Editar usuário) são uma regra só: a de Usuários
   repetia esta, com os mesmos valores (junção 5/7/8). */
.field > label, .rotulo-campo { font-size: 12.5px; font-weight: 600; color: var(--ink-2); }
/* Rádios grandes, um por linha (o motivo da dispensa): a linha inteira é o alvo, com
   48px, e a explicação vem na mesma frase. */
.radios { display: flex; flex-direction: column; gap: 6px; border-radius: var(--r-sm); }
.radio-op {
  display: flex; align-items: flex-start; gap: 10px; min-height: 48px; padding: 11px 12px;
  border: 1px solid var(--rule-2); border-radius: var(--r-sm); background: var(--surface);
  font-size: 13.5px; line-height: 1.4; color: var(--ink-2); cursor: pointer;
}
.radio-op:hover { border-color: var(--rule-3); }
.radio-op:has(input:checked) { border-color: var(--accent); background: var(--accent-soft); }
.radio-op input { width: 18px; height: 18px; margin: 1px 0 0; flex: none; accent-color: var(--accent); }
.radio-op b { color: var(--ink); }
.radios.ruim .radio-op { border-color: var(--det-ink); }
.radios.ruim { outline: 2px solid var(--det-ink); outline-offset: 3px; }
/* "0/500" embaixo do texto longo, à direita. */
.field > .contador { font-size: var(--t-xs); color: var(--muted); align-self: flex-end; }
/* A folha "Mais ações" da gaveta: um item por linha, de 48px, na largura toda. */
.folha-acoes { display: flex; flex-direction: column; gap: 8px; }
.folha-acoes .btn { width: 100%; min-height: 48px; justify-content: flex-start; }
.field .hint { font-size: var(--t-xs); color: var(--muted); }
/* Contas de demonstração: recolhidas. Quem já sabe entrar não precisa vê-las, e
   quem está abrindo a demo pela primeira vez acha em um clique. */
.login-inner .contas {
  border-top: 1px solid var(--rule); padding-top: var(--s4);
  font-size: 12.5px; color: var(--muted); line-height: 1.6;
}
.login-inner .contas > summary {
  cursor: pointer; font-weight: 700; color: var(--ink-2); list-style: none;
  display: flex; align-items: center; gap: 7px; user-select: none;
}
.login-inner .contas > summary::-webkit-details-marker { display: none; }
/* A seta é desenhada aqui porque o marcador nativo não aceita cor nem tamanho, e
   nas duas engines ele sai diferente. */
.login-inner .contas > summary::before {
  content: ""; width: 0; height: 0; flex: none;
  border-left: 5px solid currentColor; border-top: 4px solid transparent;
  border-bottom: 4px solid transparent; transition: transform .15s;
}
.login-inner .contas[open] > summary::before { transform: rotate(90deg); }
.login-inner .contas > summary:hover { color: var(--accent); }
.login-inner .contas .corpo { margin-top: var(--s3); }
.login-inner .contas .aviso { color: var(--muted); }
.login-inner .contas .senha { margin-top: 6px; color: var(--ink-2); }
.login-inner .contas .senha code {
  font-family: var(--f-id); font-size: 12px; background: var(--surface-3);
  padding: 2px 6px; border-radius: var(--r-xs); color: var(--ink);
}
.login-inner .contas ul { list-style: none; margin: var(--s3) 0 0; padding: 0; }
.login-inner .contas li { margin-bottom: 7px; }
/* Cada conta é um botão: clicar preenche os dois campos. Numa demo, o gesto que
   importa é entrar — não copiar um e-mail de um parágrafo. */
.login-inner .contas .conta {
  font: inherit; display: flex; align-items: baseline; gap: 0 7px; flex-wrap: wrap;
  width: 100%; text-align: left; cursor: pointer; padding: 5px 7px;
  border: 1px solid transparent; border-radius: var(--r-xs); background: transparent;
}
.login-inner .contas .conta:hover {
  background: var(--accent-soft); border-color: var(--accent-line);
}
.login-inner .contas .id { color: var(--ink-2); font-weight: 600; }
.login-inner .contas .papel { color: var(--muted); }
/* A nota é a terceira linha do botão (a linha inteira): o alvo e o realce do hover
   cobrem e-mail, papel e nota juntos, e a distância até a conta seguinte fica maior
   que a distância até a própria. */
.login-inner .contas .nota { flex-basis: 100%; color: var(--muted-2); font-size: var(--t-xs); line-height: 1.45; }
.alerta {
  display: flex; gap: 9px; align-items: flex-start; font-size: 13px;
  padding: 11px 13px; border-radius: var(--r-md);
  background: var(--det-soft); color: var(--det-ink); border: 1px solid var(--det-line);
}
/* A sessão que expirou não é erro de quem digita: azul, e não vermelho. */
.alerta.aviso { background: var(--accent-soft); color: var(--accent-ink); border-color: var(--accent-line); }

/* ==========================================================================
   Shell
   ========================================================================== */

#app { display: grid; grid-template-columns: var(--side-w) 1fr; min-height: 100svh; }

.side {
  background: var(--surface); border-right: 1px solid var(--rule);
  display: flex; flex-direction: column;
  position: sticky; top: 0; height: 100svh; min-width: 0;
}
.side-hd { padding: var(--s4) 18px; border-bottom: 1px solid var(--rule); display: flex; flex-direction: column;
           align-items: stretch; gap: var(--s3); }
/* A rede do cliente (só o suporte Pulso): rótulo à vista e o select na largura do
   menu. No topo ele disputava a linha com o período e ficava coberto por "Hoje". */
.tenant-sel { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.tenant-sel select { width: 100%; min-width: 0; padding: 8px 30px 8px 11px; font-size: 13px; }
.side nav { flex: 1; overflow-y: auto; padding: 10px; min-width: 0; }
.side nav .grp { padding: 15px 8px 6px; }
.side nav a {
  display: flex; align-items: center; gap: 10px; min-height: 38px;
  padding: 8px 11px; margin-bottom: 2px; border-radius: var(--r-sm);
  color: var(--ink-2); font-size: 13.5px; font-weight: 600; cursor: pointer; text-decoration: none;
  transition: background .12s, color .12s;
}
.side nav a:hover { background: var(--surface-3); color: var(--ink); text-decoration: none; }
.side nav a.on { background: var(--accent-soft); color: var(--accent); }
.side nav a .ic { width: 16px; height: 16px; flex: none; opacity: .7; }
.side nav a.on .ic { opacity: 1; }
.side nav a .badge {
  margin-left: auto; font-size: var(--t-xs); font-weight: 800;
  background: var(--det-soft); color: var(--det-ink); padding: 1px 7px; border-radius: var(--r-full);
  font-variant-numeric: tabular-nums;
}
/* Texto só para o leitor de tela: a frase que o número desenhado não diz. */
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0);
      clip-path: inset(50%); white-space: nowrap; margin: -1px; padding: 0; border: 0; }

.side-ft { border-top: 1px solid var(--rule); padding: var(--s3) var(--s4); display: flex; align-items: center; gap: 10px; }
.avatar {
  width: 32px; height: 32px; flex: none; border-radius: var(--r-full);
  background: var(--accent-soft); color: var(--accent);
  display: grid; place-items: center; font-size: var(--t-xs); font-weight: 800;
  border: 1.5px solid var(--accent-line);
}
.side-ft .who { min-width: 0; flex: 1; }
.side-ft .who b { display: block; font-size: 13px; font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.side-ft .who span { display: block; font-size: var(--t-xs); color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* O papel e o lugar da pessoa quebram em até duas linhas: é o único lugar do app em que
   o gerente vê QUAL é a loja dele ("Gerente · Loja 001 Centro"), e a 1440 ele saía
   cortado em "Gerente · Loja 001 …". */
.side-ft .who #u-papel { white-space: normal; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
/* Com "Trocar minha senha" junto do Sair (auditoria), o nome também quebra em duas
   linhas em vez de virar "Gestor da R…". Os dois botões vão um sobre o outro: lado a
   lado eles deixavam ~70px para o nome, e "Administrador" se partia no meio da palavra.
   Em coluna, o nome ganha a largura de um botão (no toque, os 44px voltam pela regra
   do .btn.quiet). */
.side-ft { gap: 6px; }
.side-ft .who b { white-space: normal; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.side-acts { display: flex; flex-direction: column; gap: 2px; flex: none; }
.side-acts .btn { width: 34px; height: 34px; min-height: 34px; padding: 0; justify-content: center; }
@media (pointer: coarse) { .side-acts .btn { width: 44px; height: 44px; } }

.main { min-width: 0; display: flex; flex-direction: column; }

.topbar {
  min-height: var(--top-h); flex: none; background: var(--surface);
  border-bottom: 1px solid var(--rule);
  display: flex; align-items: center; gap: var(--s4); padding: 10px var(--pad-x);
  padding-inline: max(var(--pad-x), calc((100% - var(--content-max)) / 2 + var(--pad-x)));
  position: sticky; top: 0; z-index: 20;
}
.topbar .tit { min-width: 0; }
.topbar .tit-linha { display: flex; align-items: center; gap: 10px; min-width: 0; }
.topbar h1 { font-size: var(--t-xl); letter-spacing: -.03em; min-width: 0; }
.topbar h1:focus { outline: none; }
.topbar h1:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
/* Selo e chip: a aparência de .tag, o alvo de botão. No toque o alvo cresce para
   44px sem a tag crescer junto (ver @pointer:coarse). */
.selo-btn {
  appearance: none; background: none; border: 0; padding: 0; margin: 0; font: inherit;
  display: inline-flex; align-items: center; justify-content: center; flex: none;
  cursor: pointer; border-radius: var(--r-full); max-width: 100%; min-width: 0;
}
/* O alvo passa da linha do título para cima e para baixo sem empurrá-la: com os
   44px do toque dentro do fluxo, a barra do tablet ia de 59 para 78px. */
.tit-linha > .selo-btn { margin-block: -12px; }
.selo-btn .tag { cursor: inherit; overflow: hidden; text-overflow: ellipsis; }
.selo-btn:hover .tag { border-color: var(--rule-3); color: var(--ink); }
.selo-btn .curto { display: none; }
#chip-rede { flex: 0 1 auto; }
/* O texto inteiro do Modo teste, num balão preso à barra do topo. */
.pop-teste {
  position: absolute; top: calc(100% - 4px); z-index: 25;
  background: var(--ink); color: #F2F2F8; font-size: var(--t-sm); font-weight: 600; line-height: 1.5;
  padding: 12px 14px; border-radius: var(--r-md); box-shadow: var(--sh-3);
}
/* "Rede: <nome> ▾" no começo da área que rola (sem a barra lateral). */
.rede-btn { justify-content: flex-start; gap: 6px; font-weight: 600; min-width: 0; }
.rede-btn .rede-rot { color: var(--muted); }
.rede-btn b { color: var(--ink); font-weight: 800; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.rede-btn .seta { margin-left: auto; color: var(--muted); }
.topbar .sub { font-size: var(--t-sm); color: var(--muted); margin-top: 1px; }
.topbar .grow { flex: 1; }
.topbar .tools { display: flex; align-items: center; gap: var(--s3); min-width: 0; }

/* Recorte por unidade da arvore, ao lado do periodo. O `—` de indentacao mostra a
   profundidade dentro do <option>, que nao aceita marcacao. */
.unidade-sel { display: flex; align-items: center; gap: 7px; min-width: 0; flex: 0 1 auto; }
/* `min-width: 0` no proprio select: sem ele o min-width intrinseco do conteudo
   (o nome mais longo da arvore) impede o flex de encolher, e a barra do topo
   empurra a pagina inteira para a rolagem horizontal no celular. */
.unidade-sel select { width: auto; min-width: 0; max-width: 260px;
                      padding: 6px 30px 6px 11px; font-size: 13px; }

.menu-btn { display: none; position: relative; }        /* só existe no celular */
/* O número de tratativas abertas no próprio ≡: com o menu fechado, ele só existia
   dentro do menu. */
.menu-ponto {
  position: absolute; top: -7px; right: -9px; min-width: 22px; height: 22px; padding: 0 5px;
  border-radius: var(--r-full); background: var(--det-ink); color: #fff; border: 2px solid var(--surface);
  font-size: var(--t-xs); font-weight: 800; line-height: 18px; text-align: center;
  font-variant-numeric: tabular-nums;
}

/* Centrado: acima de ~1700px o teto de 1440px deixava a coluna presa à esquerda e
   uma faixa vazia à direita. O topo acompanha (padding calculado), para o título
   ficar alinhado com a primeira coluna de cartões. */
.content { padding: var(--s5) var(--pad-x) 64px; min-width: 0; max-width: var(--content-max);
  width: 100%; margin-inline: auto; }

/* ==========================================================================
   Aviso
   ========================================================================== */

/* O aviso comum é NEUTRO. Era amarelo, a cor do cliente neutro, e o mesmo fundo
   pintava "envio desligado", "faltam números" e "o texto está pronto": o olho não
   sabia se lia um estado do sistema ou uma classe de cliente. A cor fica no ícone.
   Sucesso é .info (azul); erro e perigo, .crit. */
.banner {
  display: flex; gap: 10px; align-items: flex-start;
  padding: 12px 15px; border-radius: var(--r-md); font-size: var(--t-sm);
  background: var(--surface); color: var(--ink-2); border: 1px solid var(--rule-2);
  margin-bottom: var(--s4);
}
.banner .dot-ic { flex: none; margin-top: 2px; color: var(--neu-mark); }
.banner.crit .dot-ic, .banner.info .dot-ic { color: inherit; }
.banner.crit { background: var(--det-soft); color: var(--det-ink); border-color: var(--det-line); }
.banner.info { background: var(--accent-soft); color: var(--accent-ink); border-color: var(--accent-line); }
.banner b { font-weight: 800; }
/* O recorte ativo do Resumo: quando a frase e o botão não cabem lado a lado, o botão
   desce para a linha dele, à direita. A 360, espremido ao lado da frase, "Ver todas as
   lojas" encostava na borda da faixa. */
.banner.recorte { flex-wrap: wrap; align-items: center; }
.banner.recorte > span { flex: 1 1 16rem; min-width: 0; }
.banner.recorte > .btn { margin-left: auto; }
/* O envio que não deu para confirmar: uma frase, fundo neutro e o ponto de
   atenção. Nem amarelo (o cliente neutro) nem vermelho (não sabemos se há perigo). */
.banner.estado { align-items: center; }
.ponto { width: 7px; height: 7px; border-radius: 50%; flex: none; display: block; }
.ponto.atencao { background: var(--neu-mark); }
/* A regra de herança de Configurações, numa linha só. */
.linha-regra { margin: 0 0 var(--s4); }
/* Detalhe técnico recolhido (as travas de envio, só para o suporte). */
.detalhes-tec { margin-bottom: var(--s4); font-size: var(--t-sm); color: var(--ink-2); }
.detalhes-tec > summary { cursor: pointer; font-weight: 700; color: var(--muted); padding: 6px 0; }
.detalhes-tec > div { margin-top: 6px; }

/* ==========================================================================
   Ajustes (lote 8): Configurações (desde o lote 9, o único lugar onde se editam os
   parâmetros da empresa, da região e da loja)

   Cada ajuste é um bloco, e não uma linha de tabela: a coluna "Valor" de 320px
   deixava o campo com 28px no celular e o Salvar cortado na borda. No desktop, duas
   colunas (o rótulo e a ajuda | o controle e a origem); abaixo de 600px de LARGURA
   DO BLOCO, uma coluna só. A régua é a do bloco (container query), e não a da tela:
   o mesmo componente mora num cartão largo e numa tela de 360.
   ========================================================================== */
.ajustes-lista { container-type: inline-size; min-width: 0; }
.ajuste {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 340px); gap: 6px 28px;
  align-items: start; padding: 14px 0; border-top: 1px solid var(--rule);
}
.ajustes-lista > .ajuste:first-child { border-top: 0; padding-top: 0; }
.ajustes-lista > .ajuste:last-child { padding-bottom: 0; }
.aj-cab { min-width: 0; }
.aj-ctl { min-width: 0; display: flex; flex-direction: column; gap: 6px; }
.aj-rot-linha { display: flex; align-items: center; flex-wrap: wrap; gap: 4px 8px; }
.aj-rot { font-size: var(--t-md); font-weight: 700; color: var(--ink); line-height: 1.35; }
.aj-ajuda { margin: 3px 0 0; font-size: var(--t-sm); color: var(--muted); line-height: 1.45; }
.aj-origem { margin: 0; font-size: var(--t-sm); color: var(--muted); line-height: 1.45; }
.aj-origem .proprio { color: var(--accent-ink); font-weight: 700; }
/* O valor mudado e ainda não salvo: a faixa de acento à esquerda e a tag "Alterado". */
.ajuste.mudou { box-shadow: inset 3px 0 0 var(--accent); padding-left: 12px; margin-left: -12px; }
/* O ajuste inteiro com o foco (no toque, depois de salvar: focar o campo abriria o
   teclado). Sem anel no toque; com o teclado, o anel do sistema com folga. */
.ajuste:focus { outline: none; }
.ajuste:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: var(--r-sm); }
/* Link que é botão ("Voltar ao de cima"). */
.linkbtn {
  font: inherit; font-weight: 700; color: var(--accent-ink); background: none; border: 0;
  padding: 0; margin: 0; cursor: pointer; text-decoration: underline; text-underline-offset: 3px;
}
.linkbtn:hover { color: var(--accent); }

/* A fita Sim | Não | Usar o de cima: colunas pelo JS (a de herança é a mais larga),
   todas à vista, e o texto quebra em vez de sair da fita. */
.seg.aj-fita { display: grid; grid-auto-flow: row; width: 100%; }
.aj-fita button { white-space: normal; text-align: center; line-height: 1.25; padding-inline: 8px; }
.aj-fita.ruim { border: 2px solid var(--det-ink); }

/* Número com a unidade DENTRO do campo, à direita (ou o "R$" à esquerda): o campo
   pode ter a largura toda no celular sem o "90" ficar solto. */
.aj-campo { position: relative; display: flex; flex-direction: column; min-width: 0; }
.aj-numero, .aj-decimal { max-width: 220px; }
.aj-hora { max-width: 180px; }
.aj-campo > .un, .aj-campo > .pre {
  position: absolute; top: 0; height: 100%; display: flex; align-items: center;
  font-size: var(--t-sm); font-weight: 600; color: var(--muted); pointer-events: none;
}
.aj-campo > .un { right: 13px; }
.aj-campo > .pre { left: 13px; }
.aj-campo input[type="number"] { -moz-appearance: textfield; appearance: textfield; }
.aj-campo input[type="number"]::-webkit-inner-spin-button,
.aj-campo input[type="number"]::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }
/* A hora herdada, em cinza dentro do campo: é o que vale, mas não é deste nível. */
.aj-campo input.herda { color: var(--muted); }
.aj-cont { align-self: flex-end; margin-top: 4px; font-size: var(--t-xs); color: var(--muted); }

/* "Quem precisa de retorno": a peça ocupa as duas colunas, com os dois grupos lado a
   lado no desktop e um embaixo do outro no bloco estreito. */
.ajuste.aj-retorno { grid-template-columns: minmax(0, 1fr); }
.aj-grupos { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; margin-top: 6px; }
.aj-grupo {
  border: 1px solid var(--rule); border-radius: var(--r-md); background: var(--surface-2);
  padding: 12px 14px; min-width: 0;
}
.aj-grupo > h3 { font-size: var(--t-md); font-weight: 800; color: var(--ink); margin: 0 0 4px; }
.aj-grupo .ajuste { grid-template-columns: minmax(0, 1fr); padding: 10px 0; }
.aj-grupo .ajuste:last-child { padding-bottom: 0; }
.aj-grupo > h3 + .ajuste { border-top: 0; padding-top: 4px; }
.aj-grupo .ajuste.mudou { padding-left: 10px; margin-left: -10px; }
.aj-aviso:not(:empty) { margin-top: 10px; }
.aj-aviso .banner { margin-bottom: 0; }
.aj-aviso .banner + .banner { margin-top: 8px; }

/* A linha da janela de envio que vale (informativa, não é erro), na coluna dos
   controles, embaixo das duas horas. */
.aj-info-linha { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 340px); gap: 0 28px; padding: 0 0 14px; }
.aj-info-linha > .aj-info { grid-column: 2; }
.aj-info-linha:has(> .aj-info:empty) { display: none; }
.aj-info {
  margin: 0; display: flex; gap: 8px; align-items: center; font-size: var(--t-sm); font-weight: 600;
  color: var(--ink-2); background: var(--surface-2); border: 1px solid var(--rule);
  border-radius: var(--r-md); padding: 9px 12px;
}
.aj-info .dot-ic { flex: none; color: var(--accent); }
.aj-tec { grid-column: 1 / -1; margin: 0; }

/* O seletor "Ajustes de:" e a busca de loja. Na largura toda, no desktop, o select
   de uma palavra ("Toda a rede") atravessava a tela. */
.aj-escopo select { flex: 0 1 440px; }
.aj-escopo .aj-busca { flex: 0 1 260px; min-width: 0; }
.aj-escondidos { margin: calc(-1 * var(--s2)) 0 var(--s4); }

/* O cartão Avançado, recolhido: o <summary> tem a cara do cabeçalho de cartão. */
.card.aj-recolhido > summary {
  display: flex; align-items: center; gap: var(--s3); padding: 14px 18px; min-height: 56px;
  cursor: pointer; list-style: none;
}
.card.aj-recolhido > summary::-webkit-details-marker { display: none; }
.card.aj-recolhido > summary::after {
  content: ""; margin-left: auto; flex: none; width: 9px; height: 9px;
  border-right: 2px solid var(--muted); border-bottom: 2px solid var(--muted); transform: rotate(45deg);
}
.card.aj-recolhido[open] > summary { border-bottom: 1px solid var(--rule); }
.card.aj-recolhido[open] > summary::after { transform: rotate(225deg); }
.aj-sum { display: flex; flex-direction: column; min-width: 0; }
.aj-sum h2 { font-size: var(--t-lg); letter-spacing: -.02em; }
.aj-sum .sub { font-size: var(--t-sm); color: var(--muted); }

/* A barra "3 alterações não salvas [Descartar] [Salvar alterações]" de
   Configurações: presa ao pé da tela, e sobe com o teclado do iPhone (--kb,
   ancorarNoTeclado). A do painel da empresa e a dos diálogos saíram no lote 9, com a
   aba Parâmetros e os blocos de parâmetros. */
.barra-ajustes {
  display: flex; align-items: center; gap: 10px; margin-top: var(--s4);
  padding: 12px 14px; background: var(--surface); border: 1px solid var(--rule-2);
  border-radius: var(--r-lg); box-shadow: var(--sh-3);
}
.barra-ajustes.fixa {
  position: sticky; z-index: 15;
  bottom: calc(var(--kb, 0px) + 10px + env(safe-area-inset-bottom));
}
.barra-ajustes .ba-txt { flex: 1; min-width: 0; font-weight: 700; color: var(--ink); }
.aj-form { margin: 0; }

@container (max-width: 600px) {
  .ajuste, .aj-info-linha { grid-template-columns: minmax(0, 1fr); gap: 6px; }
  .aj-info-linha > .aj-info { grid-column: 1; }
  .aj-numero, .aj-decimal, .aj-hora { max-width: none; }
  .aj-grupos { grid-template-columns: minmax(0, 1fr); gap: 14px; }
  /* No bloco estreito o grupo perde a caixa cinza e fica com o título e um fio em
     cima: a borda e o respiro da caixa tiravam 30px da fita Sim | Não | Usar o de
     cima, que a 360 ficava com 262px e a opção de herança em duas linhas apertadas. */
  .aj-grupo { border: 0; border-top: 1px solid var(--rule); border-radius: 0; background: none; padding: 12px 0 0; }
}
@media (max-width: 520px) {
  /* A frase numa linha e o par [Descartar][Salvar] embaixo, da mesma largura. */
  .barra-ajustes { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 8px; }
  .barra-ajustes .ba-txt { grid-column: 1 / -1; }
  .barra-ajustes .btn { width: 100%; white-space: normal; padding-inline: 10px; }
  .aj-escopo .aj-busca { flex: 1 1 100%; }
}
@media (pointer: coarse) {
  .linkbtn { min-height: 44px; display: inline-flex; align-items: center; vertical-align: middle; }
}

/* ==========================================================================
   Cartões
   ========================================================================== */

.card {
  background: var(--surface); border: 1px solid var(--rule);
  border-radius: var(--r-lg); box-shadow: var(--sh-1);
  margin-bottom: var(--s4); overflow: hidden; min-width: 0;
}
.card > header {
  display: flex; align-items: center; gap: var(--s3);
  padding: 14px 18px; border-bottom: 1px solid var(--rule); flex-wrap: wrap;
}
.card > header h2 { font-size: var(--t-lg); letter-spacing: -.02em; }
.card > header .sub { font-size: var(--t-sm); color: var(--muted); }
.card > header .grow { flex: 1; }
.card > header .btn { margin-left: auto; }
.card > .body { padding: 18px; min-width: 0; }
.card > .flush { padding: 0; }

/* A tabela sempre vai até a borda do cartão. Colada em Ranking e recuada 18px em
   Empresas e na Meta de tratativa, a faixa cinza do cabeçalho começava em x
   diferentes de uma tela para a outra. O texto acima dela (legenda da matriz,
   barra de filtros) continua recuado. */
.card > .body > .tbl-wrap, .card > .body > div > .tbl-wrap,
.card > .body > div > div > .tbl-wrap { margin-inline: -18px; }
/* E encosta no fio do cabeçalho quando abre o corpo do cartão: sem isto sobrava uma
   faixa branca de 18px entre o fio e a faixa cinza do thead (Empresas), e no
   Ranking (.flush) os dois ficam colados. */
.card > header + .body > .tbl-wrap:first-child,
.card > header + .body > div:first-child > .tbl-wrap:first-child,
.card > header + .body > div:first-child > div:first-child > .tbl-wrap:first-child { margin-top: -18px; }

/* O espaço entre cartões é o gap da grade, e não gap MAIS a margem do cartão: os
   dois somados davam ~35px dentro da grade e 16px fora dela. */
.grid { display: grid; gap: var(--s4); align-items: start; margin-bottom: var(--s4); }
.grid:last-child { margin-bottom: 0; }
.grid > .card, .grid > div > .card { margin-bottom: 0; }
.grid.c2 { grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); }
/* Lado a lado, os dois cartões terminam na mesma linha: sem isto o rodapé da grade
   ficava serrilhado ("Precisam de atenção" 22px mais alto que "Vão bem"). O
   wrapper dos cartões que chegam depois (O que mais aparece, Onde acontece) vira
   coluna para o cartão de dentro poder esticar. */
.grid.c2 { align-items: stretch; }
.grid.c2 > div:has(> .card) { display: flex; flex-direction: column; }
.grid.c2 > .card, .grid.c2 > div > .card { height: 100%; display: flex; flex-direction: column; }
.grid.c2 .card > .body, .grid.c2 .card > .flush { flex: 1; }
.grid.c3 { grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); align-items: stretch; }
/* Cartões de passo: o texto é o cabeçalho e cresce; o botão fica preso ao pé. Com
   o fio entre os dois, um texto de 4 linhas punha o fio de um cartão 19px abaixo
   dos outros e a fileira parecia torta mesmo com os botões alinhados. */
.grid.c3 > .card { display: flex; flex-direction: column; }
.grid.c3 > .card > header { border-bottom: 0; flex: 1; align-items: flex-start; }
.grid.c3 > .card > .body { flex: 0; padding-top: 0; }

/* Régua de KPI: um bloco com divisórias internas, não um cartãozinho por número. */
.kpis {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  background: var(--surface); border: 1px solid var(--rule);
  border-radius: var(--r-lg); box-shadow: var(--sh-1); margin-bottom: var(--s4); overflow: hidden;
}
.kpi { padding: 15px 18px; border-right: 1px solid var(--rule); display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.kpi:last-child { border-right: 0; }
.kpi .k { font-size: var(--t-xs); color: var(--muted); font-weight: 600; }
.kpi .v { font-size: var(--t-2xl); font-weight: 800; letter-spacing: -.035em; line-height: 1.2; font-variant-numeric: tabular-nums lining-nums; }
/* Um valor que é palavra ou selo, e não número (o status do convite na Meta). */
.kpi .v.selo { font-size: var(--t-lg); letter-spacing: -.02em; }
.kpi .note { font-size: var(--t-xs); color: var(--muted); }

/* ==========================================================================
   Tabelas
   ========================================================================== */

/* position:relative prende aqui dentro o que é absoluto: o <span class="sr"> do
   cabeçalho ("Ações", "Abrir") não tinha ancestral posicionado, escapava da rolagem
   e alargava a página inteira no celular (436px a 360), com a folha de baixo junto. */
.tbl-wrap { overflow-x: auto; position: relative; -webkit-overflow-scrolling: touch; }
table { width: 100%; border-collapse: collapse; font-size: var(--t-sm); }
thead th {
  /* Sem position:sticky: .tbl-wrap rola no eixo X e não tem altura, então o cabeçalho
     nunca gruda em nada — a declaração só criava contexto de empilhamento à toa. */
  background: var(--surface-2); text-align: left; white-space: nowrap;
  font-size: var(--t-xs); font-weight: 800; letter-spacing: .045em; text-transform: uppercase;
  color: var(--muted); padding: 10px 16px; border-bottom: 1px solid var(--rule-2);
}
tbody td { padding: 12px 16px; border-bottom: 1px solid var(--rule); vertical-align: middle; color: var(--ink-2); }
tbody tr:last-child td { border-bottom: 0; }
/* O cabeçalho de linha (<th scope=row>, na matriz) com o mesmo recuo e o mesmo fio
   da célula comum: sem isto o nome da empresa ficava 15px à esquerda do cabeçalho
   da coluna e o fio só aparecia sob os números. */
tbody th { padding: 12px 16px; border-bottom: 1px solid var(--rule); text-align: left; font-weight: 700; color: var(--ink); }
tbody tr:last-child th { border-bottom: 0; }
tbody tr.clickable { cursor: pointer; }
tbody tr.clickable:hover td { background: var(--surface-2); }
td.r, th.r { text-align: right; }
td.strong { color: var(--ink); font-weight: 700; }
.cell-2 { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.cell-2 small { color: var(--muted); font-size: var(--t-xs); }
.trunc { display: block; max-width: 46ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Coluna que só existe no cartão do celular (a linha "meta 50 · 214 respostas" do
   Ranking): na tabela ela repetiria o que outra coluna já diz. */
th.so-cel, td.so-cel { display: none; }
/* A tabela que ainda rola para o lado é uma região focável (tabela() mede): a sombra
   na borda direita diz que há mais coluna além dela. O fundo fica preso à caixa e não
   à rolagem, então a sombra acompanha a borda. */
.tbl-wrap.rola {
  background: linear-gradient(to left, rgba(19, 19, 34, .10), rgba(19, 19, 34, 0)) right center / 18px 100% no-repeat;
}
.tbl-wrap:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
/* "Mostrar mais": a próxima página, sob a tabela e dentro do cartão. */
.tbl-mais { display: flex; justify-content: center; padding: 10px 18px 14px; border-top: 1px solid var(--rule); }
/* A saída do estado vazio ("Ver em 30 dias", "Ver todas as notas"), embaixo do texto. */
.empty-acao { margin-top: 14px; display: flex; justify-content: center; }
/* O número do NPS com a distância até a meta embaixo, em texto: a cor do farol
   sozinha não diz a quem não vê cor se a loja bateu a meta. */
.dif-meta { display: block; font-size: var(--t-xs); font-weight: 600; color: var(--muted); white-space: nowrap; }
/* A linha da loja do gerente, no Ranking: ele se acha sem ler a lista. */
tbody tr.minha > td { background: var(--accent-soft); }
tbody tr.minha > td.strong, tbody tr.minha .loja .nm { font-weight: 800; color: var(--ink); }
.etq-minha { vertical-align: middle; flex: none; }
.loja-linha { display: inline-flex; align-items: center; gap: 8px; min-width: 0; max-width: 100%; }
/* "6 de 50 respostas" com a barrinha de quanto falta, em Fora do ranking. */
.resp-meta { display: inline-flex; align-items: center; gap: 8px; white-space: nowrap; }
.resp-meta .meter { width: 60px; min-width: 60px; flex: none; }
.nps-prov { color: var(--muted-2); font-weight: 700; }
/* O pedaço de texto que só o cartão precisa (" respostas" depois do número). */
.so-cel-i, .rot-cel { display: none; }
/* A forma curta que vale até 980 (.so-medio, "há 2 meses" no lugar da data) e o que
   só existe no tablet, entre 721 e 980 (.so-tablet). Ver os @media 980 e 721-980. */
.so-medio, .so-tablet { display: none; }
/* Nota vazia: o traço apagado, sem o negrito de célula. */
.sem-nota { color: var(--muted-2); font-weight: 400; }
/* Comentários: o texto em peso 500 e na tinta, a loja apagada — o que o cliente
   escreveu é o que se lê primeiro. */
td.comentario { color: var(--ink); font-weight: 500; line-height: 1.45; }
td.loja-cel .nm { color: var(--muted); }
td.data-cel { white-space: nowrap; color: var(--muted); }
.ver-tk { white-space: nowrap; }
/* A fita de notas e o chip do assunto, acima do cartão de Comentários. */
.toolbar.filtros-nota { align-items: center; }
/* Filtro que veio de outra tela e se desfaz com um toque: "Assunto: Climatização ×". */
.chip-filtro {
  display: inline-flex; align-items: center; gap: 8px; min-height: 36px; padding: 4px 10px 4px 14px;
  border-radius: var(--r-full); border: 1px solid var(--accent-line); background: var(--accent-soft);
  color: var(--accent-ink); font: inherit; font-size: var(--t-sm); font-weight: 700; cursor: pointer;
}
.chip-filtro:hover { border-color: var(--accent); }
.chip-filtro .x { font-size: 18px; line-height: 1; font-weight: 600; }
/* A contagem dentro do chip de filtro ("Responderam 1.241"). */
.seg.chips button .n { font-variant-numeric: tabular-nums; opacity: .85; }
.card > header:last-child { border-bottom: 0; }

/* Loja = código + nome. O código é identificador: monoespaçado, discreto e
   sempre à esquerda do nome, para a leitura pegar os dois de uma vez. */
.loja { display: inline-flex; align-items: baseline; gap: 7px; min-width: 0; }
.loja .nm { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.cod {
  font-family: var(--f-id); font-size: var(--t-xs); font-weight: 500; letter-spacing: -.01em;
  color: var(--muted); background: var(--surface-3); border: 1px solid var(--rule);
  padding: 1px 6px; border-radius: var(--r-xs); white-space: nowrap; flex: none;
}
tbody tr:hover .cod { border-color: var(--rule-2); }

.lista-erro { margin: 5px 0 0 16px; padding: 0; }
.lista-erro li { margin: 3px 0; }

/* A mensagem como o cliente recebe. Não é enfeite: um texto truncado numa célula
   de tabela esconde justamente o que decide se a Meta aprova — o tamanho, a
   quebra de linha, o rodapé e os botões juntos. */
.zap { max-width: 380px; }
.zap-balao {
  background: #E8FBD9; border-radius: 12px 12px 12px 3px; padding: 9px 11px 7px;
  box-shadow: 0 1px 1px rgba(0,0,0,.12); position: relative;
}
.zap-corpo { font-size: 13.5px; line-height: 1.42; color: #111B21; white-space: pre-wrap; word-break: break-word; }
/* #54656F e não o #667781 do WhatsApp: aquele dá 4,25:1 sobre o verde do balão. */
.zap-footer { font-size: var(--t-xs); color: #54656F; margin-top: 7px; }
.zap-hora { font-size: var(--t-xs); color: #54656F; text-align: right; margin-top: 3px; }
.zap-btns { display: flex; flex-direction: column; gap: 2px; margin-top: 2px; }
.zap-btn {
  background: #fff; border-radius: 7px; padding: 9px; text-align: center;
  font-size: 13px; color: #0A7AB5; box-shadow: 0 1px 1px rgba(0,0,0,.12);
  display: flex; align-items: center; justify-content: center; gap: 6px;
}
/* O botão de link leva o ícone, como no WhatsApp; o texto nunca passa dele. */
.zap-btn svg { flex: none; }
.zap-btn span { min-width: 0; overflow-wrap: anywhere; }
/* Para onde o botão abre (com o token de exemplo): fora do balão, que é uma captura do WhatsApp e não
   mostra o endereço. Segue o tema do produto. */
.zap-end { margin-top: 8px; font-size: 12px; line-height: 1.45; color: var(--muted); overflow-wrap: anywhere; }
.zap-end .nome-tec { color: var(--ink-2); }
/* O balão é uma captura de tela do WhatsApp, não um componente do produto:
   as cores são as dele e não seguem o tema, de propósito. */

/* Diálogo de duas colunas: editar de um lado, ver do outro. */
.modal.largo { max-width: 940px; width: calc(100vw - 48px); }

/* Barra de escolha acima de um cartão: o que o cartão inteiro mostra depende
   dela (a empresa da árvore de categorias), então ela fica FORA do cartão. */
.toolbar {
  display: flex; align-items: center; gap: var(--s3); flex-wrap: wrap;
  margin-bottom: var(--s3);
}
.toolbar > label, .toolbar > .rotulo { font-size: 12.5px; font-weight: 700; color: var(--muted); }
.toolbar select { min-width: 220px; max-width: 100%; }
.toolbar .grow { flex: 1; }

/* Barra de FILTROS: vários controles pequenos na mesma linha, e não um seletor
   dominante. `select` herda `width: 100%` da regra base, então sem isto cada
   campo reivindica a linha inteira e a barra vira três linhas empilhadas. */
.toolbar.filtros select,
.toolbar.filtros input[type="search"] { flex: 0 1 250px; width: auto; min-width: 190px; }
/* O intervalo do Personalizado na fila: dois campos de data do tamanho da data, e
   nao da linha (a regra base da width: 100% a todo input). */
.toolbar.filtros .entre-datas { display: inline-flex; align-items: center; gap: var(--s2); flex-wrap: wrap; }
.toolbar.filtros input[type="date"] { width: auto; min-width: 0; flex: 0 0 auto; }
/* A fila: "Quem trata" e "Abertas em", cada um com o rótulo ao lado; "Escolher
   datas…" abre De e Até lado a lado, da mesma largura, com o rótulo em cima (o "até"
   solto entre dois campos saiu). No desktop o campo de data fica da altura dos
   outros controles da barra. */
.tk-barra { align-items: flex-end; }
.tk-filtro { display: flex; align-items: center; gap: var(--s2); min-width: 0; }
/* Largura explícita, e não flex-basis: o Chrome mede a barra pelo tamanho natural do
   select ("Todos", 80px), e com a base de 250px o select caía para baixo do rótulo. */
.toolbar.filtros .tk-filtro select { flex: none; width: 170px; min-width: 0; }
/* A linha "Filtros" do celular só existe até 720 (o @media lá embaixo). */
.tk-cel { display: none; }
.tk-periodo .so-select, .tk-periodo .tk-periodo-sel { display: none; }
/* Quem trata, Tipo e Criticidade, de escolha múltipla (app.js, multiSelecao): o botão
   tem a cara do select de antes — a mesma borda, o mesmo raio, a mesma seta —, 26px mais
   largo ("Detratores, Neutros" inteiro, sem reticências), e abre a caixinha das opções
   logo embaixo, por cima da tela. O filtro com
   escolha tem a borda de destaque: fechado, "Detratores" pesava o mesmo que "Todos".
   "Limpar" tira as escolhas, ao lado deles. */
.ms-caixa { position: relative; flex: none; width: 196px; min-width: 0; }
.ms-btn {
  display: block; width: 100%; min-height: 40px; font: inherit; text-align: left; cursor: pointer;
  color: var(--ink); background: var(--surface) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5 11 1.5' fill='none' stroke='%2363637E' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") no-repeat right 11px center;
  border: 1.5px solid var(--field-line); border-radius: var(--r-sm); padding: 8px 32px 8px 12px;
  transition: border-color .13s, box-shadow .13s;
}
.ms-btn:hover { border-color: var(--rule-3); }
.ms-btn.ativo { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); }
.ms-btn[aria-expanded="true"] { border-color: var(--accent); box-shadow: var(--anel); }
.ms-val { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ms-pop {
  position: absolute; top: calc(100% + 4px); left: 0; z-index: 40; min-width: 100%; width: max-content;
  max-width: min(320px, calc(100vw - 32px)); padding: 4px; background: var(--surface);
  border: 1px solid var(--rule-2); border-radius: var(--r-sm); box-shadow: var(--sh-3);
}
.ms-pop[hidden] { display: none; }
.ms-pop.ms-dir { left: auto; right: 0; }
.ms-ops { display: flex; flex-direction: column; gap: 2px; }
/* Uma opção por linha, a linha inteira tocável; 40px no mouse e 44 no dedo (abaixo). */
.ms-op {
  display: flex; align-items: center; gap: 10px; min-height: 40px; padding: 6px 10px;
  border-radius: var(--r-xs); cursor: pointer; font-size: var(--t-sm); font-weight: 500; color: var(--ink);
}
.ms-op:hover { background: var(--surface-3); }
.ms-op:has(input:checked) { background: var(--accent-soft); font-weight: 700; }
.ms-op input { width: 18px; height: 18px; min-width: 0; margin: 0; padding: 0; flex: none; accent-color: var(--accent); }
/* A árvore do Onde: cada nível recua 18px. A loja já incluída na região marcada fica
   marcada e apagada — ela está no filtro pela região, e não sai sozinha. */
.ms-op[style*="--nivel"] { padding-left: calc(10px + var(--nivel) * 18px); }
.ms-op.ms-coberta { color: var(--muted); font-weight: 500; cursor: default; }
.ms-op.ms-coberta:has(input:checked) { background: transparent; font-weight: 500; }
/* Lista comprida (a árvore de uma rede grande, os problemas do período): a caixinha rola
   por dentro, e não passa do fim da tela. */
.ms-pop { max-height: min(380px, 60vh); overflow-y: auto; overscroll-behavior: contain; }
/* "Todos" separado das opções: ele não é mais uma, é o "nenhum filtro". */
.ms-todos { margin-bottom: 3px; box-shadow: 0 4px 0 -3px var(--rule); }
.tk-limpar { align-self: center; }
.toolbar.filtros .entre-datas { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; width: min(100%, 360px); }
.toolbar.filtros .entre-datas .field { gap: 4px; }
.toolbar.filtros .entre-datas input[type="date"] { width: 100%; min-height: 38px; padding-block: 6px; }

.chk { display: inline-flex; align-items: center; gap: 7px; cursor: pointer; font-size: 12.5px; color: var(--muted); }
.chk input { width: 15px; height: 15px; margin: 0; accent-color: var(--accent); cursor: pointer; }
.chk:hover { color: var(--ink); }
/* A explicação sob uma caixa de marcar, alinhada ao texto dela e não à caixa: caixa
   de 15px + 7px de gap (22 e 29 no toque). A caixa vai sem a margem padrão do
   navegador (4px + 3px), que deixava a ajuda 7px à esquerda do texto. */
.chk-ajuda { color: var(--muted); font-size: var(--t-xs); margin-left: 22px; }

/* Vários botões no cabeçalho do cartão. Sem isto o `margin-left:auto` de
   `.card > header .btn` empurra cada um para um canto diferente. */
.btn-row { display: flex; align-items: center; gap: var(--s2); margin-left: auto; flex-wrap: wrap; }
.card > header .btn-row .btn { margin-left: 0; }

/* Ações na linha da tabela: quadradas, discretas, e só ganham cor no hover.
   Coloridas o tempo todo, doze linhas viram doze semáforos. */
.btn.ico { padding: 0; width: 32px; min-width: 32px; height: 32px; min-height: 32px; }
.btn.ico svg { display: block; margin: 0 auto; }
.row-acts { display: inline-flex; gap: 2px; justify-content: flex-end; }
.row-acts.quebra { flex-wrap: wrap; }
/* Discreta até o cursor chegar à linha, mas VISÍVEL: com opacity 0 ninguém
   descobria no desktop que dava para editar, e um notebook com tela de toque (o
   ponteiro principal é o mouse) nunca mostrava o lápis ao dedo. Em toque, cheia
   (ver o @media hover:none no fim). */
/* .75 e não .55: o ícone cinza (--muted) a 55% dava 2,3:1 sobre o branco, abaixo
   dos 3:1 de um controle. A 75% dá 3,4:1 (3,3:1 sobre a linha cinza) e continua
   mais apagado que no hover. */
tbody tr .row-acts { opacity: .75; transition: opacity .12s; }
tbody tr:hover .row-acts, tbody tr:focus-within .row-acts { opacity: 1; }
/* Subcategoria: recuo com fio, para a hierarquia ser visível sem ler o texto. */
td.ind { padding-left: 30px; position: relative; }
td.ind::before {
  content: ""; position: absolute; left: 18px; top: 50%; width: 7px;
  height: 1px; background: var(--rule-3);
}
/* A categoria abre o grupo; a subcategoria é subordinada. Sem esta diferença
   de peso as 27 linhas leem como uma lista plana e o recuo passa despercebido. */
tbody tr.grupo td { border-top: 1px solid var(--rule); }
tbody tr.grupo:first-child td { border-top: 0; }
td.ind .linkline { font-weight: 600; color: var(--ink-2); }

tbody tr.off td { color: var(--muted-2); }
tbody tr.off .linkline { color: var(--muted-2); font-weight: 600; }

/* Alvo focável dentro de uma linha clicável: o texto vira botão sem virar botão
   visualmente, para quem navega por teclado alcançar a gaveta de tratativa. */
.linkline {
  font: inherit; font-weight: 700; color: var(--ink); background: none; border: 0;
  padding: 0; margin: 0; text-align: left; cursor: pointer;
}
.linkline:hover { color: var(--accent); text-decoration: underline; }
/* "Sem região" é um link como os outros — clicar move a loja —, mas não é um
   nome: escrito com o mesmo peso, ele seria lido como o nome de uma região
   chamada "Sem região". */
.linkline.muted { color: var(--muted-2); font-weight: 600; font-style: italic; }


/* ==========================================================================
   Sinais
   ========================================================================== */

.tag {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: var(--t-xs); font-weight: 800; letter-spacing: .01em;
  padding: 3px 10px; border-radius: var(--r-full); white-space: nowrap;
  background: var(--surface-3); color: var(--ink-2); border: 1px solid var(--rule-2);
}
.tag::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; flex: none; }
.tag.plain::before { display: none; }
.tag.prom { background: var(--prom-soft); color: var(--prom-ink); border-color: var(--prom-line); }
.tag.neu  { background: var(--neu-soft);  color: var(--neu-ink);  border-color: var(--neu-line); }
.tag.det  { background: var(--det-soft);  color: var(--det-ink);  border-color: var(--det-line); }
.tag.acc  { background: var(--accent-soft); color: var(--accent); border-color: var(--accent-line); }

/* Verde, amarelo e vermelho de FUNDO são do cliente: promotor, neutro, detrator. Um
   estado de processo (aberta, resolvida, ativa, em cadastro) é outra pergunta, e
   pintá-lo com o mesmo fundo fazia um detrator resolvido ganhar pílula verde. O
   estado usa esta tag neutra, e a cor vai só no ponto. Sem modificador, sem ponto. */
.tag.st { background: var(--surface); border: 1px solid var(--rule-2); color: var(--ink-2); }
.tag.st::before { width: 7px; height: 7px; display: none; }
.tag.st.acao::before, .tag.st.ok::before, .tag.st.atencao::before, .tag.st.erro::before { display: block; }
.tag.st.acao::before    { background: var(--accent); }
.tag.st.ok::before      { background: var(--prom); }
.tag.st.atencao::before { background: var(--neu-mark); }
.tag.st.erro::before    { background: var(--det); }

/* A nota de 0 a 10 com a cor da classe dela. É a leitura mais rápida de uma linha
   da fila: o fundo diz a classe, o número diz o quanto. */
.nota-pill {
  display: inline-grid; place-items: center; min-width: 28px; height: 28px; padding: 0 5px;
  border-radius: 8px; font-weight: 800; font-size: 13px; font-variant-numeric: tabular-nums;
  background: var(--surface-3); color: var(--ink-2);
}
.nota-pill.prom { background: var(--prom-soft); color: var(--prom-ink); }
.nota-pill.neu  { background: var(--neu-soft);  color: var(--neu-ink); }
.nota-pill.det  { background: var(--det-soft);  color: var(--det-ink); }

.score { font-weight: 800; font-size: 16px; letter-spacing: -.03em; font-variant-numeric: tabular-nums; }
.score.pos { color: var(--prom-ink); } .score.mid { color: var(--neu-ink); } .score.neg { color: var(--det-ink); }

.stack { display: flex; height: 7px; border-radius: var(--r-full); overflow: hidden; min-width: 90px; background: var(--surface-3); }
.stack i { display: block; }
.stack .p { background: var(--prom); } .stack .n { background: var(--neu-mark); } .stack .d { background: var(--det); }

.meter { height: 7px; border-radius: var(--r-full); background: var(--surface-3); min-width: 80px; overflow: hidden; }
.meter i { display: block; height: 100%; background: var(--accent-3); border-radius: var(--r-full); }
.meter.warn i { background: var(--neu-mark); } .meter.bad i { background: var(--det); }

.legend { display: flex; gap: var(--s4); font-size: 12px; color: var(--muted); flex-wrap: wrap; }
.legend span { display: inline-flex; align-items: center; gap: 6px; font-weight: 600; }
.legend i { width: 9px; height: 9px; border-radius: 3px; display: block; }

/* ==========================================================================
   Formulários
   ========================================================================== */

.form { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: var(--s4); }
.form .field.full { grid-column: 1 / -1; }
.form-ft { display: flex; gap: 10px; align-items: center; justify-content: flex-end; flex-wrap: wrap; margin-top: var(--s4); padding-top: var(--s4); border-top: 1px solid var(--rule); }
/* A ação de perigo vai para a ESQUERDA, longe do Salvar (G15). No DOM ela vem por
   último, que é a ordem do celular (ver o @media 520 do fim). */
.form-ft > .acao-perigo, .modal > footer > .acao-perigo { order: -1; }
/* Quando o rodapé quebra em duas linhas (diálogo estreito com várias ações), a de
   perigo não pode cair a 8px do Salvar: com ela no rodapé, a linha de baixo fica a
   24px (G15). */
.form-ft:has(> .acao-perigo), .modal > footer:has(> .acao-perigo) { row-gap: var(--s6); }
/* "Campos com * são obrigatórios.", no topo de todo formulário com obrigatório. */
.obrig-nota { font-size: var(--t-sm); color: var(--muted); margin: 0 0 var(--s3); }
/* O erro de UM campo, logo embaixo dele (G14). Vermelho de tinta, com peso: a
   borda de 2px do campo e esta frase dizem a mesma coisa de dois jeitos. */
.erro-campo { font-size: var(--t-sm); font-weight: 600; color: var(--det-ink); line-height: 1.4; }
/* A frase no lugar do botão de perigo (a única empresa ativa não se desativa). */
.nota-rodape { order: -1; }
.msg { font-size: 13px; }
.msg.err { color: var(--det-ink); } .msg.ok { color: var(--prom-ink); }

/* ==========================================================================
   Estados
   ========================================================================== */

.empty { padding: 48px var(--s5); text-align: center; color: var(--muted); }
.empty h3 { font-size: 15px; color: var(--ink-2); margin-bottom: 5px; }
.empty p { font-size: 13px; max-width: 44ch; margin: 0 auto; }

.skel { padding: 18px; display: flex; flex-direction: column; gap: 11px; }
.skel i { display: block; height: 13px; border-radius: var(--r-xs);
  background: linear-gradient(90deg, var(--surface-3) 25%, var(--surface-2) 37%, var(--surface-3) 63%);
  background-size: 400% 100%; animation: shimmer 1.3s ease infinite; }
.skel i:nth-child(2) { width: 82%; } .skel i:nth-child(3) { width: 64%; } .skel i:nth-child(4) { width: 74%; }
@keyframes shimmer { 0% { background-position: 100% 50%; } 100% { background-position: 0 50%; } }

/* ==========================================================================
   Gaveta
   ========================================================================== */

.scrim { position: fixed; inset: 0; background: var(--scrim); z-index: 40; animation: fade .16s ease; }
@keyframes fade { from { opacity: 0; } }

.drawer {
  /* 680 e nao 580: com a tira da janela, as abas e o pe do campo de escrever,
     580 quebrava o pe em duas linhas. Duas gavetas usam esta regra: a da tratativa
     e, desde o lote 9, a da empresa. */
  position: fixed; top: 0; right: 0; bottom: var(--kb, 0px); width: min(680px, 100vw);
  background: var(--surface); z-index: 41; box-shadow: var(--sh-3);
  display: flex; flex-direction: column; animation: slide .22s cubic-bezier(.22,.8,.3,1);
  border-radius: var(--r-xl) 0 0 var(--r-xl);
}
@keyframes slide { from { transform: translateX(26px); opacity: .3; } }
/* A coluna que absorve a sobra da tabela: max-width 0 tira o texto do calculo
   de largura minima, width 100% da a ela o que sobrar. Sem isso, o texto
   impunha a propria largura e a tabela transbordava do cartao. */
td.relato { width: 100%; max-width: 0; }
/* A loja da fila numa linha só (ver app.js): o relato com width 100% espreme as outras
   colunas até a menor largura. Embaixo dela, em 12px, quem trata ("SAC central"). */
td.tk-loja { white-space: nowrap; }
td.tk-loja .tk-destino { display: block; font-size: var(--t-xs); font-weight: 500; color: var(--muted); margin-top: 2px; }
/* O que o cliente disse, em até 2 linhas, com o chip de risco na frente. Numa linha
   só, a 1440 sobrava "Fila muito …" e a fila não dizia do que o cliente reclamou. */
table.fila td.relato { min-width: 40%; }
table.fila td.relato .trunc {
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  white-space: normal; max-width: none; overflow: hidden; color: var(--ink);
}
table.fila td.relato .tk-riscos .risco { margin-right: 6px; vertical-align: 1px; }
/* Com quem está: até duas linhas de 14 letras, quebrando entre as palavras, e só então
   as reticências (o nome inteiro no title). Numa linha só, a 768 o nome virava
   "Gestor da R…" e não dizia com quem estava (auditoria). "ninguém" apagado — é
   ausência, não uma pessoa. */
table.fila td.tk-com { max-width: 14ch; }
table.fila td.tk-com .tk-com-n {
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
  line-height: 1.35;
}
/* A 1440 sobra largura: "Gerente Re…" e "Atendente …" cortados não diziam com quem está
   a tratativa (auditoria). O title continua. */
@media (min-width: 1280px) {
  table.fila td.tk-com { max-width: 22ch; }
  table.fila td.tk-com .tk-com-n { display: block; white-space: nowrap; text-overflow: ellipsis; }
}
table.fila .ninguem { color: var(--muted); }
table.fila td.tk-prazo, table.fila td.tk-idade { white-space: nowrap; }
table.fila td.tk-prazo .so-cel-i { display: none; }
/* Data e hora na fila: uma linha so, a hora mais apagada. */
.dh { white-space: nowrap; }
.dh .hora { color: var(--muted); }
/* Em notebook de 1280-1366 px, dia e hora lado a lado nas duas colunas deixavam
   o relato com 77 px e a tabela passando do cartao. Empilhados, cabem. */
@media (max-width: 1400px) { .dh .hora { display: block; } }
/* A gaveta remontada por uma acao dela (assumir, nota): nao entra de novo. */
.drawer.sem-anim, .scrim.sem-anim { animation: none; }

/* ==========================================================================
   A conversa com o cliente, dentro da gaveta do ticket.
   Prefixo conv-: `.msg` ja existe e e a mensagem de formulario (.msg.err pinta
   de vermelho). Chamar o balao de .msg faria a conversa herdar a cor de erro de
   uma regra sem relacao com ela.
   ========================================================================== */
.janela-tira { flex-basis: 100%; display: flex; gap: var(--s2); flex-wrap: wrap; }
.aba-conversa, .aba-caso { display: flex; flex-direction: column; gap: var(--s4); }
.aba-caso { gap: var(--s5); }
.conv-contexto { font-size: 13px; }
.conv { display: flex; flex-direction: column; gap: 10px; }
.conv-item { display: flex; flex-direction: column; max-width: 80%; }
.conv-item.ent { align-self: flex-start; }
.conv-item.sai { align-self: flex-end; align-items: flex-end; }
.conv-autor { font-size: var(--t-xs); font-weight: 700; color: var(--muted); margin-bottom: 3px; }
.conv-b {
  padding: 9px 12px; font-size: 13.5px; line-height: 1.45; border: 1px solid;
  white-space: pre-wrap; overflow-wrap: anywhere; text-align: left;
}
/* Cliente a esquerda, entalhe a esquerda — o mesmo desenho da previa do convite. */
.conv-item.ent .conv-b { background: var(--surface); border-color: var(--rule-2); border-radius: 12px 12px 12px 3px; }
.conv-item.sai .conv-b { background: var(--accent-soft); border-color: var(--accent-line); border-radius: 12px 12px 3px 12px; }
/* Automatica do MESMO lado do atendente (no celular do cliente e o mesmo
   remetente), em cinza: mesmo lado diz quem fala, a cor diz quem responde. */
.conv-item.auto .conv-b { background: var(--surface-3); border-color: var(--rule); }
.conv-item.voando .conv-b { opacity: .66; }
.conv-meta { font-size: var(--t-xs); color: var(--muted); margin-top: 3px; }
.conv-meta.duvida { color: var(--neu-ink); font-weight: 700; }
.conv-meta.ruim { color: var(--det-ink); font-weight: 700; }
/* A nota interna NAO e balao: faixa de largura inteira. */
.conv-nota {
  align-self: stretch; background: var(--neu-soft); border-left: 3px solid var(--neu-mark);
  border-radius: var(--r-xs); padding: 9px 12px; font-size: 13px; color: var(--ink-2);
}
.conv-nota .conv-autor { color: var(--neu-ink); text-transform: uppercase; letter-spacing: .06em; }
.compositor {
  border-top: 1px solid var(--rule); padding-top: var(--s3);
  display: flex; flex-direction: column; gap: 8px;
}
.compositor textarea { min-height: 76px; }
.compositor-pe { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.compositor-pe .grow { flex: 1; }
.compositor .explica { font-size: var(--t-sm); color: var(--muted); }
.compositor .explica.bloqueio { color: var(--ink-2); }

/* O bloco que inicia a conversa do SAC pelo modelo de abertura. */
.abertura {
  border: 1px solid var(--rule); border-radius: var(--r-md); background: var(--surface-2);
  padding: 12px 14px; display: flex; flex-direction: column; gap: 10px;
}
.abertura-espera { font-size: 13px; color: var(--ink-2); }

/* Passo a passo de conexao do WhatsApp, na tela de Canais. Cada passo tem o
   estado conferido na frente: "feito" ou "falta", e nunca uma lista de tarefas
   que o operador precisa lembrar de marcar. */
.passos-con { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 12px; }
.passo-con { display: grid; grid-template-columns: 58px 1fr; gap: 10px; align-items: start; }
.passo-con > div { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.passo-con .tag { justify-self: start; }
.copia-linha { display: inline-flex; align-items: center; gap: 4px; flex-wrap: wrap; }
.copia-linha code { overflow-wrap: anywhere; }
.drawer > header { padding: 10px 14px 0 20px; border-bottom: 1px solid var(--rule); }
.drawer > header h2 { font-size: 17px; letter-spacing: -.03em; }
.drawer > header h2:focus { outline: none; }
.drawer > header h2:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px; }
.drawer > header .sub { font-size: var(--t-sm); color: var(--muted); margin-top: 3px; }
/* O cabeçalho fixo da tratativa em duas linhas e as abas (lote 5): "Tratativa #799",
   o status e o X; "Eldorado · Cliente 165" numa linha, com reticências; e a fita
   Conversa | Caso, que nunca sai da vista ao rolar. O prazo e o "Aberta em" desceram
   para o corpo: com eles aqui, a 360 o cabeçalho passava de um terço da tela. */
.tk-hd-l1 { display: flex; align-items: center; gap: 10px; min-height: 36px; }
/* O número nunca corta: é ele que identifica o caso para o gerente e para o SAC. Com o
   texto em 130%, ou com id de 6 dígitos e "Aguardando cliente", o título virava
   "Trata…". Quem ganha as reticências é o status ("Em anda…"), só na tela: o texto
   inteiro continua no DOM para o leitor de tela; o mínimo deixa à vista o ponto da cor. */
.tk-hd-l1 h2 { flex: none; white-space: nowrap; }
.tk-hd-l1 > .tag { flex: 0 1 auto; min-width: 30px; overflow: hidden; }
.tk-hd-l1 > .tag > .tk-st { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tk-hd-l1 .tk-x { margin-left: auto; flex: none; }
/* Com o texto em 130% (360 vira 277), "Tratativa #123456" e o X tomam quase a linha, e
   o status encolhia até o mínimo de 30px — só o ponto e meia reticência. Ali ele desce
   para a linha de baixo, inteiro, e o X fica no canto (lote 11). */
@media (max-width: 300px) {
  .tk-hd-l1 { display: grid; grid-template-columns: minmax(0, 1fr) auto; row-gap: 2px; }
  .tk-hd-l1 > .tag { grid-column: 1 / -1; grid-row: 2; justify-self: start; min-width: 0; max-width: 100%; }
  .tk-hd-l1 .tk-x { grid-column: 2; grid-row: 1; }
  .tk-hd-l1 h2 { justify-self: start; max-width: 100%; }
}
.tk-hd-l2 { margin-top: 0 !important; padding-right: 6px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* As abas da gaveta sublinhadas, na largura do cabeçalho: a fita de caixinha (fundo,
   borda e 3px de recuo) somava 8px a cada linha, e a 360 cada pixel do cabeçalho é um
   pixel a menos da frase do cliente. */
.drawer > header > .tabs {
  display: grid; grid-auto-flow: column; grid-auto-columns: max-content; gap: 0;
  margin: 6px 0 -1px -6px; padding: 0; background: none; border: 0; border-radius: 0; width: auto;
}
.drawer > header > .tabs .tab {
  border-radius: 0; background: none; box-shadow: none; padding: 9px 14px 10px;
  border-bottom: 2.5px solid transparent; color: var(--muted); font-size: 13.5px;
}
.drawer > header > .tabs .tab.on { color: var(--accent-ink); border-bottom-color: var(--accent); background: none; box-shadow: none; }
.drawer .body { flex: 1; overflow-y: auto; padding: 16px 20px; display: flex; flex-direction: column; gap: var(--s5); }
/* Nenhum bloco do corpo encolhe: em coluna flex com altura presa, a conversa longa
   espremia a citação e o bloco do WhatsApp até sobrepô-los. */
.drawer .body > * { flex-shrink: 0; }
.drawer > footer { border-top: 1px solid var(--rule); padding: 12px 20px calc(12px + env(safe-area-inset-bottom)); display: flex; align-items: center; gap: var(--s2); flex-wrap: wrap; background: var(--surface-2); }
.drawer > footer .grow { flex: 1; }
/* "Mais ações" só existe no celular: no desktop as ações ficam à vista. */
.drawer > footer .tk-mais { display: none; }

/* O alto do corpo: o prazo e "Aberta em 05/09 12:31 · com ninguém", nas duas abas. */
.tk-topo { display: flex; align-items: center; gap: 6px 10px; flex-wrap: wrap; }
.tk-topo-txt { font-size: var(--t-sm); color: var(--muted); }
/* O que o cliente disse: a nota, o risco e a frase em 15px, no começo das duas abas. */
.tk-citacao { display: flex; flex-direction: column; gap: 7px; }
.tk-cit-selos { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.tk-cit-txt { font-size: 15px; line-height: 1.5; color: var(--ink); white-space: pre-wrap; overflow-wrap: anywhere; }
/* Os fatos numa linha de texto, sem caixas (13px): "Nota 4 de 10 · Gravidade 4 · Alta · …". */
.tk-fatos { font-size: 13px; color: var(--ink-2); line-height: 1.55; }
.tk-assunto { font-size: 13px; color: var(--ink-2); }
.tk-assunto .k { color: var(--muted); font-weight: 600; }
.tk-bloco { display: flex; flex-direction: column; gap: 7px; }
.tk-bloco > p { font-size: 13.5px; color: var(--ink-2); }
/* O bloco do WhatsApp do SAC: o título diz por qual número se fala. */
.tk-zap-tit { font-size: 14px; font-weight: 700; letter-spacing: -.01em; color: var(--ink); }
.tk-zap-frase { font-size: 13px; color: var(--ink-2); }
.tk-como > summary { cursor: pointer; font-size: 13px; font-weight: 700; color: var(--accent-ink); width: max-content; }
.tk-como > p { font-size: 13px; color: var(--muted); margin-top: 6px; }
.tk-orienta p { font-size: 13.5px; color: var(--ink-2); }

.facts { display: grid; grid-template-columns: repeat(auto-fit, minmax(92px, 1fr)); gap: 1px; background: var(--rule); border: 1px solid var(--rule); border-radius: var(--r-md); overflow: hidden; }
.facts div { background: var(--surface); padding: 11px 13px; min-width: 0; }
.facts .k { font-size: var(--t-xs); color: var(--muted); font-weight: 600; }
.facts .v { font-size: 17px; font-weight: 800; letter-spacing: -.03em; font-variant-numeric: tabular-nums; }
/* Fato que é palavra ("A loja", "Central") e não número: no tamanho do número ele
   quebra a caixa em duas linhas. */
.facts .v.palavra { font-size: var(--t-sm); letter-spacing: 0; }

.quote { position: relative; padding: 2px 0 2px 16px; color: var(--ink); font-size: 14.5px; }
.quote::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
  border-radius: var(--r-full); background: var(--accent-line);
}

.timeline { display: flex; flex-direction: column; }
.tl { display: grid; grid-template-columns: 24px 1fr; gap: var(--s3); padding-bottom: var(--s4); position: relative; }
.tl:not(:last-child)::before { content: ""; position: absolute; left: 11px; top: 22px; bottom: 0; width: 1.5px; background: var(--rule); }
.tl .pin { width: 23px; height: 23px; border-radius: var(--r-full); background: var(--surface-3); border: 1.5px solid var(--rule-2); display: grid; place-items: center; z-index: 1; }
.tl .pin i { width: 7px; height: 7px; border-radius: 50%; background: var(--muted-2); }
.tl.acc .pin { background: var(--accent-soft); border-color: var(--accent-line); } .tl.acc .pin i { background: var(--accent); }
.tl.ok .pin  { background: var(--prom-soft); border-color: var(--prom-line); }  .tl.ok .pin i { background: var(--prom); }
.tl .txt b { font-size: 13px; font-weight: 700; }
.tl .txt small { color: var(--muted); font-size: var(--t-xs); }
.tl .txt p { font-size: 13.5px; color: var(--ink-2); margin-top: 2px; }

/* ==========================================================================
   Modal
   ========================================================================== */

.modal {
  position: fixed; z-index: 45; top: 50%; left: 50%; transform: translate(-50%, -50%);
  width: min(470px, calc(100vw - 28px)); max-height: calc(100dvh - 40px);
  background: var(--surface); border-radius: var(--r-xl); box-shadow: var(--sh-3);
  display: flex; flex-direction: column; overflow: hidden;
  animation: pop .17s cubic-bezier(.22,.8,.3,1);
}
@keyframes pop { from { transform: translate(-50%, -47%) scale(.97); opacity: 0; } }
.modal > header { padding: 20px 22px 0; }
.modal > header h3 { font-size: 17px; letter-spacing: -.03em; }
.modal > header p { font-size: 13px; color: var(--muted); margin-top: 5px; }
.modal .body { padding: 18px 22px; display: flex; flex-direction: column; gap: var(--s3); overflow-y: auto; }
.modal > footer { padding: 14px 22px; background: var(--surface-2); border-top: 1px solid var(--rule); display: flex; justify-content: flex-end; align-items: center; gap: var(--s2); flex-wrap: wrap; }
/* O foco vai para a caixa ao abrir no toque (o teclado não sobe sozinho): ela
   anuncia o diálogo ao leitor de tela, e o contorno em volta dele inteiro não
   ajudaria ninguém que enxerga. */
.modal:focus { outline: none; }
/* Modal estreito é sempre uma coluna (G13): em 470px, duas colunas de 190px
   espremiam o rótulo e mandavam o erro de um campo para baixo do outro. */
.modal:not(.largo) .form { grid-template-columns: 1fr; }

/* ==========================================================================
   O Resumo (lote 6). A faixa de sete caixas iguais saiu: o NPS tinha a largura de
   "Enviadas", quatro caixas coloridas disputavam o olho e o NPS amarelo se confundia
   com os neutros. No lugar, "Precisa de você" e três cartões com hierarquia.
   ========================================================================== */

/* "Precisa de você": linhas tocáveis de 56px, de borda a borda do cartão, com o
   número grande à esquerda e a seta à direita. */
.urg-linha {
  display: flex; align-items: center; gap: 14px; width: 100%; min-height: 56px;
  padding: 8px 18px; margin: 0; background: none; border: 0; border-top: 1px solid var(--rule);
  font: inherit; text-align: left; color: var(--ink); cursor: pointer;
}
.urg > :first-child { border-top: 0; }
.urg-linha:hover { background: var(--surface-2); }
.urg-linha:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.urg-n {
  flex: none; min-width: 2ch; font-size: var(--t-2xl); font-weight: 800; letter-spacing: -.035em;
  line-height: 1; color: var(--ink); font-variant-numeric: tabular-nums lining-nums;
}
/* Na linha larga, 3ch: com "30" numa linha e "118" na outra, as frases começavam em x
   diferentes. No celular não: os 17px a mais mandavam "discriminação" para uma
   terceira linha. */
@media (min-width: 721px) { .urg-n { min-width: 3ch; } }
.urg-t { flex: 1; min-width: 0; font-weight: 600; color: var(--ink-2); line-height: 1.35; }
.urg-seta { flex: none; color: var(--muted); }
.urg-nada { margin: 0; padding: 16px 18px; font-weight: 600; color: var(--ink-2); }
.urg-retorno { margin: 0; padding: 12px 18px 14px; border-top: 1px solid var(--rule); font-size: var(--t-sm); color: var(--ink-2); }
/* As da loja que estão com o SAC: uma linha discreta, tocável (44px), sem o número grande. */
.urg-sac { display: flex; align-items: center; width: 100%; min-height: 44px; margin: 0; padding: 10px 18px;
  border-top: 1px solid var(--rule); font-size: var(--t-sm); font-weight: 600; color: var(--accent-ink); text-align: left; }
/* Com risco (saúde, Procon...) entre as que estão com o SAC: sobe de "discreta" para urgente. */
.urg-sac-risco { color: var(--det-ink); font-weight: 800; }
/* A proposta C (dono, 11/10/2026): a faixa da gravidade na borda, o ícone num círculo, o número na frase. */
.urg-linha { position: relative; align-items: center; padding-block: 12px; }
.urg-faixa { position: absolute; left: 0; top: 10px; bottom: 10px; width: 5px; border-radius: 0 4px 4px 0; background: var(--rule-2); }
.urg-linha.risco .urg-faixa { background: var(--det); }
.urg-linha.prazo .urg-faixa { background: var(--neu); }
.urg-linha.loja  .urg-faixa { background: var(--accent); }
.urg-ic { flex: none; width: 44px; height: 44px; border-radius: 50%; display: grid; place-items: center; font-size: 21px; line-height: 1;
  background: var(--surface-3); }
.urg-linha.risco .urg-ic { background: var(--det-soft); }
.urg-linha.prazo .urg-ic { background: var(--neu-soft); }
.urg-linha.loja  .urg-ic { background: var(--accent-soft); }
.urg-t { color: var(--ink); font-weight: 700; }
.urg-t .urg-n { font-size: 22px; min-width: 0; margin-right: 2px; }
.urg-linha.risco .urg-n { color: var(--det-ink); }
.urg-linha.prazo .urg-n { color: var(--neu-ink); }
.urg-tag { display: inline-block; margin-left: 8px; padding: 2px 8px; border-radius: var(--r-full); background: var(--det); color: #fff;
  font-size: 11px; font-weight: 800; vertical-align: 2px; }
.urg-apoio { display: block; margin-top: 3px; font-size: 12px; font-weight: 600; color: var(--muted); }
.urg-barra { display: block; height: 6px; max-width: 320px; margin-top: 6px; border-radius: var(--r-full); background: var(--surface-3); overflow: hidden; }
.urg-barra > i { display: block; height: 100%; background: var(--neu); border-radius: var(--r-full); }
.urg-nada { display: flex; align-items: center; gap: 12px; }
.urg-nada .urg-ic { background: var(--prom-soft); }
.urg-nada b { color: var(--ink); }

/* Primeiros passos (lote 11): uma linha recolhida de 56px no topo do Resumo, com a
   cara do cabeçalho de cartão (a borda de 1px entra na conta: 54 + 2). Aberta, um
   passo por linha: o texto e o selo à esquerda, "Fazer agora" à direita, sempre na
   mesma linha do passo — a 360 o texto quebra, o botão não. O prefixo pp-: .passo é
   o cartão de cada passo de Mensagens ao cliente, e a regra daqui o deitava de lado. */
.card.pp > summary {
  display: flex; align-items: center; gap: var(--s3); min-height: 54px; padding: 8px 18px;
  cursor: pointer; list-style: none; font-weight: 700; color: var(--ink);
}
.card.pp > summary::-webkit-details-marker { display: none; }
.card.pp > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.card.pp[open] > summary { border-bottom: 1px solid var(--rule); }
.pp-tit { min-width: 0; }
.pp-seta { display: inline-block; color: var(--muted); transition: transform .15s; }
.card.pp[open] .pp-seta { transform: rotate(90deg); }
.pp-lista { list-style: none; margin: 0; padding: 0; }
.pp-item {
  display: flex; align-items: center; gap: var(--s3); min-height: 56px;
  padding: 8px 18px; border-top: 1px solid var(--rule);
}
.pp-item:first-child { border-top: 0; }
.pp-txt { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.pp-t { font-weight: 600; color: var(--ink); line-height: 1.35; }
.pp-item.feito .pp-t { color: var(--muted); }
.pp-meta { display: flex; align-items: center; flex-wrap: wrap; gap: 4px 8px; font-size: var(--t-xs); color: var(--muted); }
.pp-det { color: var(--ink-2); }
.pp-item > .btn { flex: none; white-space: nowrap; }
.pp-pe { display: flex; justify-content: flex-end; padding: 4px 10px; border-top: 1px solid var(--rule); }
@media (max-width: 720px) {
  .card.pp > summary, .pp-item { padding-inline: 15px; }
}

/* Redes (lote 11): "Você está nesta rede" embaixo do nome da rede escolhida. */
.rede-aqui { font-size: var(--t-xs); color: var(--muted); font-weight: 600; }
/* Auditoria: o endereço interno embaixo do nome, e o que falta numa rede ("2 sem ERP",
   "sem gestor") em tom de atenção, ao lado do número. */
.rede-slug { font-size: var(--t-xs); color: var(--muted); font-weight: 400; }
.rede-falta { color: var(--det-ink); font-weight: 600; }
/* O endereço e o "desde" são dois blocos (app.js, linhaRede): a quebra cai entre eles,
   e o "desde 03/10/2026" nunca se parte. */
.rede-parte { display: inline-block; max-width: 100%; }
.rede-desde { white-space: nowrap; }
/* A rede desativada (db/036): quando, por quem e o motivo, embaixo do endereço. O
   motivo é texto livre: quebra onde precisar, sem empurrar a tabela para o lado. */
.rede-desativada { display: block; margin-top: 2px; font-size: var(--t-xs); color: var(--ink-2);
  font-weight: 400; overflow-wrap: anywhere; }
/* Tablet em pé: a tabela de Redes cabe sem rolar. Sem as larguras do desktop (que
   somavam mais que a tela), com menos recuo, e o cabeçalho podendo quebrar
   ("Respostas / em 7 dias"); "Mensagens no mês" já saiu (p: 3). */
@media (min-width: 721px) and (max-width: 980px) {
  table.tbl-redes th { width: auto !important; white-space: normal; }
  table.tbl-redes th, table.tbl-redes td { padding-inline: 10px; }
}
/* O "Mudar" do endereço interno, na dica do nome: 44px de largura também. */
.hint .linkbtn { min-width: 44px; justify-content: center; }

/* O topo: NPS, como avaliaram e o retorno. Os três terminam na mesma linha (a grade
   estica o cartão, e o corpo cresce). Na "Minha loja" são dois. */
.topo-painel { display: grid; grid-template-columns: 1.1fr 1.5fr 1fr; gap: var(--s4); margin-bottom: var(--s4); }
.topo-painel.dois { grid-template-columns: 1fr 1.4fr; }
.topo-painel > .card { margin-bottom: 0; display: flex; flex-direction: column; min-width: 0; }
.topo-painel > .card > .body { flex: 1; }
/* Lado a lado, os três cabeçalhos com a altura do que tem a tag (NPS): sem isto a linha
   de baixo do cabeçalho do NPS ficava 7px abaixo da dos vizinhos. Numa coluna só (o
   celular) cada um fica com a sua. */
@media (min-width: 721px) { .topo-painel > .card > header { min-height: 56px; } }

/* O NPS na tinta, e não na cor do farol: o estado está na tag do canto e na barra. */
.nps-num {
  font-size: var(--t-hero); font-weight: 800; letter-spacing: -.04em; line-height: 1.02;
  color: var(--ink); font-variant-numeric: tabular-nums lining-nums; margin-bottom: 10px;
}
.nps-cartao .alvo-barra { margin-bottom: 8px; }
.nps-linha { margin: 0; font-size: var(--t-sm); color: var(--muted); }
.nps-linha + .nps-linha { margin-top: 2px; }
.nps-meta, .nps-amostra { color: var(--ink-2); font-weight: 600; }
/* Sem amostra, a barra não leva cor de farol nenhuma. */
.alvo-barra.neutra > i { background: var(--muted); }

/* O <details> de texto: "O que é NPS?", "Ver detalhe da meta", "Ver os números". */
.abre { margin-top: 10px; }
.abre > summary {
  cursor: pointer; width: max-content; max-width: 100%; padding-block: 4px;
  font-size: var(--t-sm); font-weight: 700; color: var(--accent-ink);
}
.abre > p { margin: 6px 0 0; font-size: var(--t-sm); color: var(--ink-2); }
.abre > .tbl-wrap { margin: 8px -18px 0; }

/* Como os clientes avaliaram: a pilha na largura toda e o trio embaixo dela. */
.card-avaliaram .stack { height: 12px; min-width: 0; }
.cls-trio { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; margin-top: 14px; }
.cls { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.cls-n { font-size: var(--t-2xl); font-weight: 800; letter-spacing: -.035em; line-height: 1.15; font-variant-numeric: tabular-nums lining-nums; }
.cls-k { display: inline-flex; align-items: center; gap: 5px; font-size: var(--t-sm); font-weight: 700; }
.cls-k svg { flex: none; }
/* Sem transparência (G1): com opacity .75 o percentual caía para 3,25:1. */
.cls-p { font-size: var(--t-sm); font-weight: 600; }
.cls.prom > * { color: var(--prom-ink); }
.cls.neu  > * { color: var(--neu-ink); }
.cls.det  > * { color: var(--det-ink); }
/* Os três cartões do topo com a cara aprovada pelo dono (11/10/2026). */
.card-nps { position: relative; overflow: hidden; }
.card-nps::before { content: ''; position: absolute; inset: 0; pointer-events: none; }
.card-nps > * { position: relative; }
.card-nps.humor-det::before  { background: radial-gradient(120% 90% at 15% 0%, rgba(244, 45, 94, .14), transparent 62%); }
.card-nps.humor-neu::before  { background: radial-gradient(120% 90% at 15% 0%, rgba(240, 162, 2, .20), transparent 62%); }
.card-nps.humor-bom::before  { background: radial-gradient(120% 90% at 15% 0%, rgba(123, 201, 111, .22), transparent 62%); }
.card-nps.humor-prom::before { background: radial-gradient(120% 90% at 15% 0%, rgba(0, 161, 112, .18), transparent 62%); }
.nps-topo { display: flex; align-items: center; gap: 14px; margin-bottom: 4px; }
.nps-topo .nps-num { margin-bottom: 0; }
.nps-rosto { flex: none; width: 64px; height: 64px; border-radius: 50%; background: var(--surface); display: grid; place-items: center;
  font-size: 36px; line-height: 1; box-shadow: 0 0 0 6px rgba(19, 19, 34, .05); }
.humor-det .nps-rosto  { box-shadow: 0 0 0 6px rgba(244, 45, 94, .14); }
.humor-neu .nps-rosto  { box-shadow: 0 0 0 6px rgba(240, 162, 2, .20); }
.humor-bom .nps-rosto, .humor-prom .nps-rosto { box-shadow: 0 0 0 6px rgba(0, 161, 112, .16); }
.nps-zona { font-size: var(--t-sm); font-weight: 800; color: var(--ink-2); }
.humor-det .nps-zona { color: var(--det-ink); }
.humor-neu .nps-zona { color: var(--neu-ink); }
.humor-bom .nps-zona, .humor-prom .nps-zona { color: var(--prom-ink); }
.nps-regua { position: relative; height: 12px; margin: 16px 11px 6px; border-radius: var(--r-full);
  background: linear-gradient(90deg, var(--det) 0 50%, var(--neu) 50% 75%, #7BC96F 75% 87.5%, var(--prom) 87.5%); }
.nps-pino { position: absolute; top: 50%; width: 22px; height: 22px; border-radius: 50%; background: var(--surface);
  border: 3px solid var(--ink); transform: translate(-50%, -50%); box-shadow: 0 1px 3px rgba(19, 19, 34, .25); }
.nps-regua-meta { position: absolute; top: -6px; bottom: -6px; width: 2px; margin-left: -1px; background: var(--ink); }
.nps-regua-leg { position: relative; display: flex; justify-content: space-between; margin: 0 0 10px;
  font-size: 11px; font-weight: 600; color: var(--muted); }
.nps-regua-alvo { position: absolute; top: 0; transform: translateX(-50%); color: var(--ink-2); font-weight: 700; white-space: nowrap; }
.anima-cresce .nps-pino { animation: nps-pino .9s calc(var(--atraso, 0ms) + 300ms) cubic-bezier(.2, .8, .3, 1) both; }
@keyframes nps-pino { from { left: 50%; } }

.cls-frase { margin: 0 0 14px; font-size: 19px; font-weight: 800; line-height: 1.25; color: var(--ink); }
.cls-frase-det { color: var(--det-ink); }
.card-avaliaram .cls-trio { margin-top: 0; gap: 10px; }
button.cls.cls-quadro { margin: 0; padding: 12px 10px; border-radius: var(--r-md, 14px); text-align: center; align-items: center; gap: 2px; }
.cls-quadro.prom { background: var(--prom-soft); }
.cls-quadro.neu  { background: var(--neu-soft); }
.cls-quadro.det  { background: var(--det-soft); }
.cls-quadro.prom:hover { background: var(--prom-soft); }
.cls-quadro.neu:hover  { background: var(--neu-soft); }
.cls-quadro.det:hover  { background: var(--det-soft); }
.cls-rosto { font-size: 28px; line-height: 1.1; }
.cls-quadro .cls-k { justify-content: center; font-size: 12px; }
.cls-quadro .alvo-barra { align-self: stretch; height: 6px; margin-top: 8px; background: rgba(255, 255, 255, .85); }

.ret-linha { display: flex; align-items: center; gap: 16px; }
.ret-anel { flex: none; width: 112px; height: 112px; }
.ret-lado { flex: 1; min-width: 0; }
.ret-lado .ret-sub { margin-bottom: 0; }
.ret-lado .ret-acao { margin-top: 10px; }
.ret > .abre { margin-top: 12px; }
.ret-anel-fundo { fill: none; stroke: var(--surface-3); stroke-width: 13; }
.ret-anel-cheio { fill: none; stroke: var(--prom); stroke-width: 13; stroke-linecap: round; }
.ret-anel-cheio.amarelo { stroke: var(--neu-mark, var(--neu)); }
.ret-anel-cheio.vermelho { stroke: var(--det); }
.ret-anel-cheio.neutra { stroke: var(--muted); }
.ret-anel-meta { stroke: var(--ink); stroke-width: 3; stroke-linecap: round; }
.ret-anel-pct { font: 800 22px Manrope, system-ui, sans-serif; fill: var(--ink); }
.anima-cresce .ret-anel-cheio { animation: ret-anel 1s calc(var(--atraso, 0ms) + 300ms) cubic-bezier(.2, .8, .3, 1) both; }
@keyframes ret-anel { from { stroke-dashoffset: var(--volta); } }
@media (max-width: 300px) {
  .ret-linha { flex-direction: column; align-items: flex-start; }
  .card-avaliaram .cls-quadro { flex-direction: column; }
}
@media (prefers-reduced-motion: reduce) {
  .anima-cresce .nps-pino, .anima-cresce .ret-anel-cheio { animation: none; }
}
.cls-rodape { margin: 14px 0 0; padding-top: 12px; border-top: 1px solid var(--rule); font-size: var(--t-sm); color: var(--muted); }

/* Retorno aos insatisfeitos: "x de y" grande, a barra contra a meta e o botão. */
/* 8px entre o número e a tag: com 10, a 1440 "375 de 513" e "Abaixo da meta" passavam
   1px da largura do cartão e a tag descia sozinha para a linha de baixo. */
.ret-topo { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 4px 8px; }
.ret-num { font-size: var(--t-2xl); font-weight: 800; letter-spacing: -.035em; line-height: 1.15; color: var(--ink); font-variant-numeric: tabular-nums lining-nums; }
.ret-sub { margin: 2px 0 10px; font-size: var(--t-sm); color: var(--muted); }
.ret-acao { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 14px; margin-top: 14px; }
.ret-acao > .abre { margin: 0; }
.ret-acao > .abre[open] { flex-basis: 100%; }
.meta-motivo { display: flex; gap: 8px; align-items: flex-start; margin: 10px 0 0; font-size: var(--t-sm); color: var(--ink-2); }
.meta-motivo .dot-ic { flex: none; margin-top: 3px; color: var(--ink-2); }
.card-retorno .cell-2 { align-items: flex-start; }
/* O detalhe da meta mora no cartão mais estreito do topo (~310px a 1440): recuo menor
   e o cabeçalho quebrando ("Com / retorno"), para as três colunas caberem sem rolar. */
.card-retorno .abre th, .card-retorno .abre td { padding-inline: 10px; }
.card-retorno .abre thead th { white-space: normal; }

/* A posição da loja do gerente na rede. "posicao", e não "pos": .pos é a cor de
   promotor do .score (FAROL_CLASSE), e o display:flex daqui entortava o número. */
.posicao { display: flex; align-items: baseline; flex-wrap: wrap; gap: 4px 16px; }
.posicao-n { font-size: var(--t-2xl); font-weight: 800; letter-spacing: -.035em; color: var(--ink); font-variant-numeric: tabular-nums; }
.posicao-n span { font-size: var(--t-md); font-weight: 700; letter-spacing: 0; color: var(--ink-2); }
.posicao-sub { margin: 0; font-size: var(--t-sm); color: var(--ink-2); }

/* Nas listas do Resumo, quem cede é o subtítulo, e não o botão: a 1440 "Toque num
   problema para ver em quais lojas ele aparece" mandava "Ver problemas relatados" para
   uma linha só dele, com 40px de vazio. No celular o botão continua descendo (o
   título não cabe em menos de 14rem ao lado dele). */
.resumo-lista > header > div:first-child { flex: 1 1 14rem; min-width: 0; }
/* O espaçador dividia a sobra com o título, e o subtítulo quebrava com espaço de sobra
   ao lado; o botão já vai para a direita pela margem automática. */
.resumo-lista > header > .grow { display: none; }

/* O problema e, na linha de baixo, a tag "grave" antes da categoria. */
.prob-nome { display: inline-flex; align-items: center; flex-wrap: wrap; gap: 4px 8px; min-width: 0; }
.prob-cat { display: inline-flex; align-items: center; flex-wrap: wrap; gap: 2px 6px; }
/* A tag dentro da linha miúda não engorda a linha: sem o recuo vertical ela tem a
   altura do texto ao lado. */
.prob-cat .tag { padding-block: 0; line-height: 1.3; }

/* Controle por unidade: no cartão, a meta apagada ao lado do NPS. */
.uni-meta { font-size: 12.5px; font-weight: 600; color: var(--muted); }
/* E a bandeira ao lado do nome da região, quando duas bandeiras têm regiões de mesmo
   nome: apagada, para o nome continuar sendo o que se lê primeiro. Inteira numa linha:
   quebrada no meio, "Demo" ficava ao lado do nome e "Atacarejo" embaixo. O vão fica
   no nome (margem à direita, mais o espaço), e não na bandeira: com a margem nela, a
   bandeira que descia para a linha de baixo começava 8px para dentro. */
.uni-band { font-size: var(--t-sm); font-weight: 400; color: var(--muted); white-space: nowrap; }
td > :has(+ .uni-band) { margin-right: 4px; }

/* O cartão que nasce fechado no celular: o cabeçalho é o <summary>. Fechado, o
   subtítulo dá lugar ao resumo à direita ("média 6,9"). */
.card.dobra > summary {
  display: flex; align-items: center; gap: var(--s3); padding: 14px 18px; min-height: 56px;
  cursor: pointer; list-style: none;
}
.card.dobra > summary::-webkit-details-marker { display: none; }
.card.dobra > summary::after {
  content: ""; flex: none; width: 9px; height: 9px; margin: 0 4px 4px;
  border-right: 2px solid var(--muted); border-bottom: 2px solid var(--muted); transform: rotate(45deg);
}
.card.dobra[open] > summary { border-bottom: 1px solid var(--rule); }
.card.dobra[open] > summary::after { transform: rotate(225deg); margin-bottom: -4px; }
.card.dobra > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.dobra-tit { flex: 1; min-width: 0; }
.dobra-tit h2 { font-size: var(--t-lg); letter-spacing: -.02em; }
.dobra-tit .sub { font-size: var(--t-sm); color: var(--muted); }
.dobra-resumo { flex: none; font-size: var(--t-sm); font-weight: 700; color: var(--ink-2); font-variant-numeric: tabular-nums; }
.card.dobra[open] .dobra-resumo, .card.dobra:not([open]) .dobra-tit .sub { display: none; }

/* A legenda das notas, e as duas caixas embaixo. */
.legend-notas { margin-top: 12px; gap: 6px 10px; }
.legend-notas .leg-ponto { color: var(--muted-2); }
.kpis-notas { margin: 16px 0 0; }
.funil-extra { margin: 14px 0 0; }

/* Respostas por dia: o gráfico vai de borda a borda, e a tabela dia a dia embaixo. */
.card-dias .abre { margin: 0; padding: 4px 18px 8px; border-top: 1px solid var(--rule); }
.card-dias .abre[open] { padding-bottom: 0; }
.card-dias .abre > .tbl-wrap { margin: 4px -18px 0; }

/* O funil. Cada etapa e uma barra proporcional a PRIMEIRA, para que a perda entre
   elas seja visivel de relance em vez de precisar da conta. */
.funil { display: flex; flex-direction: column; gap: 11px; }
.funil-e { display: grid; grid-template-columns: 132px 1fr auto; gap: 12px; align-items: center; }
.funil-e .r { font-size: var(--t-sm); font-weight: 700; color: var(--ink-2); }
.funil-e .b { height: 20px; border-radius: var(--r-sm); background: var(--surface-3); overflow: hidden; }
/* Todas as etapas em acento, cada uma mais clara (a opacidade vem do JS). "Entregues"
   era amarela e "Respondidas" verde: as cores de neutro e promotor numa conta que
   não tem cliente nenhum, e o vermelho da perda gritava "detrator". */
.funil-e .b > i { display: block; height: 100%; background: var(--accent); border-radius: var(--r-sm); }
.funil-e .n { font-size: var(--t-sm); font-weight: 800; font-variant-numeric: tabular-nums; min-width: 96px; text-align: right; }
.funil-e .n small { display: block; font-size: var(--t-xs); font-weight: 600; color: var(--muted); }
.funil-perda { grid-column: 2 / -1; font-size: var(--t-xs); color: var(--muted); margin-top: -4px; }

/* Histograma das notas 0..10. */
/* `align-items: stretch` e `height: 100%` sao o que faz a barra ter de onde
   crescer: com `end`, a coluna encolhia ate o texto e a barra ficava com zero de
   altura para distribuir — os numeros apareciam e o grafico, nao. */
.notas { display: grid; grid-template-columns: repeat(11, 1fr); gap: 4px; align-items: stretch; height: 190px; }
.notas > * { display: flex; flex-direction: column; align-items: center; gap: 4px;
               min-width: 0; height: 100%; }
/* Sem trilho cinza: com ele, uma barra de 15% dentro de uma caixa cinza de altura
   cheia le como "caixa cheia com um pedacinho colorido", e a forma da distribuicao
   — que e a unica coisa que este grafico existe para mostrar — some. */
.notas .b { width: 100%; flex: 1; display: flex; align-items: flex-end; min-height: 0; }
.notas .b > i { display: block; width: 100%; height: var(--p, 0%); border-radius: 3px 3px 0 0; }
.notas .det > i { background: var(--det); }
.notas .neu > i { background: var(--neu-mark); }
.notas .prom > i { background: var(--prom); }
.notas .v { font-size: var(--t-xs); font-weight: 800; font-variant-numeric: tabular-nums; }
.notas .k { font-size: var(--t-xs); color: var(--muted); font-weight: 700; }
/* No celular as 11 notas deitam: em pé, a 360, cada barra tinha 24px e o número de três
   dígitos encostava no vizinho. Uma linha por nota (nota · barra · quantidade), a linha
   inteira é o alvo de 44px e a barra cresce da esquerda, na largura útil do cartão. */
@media (max-width: 720px) {
  .notas { grid-template-columns: 1fr; gap: 0; height: auto; }
  .notas > button { display: grid; grid-template-columns: 22px minmax(0, 1fr) auto; grid-template-areas: "k b v";
    align-items: center; column-gap: 10px; min-height: 44px; height: auto; padding: 0 2px; }
  .notas .k { grid-area: k; text-align: right; font-size: var(--t-sm, 13px); color: var(--ink-2, var(--muted)); }
  .notas .b { grid-area: b; flex: none; height: 20px; align-items: stretch; }
  .notas .b > i { width: var(--p, 0%); height: 100%; border-radius: 0 3px 3px 0; }
  .notas .v { grid-area: v; min-width: 3ch; text-align: right; font-size: var(--t-sm, 13px); }
}

/* Barra de progresso contra a meta. O tracinho e a meta: sem ele a barra so diz
   "quanto", e a pergunta da tela e "quanto FALTA". */
.alvo-barra { position: relative; height: 10px; border-radius: var(--r-full);
              background: var(--surface-3); overflow: hidden; }
.alvo-barra > i { display: block; height: 100%; background: var(--prom); border-radius: var(--r-full); }
.alvo-barra.amarelo > i { background: var(--neu-mark); }
.alvo-barra.vermelho > i { background: var(--det); }
.alvo-marca { position: absolute; top: -3px; bottom: -3px; width: 2px; background: var(--ink);
              border-radius: 1px; opacity: .55; }

/* Popover do grafico. Segue o ponteiro dentro da caixa do proprio grafico, entao
   nao precisa de posicionamento global nem fecha ao rolar a pagina. */
.graf-wrap { position: relative; }
.pop {
  position: absolute; z-index: 6; pointer-events: none; min-width: 148px;
  background: var(--ink); color: #fff; border-radius: var(--r-md);
  padding: 9px 11px; font-size: 12px; line-height: 1.45; box-shadow: var(--sh-2);
  transform: translate(-50%, -112%); white-space: nowrap;
}
.pop b { display: block; font-size: 12.5px; margin-bottom: 4px; }
.pop .l { display: flex; align-items: center; gap: 6px; justify-content: space-between; }
.pop .l i { width: 8px; height: 8px; border-radius: 2px; display: inline-block; }
.pop .l span:first-child { display: inline-flex; align-items: center; gap: 6px; opacity: .82; }
.pop .l b { display: inline; margin: 0; font-variant-numeric: tabular-nums; }
.pop hr { border: 0; border-top: 1px solid rgba(255,255,255,.22); margin: 6px 0; }

/* Linha clicavel de subcategoria: o painel de filiais responde a ela. */
tbody tr.clicavel { cursor: pointer; }
tbody tr.clicavel:hover { background: var(--surface-2); }
tbody tr.sel { background: var(--accent-soft); }
tbody tr.sel td:first-child { box-shadow: inset 3px 0 0 var(--accent); }

/* Barra horizontal de comparacao entre filiais. */
.barras { display: flex; flex-direction: column; gap: 9px; }
.barra-l { display: grid; grid-template-columns: 1fr auto; gap: 3px 10px; align-items: baseline; }
.barra-l .t { font-size: 12.5px; font-weight: 700; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.barra-l .n { font-size: 12.5px; color: var(--muted); font-variant-numeric: tabular-nums; }
.barra-l .b { grid-column: 1 / -1; height: 8px; border-radius: var(--r-full); background: var(--surface-3); overflow: hidden; }
.barra-l .b > i { display: block; height: 100%; background: var(--accent); border-radius: var(--r-full); }

/* ==========================================================================
   Avisos flutuantes
   ========================================================================== */

#toasts { position: fixed; right: 18px; bottom: calc(18px + env(safe-area-inset-bottom)); z-index: 60; display: flex; flex-direction: column; gap: 10px; max-width: calc(100vw - 36px); }
.toast {
  display: flex; gap: 10px; align-items: flex-start; min-width: 240px; max-width: 380px;
  background: var(--ink); color: #F2F2F8; font-size: 13.5px; font-weight: 600;
  padding: 12px 15px; border-radius: var(--r-md); box-shadow: var(--sh-3);
  animation: toastin .19s cubic-bezier(.22,.8,.3,1);
}
@keyframes toastin { from { transform: translateY(10px); opacity: 0; } }
@keyframes toastin-cima { from { transform: translateY(-10px); opacity: 0; } }
.toast > svg { flex: none; margin-top: 2px; }
.toast .txt { flex: 1; min-width: 0; }
.toast.ok  { background: var(--prom-ink-2); }
.toast.err { background: var(--det-ink-2); }
/* O toque atravessa a pilha: o toast de sucesso e o aviso não têm botão, e em cima da
   linha "Acrescentar" do editor de Riscos o terceiro toque seguido caía no toast. Só o
   de erro, que tem "Fechar", recebe o toque. */
#toasts, .toast:not(.err) { pointer-events: none; }
.toast.err { pointer-events: auto; }
/* Aviso: pede atenção sem ser erro. Escuro, com o ícone de alerta; nunca amarelo. */
.toast.aviso { background: var(--ink); }
/* O erro não some sozinho: o "Fechar" é o jeito de tirá-lo, e tem 44px. */
.fecha-toast {
  flex: none; align-self: center; min-height: 44px; min-width: 44px; padding: 0 12px;
  border: 1px solid rgba(255, 255, 255, .45); border-radius: var(--r-sm); background: transparent;
  color: #fff; font: inherit; font-size: var(--t-sm); font-weight: 700; cursor: pointer;
}
.fecha-toast:hover { background: rgba(255, 255, 255, .12); }

/* ==========================================================================
   Tratativas: as vistas Fila · Painel, o Painel das tratativas e o Horário do SAC
   (lote 12)
   ========================================================================== */

/* Fila · Painel: a primeira escolha da barra, com 44px no dedo (a regra do .seg). */
.seg.tk-vista button { min-width: 76px; }

/* Os quatro números são botões: cada um abre a fila que o explica. Continuam a régua
   de KPI (fio entre as caixas, número grande), com o rótulo em negrito e a seta que
   diz "toque para ver". 4 em linha a partir de 721; 2×2 abaixo (o @720). */
.kpis.tk-kpis { grid-template-columns: repeat(4, minmax(0, 1fr)); }
button.kpi {
  font: inherit; color: inherit; text-align: left; cursor: pointer;
  background: var(--surface); border: 0; border-right: 1px solid var(--rule);
  justify-content: flex-start;
}
button.kpi:last-child { border-right: 0; }
button.kpi:hover { background: var(--surface-2); }
button.kpi:focus-visible { outline: 2px solid var(--accent); outline-offset: -3px; }
button.kpi .k {
  display: flex; align-items: center; justify-content: space-between; gap: 6px;
  font-size: var(--t-sm); font-weight: 800; color: var(--ink-2);
}
.kpi-seta { color: var(--muted); flex: none; }
button.kpi .note { line-height: 1.4; }
.kpi-farol { margin-top: 5px; }
/* A tag do farol quebra linha dentro da caixa estreita a 360, em vez de sair dela. */
.kpi-farol .tag { white-space: normal; line-height: 1.3; }

/* O aviso com botão (cadastrar o horário, tentar de novo): no celular o botão desce
   para a linha de baixo, em vez de espremer a frase em quatro linhas ao lado dele. */
.tk-aviso { align-items: center; flex-wrap: wrap; }
.tk-aviso .tk-aviso-txt { flex: 1 1 220px; min-width: 0; }
.tk-aviso > .btn { margin-left: auto; }
.tk-painel-pe { display: flex; justify-content: center; margin: 4px 0 var(--s4); }

/* Por status: a barra empilhada e a legenda em linhas, cada linha um botão. */
.tk-st-barra {
  display: flex; gap: 2px; height: 14px; border-radius: var(--r-full); overflow: hidden;
  background: var(--surface-3);
}
.tk-st-barra i { display: block; min-width: 4px; }
.tk-st-lista { list-style: none; margin: 12px 0 0; padding: 0; }
.tk-st-lista li + li { border-top: 1px solid var(--rule); }
.tk-st-linha {
  width: 100%; display: flex; align-items: center; gap: 10px; min-height: 48px; padding: 8px 6px;
  font: inherit; color: var(--ink); text-align: left; background: none; border: 0;
  border-radius: var(--r-xs); cursor: pointer;
}
.tk-st-linha:hover { background: var(--surface-2); }
.tk-st-cor { width: 12px; height: 12px; border-radius: 3px; flex: none; }
.tk-st-nome { flex: 1; min-width: 0; display: flex; flex-direction: column; font-weight: 700; line-height: 1.35; }
.tk-st-nome small { font-size: var(--t-xs); font-weight: 500; color: var(--muted); }
.tk-st-num { display: flex; align-items: baseline; gap: 8px; font-variant-numeric: tabular-nums; white-space: nowrap; }
.tk-st-num b { font-size: var(--t-lg); }
.tk-st-num span { min-width: 3.2em; text-align: right; font-size: var(--t-sm); color: var(--muted); }
.tk-seta { color: var(--muted); flex: none; }

/* Realizadas por dia: o gráfico e, ao lado, as abertas no mesmo período. Sem espaço
   (o celular), o número desce para baixo do gráfico, na largura toda. */
.tk-dia { display: flex; flex-wrap: wrap; gap: 16px; align-items: stretch; }
.tk-dia > .tk-graf, .tk-dia > .tk-dia-um { flex: 1 1 260px; min-width: 0; }
.tk-dia-um { align-self: center; font-size: var(--t-md); color: var(--ink-2); }
.tk-dia-lado { flex: 0 0 150px; display: flex; flex-direction: column; justify-content: center; gap: 10px; }
.tk-dia-num {
  display: flex; flex-direction: column; gap: 2px; padding: 10px 12px;
  border: 1px solid var(--rule); border-radius: var(--r-md); background: var(--surface-2);
}
.tk-dia-num .k { font-size: var(--t-xs); font-weight: 700; color: var(--muted); line-height: 1.35; }
.tk-dia-num b { font-size: var(--t-xl); font-variant-numeric: tabular-nums; }
/* O gráfico inteiro é o alvo do toque (um dia por posição X): o gesto de lado é dele
   — arrastar percorre os dias — e o de cima para baixo continua rolando a página. */
.tk-graf svg { touch-action: pan-y; -webkit-user-select: none; user-select: none; }

/* Maiores problemas: cada linha um botão (escolhe o problema do bloco ao lado). */
.tk-prob-lista, .tk-lojas, .sac-dias, .sac-feriados { list-style: none; margin: 0; padding: 0; }
.tk-prob {
  width: 100%; display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 4px 12px;
  align-items: baseline; min-height: 44px; padding: 8px 8px 10px;
  font: inherit; color: var(--ink); text-align: left; background: none; border: 0;
  border-radius: var(--r-sm); cursor: pointer;
}
.tk-prob:hover { background: var(--surface-2); }
.tk-prob.on { background: var(--accent-soft); box-shadow: inset 3px 0 0 var(--accent); }
.tk-prob-nome { min-width: 0; font-weight: 700; line-height: 1.35; }
.tk-prob-nome small { display: block; font-size: var(--t-xs); font-weight: 500; color: var(--muted); }
.tk-prob-num { display: flex; align-items: baseline; gap: 8px; font-variant-numeric: tabular-nums; white-space: nowrap; }
.tk-prob-num span { min-width: 3em; text-align: right; font-size: var(--t-sm); color: var(--muted); }
.tk-prob-barra { grid-column: 1 / -1; height: 6px; border-radius: var(--r-full); background: var(--surface-3); overflow: hidden; }
.tk-prob-barra i { display: block; height: 100%; background: var(--accent); border-radius: var(--r-full); }
.tk-prob-sem { display: flex; gap: 8px; align-items: flex-start; margin: 12px 0 0; font-size: var(--t-sm); color: var(--muted); }
.tk-prob-sem .dot-ic { flex: none; margin-top: 2px; color: var(--accent); }

/* Um problema, loja por loja. A rolagem para cá (tocar num problema) para abaixo
   do topo fixo, e não por baixo dele. */
#tk-loja-problema { scroll-margin-top: calc(var(--top-h) + 12px); }
.tk-prob-campo { margin-bottom: 14px; }
.tk-prob-campo select { width: 100%; }
.tk-loja { padding: 8px 0; border-top: 1px solid var(--rule); }
.tk-loja:first-child { border-top: 0; padding-top: 0; }
.tk-loja:focus { outline: none; }
.tk-loja:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: var(--r-xs); }
.tk-loja-l1 { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 2px 10px; }
/* O nome quebra linha nos espaços, em vez de ser cortado; o title guarda o nome
   inteiro. Ele nunca fica mais estreito que 12 letras: sem espaço para o nome e o
   número na mesma linha, o número desce, alinhado à direita — antes o número não
   cedia e o nome era partido no meio da palavra ("Gutierre / z") a 360 com nome
   longo e número grande, e com o texto em 130%. */
.tk-loja-nome { flex: 1 1 12ch; min-width: 0; font-weight: 700; color: var(--ink); }
.tk-loja-nome .loja { display: inline; }
.tk-loja-nome .cod { margin-right: 6px; }
.tk-loja-qtd { flex: none; margin-left: auto; font-variant-numeric: tabular-nums; white-space: nowrap; }
.tk-loja-barra { height: 8px; margin: 5px 0 3px; border-radius: var(--r-full); background: var(--surface-3); overflow: hidden; }
.tk-loja-barra i { display: block; height: 100%; background: var(--accent); border-radius: var(--r-full); }
.tk-loja-peso { font-size: var(--t-sm); color: var(--muted); line-height: 1.4; }
.tk-lojas-mais { display: flex; justify-content: center; margin-top: 8px; }

/* A segunda linha sem par (ajustarGradeProblemas, no app.js): com alturas muito
   diferentes, os dois cartões iam lado a lado e a grade abria um vão branco de até
   430px dentro do mais curto. Aqui vão um embaixo do outro, cada um na largura toda,
   e as listas ganham colunas para não virarem uma tira de 1.100px de largura. */
.grid.c2.tk-painel-grid.empilha { grid-template-columns: minmax(0, 1fr); }
@media (min-width: 1100px) {
  /* Os problemas em duas colunas lidas de cima para baixo (1 a 4, 5 a 8). */
  .tk-painel-grid.empilha .tk-prob-lista {
    display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
    grid-template-rows: repeat(var(--linhas, 4), auto); grid-auto-flow: column; column-gap: 24px;
  }
  /* As lojas em até três colunas (--cols: nunca mais que as lojas), lidas por linha. */
  .tk-painel-grid.empilha .tk-lojas {
    display: grid; grid-template-columns: repeat(var(--cols, 3), minmax(0, 1fr)); column-gap: 24px;
  }
  .tk-painel-grid.empilha .tk-loja:nth-child(-n+3) { border-top: 0; padding-top: 0; }
}

/* Horário do SAC (Configurações): uma linha por dia — o nome, a fita Aberto |
   Fechado e as duas horas. No desktop numa linha; no celular (@720) o nome e a fita
   em cima e as horas embaixo, lado a lado e da mesma largura. */
#horario-sac { scroll-margin-top: calc(var(--top-h) + 12px); }
#horario-sac h2:focus { outline: none; }
#horario-sac h2:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.sac-fuso { margin: 0 0 12px; }
.sac-dia {
  display: grid; grid-template-columns: 110px 200px minmax(0, 340px); gap: 8px 18px; align-items: center;
  padding: 12px 0; border-top: 1px solid var(--rule);
}
.sac-dia:first-child { border-top: 0; padding-top: 0; }
.sac-dia.mudou { box-shadow: inset 3px 0 0 var(--accent); padding-left: 12px; margin-left: -12px; }
.sac-dia-nome { font-weight: 800; color: var(--ink); }
.seg.sac-fita { display: grid; grid-template-columns: 1fr 1fr; width: 100%; }
.sac-horas { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.sac-horas .field input { width: 100%; }
.sac-fechado { margin: 0; font-size: var(--t-sm); color: var(--muted); }
.sac-aviso:not(:empty) { margin-top: 10px; }
.sac-aviso .banner { margin-bottom: 0; }
.sac-sub { font-size: var(--t-md); font-weight: 800; margin: 20px 0 2px; padding-top: 16px; border-top: 1px solid var(--rule); }
.sac-feriados { margin: 10px 0 14px; }
.sac-feriado {
  display: flex; align-items: center; gap: 12px; min-height: 44px; padding: 4px 0;
  border-top: 1px solid var(--rule);
}
.sac-feriado:first-child { border-top: 0; }
.sac-feriado.mudou { box-shadow: inset 3px 0 0 var(--accent); padding-left: 12px; margin-left: -12px; }
.sac-feriado-data { flex: none; font-weight: 800; font-variant-numeric: tabular-nums; min-width: 6.5em; }
.sac-feriado-nome { flex: 1; min-width: 0; display: flex; align-items: center; flex-wrap: wrap; gap: 4px 8px; }
.vazio-feriado { color: var(--muted); font-size: var(--t-sm); }
.sac-novo { display: grid; grid-template-columns: 180px minmax(0, 1fr) auto; gap: 10px; align-items: end; }
.sac-novo .field input { width: 100%; }


/* ==========================================================================
   RESPONSIVO — tudo daqui para baixo, para nenhuma regra posterior anular.
   Os pontos de quebra vêm do conteúdo, não de nome de aparelho:
     1180  a régua de KPI deixa de caber em uma linha confortável
      980  a barra lateral fixa rouba largura demais da tabela; o topo preso
           fica só com menu e título; colunas de prioridade 3 saem
      940  o painel ilustrado do login não tem mais onde respirar
      720  tabela com papéis vira lista de cartões
      520  colunas de prioridade 2 saem, formulários viram uma coluna
      380  aperto máximo
   ========================================================================== */

@media (max-width: 1180px) {
  :root { --pad-x: 20px; --side-w: 216px; }
  .kpis { grid-template-columns: repeat(auto-fit, minmax(128px, 1fr)); }
  .trunc { max-width: 32ch; }

  /* Três cartões no topo ficariam com ~200px a 1024: o retorno desce e ocupa a
     linha de baixo inteira, e o NPS e a divisão das notas dividem a de cima. */
  .topo-painel { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .topo-painel > .card-retorno { grid-column: 1 / -1; }
}

/* Com a barra lateral (acima de 980), a fita do período não se parte dentro da
   pílula: entre 981 e 1280 ela ficava com "90 dias" sozinho na segunda linha. Quem
   cede é o topo, nesta ordem: primeiro o subtítulo quebra linha (o bloco do título
   entra na conta só com a largura do h1), e só quando nem o h1 cabe ao lado as
   ferramentas descem INTEIRAS para a linha de baixo, à direita. */
@media (min-width: 981px) {
  .topbar { flex-wrap: wrap; row-gap: 10px; }
  .topbar .grow { display: none; }
  .topbar .tit { flex: 1 1 min-content; }
  .topbar h1 { white-space: nowrap; }
  .topbar .tools { flex-wrap: wrap; justify-content: flex-end; margin-left: auto; }
  #periodo { flex-wrap: nowrap; flex: none; }
  /* Com a barra lateral, a rede ativa está no chip ao lado do título e o seletor
     no menu à vista: o botão "Rede:" é só do celular e do tablet. */
  #rede-btn { display: none; }
}
/* Notebook pequeno: a 1024 o selo "Modo teste" ao lado do título tirou da linha os
   ~50px que faltavam, as ferramentas desciam inteiras e o topo preso do Resumo ia de
   87 para 117px (15% de uma tela de 768 de altura). Quem cede é o recorte, de 260
   para 180px — o nome comprido corta dentro do select fechado e aparece inteiro na
   lista aberta —, e o selo continua por extenso. */
@media (min-width: 981px) and (max-width: 1180px) {
  .unidade-sel select { max-width: 180px; }
}

/* Régua de seis números entre o celular e o notebook: o auto-fit fazia 5 + 1, com a
   sexta caixa sozinha na segunda linha e a quinta com o fio colado na borda. Três
   por linha, duas linhas cheias. Abaixo de 721 vale a régua de duas colunas. */
@media (min-width: 721px) and (max-width: 1180px) {
  .kpis:has(> .kpi:nth-child(6):last-child) { grid-template-columns: repeat(3, 1fr); }
  .kpis:has(> .kpi:nth-child(6):last-child) > .kpi { border-bottom: 1px solid var(--rule); }
  .kpis:has(> .kpi:nth-child(6):last-child) > .kpi:nth-child(3n) { border-right: 0; }
  .kpis:has(> .kpi:nth-child(6):last-child) > .kpi:nth-last-child(-n+3) { border-bottom: 0; }
}

/* --- a barra lateral vira gaveta ----------------------------------------- */
@media (max-width: 980px) {
  #app { grid-template-columns: 1fr; }

  /* Prioridade 3: detalhe que ajuda, não indispensável. Sai já no tablet: a 768, em
     pé, a última coluna ficava cortada na borda do cartão. */
  th.p3, td.p3 { display: none; }
  /* A data longa dá lugar à forma curta: na fila, "há 2 meses" sob "Aberta". */
  .so-largo { display: none; }
  .so-medio { display: inline; white-space: nowrap; }

  /* Fechado, o menu sai também do leitor de tela e do Tab: só com o transform, o
     TalkBack lia os links invisíveis em toda tela. O visibility espera a animação
     de saída terminar (o atraso de .22s) e entra na hora ao abrir. */
  .side {
    position: fixed; top: 0; left: 0; bottom: 0; width: min(272px, 84vw);
    z-index: 50; transform: translateX(-102%); visibility: hidden;
    transition: transform .22s cubic-bezier(.22,.8,.3,1), visibility 0s linear .22s;
    box-shadow: var(--sh-3);
  }
  #app.menu-aberto .side { transform: none; visibility: visible;
    transition: transform .22s cubic-bezier(.22,.8,.3,1); }
  /* A rede ativa: sem a barra lateral, quem mostra é o botão "Rede:" da área que rola. */
  #chip-rede { display: none; }
  .rede-btn { flex: 1 1 100%; }
  #app.menu-aberto::before {
    content: ""; position: fixed; inset: 0; background: var(--scrim);
    z-index: 45; animation: fade .16s ease;
  }
  .menu-btn {
    display: inline-flex; align-items: center; justify-content: center;
    width: 38px; height: 38px; flex: none; border-radius: var(--r-sm);
    border: 1.5px solid var(--rule-2); background: var(--surface); color: var(--ink-2); cursor: pointer;
  }
  .menu-btn:hover { background: var(--surface-3); }

  .content { padding: var(--s4) var(--pad-x) 56px; }
  .grid.c2 { grid-template-columns: 1fr; }

  /* Sem a barra lateral, a parte fixa do topo é só o menu e o título, numa linha.
     Com as ferramentas dentro dela, a barra presa chegava a 250px a 360 (um terço
     da tela) e a 185px com o celular deitado (740x360, metade da tela). Título e
     subtítulo terminam em reticências. 6px + o botão de 44px do toque + o fio =
     57px; com o subtítulo, no tablet, 59. */
  .topbar { padding: 6px var(--pad-x); gap: 10px; flex-wrap: nowrap; min-height: 56px; }
  .topbar .tit { flex: 1 1 0; }
  .topbar h1, .topbar .sub { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .topbar .grow { display: none; }
  /* As ferramentas vêm para o começo do conteúdo (#tools-slot, o app.js move o nó)
     e rolam com a página. Elas quebram linha em vez de rolar: rolando, com a barra
     escondida, o seletor de rede ficava coberto pelo período e o período terminava
     em "30 d". Sem nenhuma à vista (Usuários do gestor), o bloco some e não deixa a
     margem sobrando. */
  #tools-slot .tools {
    display: flex; align-items: center; flex-wrap: wrap; gap: var(--s2);
    margin-bottom: var(--s4);
  }
  #tools-slot .tools:not(:has(> :not([hidden]))) { display: none; }
  /* Voltando com Shift+Tab, o navegador rolava o campo focado só até a borda de
     cima da janela, e ele ficava inteiro embaixo da barra presa (WCAG 2.4.11).
     65 = a barra (57 a 59) e uma folga. */
  html { scroll-padding-top: 65px; }
}

/* Tablet em pé e celular deitado: ainda tabela, e não cartão, mas sem a largura do
   desktop. Na fila, o responsável desce para baixo do status (a coluna dele é p3) e o
   relato ganha duas linhas: numa só, a 768, sobravam "Fila muito …". */
@media (min-width: 721px) and (max-width: 980px) {
  .so-tablet { display: block; }
  .quem { margin-top: 4px; font-size: 12.5px; font-weight: 500; color: var(--ink-2); line-height: 1.3; }
  .quem.ninguem { color: var(--muted); white-space: nowrap; }
  /* A loja pode quebrar ("Santa / Efigênia"): a linha já tem duas, e a largura vai
     para o que o cliente disse. */
  td.tk-loja { white-space: normal; }
  td.tk-loja .loja { flex-wrap: wrap; }
  /* Lojas: a coluna Situação sai (p3), e a loja inativa leva a tag embaixo do nome. */
  .sob-nome { margin-top: 4px; }
  td.relato .trunc {
    white-space: normal; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  }
}

/* Celular deitado: com pouca altura cada linha presa pesa, e o subtítulo sai. A
   barra fica nos mesmos 57px do celular em pé. */
@media (max-width: 980px) and (max-height: 500px) {
  .topbar .sub { display: none; }
}

@media (max-width: 940px) {
  .login { grid-template-columns: 1fr; grid-template-rows: auto 1fr; }
  /* A arte vira uma faixa no alto, com o pulso animado (dono, 13/10/2026): a marca e a frase, sem o texto longo
     nem os três números, que não cabem. */
  .login-art { height: clamp(200px, 32svh, 280px); border-right: 0; border-bottom: 1px solid var(--rule); padding: 20px 20px 18px; }
  .login-art .art-bottom p:not(.art-h), .login-art .art-stats { display: none; }
  .login-art .art-bottom .art-h { font-size: clamp(22px, 6.4vw, 30px); max-width: 17ch; margin-bottom: 0; }
  .login-inner .so-celular { display: none !important; }
  /* A marca, 32px (o gap de 20 e mais 12) e o "Entrar". Alinhado ao topo, e não
     centralizado: centralizado, o teclado do celular empurrava a tela ao abrir. */
  .login-form { place-items: start center; padding-top: 28px; }
}

@media (max-width: 720px) {
  :root { --pad-x: 14px; }

  /* ---- A tabela vira lista de cartões (tabela() com papéis, ver app.js) --------
     Um cartão por linha: flex com quebra, a ORDEM visual vem do papel da coluna e não
     da ordem no DOM. Os seletores vão por filho direto (>) de propósito: a tabela de
     de dentro de outra (uma tabela num cartão de tabela) não herda o cartão da de fora. */
  table.empilha, table.empilha > tbody { display: block; width: 100%; }
  table.empilha > thead { display: none; }
  table.empilha > tbody > tr {
    display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px;
    padding: 12px 15px; border-bottom: 1px solid var(--rule); position: relative; min-height: 64px;
  }
  table.empilha > tbody > tr:last-child { border-bottom: 0; }
  /* A quebra antes da linha de detalhe: sem ela, as células 'meta' (que encolhem)
     subiam para a linha do título e o nome da loja sumia espremido entre o número e
     o selo. Um item de altura zero e largura total, na ordem 4. */
  table.empilha > tbody > tr::after { content: ""; content: "" / ""; order: 4; flex-basis: 100%; height: 0; }
  /* Anula o recuo e o fio de célula — e também o display:none de p2 e p3: no cartão,
     quem esconde é o papel 'oculto', não a largura. */
  /* break-word, e não anywhere: a palavra só quebra se sozinha não couber na linha.
     Com anywhere, o nome da loja espremido ao lado dos selos virava "Pampulh / a". */
  table.empilha > tbody > tr > td, table.empilha > tbody > tr > th {
    display: block; padding: 0; border: 0; min-width: 0; text-align: left; overflow-wrap: break-word;
  }
  table.empilha > tbody > tr.clickable:hover > td { background: none; }
  table.empilha > tbody > tr.clickable:hover { background: var(--surface-2); }
  table.empilha > tbody > tr > td.so-cel { display: block; }
  table.empilha .so-desk { display: none; }
  table.empilha .so-cel-i { display: inline; }

  table.empilha > tbody > tr > [data-m=topo] { order: 1; flex: 0 0 auto; }
  /* A loja no topo (Comentários) encolhe, como a do título: sem isso, um nome de 30
     letras ou mais passava da borda do cartão a 277 e a lista inteira rolava para o
     lado. Quando não cabe ao lado da nota ela desce para a linha de baixo, como já
     fazia; e, se nem ali couber, o nome ganha reticências (.loja .nm). */
  table.empilha > tbody > tr > [data-m=topo].loja-cel { flex: 0 1 auto; min-width: 0; }
  /* O título parte de 7rem, e não de zero: sem base, um selo largo ("Entregue, sem
     resposta") espremia o nome até sobrar só "LJ-12" a 277 (o 360 com texto a 130%).
     Com a base, quando os dois não cabem, o selo desce para a linha de baixo, à
     direita, e o nome fica inteiro. A 360 e a 390 tudo continua numa linha só (o
     menor título ali tem 130px). */
  table.empilha > tbody > tr > [data-m=titulo] { order: 1; flex: 1 1 7rem; min-width: 0; font-weight: 700; color: var(--ink); }
  /* Dois títulos seguidos (a posição e a loja, no Ranking): o primeiro fica do tamanho
     dele e o segundo leva a sobra. */
  table.empilha > tbody > tr > [data-m=titulo]:has(+ [data-m=titulo]) { flex: 0 0 auto; }
  table.empilha > tbody > tr > [data-m=selo] { order: 2; margin-left: auto; flex: 0 0 auto; }
  /* Dois selos (a situação e o lápis): juntos, à direita. */
  table.empilha > tbody > tr > [data-m=selo] ~ [data-m=selo] { margin-left: 0; }
  /* ...a não ser que o segundo tenha descido sozinho (marcarQuebras): aí ele também
     encosta à direita. */
  table.empilha > tbody > tr > [data-m=selo].desceu { margin-left: auto; }
  table.empilha > tbody > tr > [data-m=texto] {
    order: 4; flex-basis: 100%; font-size: 14px; color: var(--ink);
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
  }
  table.empilha > tbody > tr > [data-m=texto-inteiro] { order: 4; flex-basis: 100%; font-size: 14px; color: var(--ink); }
  table.empilha > tbody > tr > [data-m=meta] { order: 5; flex: 0 1 auto; font-size: 12.5px; color: var(--muted); font-weight: 500; }
  /* O ponto entre dois detalhes, a meio caminho dos dois: o gap de 10px do cartão
     somado ao "· " deixava o ponto colado no detalhe da direita. */
  table.empilha > tbody > tr > [data-m=meta] ~ [data-m=meta] { margin-left: -5px; }
  /* O ponto é só desenho: o texto alternativo vazio (/ "") o tira do que o leitor de
     tela lê ("·82 respostas"). A primeira declaração fica para o navegador que não
     conhece o texto alternativo. Largura fixa, para o .inicio saber quanto recuar. */
  table.empilha > tbody > tr > [data-m=meta] ~ [data-m=meta]::before {
    content: "·"; content: "·" / ""; display: inline-block; width: 6px; margin-right: 5px; text-align: center;
  }
  /* O detalhe que abre uma linha nova (tabela() mede, ver marcarQuebras): o ponto fica
     invisível no lugar dele e o texto recua até a borda. Mudar a largura faria o
     detalhe caber de novo na linha de cima, sem ponto nenhum. */
  table.empilha > tbody > tr > [data-m=meta].inicio { position: relative; left: -6px; }
  table.empilha > tbody > tr > [data-m=meta].inicio::before { visibility: hidden; }
  /* O detalhe que é botão (a Empresa das Lojas, a Região) não pode ser mais largo que
     a linha menos o ponto (6px + 5px de margem): o botão inteiro caía para baixo do
     ponto, deixava uma linha fantasma só com ele e começava 11px à esquerda do resto
     do cartão, porque o .inicio recua a célula. Assim ele fica ao lado do ponto e
     quebra o texto dentro dele. */
  table.empilha > tbody > tr > [data-m=meta] ~ [data-m=meta] > .linkline { max-width: calc(100% - 11px); }
  /* O rótulo que vai antes do valor no cartão ("CNPJ", "Último acesso"). */
  table.empilha .rot-cel { display: inline; }
  table.empilha > tbody > tr > [data-m=acao] { order: 6; flex-basis: 100%; text-align: right; }
  table.empilha > tbody > tr > [data-m=oculto] { display: none; }
  /* Com 'topo', a primeira linha é topo à esquerda e selo à direita, e o título desce
     para a segunda. */
  table.empilha.com-topo > tbody > tr > [data-m=topo] + [data-m=topo] { margin-left: -2px; }
  table.empilha.com-topo > tbody > tr > [data-m=titulo] { order: 3; flex-basis: 100%; }

  /* O nome da loja no título e no topo: uma linha, com reticências. */
  table.empilha > tbody > tr > :is([data-m=titulo], [data-m=topo]) .loja { display: flex; max-width: 100%; }
  table.empilha > tbody > tr > :is([data-m=titulo], [data-m=topo]) .loja .nm { white-space: nowrap; }
  table.empilha > tbody > tr > [data-m=titulo] > .linkline { display: flex; max-width: 100%; min-width: 0; }
  /* O botão que estica já tem o cartão inteiro (≥64px) como alvo: os 44px dele só
     engordavam a linha do título. */
  table.empilha > tbody > tr > [data-m=titulo] > .linkline.estica { min-height: 0; }
  /* A bandeira ao lado da região de nome repetido (Controle por unidade): na linha do
     nome, sem abrir andar no cartão. Ela parte do zero e leva a sobra entre o nome e o
     selo, com reticências ("Demo Supermerc…" ao lado de "Metropolitana" a 360): o nome
     fica inteiro, e a parte que sobra já separa uma bandeira da outra. Só quando nem
     6 letras cabem (a 277) ela desce para baixo do nome. */
  table.empilha > tbody > tr > [data-m=titulo]:has(> .uni-band) {
    display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 8px;
  }
  table.empilha > tbody > tr > [data-m=titulo] > .uni-band {
    flex: 1 1 0; min-width: 6ch; overflow: hidden; text-overflow: ellipsis;
  }
  /* No cartão o vão é o gap (o espaço entre os dois some no flex). */
  table.empilha > tbody > tr > [data-m=titulo] > :has(+ .uni-band) { margin-right: 0; }
  table.empilha > tbody > tr > :is([data-m=titulo], [data-m=topo]) .loja-linha .loja { display: flex; min-width: 0; }
  /* A loja do gerente e a etiqueta "sua loja": quando as duas não cabem juntas (a 277,
     o 360 com texto a 130%), a etiqueta desce para baixo do nome, e o nome fica
     inteiro — antes ele virava "Cen…" para a etiqueta caber ao lado. */
  table.empilha > tbody > tr > :is([data-m=titulo], [data-m=topo]) .loja-linha { display: flex; flex-wrap: wrap; gap: 4px 8px; }
  /* A linha da loja do gerente: o cartão inteiro no tom de acento, e não célula a célula. */
  table.empilha > tbody > tr.minha { background: var(--accent-soft); }
  table.empilha > tbody > tr.minha > td { background: none; }
  /* O relato da fila e a data com hora: no cartão, o texto quebra (o corte é o do
     papel) e o dia e a hora ficam na mesma linha. */
  table.empilha > tbody > tr > td.relato { width: auto; max-width: none; }
  /* O cartão da fila: pelo menos 88px (a linha do prazo, a da loja e o texto), o
     risco no alto junto do prazo, e o cliente depois da loja sem nunca ser cortado —
     quem encolhe, com reticências, é o nome da loja. */
  table.empilha.fila > tbody > tr { min-height: 88px; }
  /* O alto encolhe e quebra linha: com o prazo e dois riscos ("Risco: saúde",
     "Risco: Procon/justiça") ele media 372px e empurrava o cartão para o lado. A base
     0 deixa a nota na mesma linha, à direita: com a base do conteúdo, o alto largo
     ocupava a linha inteira e a nota descia sozinha para a linha de baixo. */
  table.empilha.fila td.tk-prazo { display: flex; flex-wrap: wrap; gap: 4px 6px; align-items: center;
                                    flex: 1 1 0; min-width: 0; }
  table.empilha.fila td.tk-prazo .so-cel-i { display: contents; }
  table.empilha.fila td.relato .trunc { -webkit-line-clamp: unset; display: inline; }
  /* O espaço antes do "·": no botão em flex, o espaço do começo do texto some. */
  table.empilha.fila .linkline.estica .tk-cli { flex: none; white-space: nowrap; margin-left: .3em; }
  table.empilha.fila .linkline.estica > .loja { min-width: 0; flex: 0 1 auto; }
  /* O número que é botão ("Lojas 13") fica junto do rótulo, e não na ponta do alvo. */
  table.empilha > tbody > tr > td.r .linkline { justify-content: flex-start; }
  table.empilha > tbody > tr > [data-m=texto] .trunc { display: inline; white-space: normal; max-width: none; }
  table.empilha .dh .hora { display: inline; }

  /* O cartão inteiro como alvo: o ::after do botão do título cobre o <tr> (que é o
     position:relative). Só aqui — a 1440 a linha não vira botão. Os outros controles
     do cartão (lápis, chips, "Ver tratativa ›") sobem por cima dele e continuam
     disparando a própria ação. */
  table.empilha > tbody > tr .estica::after { content: ""; position: absolute; inset: 0; }
  table.empilha > tbody > tr .estica:focus-visible { outline: none; }
  table.empilha > tbody > tr .estica:focus-visible::after { outline: 2px solid var(--accent); outline-offset: -2px; border-radius: var(--r-sm); }
  table.empilha > tbody > tr :is(button, a[href], input, select, summary):not(.estica) { position: relative; z-index: 1; }
  /* Ação vazia (comentário sem tratativa) não deixa uma linha em branco no cartão. */
  table.empilha > tbody > tr > [data-m=acao]:empty { display: none; }

  /* Comentários: a data pequena à direita, e o texto inteiro em peso normal. */
  table.empilha > tbody > tr > td.data-cel { font-size: var(--t-xs); }
  table.empilha > tbody > tr > td.comentario { font-weight: 400; }
  /* Problemas relatados: a proporção vira um fio de 4px na largura toda, no pé. */
  table.empilha > tbody > tr > td.barra-prop { order: 7; }
  table.empilha > tbody > tr > td.barra-prop .meter { height: 4px; min-width: 0; }

  /* O topo fixo já é só menu e título desde o @980. No celular o título diminui
     para caber mais dele antes das reticências, e o subtítulo sai: a 320x256 (zoom
     de 400%) a barra presa cobria 86% da tela. */
  .topbar h1 { font-size: var(--t-lg); }
  .topbar .sub { display: none; }
  /* O título fica com a sobra da linha, e o selo encosta na direita: sempre no mesmo
     lugar, qualquer que seja o tamanho do título. */
  .topbar .tit-linha h1 { flex: 1 1 auto; }
  /* Menos respiro entre a barra presa, as ferramentas e o primeiro cartão: a 360 são
     duas linhas de 44px (período e recorte) antes do primeiro número, e cada 4px
     aqui é conteúdo que sobe. A fita do período perde o recuo interno — os botões
     continuam com 44px e a borda da fita fica. */
  .content { padding-top: var(--s3); }
  /* O grupo de ferramentas é uma extensão da barra: mais junto dela e entre si
     (8px acima e abaixo, 6px entre as linhas). Assim o primeiro número do Resumo
     começa em y=169 a 360 (eram 193). Tela sem ferramenta fica com os 12px. */
  #tools-slot .tools { margin-top: calc(-1 * var(--s1)); margin-bottom: var(--s2); row-gap: 6px; }
  #tools-slot #periodo { padding: 0; gap: 0; }
  /* Rede, recorte e período (em #tools-slot, ver o @980) em linhas próprias: o
     botão "Rede:" e o recorte na largura toda, o período em 4 colunas iguais. */
  #periodo button { padding-inline: 0; text-align: center; }
  /* "Teste" no lugar de "Modo teste": a linha presa é só ≡, título e selo, e o
     título precisa de pelo menos 180px a 360. */
  .selo-btn .longo { display: none; }
  .selo-btn .curto { display: inline; }
  /* Abaixo de 940 o recorte ganha a linha inteira: espremido ao lado do periodo
     ele mostra tres letras do nome da regiao, que nao serve para escolher nada. */
  .unidade-sel { flex: 1 1 100%; order: 3; }
  .unidade-sel select { width: 100%; max-width: none; }
  #periodo { flex: 1 1 100%; }

  /* Fita de escolha única com até 5 opções curtas: colunas iguais na largura toda,
     todas à vista. Com 6 ou mais, ela quebra linha. Os chips de contagem ficam de
     fora (ver .seg.chips): cada um na largura do próprio texto. */
  .seg:not(.chips):not(:has(> :nth-child(6))), .tabs:not(:has(> :nth-child(6))) {
    display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; width: 100%;
  }
  .seg:not(.chips):has(> :nth-child(6)), .tabs:has(> :nth-child(6)) { display: flex; width: 100%; }
  .seg:not(.chips):has(> :nth-child(6)) > button, .tabs:has(> :nth-child(6)) > .tab { flex: 1 1 auto; }
  .seg button, .tabs .tab { white-space: normal; text-align: center; line-height: 1.2; padding-inline: 6px; }
  .seg.chips button { padding-inline: 11px; }

  .kpis { grid-template-columns: repeat(2, 1fr); }
  .kpi { padding: 13px 15px; }
  /* Duas colunas: a caixa da direita não leva fio à direita, e a última linha não
     leva fio embaixo. Sem isto, a 390 um fio vertical ficava colado na borda
     arredondada. */
  .kpis .kpi { border-right: 1px solid var(--rule); border-bottom: 1px solid var(--rule); }
  .kpis .kpi:nth-child(2n) { border-right: 0; }
  .kpis .kpi:nth-last-child(-n+2) { border-bottom: 0; }

  .card > header { padding: 13px 15px; }
  .card > .body { padding: 15px; }
  .card > .body > .tbl-wrap, .card > .body > div > .tbl-wrap,
  .card > .body > div > div > .tbl-wrap { margin-inline: -15px; }
  .card > header + .body > .tbl-wrap:first-child,
  .card > header + .body > div:first-child > .tbl-wrap:first-child,
  .card > header + .body > div:first-child > div:first-child > .tbl-wrap:first-child { margin-top: -15px; }
  thead th { padding: 9px 13px; }
  tbody td, tbody th { padding: 11px 13px; }
  .trunc { max-width: 24ch; }

  .drawer { width: 100vw; border-radius: 0; }
  .modal { width: calc(100vw - 20px); border-radius: var(--r-lg); }
  /* Sem gaveta nem diálogo, o toast desce do alto: embaixo ele cobria o rodapé de
     ação. Com gaveta ou diálogo, fica logo acima do rodapé deles (posicionarToasts). */
  #toasts { top: calc(8px + env(safe-area-inset-top)); bottom: auto; left: 12px; right: 12px; max-width: none; }
  #toasts:not(.sobre-rodape) .toast { animation-name: toastin-cima; }
  .toast { max-width: none; min-width: 0; }

  .grid.c3 { grid-template-columns: 1fr; }
}

@media (max-width: 860px) {
  /* Editar e ver lado a lado exige largura. Abaixo disso, um embaixo do outro. */
  .modal.largo { width: calc(100vw - 24px); }
  .modal.largo .grid.c2 { grid-template-columns: 1fr; }
  .zap { max-width: 100%; }
}

@media (max-width: 620px) {
  /* A barra vira duas linhas: o rótulo e o seletor ocupam a largura toda,
     senão o nome da empresa fica cortado em três caracteres. */
  .toolbar { gap: var(--s2); }
  .toolbar select { flex: 1 1 100%; min-width: 0; }
  .btn-row { width: 100%; margin-left: 0; }
  .btn-row .btn { flex: 1 1 auto; }
}

@media (max-width: 520px) {
  /* Prioridade 2: some antes de a tabela virar rolagem infinita. */
  th.p2, td.p2 { display: none; }

  .form { grid-template-columns: 1fr; }
  .facts { grid-template-columns: repeat(2, 1fr); }
  .kpi .v { font-size: var(--t-xl); }
  .kpi .note, .field .hint { font-size: var(--t-sm); }
  .empty { padding: 34px var(--s4); }
  .login-inner { width: 100%; }

  /* "Abertas em" vira um select na largura toda, com o rótulo visível em cima: seis
     opções numa fita, a 360, quebravam em três linhas. De e Até na largura toda. */
  .tk-filtro { flex-direction: column; align-items: stretch; gap: 6px; }
  /* flex: none — em coluna, o `flex: 1 1 100%` do select da barra (@620) virava
     ALTURA, e o select ficava com 240px. */
  .toolbar.filtros .tk-filtro select { width: 100%; flex: none; }
  .tk-barra .tk-periodo .so-fita, .tk-barra .tk-periodo .seg.tk-periodo-fita { display: none; }
  .tk-barra .tk-periodo .so-select, .tk-barra .tk-periodo .tk-periodo-sel { display: block; }
  .toolbar.filtros .entre-datas { width: 100%; }

  /* O rodapé da gaveta: [Mais ações] [principal], o principal com o dobro da largura.
     A grade 2x2 de quatro botões iguais saiu: todo botão parecia o principal. */
  .drawer > footer { display: grid; grid-template-columns: minmax(0, 1fr); gap: 8px; }
  .drawer > footer.com-mais { grid-template-columns: minmax(0, 1fr) minmax(0, 2fr); }
  /* A 277 (texto em 130%) o terço da largura não cabe "Mais ações" numa linha: o botão
     ficava com 66px de altura. Ele fica do tamanho do texto, e o principal com o resto. */
  @media (max-width: 300px) {
    .drawer > footer.com-mais { grid-template-columns: max-content minmax(0, 1fr); }
    .drawer > footer .tk-mais { white-space: nowrap; }
  }
  .drawer > footer .tk-sec, .drawer > footer .grow { display: none; }
  .drawer > footer .tk-mais { display: inline-flex; }
  .drawer > footer .btn { width: 100%; white-space: normal; padding-inline: 10px; }
  /* Escrevendo ao cliente, o teclado já toma metade da tela: o rodapé sai. */
  .drawer:has(textarea:focus) > footer { display: none; }
}

@media (max-width: 380px) {
  :root { --pad-x: 11px; }
  /* A régua continua em duas colunas (a de 720): 168px por caixa bastam para
     "4.206", e uma coluna só empilhava seis números de um dígito em 480px. */

  /* O trio de "Como os clientes avaliaram" fica lado a lado, apertado: empilhados,
     promotor, neutro e detrator viram três números que não se somam. */
  .cls-n { font-size: 22px; }
  .seg button, .tabs .tab { padding-inline: 4px; font-size: var(--t-xs); }
  .trunc { max-width: 18ch; }
  .wordmark .txt { font-size: 16px; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

/* ==========================================================================
   Usuários (lote 7)
   ========================================================================== */

/* O campo com botões ao lado (a senha com Gerar e Copiar). Os três cabem numa linha
   a 360 (recuo de 12px nos botões); com a fonte grande do sistema, os botões descem
   inteiros para baixo do campo, em vez de espremê-lo. */
.com-botoes { display: flex; flex-wrap: wrap; gap: 8px; align-items: stretch; }
.com-botoes > input { flex: 1 1 140px; width: auto; }
.com-botoes > .btn { flex: 0 0 auto; padding-inline: 12px; }

/* A escolha única com busca (a loja do gerente). A lista rola sozinha, com altura
   limitada: com o teclado aberto na folha de baixo, a busca, as primeiras lojas e o
   rodapé com Criar cabem juntos. position: relative é o que faz o offsetTop das
   opções contar a partir da lista (mostrarEscolhida). */
.lista-ops {
  position: relative; max-height: min(248px, 34dvh); overflow-y: auto; overscroll-behavior: contain;
  border: 1.5px solid var(--field-line); border-radius: var(--r-sm); background: var(--surface); padding: 4px;
}
.lista-ops.ruim { border: 2px solid var(--det-ink); }
.lista-ops:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
/* 36px no mouse; no dedo, 44 (o @media pointer: coarse, mais abaixo). */
.lista-ops .op {
  display: flex; align-items: center; gap: 10px; min-height: 36px; padding: 6px 10px;
  border-radius: var(--r-xs); cursor: pointer; font-size: var(--t-sm); color: var(--ink);
}
.lista-ops .op:hover { background: var(--surface-3); }
.lista-ops .op:has(input:checked) { background: var(--accent-soft); font-weight: 700; }
.lista-ops .op input { width: 18px; height: 18px; margin: 0; flex: none; accent-color: var(--accent); }
.lista-nada { padding: 10px; color: var(--muted); font-size: var(--t-sm); }
.lista-nada:empty { display: none; }

/* "Vê a rede inteira.", no lugar do campo de loja ou de região (SAC e gestor). Numa
   caixa com ícone, e não solta: solta, ela se lia como a última linha da dica do papel. */
.ve-tudo {
  display: flex; align-items: center; gap: 8px; padding: 10px 12px;
  border: 1px solid var(--rule); border-radius: var(--r-sm); background: var(--surface-2);
  font-size: var(--t-sm); font-weight: 600; color: var(--ink-2);
}
.ve-tudo svg { flex: none; color: var(--muted); }
/* Gerar nova senha, e a senha nova mostrada uma vez, com Copiar ao lado. */
.bloco-senha { display: flex; flex-direction: column; align-items: flex-start; gap: 8px; }
.senha-gerada {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; width: 100%;
  padding: 12px 14px; border: 1px solid var(--rule-2); border-radius: var(--r-sm); background: var(--surface-2);
}
.senha-gerada p { flex: 1 1 220px; margin: 0; font-size: var(--t-sm); color: var(--ink); line-height: 1.5; }
.senha-gerada code { font-size: 15px; font-weight: 700; letter-spacing: .04em; user-select: all; overflow-wrap: anywhere; }
/* "Falta a loja": o gerente salvo sem loja vê a rede toda até alguém escolher. Na
   tabela o selo desce para baixo do "Toda a rede": lado a lado, os dois alargavam a
   coluna Vê e a tabela passava do cartão a 768. No cartão do celular ele continua ao
   lado da frase, que tem a linha inteira para ela. */
.falta-escopo { display: flex; width: fit-content; margin-top: 4px; }
/* O e-mail quebra no meio de um pedaço só quando nem as quebras antes do @ e dos
   pontos (os <wbr> de VIEWS.usuarios) bastam. Sem o anywhere a largura mínima da
   coluna Nome era o endereço inteiro, e o break-word do body não a diminui. O
   balance escolhe, entre as quebras, a que deixa as linhas de tamanho parecido: sem
   ele, "maria.aparecida.figueiredo@supermercadosdemo / .com.br" no celular. */
.email { overflow-wrap: anywhere; text-wrap: balance; }
@media (max-width: 720px) {
  table.empilha .falta-escopo { display: inline-flex; margin: 0 0 0 8px; vertical-align: middle; }
  /* O cartão de Usuários: "Gerente de loja · vê só 001 Centro" numa linha só dela, e o
     e-mail abrindo a de baixo sem o ponto e sem o recuo do .inicio, alinhado às outras
     linhas. O último acesso vem ao lado quando cabe, com o ponto dele; quando não
     cabe, desce como qualquer detalhe. A especificidade (td + atributo + classe) é
     para vencer as regras de [data-m=meta] ~ [data-m=meta] e .inicio. */
  table.empilha > tbody > tr > td[data-m=meta].papel-ve { flex-basis: 100%; }
  table.empilha > tbody > tr > td[data-m=meta].email-cel { margin-left: 0; left: 0; overflow-wrap: anywhere; }
  table.empilha > tbody > tr > td[data-m=meta].email-cel::before { content: none; }
}

/* ==========================================================================
   Empresas e lojas (lote 9)
   ========================================================================== */

/* A fita "Lojas | Regiões | Empresas", entre o que falta e a lista. No ≤720 ela vira
   três colunas iguais (a regra das fitas de até 5 opções, G22). */
.lj-visoes { margin-bottom: var(--s3); }

/* "Cadastro incompleto": um cartão neutro, e não a faixa vermelha de antes. Dois
   grupos; o segundo ("Pode completar depois") recolhe no celular. */
.pend { display: flex; flex-direction: column; gap: var(--s4); }
.pend-grupo { display: flex; flex-direction: column; gap: 8px; }
.pend-tit { margin: 0; font-size: var(--t-sm); font-weight: 700; color: var(--ink-2); }
.pend-n { font-size: var(--t-sm); font-weight: 600; color: var(--muted); }
/* O gap, e não o espaço do texto: no flex, o espaço do começo de " (5)" some. */
.pend-depois > summary {
  display: flex; align-items: center; gap: 5px; min-height: 44px; margin-block: -10px;
  cursor: pointer; list-style: none; width: fit-content;
}
.pend-depois > summary::-webkit-details-marker { display: none; }
.pend-depois > summary::after {
  content: ""; margin-left: 10px; width: 7px; height: 7px;
  border-right: 2px solid var(--muted); border-bottom: 2px solid var(--muted); transform: rotate(45deg);
}
.pend-depois[open] > summary::after { transform: rotate(225deg); margin-top: 4px; }
.pend-depois[open] > summary { margin-bottom: 0; }
.pend-chips { display: flex; flex-wrap: wrap; gap: 8px; }
/* O chip é um botão com a cara da tag de estado (.tag.st): o ponto diz a cor —
   vermelho, impede medir; amarelo, pode esperar —, e o fundo continua neutro. 44px em
   qualquer largura: é o alvo do aceite, e a fileira quebra em vez de rolar. Acima do
   .estica de um cartão (z-index), ele continua disparando a própria ação. */
.pend-chip {
  font: inherit; font-size: var(--t-sm); font-weight: 700; letter-spacing: 0;
  min-height: 44px; padding: 8px 14px; gap: 8px; cursor: pointer;
  white-space: normal; text-align: left; position: relative; z-index: 1;
}
.pend-chip:hover { border-color: var(--rule-3); color: var(--ink); }
.pend-seta { color: var(--muted); font-weight: 800; }

/* Lojas numa bandeira de outra empresa: uma linha por loja no desktop; no celular, a
   frase do cabeçalho e o atalho para a lista filtrada. */
.cruz-acao { margin-top: var(--s3); }

/* Os filtros das lojas: a busca com a sobra da linha e os selects do tamanho deles,
   cada um com o rótulo ao lado ("Empresa [Todas]", como "Quem trata" na fila). O
   rótulo à vista, e não "Todas as empresas" dentro do select: a 360 cada select tem
   100px de texto, e a frase passava por baixo da seta. No ≤620 (abaixo), a busca na
   linha toda e os dois selects lado a lado, 50/50, com o rótulo em cima. */
.toolbar.filtros.lj-filtros input[type="search"] { flex: 1 1 320px; width: auto; min-width: 0; }
.lj-filtro { display: flex; align-items: center; gap: var(--s2); flex: 0 1 auto; min-width: 0; }
/* O <label> em volta é filho direto da barra, e `.toolbar > label` o encolhe e põe
   em negrito: o select herdava (font: inherit) e o "Todas" saía miúdo e pesado. */
.toolbar > label.lj-filtro { font: inherit; color: inherit; }
.lj-filtro-rot { font-size: 12.5px; font-weight: 700; color: var(--muted); white-space: nowrap; }
.toolbar.filtros.lj-filtros select { flex: 0 1 240px; width: 240px; min-width: 0; }
.lj-filtros-extra { display: flex; align-items: center; gap: var(--s3); flex-wrap: wrap; margin-left: auto; }

/* A lista de lojas no desktop: uma linha por loja, todas da mesma altura. A cidade
   não quebra ("Belo Horizonte/MG" ou reticências em 18ch), e a empresa — quando a
   coluna existe — vai apagada, em peso normal: o que decide é a loja. */
table.lj-tabela tbody td { padding-block: 11px; }
/* A reticência corta só a cidade (o <span class="cid">), e não a célula: cortada na
   célula, ela comia a UF ("Belo Horizo…"), e a coluna chamada Cidade/UF não mostrava
   a UF em linha nenhuma. Assim fica "Belo Hor…/MG", com a UF sempre à vista. */
table.lj-tabela td.cidade-uf { white-space: nowrap; }
table.lj-tabela .cidade-uf .cid {
  display: inline-block; max-width: 18ch; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; vertical-align: bottom;
}
table.lj-tabela td.emp-cel { color: var(--muted); font-weight: 400; white-space: nowrap; }
/* A empresa debaixo do nome da loja: só entre 721 e 1149 (abaixo), onde a coluna
   Empresa não cabe. Fora dessa faixa, a coluna (ou, no cartão, a linha dela) diz. */
.emp-sub { display: none; }
td.falta-cel { white-space: nowrap; }
td.sem-regiao, .linkline.sem-regiao { color: var(--muted-2); font-style: italic; }
td.cnpj-cel { white-space: nowrap; }
/* "Falta CNPJ" e "Falta CEP": abrem Editar loja já no campo que falta. */
.falta-chip { font: inherit; font-size: var(--t-xs); font-weight: 700; cursor: pointer; margin-right: 6px; }
.falta-chip:last-child { margin-right: 0; }
.falta-chip:hover { border-color: var(--rule-3); color: var(--ink); }
/* A razão social embaixo do nome da marca, sem o negrito do botão. */
.linkline .cell-2 small { font-weight: 500; }

/* O link "N ajustes próprios · Ver em Configurações ›" e o fuso de Editar loja. */
.link-ajustes { color: var(--accent-ink); font-size: var(--t-sm); }
.fuso-linha { display: flex; align-items: center; gap: 6px 14px; flex-wrap: wrap; font-size: 14px; color: var(--ink); }
.fuso-linha .linkline { color: var(--accent-ink); font-size: var(--t-sm); }

/* A gaveta da empresa: a mesma .drawer da tratativa, com o nome da marca e o CNPJ
   no cabeçalho, três seções e o "Salvar alterações" no rodapé. */
.gv-emp > header { padding: 10px 14px 12px 20px; }
.gv-hd { display: flex; align-items: center; gap: 10px; min-height: 36px; }
.gv-hd h2 { flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; }
.gv-hd > .tag { flex: none; }
.gv-hd .gv-x { flex: none; margin-left: auto; }
.gv-voltar { display: none; }
.gv-hd-sub { margin-top: 2px !important; }
.gv-fatos { margin: 0; font-size: 13px; color: var(--ink-2); line-height: 1.5; }
.gv-links { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 18px; }
.gv-links .linkline { color: var(--accent-ink); font-size: var(--t-sm); }
.gv-links-txt { font-size: var(--t-sm); color: var(--muted); }
.gv-sec { border-top: 1px solid var(--rule); padding-top: var(--s4); }
.gv-sec-tit { margin: 0 0 var(--s3); font-size: 15px; letter-spacing: -.01em; }
.gv-sec-fixo { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.gv-sec-btn { display: none; }
.gv-sec-intro { margin: 0 0 var(--s3); font-size: 13px; color: var(--muted); line-height: 1.5; }
.gv-falta { font-weight: 700; }

/* A marca da pesquisa (gaveta da empresa): a prévia da faixa que o cliente vê no topo da pesquisa
   por link, o botão da logo e a cor. A faixa usa a cor que a EMPRESA escolheu, e não os tokens
   do app: --mq-cor, --mq-sobre (branco ou tinta, o de maior contraste) e --mq-escura vêm do JS. */
.mq-faixa {
  --mq-cor: #0E7C66; --mq-sobre: #FFFFFF; --mq-escura: #0A5B4B;
  display: flex; align-items: center; gap: 14px; min-height: 78px; padding: 16px 18px;
  background: var(--mq-cor); color: var(--mq-sobre);
  border: 1px solid var(--rule-2); border-radius: var(--r-sm);
  transition: background-color .15s, color .15s;
}
.mq-avatar {
  flex: none; width: 46px; height: 46px; border-radius: 50%; background: #fff; color: var(--mq-escura);
  display: grid; place-items: center; font-size: 22px; font-weight: 800; box-shadow: 0 0 0 1px rgba(0, 0, 0, .12);
}
/* A logo sobre um fundo branco: qualquer logo (escura, clara, com transparência) se lê sobre qualquer cor. */
.mq-logo {
  flex: none; display: grid; place-items: center; max-width: 52%; height: 50px; padding: 5px 10px;
  background: #fff; border-radius: 10px; box-shadow: 0 0 0 1px rgba(0, 0, 0, .12);
}
.mq-logo img { display: block; max-width: 100%; max-height: 40px; object-fit: contain; }
.mq-logo-carrega { width: 96px; background: rgba(255, 255, 255, .4); box-shadow: none; }
.mq-textos { min-width: 0; }
.mq-textos strong { display: block; font-size: 17px; font-weight: 750; line-height: 1.2; overflow-wrap: anywhere; }
.mq-textos span { display: block; font-size: 14px; line-height: 1.3; opacity: .9; }
.mq-textos strong + span { margin-top: 2px; }
.mq-status { margin: 0; }
.mq-botoes .btn { flex: 0 0 auto; }
.mq-botoes .btn.ruim { border-color: var(--det-ink); }
/* O seletor de cor do sistema ao lado do campo do hex, na altura dele. */
.com-botoes > input.mq-seletor { flex: 0 0 56px; width: 56px; min-height: 40px; padding: 3px; cursor: pointer; }
.mq-seletor::-webkit-color-swatch-wrapper { padding: 0; }
.mq-seletor::-webkit-color-swatch { border: 0; border-radius: 4px; }
.mq-seletor::-moz-color-swatch { border: 0; border-radius: 4px; }
.mq-cor-campo .com-botoes > input:not(.mq-seletor) { font-family: var(--f-id); text-transform: uppercase; }
.mq-cor-campo .com-botoes > input::placeholder { font-family: var(--f-ui); text-transform: none; }
.mq-aviso { margin: 0; color: var(--neu-ink); }
/* Dados e Responsável em duas colunas até 760px; o endereço numa grade de seis, com
   cada campo do tamanho do que cabe nele (CEP | Logradouro; Número | Complemento;
   Bairro | Cidade | UF). No ≤520 (abaixo) muda a divisão, e não o número de colunas. */
.form.g2 { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); max-width: 760px; }
.form.g6 { grid-template-columns: repeat(6, minmax(0, 1fr)); column-gap: 12px; max-width: 760px; }
.form.g6 > .field { grid-column: span 6; }
.form.g6 > .c-cep, .form.g6 > .c-num, .form.g6 > .c-cidade { grid-column: span 2; }
.form.g6 > .c-logr, .form.g6 > .c-comp { grid-column: span 4; }
.form.g6 > .c-bairro { grid-column: span 3; }
.form.g6 > .c-uf { grid-column: span 1; }
/* O CNPJ que não muda mais (a empresa já tem resposta): texto, e não campo. */
.valor-fixo { font-size: 15px; font-weight: 700; color: var(--ink); padding: 9px 0 3px; }
/* O fim do corpo: um fio, e o link vermelho longe do Salvar (G15). */
.gv-perigo { border-top: 1px solid var(--rule); padding-top: var(--s4); margin-bottom: var(--s4); }
.gv-perigo-link { color: var(--det-ink); text-decoration: underline; text-underline-offset: 3px; }
.gv-perigo-link.reativar { color: var(--accent-ink); }
.gv-nota { margin: 0; font-size: 13px; color: var(--muted); }
/* "Campos com * são obrigatórios.": o espaço até a primeira seção é o gap do corpo. */
.gv-emp .obrig-nota { margin: 0; }
.gv-emp > footer { justify-content: flex-end; }
.gv-emp > footer > .msg:empty { display: none; }

@media (max-width: 720px) {
  /* A lista de lojas em cartões: os chips numa linha deles, à esquerda. */
  table.empilha > tbody > tr > td.falta-cel { display: flex; flex-wrap: wrap; gap: 6px; text-align: left; }
  table.empilha > tbody > tr > td.falta-cel:empty { display: none; }
  .falta-chip { margin-right: 0; }
  table.lj-tabela .cidade-uf .cid { display: inline; max-width: none; }
  /* A empresa numa linha dela em TODOS os cartões, como o e-mail em Usuários: como
     terceiro detalhe, ela ora cabia ao lado de "Região · Cidade/UF", ora descia
     sozinha e sem o ponto, e os cartões da mesma lista saíam com 3 e 4 linhas, em
     zigue-zague. O td[data-m=meta] é o que vence o .inicio e o "~ [data-m=meta]". */
  table.empilha > tbody > tr > td[data-m=meta].emp-cel { flex-basis: 100%; margin-left: 0; left: 0; }
  table.empilha > tbody > tr > td[data-m=meta].emp-cel::before { content: none; }
  /* O detalhe vazio (a Bandeira da linha "Sem região") some do cartão: sobrava só o
     ponto, "2 lojas · ". No desktop a célula vazia segura a coluna. */
  table.empilha > tbody > tr > td[data-m=meta]:empty { display: none; }
  /* Lojas numa bandeira de outra empresa: no celular, vira a frase. */
  .cruz-tabela { display: none; }
  .cruz-acao { margin-top: 0; }

  /* A gaveta da empresa na tela toda: "‹ Voltar" no lugar do X, e as seções em
     acordeão, com o título como botão. */
  .gv-emp > header { padding: 6px 12px 10px 16px; }
  .gv-voltar { display: inline-flex; margin-left: -8px; flex: none; }
  .gv-hd .gv-x { display: none; }
  .gv-hd-sub { padding-left: 2px; }
  .gv-emp .body { padding: 16px; }
  .gv-sec { padding-top: 4px; }
  .gv-sec-fixo { display: none; }
  .gv-sec-tit { margin-bottom: 0; }
  .gv-sec-btn {
    display: flex; align-items: center; gap: 10px; width: 100%; min-height: 48px; padding: 6px 0;
    font: inherit; font-size: 15px; font-weight: 800; color: var(--ink); text-align: left;
    background: none; border: 0; cursor: pointer;
  }
  .gv-sec-btn .gv-seta { margin-left: auto; flex: none; color: var(--muted); transition: transform .15s; }
  .gv-sec-btn[aria-expanded="true"] .gv-seta { transform: rotate(180deg); }
  .gv-sec-corpo { padding: 4px 0 var(--s3); }
  .gv-sec.fechada > .gv-sec-corpo { display: none; }
}

/* Entre o celular e o notebook largo (a 768 e a 1024 a lista tinha 984px para 726 e
   766) as sete colunas não cabiam, e a tabela rolava com a Situação e o lápis fora da
   vista. Cada coisa sai só até onde precisa (medido de 768 a 1440, nas bordas de
   cada faixa, com a cidade mais longa e não só com a da demo):
   - até 1149, a coluna Empresa, que desce para debaixo do nome da loja (.emp-sub,
     apagada; só existe quando a lista tem lojas de mais de uma empresa). De 1111 a
     1149 ela já cabia, mas quebrava "Supermercados Demo" em duas linhas, e a lista
     saía com linhas de 63 e de 55px;
   - até 1239, a palavra "Falta" dos chips, que ficam "CNPJ" e "CEP" debaixo de
     "Pendência" (de 1180 a 1239, a mesma quebra da empresa). O notebook de 1280, com
     a barra de rolagem, tem uns 1265px: cabe tudo, numa linha só;
   - a cidade corta antes, mas só a cidade: a UF continua ("São José dos C…/SP");
   - as células têm 10px de lado, e não 16 (são 84px a mais para o texto, em sete
     colunas), até 1319: de 1281 a 1319, com os 16px, "AT-01 Atacado Contagem"
     quebrava na coluna Loja;
   - uma empresa de nome longo quebra em duas linhas em vez de empurrar a tabela
     para o lado. */
@media (min-width: 721px) and (max-width: 1319px) {
  table.lj-tabela thead th, table.lj-tabela tbody td { padding-inline: 10px; }
  table.lj-tabela tbody td.r { padding-inline: 6px; }
  table.lj-tabela .cidade-uf .cid { max-width: 14ch; }
  table.lj-tabela td.emp-cel { white-space: normal; }
}
@media (min-width: 721px) and (max-width: 1239px) {
  table.lj-tabela .falta-pre { display: none; }
}
@media (min-width: 721px) and (max-width: 1149px) {
  table.lj-tabela .emp-cel { display: none; }
  table.lj-tabela .emp-sub { display: block; color: var(--muted); font-weight: 400; font-size: var(--t-xs); }
}

/* Até 1240 a busca e os dois filtros não cabem numa linha (945px), e a Região caía
   sozinha na segunda: a busca fica com a linha toda, e os dois filtros dividem a de
   baixo, cada um com o rótulo ao lado. */
@media (min-width: 621px) and (max-width: 1240px) {
  .toolbar.filtros.lj-filtros input[type="search"] { flex-basis: 100%; }
  .lj-filtro { flex: 1 1 0; }
  .toolbar.filtros.lj-filtros .lj-filtro select { flex: 1 1 auto; width: auto; }
}

@media (max-width: 620px) {
  .toolbar.filtros.lj-filtros { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 8px; }
  .toolbar.filtros.lj-filtros input[type="search"], .lj-filtros-extra { grid-column: 1 / -1; }
  .lj-filtro { flex-direction: column; align-items: stretch; gap: 4px; }
  .toolbar.filtros.lj-filtros select { width: 100%; flex: none; }
  .toolbar.filtros.lj-filtros.um-select .lj-filtro { grid-column: 1 / -1; }
  .lj-filtros-extra { margin-left: 0; justify-content: space-between; }
}

@media (max-width: 520px) {
  .form.g2 { grid-template-columns: minmax(0, 1fr); }
  .form.g6 > .c-cep { grid-column: span 3; }
  .form.g6 > .c-logr, .form.g6 > .c-bairro { grid-column: span 6; }
  .form.g6 > .c-num, .form.g6 > .c-uf { grid-column: span 2; }
  .form.g6 > .c-comp, .form.g6 > .c-cidade { grid-column: span 4; }
}

@media (pointer: coarse) {
  .falta-chip { min-height: 44px; padding-inline: 12px; }
}

/* ==========================================================================
   Aparelho de toque. É função do dedo, não da largura: um tablet de 1180 px
   também precisa disso. Abaixo de 16 px o Safari do iOS dá zoom a cada foco.
   ========================================================================== */

@media (pointer: coarse) {
  .btn.ico { width: 44px; min-width: 44px; height: 44px; min-height: 44px; }

  input, select, textarea { font-size: 16px; padding: 11px 13px; }
  /* A seta do select mora nos 32px da direita (regra base): o padding de cima a
     tirava, e no toque o texto passava por baixo dela ("Todas as regiõe⌄"). */
  select { padding-right: 32px; }
  /* O campo de identificador (.id, em Configurações) encolhia para 12px: abaixo de
     16 o Safari do iOS dá zoom a cada foco, e o campo ficava com 43px de altura. */
  input.id, select.id, textarea.id { font-size: 16px; }
  /* O seletor de rede e o de recorte têm padding próprio, mais baixo: sem o piso
     eles ficavam com 40px. */
  .tenant-sel select, .unidade-sel select { min-height: 44px; }
  .btn { min-height: 44px; padding: 11px 18px; }
  /* 44px é o dedo, em todo alvo: botão pequeno, fita, aba, caixa de marcar, conta
     de demonstração e o texto que é botão numa linha de tabela. */
  .btn.sm { min-height: 44px; }
  .btn.quiet { min-width: 44px; min-height: 44px; }
  .seg, .tabs { gap: 4px; }
  .seg button, .tabs .tab { min-height: 44px; min-width: 44px; padding-top: 8px; padding-bottom: 8px; }
  .chk { min-height: 44px; }
  .chk input { width: 22px; height: 22px; }
  .chk-ajuda { margin-left: 29px; }
  .login-inner .contas .conta { min-height: 44px; padding: 10px 8px; }
  .login-inner .contas li { margin-bottom: 4px; }
  .login-inner .contas > summary { padding: 12px 0; }
  .linkline { min-height: 44px; min-width: 44px; display: inline-flex; align-items: center; }
  td.r .linkline { justify-content: flex-end; }
  .side nav a { min-height: 44px; }
  tbody td { padding-block: 14px; }
  .menu-btn { width: 44px; height: 44px; }
  .selo-btn { min-height: 44px; min-width: 44px; }
  .chip-filtro { min-height: 44px; }
  .ver-senha { min-height: 44px; }
  .detalhes-tec > summary { min-height: 44px; display: flex; align-items: center; }
  /* O "Como funciona?" da gaveta tinha 20px de altura; com padding, e não com flex,
     para o triângulo do <summary> continuar ali. */
  .tk-como > summary { padding-block: 12px; }
  /* De e Até da fila: a regra da barra (38px, da altura da fita no desktop) vencia o
     piso de 44 do dedo. */
  .toolbar.filtros .entre-datas input[type="date"] { min-height: 44px; }
  .lista-ops .op { min-height: 44px; }
  /* A linha inteira já é o alvo, mas o rádio de 18px ficava menor que a caixa de
     marcar do .chk: o mesmo 22px, para o dedo ver onde marcou. */
  .lista-ops .op input { width: 22px; height: 22px; }
}

/* Sem cursor não existe hover: a ação da linha, discreta no desktop, fica cheia.
   any-pointer e não pointer: o notebook com tela de toque tem mouse como ponteiro
   principal, e o dedo dele também precisa ver o lápis. */
@media (hover: none), (any-pointer: coarse) {
  tbody tr .row-acts { opacity: 1; }
}

/* Campo que o servidor (ou o ViaCEP) recusou. Vive no fim porque a borda tem de
   ganhar do :hover e do :focus do campo normal. */
/* Borda cheia e grossa na tinta de erro: a --det-line dava 1,29:1 contra o fundo
   rosa, e o erro só se notava pelo fundo. O fundo volta a ser o do campo. */
input.ruim, select.ruim, textarea.ruim { border: 2px solid var(--det-ink); background: var(--surface); }
input.ruim:focus, select.ruim:focus, textarea.ruim:focus { border-color: var(--det-ink); box-shadow: 0 0 0 3px var(--det-soft); }

.nota-corte { font-size: var(--t-sm); color: var(--muted); padding: 10px var(--s4) 0; }

/* ==========================================================================
   Mensagens ao cliente (lote 10)

   A conversa em ordem: um cartão por passo, numerado, com o balão do WhatsApp à
   esquerda e o que se edita à direita no desktop; no celular (≤860), um embaixo do
   outro, com o balão na largura toda.
   ========================================================================== */
.conversa { list-style: none; margin: 0; padding: 0; }
.conversa > li { margin: 0; }
.passo-n {
  display: inline-grid; place-items: center; width: 24px; height: 24px; margin-right: 9px;
  border-radius: 50%; background: var(--accent-soft); color: var(--accent-ink);
  font-size: 13px; font-weight: 800; vertical-align: 2px;
}
.passo-corpo { display: grid; grid-template-columns: minmax(0, 380px) minmax(0, 1fr); gap: 16px 28px; align-items: start; }
.passo-lado { min-width: 0; display: flex; flex-direction: column; align-items: flex-start; gap: 10px; }
.passo-lado > * { max-width: 100%; }
.passo-lado > .banner { margin: 0; align-self: stretch; }
.passo-editar { min-height: 44px; }
.passo-frase { margin: 0 0 8px; font-size: var(--t-md); color: var(--ink-2); }
.passo-empresas { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; margin-bottom: 10px; }
.passo-empresas .linkline { color: var(--accent-ink); }
.tpl-cab { display: flex; flex-direction: column; gap: 2px; }
.tpl-cab h3 { font-size: var(--t-md); font-weight: 800; color: var(--ink); margin: 0; }
.nome-tec { font-family: var(--f-id); font-size: 12px; color: var(--muted); overflow-wrap: anywhere; }
.tpl-status { display: flex; gap: 8px; align-items: baseline; margin: 0; font-size: var(--t-sm); color: var(--ink-2); line-height: 1.45; }
.tpl-status .ponto { background: var(--muted-2); transform: translateY(-1px); }
.ponto.ok { background: var(--prom); }
.ponto.erro { background: var(--det); }
.ponto.acao { background: var(--accent); }
.nota-custo { margin: 0; font-size: 12px; color: var(--muted); line-height: 1.45; }
/* O campo de texto de cada passo: fechado, só a origem ("Usando o texto da rede")
   fica à vista embaixo do balão; "Editar" abre o rótulo e a caixa de texto. Uma
   coluna só, porque o texto é longo e o cartão já tem o balão ao lado. */
.passo-texto, .passo-ajuste { align-self: stretch; }
.passo-texto .ajuste, .passo-ajuste .ajuste { grid-template-columns: minmax(0, 1fr); padding: 0; border-top: 0; }
.passo-texto:not(.aberto) .ajuste > .aj-cab,
.passo-texto:not(.aberto) .aj-campo,
.passo-texto:not(.aberto) .aj-tec { display: none; }
.passo-ajuste { padding-top: 12px; border-top: 1px solid var(--rule); }
/* A faixa de "alterado" com o respiro dela: o padding 0 de cima a colava no texto. */
.passo-texto .ajuste.mudou, .passo-ajuste .ajuste.mudou { padding-left: 12px; margin-left: -12px; }
/* O nome da rede é curto: o campo não atravessa a coluna no desktop. */
.passo-ajuste .aj-linha { max-width: 440px; }
/* "Criar a partir do convite de Supermercados Demo" quebra linha em vez de sair do
   cartão (a 277, com o texto do sistema em 130%). */
.passo .empty-acao .btn { white-space: normal; text-align: center; max-width: 100%; }
@media (max-width: 860px) {
  .passo-corpo { grid-template-columns: minmax(0, 1fr); }
}
/* Os botões do modelo, no editor do convite: cada um num quadro, o endereço do link só para leitura. */
.ed-botoes { margin-top: 14px; display: flex; flex-direction: column; gap: 8px; }
.ed-botao {
  display: flex; flex-direction: column; gap: 4px; padding: 10px 12px;
  border: 1px solid var(--rule); border-radius: var(--r-sm); background: var(--surface-2);
}
.ed-botao-cab { display: flex; align-items: center; gap: 6px; color: var(--ink); font-size: var(--t-sm); }
.ed-botao-cab svg { flex: none; color: var(--accent-ink); }
.ed-endereco { display: block; overflow-wrap: anywhere; }
.ed-botao .sub { margin: 0; }
.ed-botao-falta { border-style: dashed; align-items: flex-start; gap: 8px; background: transparent; }

/* O nome técnico embaixo da versão, nas Mensagens reserva. */
.card.reserva small.nome-tec { display: block; margin-top: 2px; font-weight: 400; }

/* ==========================================================================
   Números de WhatsApp (lote 10): a frase-resposta e um cartão por número
   ========================================================================== */
.numeros-topo { align-items: center; }
.numeros-topo .resposta { margin: 0; flex: 1 1 280px; font-size: var(--t-md); font-weight: 600; color: var(--ink); }
.card.numero > header { flex-wrap: nowrap; align-items: flex-start; }
.numero-cab { flex: 1 1 auto; min-width: 0; }
/* O apelido numa linha só: "sac-demo" quebrava em "sac-" / "demo". */
.numero-cab h2 { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.card.numero > header .tag { flex: none; margin-top: 2px; }
.numero-tel, .tax-escala { white-space: nowrap; }
.numero-linha { margin: 0 0 6px; font-size: var(--t-sm); color: var(--ink-2); }
.rot-inline { color: var(--muted); font-weight: 600; }
.numero-falta h3 { font-size: var(--t-sm); font-weight: 800; color: var(--ink); margin: 12px 0 2px; }
.numero-falta ul { list-style: none; margin: 0; padding: 0; }
.numero-falta li { padding: 7px 0; border-top: 1px solid var(--rule); font-size: var(--t-sm); color: var(--ink-2); line-height: 1.45; }
.numero-falta li:first-child { border-top: 0; }
.numero-falta li small { display: block; margin-top: 2px; font-size: var(--t-xs); color: var(--muted); }
.falta-link {
  font: inherit; font-weight: 700; color: var(--accent-ink); background: none; border: 0;
  padding: 0; margin: 0; text-align: left; cursor: pointer; line-height: 1.45;
  min-height: 44px; display: inline-flex; align-items: center;
}
.falta-link:hover { text-decoration: underline; }
/* As ações no pé do cartão, na mesma altura nos dois cartões lado a lado. */
.card.numero > .body { display: flex; flex-direction: column; }
.numero-acoes { display: flex; flex-wrap: wrap; gap: 6px; justify-content: flex-end; margin-top: auto; padding-top: 12px; }
/* Os detalhes técnicos do suporte: seções com um fio entre elas, e não cartões
   dentro do cartão. */
.tec-canais .tec-sec + .tec-sec { margin-top: 18px; padding-top: 16px; border-top: 1px solid var(--rule); }
.tec-canais .tec-sec:empty { display: none; }
.tec-sec > h3 { font-size: var(--t-md); font-weight: 800; color: var(--ink); margin: 0 0 4px; }
.tec-num + .tec-num { margin-top: 10px; }
/* Os dados da Meta, recolhidos no formulário do número. */
.form-meta { margin-top: 14px; padding-top: 4px; border-top: 1px solid var(--rule); }
.form-meta > summary { cursor: pointer; font-weight: 700; color: var(--ink-2); padding: 10px 0; min-height: 44px; display: flex; align-items: center; gap: 12px; list-style: none; }
/* A seta de abrir, como a dos cartões recolhidos: o display:flex apaga o triângulo do
   navegador, e sem ela a linha lia como um título, e não como algo que abre. */
.form-meta > summary::-webkit-details-marker { display: none; }
.form-meta > summary::after {
  content: ""; margin-left: auto; margin-right: 4px; flex: none; width: 9px; height: 9px;
  border-right: 2px solid var(--muted); border-bottom: 2px solid var(--muted); transform: rotate(45deg);
}
.form-meta[open] > summary::after { transform: rotate(225deg); }
.form-meta[open] > summary { margin-bottom: 8px; }

/* ==========================================================================
   Categorias de problema (lote 10)
   ========================================================================== */
/* O rótulo e o select na mesma linha, e o select com até 360px (só no celular ele
   ocupa a linha: o @media 620 da .toolbar). */
.toolbar.tax-barra select { flex: 0 1 360px; width: auto; min-width: 0; max-width: 360px; }
.tax-legenda { margin: 0 0 var(--s3); }
.tax-subs { font-size: var(--t-sm); color: var(--muted); white-space: nowrap; }
/* "+ Subcategoria em Atendimento": só no celular, onde a coluna do "+" sai. */
/* A largura da gravidade pelo CSS, e não no JS: no celular ela solta (abaixo). */
table.tax th:nth-child(2) { width: 140px; }
table.tax tr.tax-mais { display: none; }
table.tax tr.tax-mais > td { padding-top: 2px; padding-bottom: 8px; border-top: 0; }
table.tax tr.tax-mais .linkline { position: relative; z-index: 1; color: var(--accent-ink); min-height: 44px; display: inline-flex; align-items: center; }
@media (max-width: 520px) {
  table.tax tr.tax-mais { display: table-row; }
  table.tax th:nth-child(3), table.tax tr:not(.tax-mais) > td:nth-child(3) { display: none; }
  /* O cabeçalho quebra linha: numa linha só, "Categoria e subcategorias" e
     "Gravidade (1 a 5)" somavam mais que os 326px do cartão, e a tabela rolava. */
  table.tax th { white-space: normal; }
  table.tax th:nth-child(2) { width: auto; }
  /* 12px de respiro, e não 16: com a coluna das ações fora, sobram só o nome e a
     gravidade, e a 277 (texto em 130%) os 16px empurravam a tag para fora do cartão. */
  table.tax thead th, table.tax tbody td { padding-left: 12px; padding-right: 12px; }
  table.tax tbody td.ind { padding-left: 26px; }
  table.tax tbody td.ind::before { left: 12px; }
}
/* Texto do sistema em 130% num celular de 360 (277px de CSS): "SUBCATEGORIAS" e
   "4 subcategorias", que não quebram, somavam mais que o cartão, e a tabela rolava
   para o lado com a gravidade cortada. O cabeçalho sai (a legenda logo acima já diz a
   escala, e cada linha diz a gravidade por extenso) e "4 subcategorias" pode quebrar. */
@media (max-width: 300px) {
  table.tax thead { display: none; }
  table.tax .tax-subs { white-space: normal; display: inline-block; text-align: right; }
}
/* A fita de escolha no formulário (a gravidade 1 a 5): cinco colunas iguais, com o
   nome da escolhida embaixo. */
.fita-campo { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.fita-campo > .seg { display: grid; width: 100%; }
.fita-campo > .seg button { min-height: 44px; font-size: var(--t-md); }
.fita-campo.ruim > .seg { border: 2px solid var(--det-ink); }
.fita-nome { font-size: var(--t-sm); font-weight: 700; color: var(--ink-2); min-height: 1.3em; }
@media (max-width: 620px) {
  .toolbar.tax-barra select { flex: 1 1 100%; max-width: none; }
}

/* ==========================================================================
   Folha de baixo (G13) e rodapé do formulário no celular (G15, G24)

   No fim do arquivo de propósito: ganha dos @media 720 e 860 do modal, que só
   mudavam a largura da caixa flutuante.
   ========================================================================== */
@media (max-width: 520px) {
  /* O diálogo encosta no fundo, na largura toda, e sobe com o teclado do iPhone:
     --kb é a altura que o teclado tomou (ancorarNoTeclado, app.js). */
  .modal, .modal.largo {
    top: auto; bottom: var(--kb, 0px); left: 0; transform: none; width: 100%;
    max-height: calc(92dvh - var(--kb, 0px)); border-radius: 22px 22px 0 0;
    animation: folha .2s cubic-bezier(.22,.8,.3,1);
  }
  .modal > .body { overflow-y: auto; }
  /* [Cancelar][Principal] lado a lado e da mesma largura; o resumo do erro e as
     ações extras em linhas próprias, acima do par; a de perigo, um link vermelho
     no fim, a 24px do par (8 da grade + 16 de margem). */
  .modal > footer, .modal > footer:has(> .acao-perigo) {
    /* minmax(0,1fr) e não 1fr: o mínimo automático do 1fr deixava o rótulo longo
       ("Continuar editando", "Desativar empresa") alargar a própria coluna. */
    position: sticky; bottom: 0; display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 8px;
    /* stretch: se um rótulo ainda quebrar (a 277 do texto em 130%), o par cresce
       junto e não fica um botão mais alto e desalinhado do outro. */
    align-items: stretch;
    padding-bottom: calc(14px + env(safe-area-inset-bottom));
  }
  .modal > footer .grow { display: none; }
  /* A folha de escolhas ("Mais ações") só tem o Fechar: na largura toda. */
  .modal.so-escolhas > footer { grid-template-columns: minmax(0, 1fr); }
  /* Recuo de 10px, e não 17: "Continuar editando" e "Desativar categoria" cabem numa
     linha nos 154px de cada metade a 360. */
  .modal > footer .btn { width: 100%; white-space: normal; text-align: center; padding-inline: 10px; }
  .modal > footer > .msg, .modal > footer > .acao-extra, .modal > footer > .nota-rodape { grid-column: 1 / -1; }
  .modal > footer > .msg:empty { display: none; }
  /* A ação extra discreta ("Mover de região") ganha contorno na folha: na largura
     toda e sem borda, ela parecia um rótulo, e não um botão. */
  .modal > footer > .btn.quiet.acao-extra, .form-ft > .btn.quiet.acao-extra {
    background: var(--surface); border-color: var(--rule-2); color: var(--ink-2);
  }

  /* O rodapé do formulário na página: o Salvar na largura toda, por último, e o
     perigo embaixo dele. */
  .form-ft, .form-ft:has(> .acao-perigo) { display: grid; grid-template-columns: 1fr; gap: 8px; }
  .form-ft .grow { display: none; }
  .form-ft .btn { width: 100%; }
  .form-ft > .msg:empty { display: none; }
  .form-ft > .nota-rodape { order: 0; }

  /* .btn duas vezes: ganha de .btn.danger.ghost, que pintaria a borda e o fundo. */
  .modal > footer > .btn.btn.acao-perigo, .form-ft > .btn.btn.acao-perigo {
    grid-column: 1 / -1; order: 9; justify-self: center; width: auto;
    margin-top: 16px; min-height: 44px; padding: 8px 12px;
    background: transparent; border-color: transparent; color: var(--det-ink);
    font-weight: 700; text-decoration: underline; text-underline-offset: 3px;
  }
  .modal > footer > .btn.btn.acao-perigo:hover, .form-ft > .btn.btn.acao-perigo:hover { background: var(--det-soft); }
}
@keyframes folha { from { transform: translateY(24px); opacity: 0; } }

/* ==========================================================================
   Resumo (lote 6): o responsivo. No fim, para ganhar das regras de layout.
   ========================================================================== */
@media (pointer: coarse) {
  .abre > summary { padding-block: 12px; }
}
@media (pointer: coarse) and (min-width: 721px) {
  /* No tablet as listas do Resumo são tabela, e o nome (o problema, a unidade) é o
     botão de 44px do dedo: a linha crescia para 73-93px com o texto solto no meio. O
     alvo continua com 44px, e os 12px de cima e de baixo, que são só ar, se sobrepõem
     aos 14px de recuo da célula. */
  .resumo-lista td .linkline.estica { margin-block: -12px; }
}
/* O contrário: a linha que só o celular mostra. A lista "precisam de atenção" leva 3
   lojas no celular mesmo quando a metade dá menos (a região do regional tem 3); no
   desktop a que passa da metade já está em "vão bem" e não se repete. */
@media (min-width: 721px) {
  .so-cel-720 { display: none !important; }
  /* A última linha À VISTA fica sem o fio de baixo, como a última da tabela. */
  tbody tr:has(+ tr.so-cel-720) > td { border-bottom: 0; }
}
@media (max-width: 720px) {
  /* O que no celular não aparece: "Lojas que vão bem" (fica "precisam de atenção",
     com 3 lojas e o caminho para o ranking) e "Onde acontece" antes do toque num
     problema. !important porque as regras de grade (.grid.c2 > ...) põem display. */
  .so-desk-720 { display: none !important; }
  /* As listas do Resumo: três seguidas numa página que se rola inteira, com as linhas
     mais baixas (8px de recuo, 2px entre os andares e a entrelinha de 1,3, e não 12, 4
     e 1,5): de 69 para 57px por linha, e os 56px do dedo continuam. */
  .resumo-lista table.empilha > tbody > tr { padding-block: 8px; row-gap: 2px; min-height: 56px; }
  .resumo-lista table.empilha > tbody > tr > td { line-height: 1.3; }
  .resumo-lista .score { line-height: 1.2; }
  /* O que se abre dentro de um cartão do topo não soma recuo ao do cartão. */
  .nps-cartao .abre { margin-top: 4px; }
  .card-dias .abre { padding-block: 0; }
  .cls-trio { margin-top: 12px; }
  .cls-rodape { margin-top: 10px; padding-top: 10px; }
  .ret-sub { margin-bottom: 8px; }
  .ret-acao { margin-top: 10px; }
  /* O cabeçalho cujo botão desce para a linha de baixo ("Ver ranking completo", a
     legenda das respostas, "Bandeira · Região · Loja"): 4px entre as linhas, e não os
     12 do espaço entre título e botão. O botão de texto continua com 44px de alvo,
     mas os 8px de cima e de baixo, que são só ar, se sobrepõem ao recuo do cabeçalho. */
  .resumo-lista > header, .card-dias > header { row-gap: 4px; }
  .resumo-lista > header > .btn.sm { margin-block: -8px; }
  /* O mesmo para "O que é NPS?": o alvo desce sobre o recuo do cartão. */
  .nps-cartao .abre > summary { margin-bottom: -8px; }
  /* "Onde acontece": a loja numa linha e a frase ("11 reclamações · 8% das respostas
     desta loja") na de baixo. Lado a lado, a frase espremia o nome da loja até sobrar
     só o código. */
  .barra-l { grid-template-columns: minmax(0, 1fr); }
  /* Na legenda das notas que quebra linha, o ponto ficava sozinho no fim da linha. */
  .legend-notas .leg-ponto { display: none; }
  /* O subtítulo que só repete o período (a fita está no alto da tela). */
  .sub-so-desk > header .sub { display: none; }
  .topo-painel, .topo-painel.dois { grid-template-columns: minmax(0, 1fr); }
  .topo-painel > .card-retorno { grid-column: auto; }
  .urg-linha, .urg-nada, .urg-retorno, .urg-sac { padding-inline: 15px; }
  .card.dobra > summary { padding: 13px 15px; }
  .abre > .tbl-wrap { margin-inline: -15px; }
  .card-dias .abre { padding-inline: 15px; }
  .card-dias .abre > .tbl-wrap { margin-inline: -15px; }
  /* O problema escolhido, no cartão: o fio de acento na borda da linha inteira, e não
     só da primeira célula. */
  table.empilha > tbody > tr.sel { box-shadow: inset 3px 0 0 var(--accent); }
  table.empilha > tbody > tr.sel > td:first-child { box-shadow: none; }
  /* O nome do problema é o botão que estica (o cartão inteiro é o alvo): os 44px do
     dedo só engordavam a linha do título, como no .estica direto na célula. */
  table.empilha .prob-nome > .linkline.estica { min-height: 0; }
}
@media (max-width: 520px) {
  /* O funil: rótulo e número numa linha, a barra na largura toda embaixo. Na grade de
     três colunas a barra ficava com ~55px a 360, e a perda não se via. */
  .funil-e { grid-template-columns: 1fr auto; row-gap: 6px; }
  .funil-e .b { grid-column: 1 / -1; order: 3; }
  .funil-e .n { min-width: 0; }
  .funil-e .n small { display: inline; margin-left: 6px; }
  .funil-perda { grid-column: 1 / -1; margin-top: 0; }
}
@media (max-width: 380px) {
  /* O título mais longo do topo ("Resumo da região Centro-Sul") perdia o "Sul" nas
     reticências a 360, ao lado do selo "Teste": 1px a menos na fonte e 2px no vão. Só
     nele (render() põe o .tit-longo): os títulos das outras telas ficam nos 16px. */
  .topbar h1.tit-longo { font-size: 15px; letter-spacing: -.035em; }
  .topbar .tit-linha:has(> .tit-longo) { gap: 8px; }
  /* "Precisa de você" com três dígitos ("123 tratativas citam saúde, Procon/justiça ou
     discriminação"): com os 14px de vão, "discriminação" descia para uma terceira linha
     a 360 e a linha ia de 56 para 73px. Com 10px ela fica em duas, na mesma fonte. */
  .urg-linha { gap: 10px; }
}
@media (max-width: 300px) {
  /* 360 com o texto do sistema em 130%: o trio não cabe lado a lado. */
  .cls-trio { grid-template-columns: minmax(0, 1fr); gap: 8px; }
  .cls { flex-direction: row; flex-wrap: wrap; align-items: baseline; gap: 2px 8px; }
}

/* ==========================================================================
   Tratativas (lote 12) no celular
   ========================================================================== */
@media (max-width: 720px) {
  /* Os quatro números em 2×2 (a régua de KPI do @720, que perde para .tk-kpis). */
  .kpis.tk-kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .tk-dia-lado { flex: 1 1 100%; flex-direction: row; }
  .tk-dia-num { flex: 1 1 0; }
  .sac-dia { grid-template-columns: minmax(0, 1fr) minmax(150px, 190px); }
  .sac-horas, .sac-fechado { grid-column: 1 / -1; }
  .sac-novo { grid-template-columns: minmax(0, 1fr); }
  .sac-novo > .btn { width: 100%; }
}
@media (max-width: 380px) {
  button.kpi { padding: 12px 11px; }
  .tk-st-num span { min-width: 2.8em; }
}

/* ==========================================================================
   Auditoria — a evolução do NPS, a variação no ranking, a região da loja
   ========================================================================== */
.rk-regiao { font-size: var(--t-xs); color: var(--muted); font-weight: 400; }
.rk-var { display: block; font-size: var(--t-xs); font-weight: 700; color: var(--muted); white-space: nowrap; }
.rk-var.sobe { color: var(--prom-ink); }
.rk-var.desce { color: var(--det-ink); }
/* NPS por semana (ou por mês): uma linha por faixa, a barra de -100 a 100 e a marca
   da meta. Rótulo, barra e número numa grade só, em toda largura. */
.evo { display: flex; flex-direction: column; gap: 10px; }
.evo-l { display: grid; grid-template-columns: 92px minmax(0, 1fr) 76px; align-items: center; gap: 12px; }
.evo-k { font-size: var(--t-sm); color: var(--muted); white-space: nowrap; }
/* Quantas respostas a faixa tem, e se ela é parcial: à vista, e não só no title. */
.evo-k small { display: block; font-size: var(--t-xs); white-space: normal; line-height: 1.3; }
.evo-k small.evo-parcial { color: var(--neu-ink, var(--muted)); font-weight: 700; }
.evo-b { position: relative; height: 12px; border-radius: 6px; background: var(--surface-3); overflow: visible; }
.evo-b i { position: absolute; left: 0; top: 0; bottom: 0; border-radius: 6px; background: var(--det); }
.evo-b i.ok { background: var(--prom); }
.evo-b i.medio { background: var(--neu-mark); }
.evo-meta { position: absolute; top: -4px; bottom: -4px; width: 2px; background: var(--ink); border-radius: 1px; }
.evo-v { font-weight: 800; text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.evo-v small { font-weight: 700; margin-left: 2px; font-size: var(--t-xs); }
.evo-v small.sobe { color: var(--prom-ink); }
.evo-v small.desce { color: var(--det-ink); }
@media (max-width: 380px) {
  .evo-l { grid-template-columns: 76px minmax(0, 1fr) 64px; gap: 8px; }
}

/* Imprimir o Resumo, o Ranking ou o Painel para a reunião: só o conteúdo, sem o menu,
   os filtros e os botões. */
@media print {
  aside, .topbar .menu-btn, .tools-slot, #periodo, .toolbar, .btn, .seg, .tbl-mais, .pp, #toasts { display: none !important; }
  body, .card { background: #fff !important; box-shadow: none !important; }
  .card { break-inside: avoid; border: 1px solid #ccc; }
  main, #view { margin: 0 !important; padding: 0 !important; }
}

/* Os filtros da fila no desktop e no tablet (>720): uma linha da barra, ao lado de Fila ·
   Painel. No celular eles são a linha "Filtros" e a folha de baixo (.tk-cel). */
.tk-dobra { min-width: 0; }
.tk-dobra-corpo { display: flex; flex-wrap: wrap; align-items: flex-end; gap: var(--s3); }
@media (min-width: 721px) {
  /* Com Tipo e Criticidade a barra não cabe numa linha: duas linhas alinhadas, os
     selects na primeira (ao lado de Fila · Painel) e "Abertas em" sozinho na segunda,
     começando embaixo do primeiro select. Antes a quebra era onde sobrasse espaço, e a
     fita caía torta embaixo de um select. */
  .tk-barra { align-items: flex-start; }
  .tk-barra > .tk-dobra { flex: 1 1 0; }
  .tk-dobra-corpo > .tk-periodo { flex-basis: 100%; }
}
/* Tablet e notebook pequeno: os três selects ao lado de Fila · Painel só cabem com uns
   1030px de conteúdo. Abaixo disso, os filtros vão na largura toda, embaixo da fita
   da vista, em três colunas iguais com o rótulo em cima ("Detratores (0 a 6)" cortava
   em 170px a 768), e "Abertas em" na linha de baixo, também com o rótulo em cima. */
@media (min-width: 721px) and (max-width: 1319px) {
  .tk-barra > .tk-dobra { flex: 1 1 100%; }
  .tk-dobra-corpo { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); align-items: end; gap: 12px 16px; }
  .tk-dobra-corpo > .tk-filtro { flex-direction: column; align-items: stretch; gap: 6px; }
  .toolbar.filtros .tk-dobra-corpo > .tk-filtro select, .tk-dobra-corpo > .tk-filtro .ms-caixa { width: 100%; }
  .tk-dobra-corpo > .tk-periodo, .tk-dobra-corpo > .entre-datas { grid-column: 1 / -1; }
  .tk-dobra-corpo > .tk-periodo > .seg { align-self: flex-start; }
  .tk-limpar { justify-self: start; align-self: end; min-height: 44px; }
}
/* Celular (≤720, pedido do dono: "os filtros ocupam mais de meia tela"): a barra é UMA
   linha de 48px — Fila · Painel, compacta, e a linha "Filtros · N" com o resumo, que
   abre a folha de baixo — e o gerente tem embaixo dela o "Da loja · Com o SAC". Os
   campos da barra do desktop não aparecem: estão na folha. */
@media (max-width: 720px) {
  .tk-desk { display: none; }
  .toolbar.tk-barra { flex-direction: row; flex-wrap: wrap; align-items: stretch; gap: 8px; }
  .toolbar.tk-barra > .seg.tk-vista { display: inline-flex; width: auto; flex: none; padding: 1px; }
  .toolbar.tk-barra > .seg.tk-vista button { min-width: 0; padding-inline: 12px; }
  .toolbar.tk-barra > .tk-cel { display: flex; flex: 1 1 0; min-width: 0; }
  .tk-cel > .tk-filtros-btn { width: 100%; }
  .toolbar.tk-barra > .tk-quem-ger { flex: 1 1 100%; padding: 1px; }
}
/* As caixas de marcar da folha (Quem trata, Tipo, Criticidade): o mesmo "Todos" no alto
   da caixinha do desktop, cada linha com 48px para o dedo e o texto em 16px. */
.ms-folha { border: 0; margin: 0; padding: 0; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.ms-folha > legend { padding: 0; margin-bottom: 6px; font-weight: 700; color: var(--muted); }
.ms-folha .ms-op { min-height: 48px; font-size: 16px; }
/* Na folha do Resumo, o Onde e o Problema começam fechados, numa linha de 48px com o que
   está valendo ("Onde · Betim, Savassi"): abertos, a árvore de lojas passava de uma tela. */
.ms-dobra > summary {
  display: flex; align-items: center; gap: 8px; min-height: 48px; padding: 0 12px; cursor: pointer;
  list-style: none; border: 1.5px solid var(--field-line); border-radius: var(--r-sm); background: var(--surface);
}
.ms-dobra > summary::-webkit-details-marker { display: none; }
.ms-dobra > summary::after { content: '▾'; margin-left: auto; color: var(--muted); }
.ms-dobra[open] > summary::after { content: '▴'; }
.ms-dobra > summary .pf-rot { flex: none; }
.ms-dobra-val { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 16px; color: var(--ink); }
.ms-dobra > fieldset { margin-top: 6px; }
.ms-folha .ms-op input { width: 22px; height: 22px; }
.folha-corpo .entre-datas { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-top: 8px; }
.folha-corpo .entre-datas input[type="date"] { min-height: 44px; font-size: 16px; }
@media (pointer: coarse) {
  .ms-op { min-height: 44px; }
  .ms-btn { min-height: 44px; font-size: 16px; }
}
/* O cliente e a compra na gaveta, na mesma ficha dos fatos (app.js, tk-ficha): entre
   eles, o espaço de uma linha, e não o vão das seções do Caso. */
.tk-ficha { display: flex; flex-direction: column; gap: 4px; }
.tk-cliente, .tk-compra { margin: 0; font-size: var(--t-sm); color: var(--ink-2); line-height: 1.55; }
.tk-tel { font-variant-numeric: tabular-nums; font-weight: 600; white-space: nowrap; }
.tk-tel-grupo { white-space: nowrap; }
/* O alvo de 44px do "Copiar" sem empurrar a linha: a margem negativa devolve a altura
   que ele passa da linha de texto, e o parágrafo fica com a altura das outras linhas. */
.tk-copiar { font-size: var(--t-sm); min-height: 44px; padding: 0 6px; margin-block: -12px; vertical-align: middle; }

/* Os campos da folha "Filtros" das Tratativas (app.js, abrirFolhaTk): o rótulo em cima e
   o campo na largura toda. O Resumo e o Ranking têm a barra de filtros própria (fx-). */
.pf-campo { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.pf-rot { font-size: 12.5px; font-weight: 700; color: var(--ink-2); }
.pf-campo select { width: 100%; min-width: 0; }
.pf-campo .ms-caixa { width: 100%; }

/* O problema que filtra a tela, marcado na lista (além do fundo da linha .sel). */
.prob-filtro {
  display: inline-block; margin-left: 6px; padding: 1px 7px; border-radius: var(--r-full);
  background: var(--accent); color: #fff; font-size: var(--t-xs); font-weight: 800; vertical-align: 1px;
}
/* A frase do NPS de um problema: quem reclama costuma dar nota baixa. */
.nps-linha.nps-prob { color: var(--ink-2); }

/* Os atalhos de tipo e nota para Comentários: os grupos de "Como os clientes avaliaram"
   e as barras e a legenda de "Distribuição das notas" são botões, com a cara de antes. */
button.cls {
  font: inherit; text-align: left; background: transparent; border: 0; cursor: pointer;
  min-height: 44px; padding: 6px 8px; margin: -6px -8px; border-radius: var(--r-sm);
}
button.cls:hover { background: var(--surface-3); }
.notas > button { font: inherit; background: transparent; border: 0; padding: 0; cursor: pointer; border-radius: 4px; }
.notas > button:hover .b > i { filter: brightness(.9); }
.legend .leg-btn {
  display: inline-flex; align-items: center; gap: 6px; font: inherit; font-weight: 600; color: inherit;
  background: transparent; border: 0; padding: 4px 6px; margin: -4px -6px; border-radius: var(--r-xs); cursor: pointer;
}
.legend .leg-btn:hover { color: var(--ink); text-decoration: underline; text-underline-offset: 2px; }

/* Celular: a barra-botão de 48px das Tratativas, com "Filtros · N" e o resumo numa linha
   só, com reticências. */
@media (max-width: 720px) {
  .filtros-barra {
    flex: 1 1 auto; min-width: 0; min-height: 48px; display: flex; align-items: center; gap: 8px;
    padding: 8px 12px; border-radius: var(--r-md); border: 1px solid var(--accent-line);
    background: var(--accent-soft); color: var(--accent-ink); font: inherit; font-size: var(--t-sm);
    text-align: left; cursor: pointer;
  }
  .filtros-barra svg { flex: none; }
  .filtros-barra b { flex: none; font-weight: 800; }
  .filtros-resumo { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    color: var(--ink-2); font-weight: 600; }
  .legend .leg-btn { min-height: 44px; }
  button.cls { min-height: 44px; }
}

/* A folha de baixo do celular (<dialog> modal): até 85% da altura, rola só por dentro,
   o título com o × no alto e "Limpar" e "Ver resultados" presos no pé. Todo alvo com
   44px, e os campos em 16px (abaixo disso o iPhone aproxima a tela ao tocar). */
dialog.folha-filtros {
  position: fixed; inset: auto 0 0 0; margin: 0; width: 100%; max-width: 100%;
  max-height: 85dvh; padding: 0; border: 0; border-radius: 16px 16px 0 0;
  background: var(--surface); color: var(--ink); box-shadow: 0 -8px 30px rgba(0, 0, 0, .2);
  display: flex; flex-direction: column; overflow: hidden;
}
dialog.folha-filtros:not([open]) { display: none; }
dialog.folha-filtros::backdrop { background: rgba(19, 19, 34, .5); }
html.folha-aberta { overflow: hidden; }
.folha-topo { flex: none; display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding: 4px 6px 4px 16px; border-bottom: 1px solid var(--rule); }
.folha-topo h2 { font-size: var(--t-lg); letter-spacing: -.02em; }
.folha-x { width: 44px; height: 44px; display: grid; place-items: center; border: 0; background: transparent;
  border-radius: var(--r-sm); color: var(--ink-2); cursor: pointer; }
.folha-x:hover { background: var(--surface-3); }
.folha-corpo { flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain;
  padding: 16px; display: flex; flex-direction: column; gap: 18px; }
.folha-corpo .pf-rot, .folha-corpo .field > label { font-size: var(--t-sm); }
.folha-corpo select { min-height: 44px; font-size: 16px; }
.folha-pe { flex: none; display: flex; gap: 8px; padding: 10px 16px calc(10px + env(safe-area-inset-bottom));
  border-top: 1px solid var(--rule); background: var(--surface); }
.folha-pe .btn.quiet { min-height: 48px; min-width: 44px; }
.folha-pe .folha-ver { flex: 1 1 auto; min-height: 48px; }
/* ==========================================================================
   Convites enviados (app.js, VIEWS.pesquisas e abrirConvite)
   ========================================================================== */
/* Os quatro contadores filtram ao tocar: o que está filtrando fica azul, com o fio
   embaixo, e o X no lugar da seta diz que tocar de novo tira o filtro. */
.cv-kpis button.kpi[aria-pressed="true"] { background: var(--accent-soft); box-shadow: inset 0 -3px 0 var(--accent); }
.cv-kpis button.kpi[aria-pressed="true"] .k,
.cv-kpis button.kpi[aria-pressed="true"] .kpi-seta { color: var(--accent-ink); }
/* A busca no cabeçalho do cartão, à direita da frase; no celular, a linha toda. */
.card > header .cv-busca { flex: 0 1 300px; width: 300px; min-width: 0; }
/* O cliente em negrito, o telefone embaixo em 12px; a situação com o porquê embaixo. */
td.cv-cli .cv-tel { display: block; margin-top: 2px; font-size: var(--t-xs); font-weight: 500; color: var(--muted);
  font-variant-numeric: tabular-nums; white-space: nowrap; }
td.cv-sit .cv-det { display: block; margin-top: 3px; font-size: var(--t-xs); color: var(--muted); line-height: 1.35; }
/* "Não enviados": o CPF e o número tentado em colunas próprias, sem quebrar; o que
   falta ("sem CPF na compra") apagado, e o aviso de que o cadastro mudou embaixo. */
td.cv-linha.num { white-space: nowrap; }
.cv-falta { color: var(--muted); font-style: italic; }
.cv-mudou { display: block; margin-top: 2px; font-size: var(--t-xs); color: var(--muted); white-space: normal; }
.cv-nota-num { display: block; margin-top: 2px; font-size: var(--t-xs); color: var(--muted); }
.cv-erro { padding: var(--s4); }
.cv-erro .banner { margin: 0; align-items: center; flex-wrap: wrap; }
.cv-erro .banner .btn { margin-left: auto; }
/* A busca pelo CPF acima da fila de Tratativas: 320px no desktop, a linha toda no
   celular; a frase do CPF que não fecha o verificador logo ao lado (embaixo, no celular). */
.tk-busca { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px; margin: 0 0 var(--s4); }
.tk-busca .tk-busca-cpf { flex: 0 1 320px; width: 320px; min-width: 0; min-height: 44px; }
.tk-busca-msg { flex: 1 1 240px; margin: 0; font-size: var(--t-sm); font-weight: 600; color: var(--det-ink); }
.tk-busca-msg:empty { display: none; }
.tk-cpf-voltar { white-space: nowrap; }
@media (max-width: 720px) {
  .tk-busca .tk-busca-cpf { flex: 1 1 100%; width: 100%; }
}
@media (max-width: 720px) {
  .card > header .cv-busca { flex: 1 1 100%; width: 100%; }
  /* No cartão, o detalhe da situação é um item da linha de baixo, como a data e a loja. */
  td.cv-sit .cv-det { display: inline; margin: 0; font-size: inherit; color: inherit; }
  /* No cartão de "Não enviados", o CPF, o número e o porquê, um por linha: são o que se
     lê para acertar o cadastro, e enfileirados com a data e a loja viravam um bloco só. */
  table.empilha > tbody > tr > td[data-m=meta].cv-linha { flex-basis: 100%; margin-left: 0; left: 0; }
  table.empilha > tbody > tr > td[data-m=meta].cv-linha::before { content: none; }
  table.empilha > tbody > tr > td.cv-linha .cv-mudou { display: inline; margin: 0 0 0 6px; }
}

/* Importar vendas, ao lado da busca no cabeçalho do cartão: a linha toda no celular (a busca
   em cima, o botão embaixo). */
.card > header .cv-acoes { flex-wrap: wrap; justify-content: flex-end; }
@media (max-width: 720px) {
  .card > header .cv-acoes { justify-content: stretch; }
}
/* O link da pesquisa na gaveta do convite: o endereço quebra em qualquer ponto (o token são 22
   caracteres seguidos) e fica selecionável de uma vez; Copiar e Abrir com 44px. */
.cv-link { display: flex; flex-direction: column; gap: 8px; }
.cv-link-url { display: block; padding: 10px 12px; background: var(--surface-3); border: 1px solid var(--rule);
  border-radius: var(--r-sm); font-family: var(--f-id); font-size: 12.5px; line-height: 1.5; color: var(--ink);
  overflow-wrap: anywhere; word-break: break-all; user-select: all; }
.cv-link-acoes { display: flex; flex-wrap: wrap; gap: 8px; }
.cv-link-acoes .btn { min-height: 44px; }
.cv-link-nota { margin: 0; font-size: var(--t-xs); color: var(--muted); }

/* Pesquisa avulsa (db/047): o selo na lista, o quinto contador (Avulsas) e o diálogo de Convites enviados. */
.cv-avulsa { margin-left: 6px; vertical-align: 1px; font-size: var(--t-xs); }
.tk-hd-l2 .cv-avulsa { margin: 0 6px 0 0; }
@media (min-width: 721px) {
  .kpis.tk-kpis.com-avulsas { grid-template-columns: repeat(5, minmax(0, 1fr)); }
}
.av .av-confere { margin: 4px 0 0; font-size: var(--t-xs); color: var(--muted); font-variant-numeric: tabular-nums; }
.av .av-confere:empty { display: none; }
.av-prev { display: flex; flex-direction: column; gap: 8px; margin-top: var(--s3); }
.av-prev:empty, .av-aviso:empty { display: none; }
.av-aviso { margin-top: 8px; }
.av-frase { margin: 0; font-size: var(--t-sm); color: var(--ink-2); }
.av-nota { margin: 0; font-size: var(--t-xs); color: var(--muted); }
.av-ruim { color: var(--det-ink); font-weight: 600; }
.av-caixa { display: flex; align-items: flex-start; gap: 10px; min-height: 44px; padding: 10px 12px;
  border: 1px solid var(--rule); border-radius: var(--r-sm); cursor: pointer; font-size: var(--t-sm); }
.av-caixa input { flex: none; width: 18px; height: 18px; margin: 1px 0 0; }
.av-res { display: flex; flex-direction: column; gap: 12px; }
.av-res p { margin: 0; }
.av-res .com-botoes { display: flex; gap: 8px; }
.av-link { flex: 1 1 auto; min-width: 0; font-family: var(--f-id); font-size: 13px; }
.av-res .banner { margin: 0; }
.av-quem { font-weight: 600; color: var(--ink); overflow-wrap: anywhere; }
.av-acoes { display: flex; flex-wrap: wrap; gap: 8px; }
.av-acoes .btn, .av-res .com-botoes .btn { min-height: 44px; }

/* A gaveta do convite: a .drawer da tratativa (tela cheia abaixo de 720), com a
   situação no alto e as fichas em duas colunas — rótulo e valor —, que no celular
   empilham. */
.cv-detalhes { gap: var(--s5); }
section.cv-sit { display: flex; flex-direction: column; gap: 8px; }
.cv-sit-l1 { display: flex; align-items: center; gap: 8px 10px; flex-wrap: wrap; }
.cv-sit-det { font-size: 13.5px; color: var(--ink-2); }
.cv-sit .explica { font-size: var(--t-sm); color: var(--muted); margin: 0; }
.cv-sit .explica.bloqueio { color: var(--ink-2); }
.cv-bloco > .eyebrow { margin: 0; }
.cv-ficha { display: grid; grid-template-columns: minmax(120px, 32%) minmax(0, 1fr); gap: 7px 14px; margin: 0;
  font-size: 13.5px; line-height: 1.45; }
.cv-ficha dt { color: var(--muted); }
.cv-ficha dd { margin: 0; color: var(--ink); min-width: 0; overflow-wrap: anywhere; }
.cv-chave { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 12.5px; letter-spacing: .01em; }
@media (max-width: 520px) {
  .cv-ficha { grid-template-columns: minmax(0, 1fr); gap: 0; }
  .cv-ficha dt { font-size: var(--t-xs); font-weight: 700; }
  .cv-ficha dd { margin-bottom: 10px; }
  .cv-ficha dd:last-child { margin-bottom: 0; }
}
/* A linha do tempo: o que deu errado com o ponto vermelho, e o que ainda falta com o
   ponto vazado e o texto apagado. */
.tl.erro .pin { background: var(--det-soft); border-color: var(--det-line); }
.tl.erro .pin i { background: var(--det); }
.tl.espera .pin { background: var(--surface); border-style: dashed; }
.tl.espera .pin i { background: transparent; }
.tl.espera .txt b { color: var(--muted); font-weight: 600; }
.cv-conv-nota { margin: 0; font-size: var(--t-sm); color: var(--muted); }
.cv-conv-vazia { padding: 32px var(--s3); }
.cv-gaveta > footer .cv-teste { white-space: normal; }

/* ==========================================================================
   Ranking de lojas — o pódio, a lista e a chegada (pedido do dono: "uma entrada tão
   triunfal no login e aqui o ranking está bem fraquinho"). Tudo com o prefixo rk-.
   A forma final é a regra de base; a animação só existe embaixo de .rk-anima, que o
   app.js põe na chegada e na troca de período ou recorte, nunca com movimento reduzido.
   ========================================================================== */
.rk { position: relative; }

/* "Sua loja", para o gerente: grudada embaixo do topo enquanto ele rola (o top vem do
   app.js, que mede a barra do topo). Botão inteiro, ≥ 48px: leva à loja na lista. */
.rk-eu {
  position: sticky; z-index: 15; top: 68px;
  display: flex; align-items: center; flex-wrap: wrap; gap: 2px 12px;
  width: 100%; min-height: 48px; margin: 0 0 var(--s4); padding: 8px 16px;
  font: inherit; text-align: left; color: var(--ink);
  background: var(--surface); border: 1px solid var(--accent-line); border-radius: var(--r-lg);
  box-shadow: var(--sh-2); cursor: pointer;
}
button.rk-eu:hover { border-color: var(--accent); }
button.rk-eu:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.rk-eu.medindo { cursor: default; border-color: var(--rule-2); }
.rk-eu.medindo .btn { margin-left: auto; }
.rk-eu-rot { font-size: var(--t-xs); font-weight: 800; letter-spacing: .08em; text-transform: uppercase; color: var(--accent-ink); }
.rk-eu-nome { font-weight: 700; }
.rk-eu-pos { font-size: 20px; font-weight: 800; letter-spacing: -.03em; line-height: 1.2; font-variant-numeric: tabular-nums; }
.rk-eu-pos span { font-size: var(--t-sm); font-weight: 700; letter-spacing: 0; color: var(--ink-2); }
.rk-eu-nps { font-size: var(--t-sm); font-weight: 600; color: var(--ink-2); }
.rk-eu-ver { margin-left: auto; font-size: var(--t-sm); font-weight: 700; color: var(--accent); }

/* Quem subiu, quem caiu: a seta e "+3 posições" numa pílula com a cor do sentido. */
.rk-mov {
  display: inline-flex; align-items: center; gap: 4px; padding: 2px 8px; border-radius: var(--r-full);
  font-size: var(--t-xs); font-weight: 800; line-height: 1.45; white-space: nowrap;
  background: var(--surface-3); color: var(--ink-2);
}
.rk-mov.sobe { background: var(--prom-soft); color: var(--prom-ink); }
.rk-mov.desce { background: var(--det-soft); color: var(--det-ink); }
.rk-mov.novo { background: var(--accent-soft); color: var(--accent-ink); }

/* ---- o pódio ------------------------------------------------------------- */
/* Simétrico e com medida própria: a 1440, três colunas da largura do cartão viravam
   três ilhas longe uma da outra. */
.rk-palco { max-width: 760px; margin: 0 auto; }
/* A faixa da coroa: a linha de pulso do login de ponta a ponta e a coroa no meio, em
   cima do 1º (as três colunas têm a mesma largura, então o meio é o centro do 1º). */
.rk-faixa-coroa { position: relative; height: 40px; display: grid; place-items: center; margin-bottom: 6px; }
.rk-pulso { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.rk-pulso path { fill: none; stroke: var(--accent-3); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; opacity: .5; }
.rk-coroa { position: relative; width: 30px; height: 30px; padding: 2px 8px; box-sizing: content-box;
  color: var(--neu-mark); background: var(--surface); }

/* O 1º no centro, o 2º à esquerda, o 3º à direita; no DOM (e no leitor de tela) a
   ordem é 1, 2, 3. Sempre três colunas: com duas lojas, o 1º continua no meio. */
.rk-podio { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 12px; align-items: end; }
.rk-deg { position: relative; display: flex; flex-direction: column; min-width: 0; text-align: center; border-radius: var(--r-md); }
.rk-deg-1 { grid-column: 2; grid-row: 1; }
.rk-deg-2 { grid-column: 1; grid-row: 1; }
.rk-deg-3 { grid-column: 3; grid-row: 1; }
.rk-deg-info { display: flex; flex-direction: column; align-items: center; gap: 4px; min-width: 0; padding: 4px 2px 10px; }
/* O nome INTEIRO, quebrando em linhas, e não "Atacado Cont…": no pódio o nome é a notícia. */
.rk-deg-nome { font-size: var(--t-sm); line-height: 1.3; min-width: 0; max-width: 100%; }
.rk-deg-nome .linkline { text-align: center; }
.rk-deg-nome .loja { display: inline-flex; flex-direction: column; align-items: center; gap: 3px; max-width: 100%; }
.rk-deg-nome .loja .nm { overflow: visible; white-space: normal; text-overflow: clip; overflow-wrap: anywhere; font-weight: 700; }
.rk-deg-nps { display: flex; align-items: baseline; justify-content: center; gap: 4px; color: var(--ink); }
.rk-deg-nps .rk-num { font-size: 34px; font-weight: 800; letter-spacing: -.04em; line-height: 1.05; font-variant-numeric: tabular-nums; }
.rk-deg-1 .rk-deg-nps .rk-num { font-size: var(--t-hero); }
.rk-deg-nps small { font-size: var(--t-xs); font-weight: 700; color: var(--muted); }
:is(.rk-deg-nps, .rk-nota).pos .rk-num { color: var(--prom-ink); }
:is(.rk-deg-nps, .rk-nota).mid .rk-num { color: var(--neu-ink); }
:is(.rk-deg-nps, .rk-nota).neg .rk-num { color: var(--det-ink); }
.rk-deg-meta { font-size: var(--t-xs); line-height: 1.35; color: var(--ink-2); }
.rk-deg .stack { width: 100%; max-width: 140px; min-width: 0; height: 6px; margin: 2px 0; }
/* O degrau: a posição grande e as respostas. O do 1º no degradê do acento (o do login),
   claro só embaixo, longe do texto branco (≥ 5:1 na metade de cima do degrau). */
.rk-degrau { position: relative; overflow: hidden; display: flex; flex-direction: column; align-items: center; gap: 2px;
  padding: 10px 4px 8px; border-radius: var(--r-md) var(--r-md) 4px 4px; transform-origin: 50% 100%;
  background: var(--accent-soft); border: 1px solid var(--accent-line); color: var(--accent-ink); }
.rk-degrau b { font-size: 26px; font-weight: 800; letter-spacing: -.03em; line-height: 1; }
.rk-degrau small { font-size: var(--t-xs); font-weight: 700; }
.rk-deg-1 .rk-degrau { height: 112px; color: #fff; border-color: transparent;
  background: linear-gradient(180deg, var(--accent) 0%, var(--accent-2) 55%, var(--accent-3) 120%);
  box-shadow: 0 10px 24px rgba(61, 61, 245, .22); }
.rk-deg-2 .rk-degrau { height: 88px; }
.rk-deg-3 .rk-degrau { height: 70px; }
/* A loja do gerente no pódio: contorno do acento em volta da coluna e a etiqueta. */
.rk-deg.minha { outline: 2px dashed var(--accent); outline-offset: 4px; }
/* A coluna (e, na lista, a linha) inteira é o alvo do toque que abre o Resumo da loja. */
:is(.rk-deg, .rk-item) .estica::after { content: ""; position: absolute; inset: 0; border-radius: inherit; }
:is(.rk-deg, .rk-item) .estica:focus-visible { outline: none; }
:is(.rk-deg, .rk-item) .estica:focus-visible::after { outline: 2px solid var(--accent); outline-offset: 2px; }
.rk-deg:has(.estica):hover .rk-deg-nome .nm, .rk-item:has(.estica):hover .loja .nm { color: var(--accent); text-decoration: underline; }
.rk-deg:focus, .rk-item:focus { outline: none; }

/* ---- do 4º em diante ------------------------------------------------------ */
.rk-lista-wrap { margin: var(--s6) -18px 0; border-top: 1px solid var(--rule); }
.rk-cab, .rk-item { display: grid; align-items: center; column-gap: 16px; padding-inline: 18px;
  grid-template-columns: 3rem minmax(0, 1.25fr) minmax(140px, 1.4fr) 8.5rem 10rem 11rem; }
.rk-cab { min-height: 36px; background: var(--surface-2); border-bottom: 1px solid var(--rule);
  font-size: var(--t-xs); font-weight: 800; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
.rk-cab span:nth-child(4) { text-align: right; }
.rk-lista { list-style: none; margin: 0; padding: 0; }
.rk-item { position: relative; min-height: 60px; padding-block: 10px; border-bottom: 1px solid var(--rule); }
.rk-item:hover { background: var(--surface-2); }
.rk-item.minha, .rk-item.minha:hover { background: var(--accent-soft); }
.rk-item.minha .loja .nm { font-weight: 800; }
.rk-pos { font-size: var(--t-md); font-weight: 800; color: var(--muted); }
.rk-loja { min-width: 0; font-size: var(--t-sm); font-weight: 700; }
.rk-nota { display: flex; flex-direction: column; align-items: flex-end; text-align: right; line-height: 1.25; }
.rk-nota .rk-num { font-size: 20px; font-weight: 800; letter-spacing: -.03em; font-variant-numeric: tabular-nums; }
.rk-nota small { font-size: var(--t-xs); color: var(--ink-2); }
.rk-extra { display: contents; }
.rk-resp { display: flex; flex-direction: column; gap: 5px; font-size: var(--t-sm); color: var(--ink-2); min-width: 0; }
.rk-resp .stack { width: 100%; max-width: 140px; min-width: 0; }
.rk-tend { display: flex; flex-wrap: wrap; align-items: center; gap: 3px 6px; min-width: 0; }
.rk-tend .rk-var { flex-basis: 100%; }
.rk-era { font-size: var(--t-xs); font-weight: 600; color: var(--muted); }
/* A barra do NPS a partir do zero, a faixa da meta (da meta até 100) e o traço da meta. */
.rk-barra { position: relative; display: block; height: 12px; border-radius: 6px; background: var(--surface-3); }
.rk-faixa { position: absolute; top: 0; bottom: 0; right: 0; border-radius: 0 6px 6px 0;
  background: var(--prom-soft); box-shadow: inset 0 0 0 1px var(--prom-line); }
.rk-zero { position: absolute; left: 50%; top: -2px; bottom: -2px; width: 1px; background: var(--rule-3); }
.rk-fill { position: absolute; top: 2px; bottom: 2px; border-radius: 4px; transform-origin: 0 50%; background: var(--rule-3); }
.rk-fill.neg-lado { transform-origin: 100% 50%; }
.rk-fill.pos { background: var(--prom); }
.rk-fill.mid { background: var(--neu-mark); }
.rk-fill.neg { background: var(--det); }
.rk-meta { position: absolute; top: -4px; bottom: -4px; width: 2px; margin-left: -1px; border-radius: 1px; background: var(--ink); }
.rk-legenda { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 6px; margin: 0; padding: 12px 18px 0;
  font-size: var(--t-xs); color: var(--muted); }
.rk-leg-faixa { width: 16px; height: 10px; border-radius: 3px; background: var(--prom-soft); border: 1px solid var(--prom-line); }
.rk-leg-meta { width: 2px; height: 12px; margin-left: 8px; border-radius: 1px; background: var(--ink); }

/* O toque em "Sua loja" acende a loja onde ela está. */
@keyframes rk-achou { 0%, 100% { box-shadow: 0 0 0 0 transparent; } 25%, 60% { box-shadow: 0 0 0 3px var(--accent); } }
.rk-achou { animation: rk-achou 1.2s ease both; }

/* ---- a chegada (≤ 1,2 s) ----------------------------------------------------
   0–800 ms   a linha de pulso corre da esquerda para a direita, como no login
   0–660 ms   os degraus sobem: o 3º, o 2º (+120) e o 1º (+240)
   200–1040   o nome e o NPS de cada um aparecem, e o NPS conta do 0 (app.js, 600 ms)
   660–1160   um brilho atravessa o degrau do 1º; 800–1140 a coroa pousa
   900–1160   as setas de quem subiu ou caiu
   360–1200   as linhas da lista, 30 ms uma da outra (com teto), e as barras crescem */
/* O traçado se revela por recorte, da esquerda para a direita, e não pelo tracejado: com
   o traço que não estica (vector-effect), o pathLength não vale e a linha parava pela
   metade a 1440. */
@keyframes rk-traco { from { clip-path: inset(0 100% 0 0); } to { clip-path: inset(0 0 0 0); } }
@keyframes rk-sobe { from { transform: scaleY(0); } }
@keyframes rk-surge { from { opacity: 0; transform: translateY(10px); } }
@keyframes rk-cresce { from { transform: scaleX(0); } }
@keyframes rk-pop { from { opacity: 0; transform: scale(.6); } }
@keyframes rk-coroa {
  0% { opacity: 0; transform: translateY(-10px) scale(.4) rotate(-14deg); }
  70% { opacity: 1; transform: translateY(1px) scale(1.12) rotate(3deg); }
}
@keyframes rk-brilho { from { transform: translateX(-120%); } to { transform: translateX(120%); } }
.rk-deg-3 { --rk-d: 0ms; } .rk-deg-2 { --rk-d: 120ms; } .rk-deg-1 { --rk-d: 240ms; }
.rk-anima .rk-pulso { animation: rk-traco .8s cubic-bezier(.45, 0, .25, 1) both; }
.rk-anima .rk-coroa { animation: rk-coroa .34s .8s cubic-bezier(.2, .9, .3, 1.2) both; }
.rk-anima .rk-degrau { animation: rk-sobe .42s var(--rk-d) cubic-bezier(.2, .9, .3, 1.12) both; }
.rk-anima .rk-deg-info { animation: rk-surge .36s calc(var(--rk-d) + 200ms) cubic-bezier(.2, .7, .3, 1) both; }
.rk-anima .rk-deg .rk-mov { animation: rk-pop .26s .9s cubic-bezier(.2, .9, .3, 1.3) both; }
.rk-anima .rk-deg-1 .rk-degrau::after { content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(100deg, transparent 30%, rgba(255, 255, 255, .35) 50%, transparent 70%);
  animation: rk-brilho .5s .66s ease-out both; }
.rk-anima .rk-item { animation: rk-surge .3s var(--rk-at) cubic-bezier(.2, .7, .3, 1) both; }
.rk-anima .rk-fill { animation: rk-cresce .5s calc(var(--rk-at) + 100ms) cubic-bezier(.2, .8, .3, 1) both; }
.rk-anima .rk-item .rk-mov { animation: rk-pop .2s calc(var(--rk-at) + 400ms) cubic-bezier(.2, .9, .3, 1.3) both; }
.rk-anima > .card + .card { animation: rk-surge .36s .5s cubic-bezier(.2, .7, .3, 1) both; }
/* A regra geral do movimento reduzido encurta a duração, mas não o atraso: sem esta, a
   coroa ficaria 0,8 s invisível. O app.js nem põe .rk-anima nesse caso; é a garantia. */
@media (prefers-reduced-motion: reduce) {
  .rk-anima *, .rk-anima *::after, .rk-anima > .card { animation: none !important; }
}

/* ---- tablet e celular: a linha da lista vira um cartão de três andares ------- */
@media (max-width: 980px) {
  .rk-cab { display: none; }
  .rk-item { grid-template-columns: 2.4rem minmax(0, 1fr) auto; column-gap: 10px; row-gap: 6px;
    grid-template-areas: "pos loja nota" "pos medida medida" "pos extra extra"; }
  .rk-pos { grid-area: pos; align-self: start; }
  .rk-loja { grid-area: loja; }
  .rk-nota { grid-area: nota; }
  .rk-medida { grid-area: medida; }
  .rk-extra { grid-area: extra; display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 6px 12px; }
  .rk-resp { flex-direction: row; align-items: center; gap: 8px; }
  .rk-resp .stack { width: 72px; }
  .rk-tend { gap: 4px 8px; }
  .rk-tend .rk-var { flex-basis: auto; }
}
/* No tablet a barra cabe na linha do nome: dois andares em vez de três. */
@media (min-width: 521px) and (max-width: 980px) {
  .rk-item { grid-template-columns: 2.4rem minmax(0, 1fr) minmax(140px, 1fr) 8.5rem; column-gap: 14px;
    grid-template-areas: "pos loja medida nota" "pos extra extra extra"; }
  .rk-extra { justify-content: flex-start; column-gap: 20px; }
}
@media (max-width: 520px) {
  .rk-lista-wrap { margin-inline: -15px; }
  .rk-item, .rk-legenda { padding-inline: 15px; }
  /* O pódio compacto: três colunas de ~95px a 360, sem rolar para o lado. */
  .rk-podio { gap: 6px; }
  .rk-deg-nps .rk-num { font-size: 26px; }
  .rk-deg-1 .rk-deg-nps .rk-num { font-size: 32px; }
  .rk-degrau b { font-size: 20px; }
  .rk-deg-1 .rk-degrau { height: 92px; }
  .rk-deg-2 .rk-degrau { height: 72px; }
  .rk-deg-3 .rk-degrau { height: 58px; }
  .rk-deg .rk-mov { white-space: normal; justify-content: center; padding-inline: 6px; border-radius: 10px; }
  .rk-eu { padding: 6px 12px; column-gap: 8px; }
}

/* ==========================================================================
   Os filtros do recorte — Resumo e Ranking (app.js, fxBarraDeFiltros e companhia).
   Fechada, uma linha de três chips-botão (Período, Onde, Problema): no padrão, fundo
   neutro e borda fina; com filtro, a cor de destaque e o × de 44px ao lado. Aberta, o
   popover (≥768) ou a folha de baixo (celular). Todo alvo com 44px, texto de 14px.
   ========================================================================== */
.fx { position: relative; margin-bottom: var(--s4); min-width: 0; }
.fx-chips { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; min-width: 0; }
.fx-chip {
  display: inline-flex; align-items: stretch; min-width: 0; max-width: 100%;
  border: 1px solid var(--rule-2); border-radius: var(--r-full); background: var(--surface); box-shadow: var(--sh-1);
}
.fx-chip-b {
  display: inline-flex; align-items: center; gap: 6px; min-width: 44px; min-height: 44px; padding: 4px 12px 4px 16px;
  border: 0; border-radius: inherit; background: transparent; color: var(--ink); cursor: pointer;
  font: inherit; font-size: 14px; font-weight: 700; line-height: 1.3; text-align: left;
}
.fx-chip-b:hover { background: var(--surface-3); }
.fx-chip-b .seta { flex: none; color: var(--muted); transition: transform .15s; }
.fx-chip-b[aria-expanded="true"] .seta { transform: rotate(180deg); }
.fx-chip-t { min-width: 0; }
@media (max-width: 767px) { .fx-chip-dias { display: none; } }
.fx-chip.ativo { border-color: var(--accent-line); background: var(--accent-soft); }
.fx-chip.ativo .fx-chip-b { color: var(--accent-ink); padding-right: 8px; border-radius: var(--r-full) 0 0 var(--r-full); }
.fx-chip.ativo .fx-chip-b:hover { background: #E0E0FD; }
.fx-chip.ativo .fx-chip-b .seta { color: var(--accent-ink); }
.fx-chip-x {
  flex: none; width: 44px; min-height: 44px; display: grid; place-items: center; padding: 0;
  border: 0; border-left: 1px solid var(--accent-line); border-radius: 0 var(--r-full) var(--r-full) 0;
  background: transparent; color: var(--accent-ink); cursor: pointer;
}
.fx-chip-x:hover { background: #E0E0FD; }
.fx-limpar {
  margin-left: auto; min-height: 44px; padding: 0 6px; border: 0; background: none; cursor: pointer;
  font: inherit; font-size: 14px; font-weight: 700; color: var(--accent);
  text-decoration: underline; text-underline-offset: 3px;
}
.fx-limpar:hover { color: var(--accent-ink); }

/* A barra compacta: 48px, grudada logo abaixo do topo (a altura dele vem do app.js, em
   --fx-topo), com fundo sólido e sombra. Fora de cena ela não ocupa espaço (a margem
   negativa) nem recebe toque. */
.fx-compacta {
  position: sticky; top: var(--fx-topo, 62px); z-index: 15; height: 48px; margin-bottom: -48px;
  visibility: hidden; pointer-events: none;
}
.fx-compacta.visivel { visibility: visible; pointer-events: auto; }
.fx-compacta-b {
  display: flex; align-items: center; gap: 12px; width: 100%; height: 48px; padding: 0 2px 0 16px;
  border: 1px solid var(--rule-2); border-radius: var(--r-md); background: var(--surface); color: var(--ink);
  box-shadow: 0 6px 18px -6px rgba(19, 19, 34, .22), var(--sh-1);
  font: inherit; font-size: 14px; font-weight: 600; text-align: left; cursor: pointer;
}
.fx-c-txt { flex: 1 1 auto; min-width: 0; white-space: nowrap; overflow: hidden; }
.fx-c-txt b { font-weight: 800; }
.fx-c-curto { display: none; }
.fx-compacta.curta .fx-c-longo { display: none; }
.fx-compacta.curta .fx-c-curto { display: block; }
.fx-c-filtrar {
  flex: none; display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  min-width: 44px; height: 44px; padding: 0 14px; border-radius: var(--r-sm);
  background: var(--accent); color: #fff; font-weight: 800;
}
.fx-compacta-b:hover .fx-c-filtrar { background: var(--accent-2); }
/* "Sua loja" do Ranking (o gerente) gruda embaixo do topo; com a compacta à vista, embaixo dela. */
.rk-eu { top: calc(var(--fx-topo, 62px) + 6px); }
.fx-grudada .rk-eu { top: calc(var(--fx-topo, 62px) + 54px); }

/* O popover do desktop: por cima do conteúdo, sem empurrar nada; 880px em três colunas
   a partir de 1100, e as seções empilhadas abaixo disso. A altura máxima (70% da janela,
   sem passar do pé dela) vem do app.js; o corpo rola, o rodapé fica. */
.fx-pop {
  position: absolute; top: calc(100% + 8px); left: 0; z-index: 19; width: 100%;
  display: flex; flex-direction: column; max-height: 70vh;
  background: var(--surface); color: var(--ink); border: 1px solid var(--rule-2); border-radius: var(--r-lg);
  box-shadow: var(--sh-3); overflow: hidden;
}
.fx-pop-corpo {
  flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain;
  display: grid; grid-template-columns: minmax(0, 1fr); gap: 22px 24px; padding: 18px 20px;
}
@media (min-width: 1100px) {
  .fx-pop { width: min(880px, 100%); }
  .fx-pop-corpo { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .fx-pop-corpo.dois { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* Só o Período (os Convites do gerente de uma loja): uma coluna, e o popover estreito. */
  .fx-pop-corpo.um { grid-template-columns: minmax(0, 1fr); }
  .fx-pop:has(> .fx-pop-corpo.um) { width: min(440px, 100%); }
  /* Duas colunas, e Personalizado na linha inteira: 3 linhas de 44px no lugar de 5, e
     De/Até cabem no corpo a 1440x900 sem rolar. */
  .fx-pop .fx-fita { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .fx-pop .fx-op[data-v="entre"] { grid-column: 1 / -1; }
  .fx-pop .fx-op { text-align: left; padding-inline: 14px; }
}
.fx-pe { flex: none; display: flex; align-items: center; gap: 8px; padding: 12px 20px; border-top: 1px solid var(--rule); background: var(--surface); }
.fx-pe .btn { min-height: 44px; }
.fx-pe .fx-limpar-tudo { color: var(--ink-2); }
.fx-motivo { flex: 1 1 auto; margin: 0; font-size: 13px; font-weight: 600; color: var(--det-ink); text-align: right; }
.fx-aplicar.desligado, .fx-aplicar.desligado:hover { background: var(--accent); opacity: .45; cursor: default; transform: none; }

/* As seções: Período, Onde, Problema. */
.fx-sec { display: flex; flex-direction: column; gap: 10px; min-width: 0; }
.fx-sec-cab { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-height: 44px; }
.fx-rot { margin: 0; font-size: 14px; font-weight: 800; color: var(--ink); }
.fx-sec-periodo > .fx-rot { min-height: 44px; display: flex; align-items: center; }
.fx-limpar-sel {
  min-height: 44px; padding: 0 4px; border: 0; background: none; cursor: pointer;
  font: inherit; font-size: 13px; font-weight: 700; color: var(--accent); text-decoration: underline; text-underline-offset: 2px;
}
/* A fita de 5 períodos: uma linha no tablet, duas colunas no popover largo, e 3 + 2 de
   larguras iguais a 360 (sem rolar para o lado). */
.fx-fita {
  display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 3px; padding: 3px;
  background: var(--surface-3); border: 1px solid var(--rule); border-radius: var(--r-md);
}
.fx-op {
  min-height: 44px; min-width: 0; padding: 0 8px; border: 0; border-radius: var(--r-xs); background: transparent;
  font: inherit; font-size: 14px; font-weight: 600; color: var(--ink-2); cursor: pointer; white-space: nowrap;
}
.fx-op:hover { color: var(--ink); }
.fx-op.on { background: var(--surface); color: var(--accent); font-weight: 800; box-shadow: var(--sh-1); }
.fx-entre { display: flex; flex-direction: column; gap: 10px; }
.fx-atalhos { display: flex; flex-wrap: wrap; gap: 6px; }
.fx-atalho {
  min-height: 44px; padding: 0 10px; border: 1px solid var(--rule-2); border-radius: var(--r-full);
  background: var(--surface); font: inherit; font-size: 13px; font-weight: 700; color: var(--ink-2); cursor: pointer;
}
.fx-atalho:hover { border-color: var(--accent); color: var(--accent); }
.fx-datas { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
.fx-campo { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.fx-campo > label { font-size: 13px; font-weight: 700; color: var(--ink-2); }
.fx-data { min-height: 44px; font-size: 16px; font-variant-numeric: tabular-nums; }
.fx-erro { margin: 0; font-size: 13px; font-weight: 600; line-height: 1.35; color: var(--det-ink); }
.fx-erro:empty, .fx-entre-resumo:empty { display: none; }
.fx-entre-resumo { margin: 0; font-size: 13px; font-weight: 600; color: var(--ink-2); }

/* A escolha múltipla com busca: as escolhidas no alto, a árvore recuada 16px por nível,
   e no popover a lista rola sozinha (280px). */
.fx-busca { min-height: 44px; }
.fx-ms-lista {
  display: flex; flex-direction: column; gap: 2px; max-height: 280px; overflow-y: auto; overscroll-behavior: contain;
  padding: 4px; border: 1px solid var(--rule); border-radius: var(--r-sm); background: var(--surface);
}
.fx-ms-grupo { margin: 6px 10px 2px; font-size: 12px; font-weight: 800; letter-spacing: .04em; text-transform: uppercase; color: var(--muted); }
.fx-ms-div { width: 100%; margin: 4px 0; border: 0; border-top: 1px solid var(--rule); }
.fx-ms-op {
  display: flex; align-items: center; gap: 10px; min-height: 44px; padding: 6px 10px;
  padding-left: calc(10px + var(--nivel, 0) * 16px); border-radius: var(--r-xs); cursor: pointer; font-size: 14px;
}
.fx-ms-op:hover { background: var(--surface-3); }
.fx-ms-op:has(input:checked:not(:disabled)) { background: var(--accent-soft); }
.fx-ms-op input { flex: none; width: 18px; height: 18px; min-width: 0; margin: 0; padding: 0; accent-color: var(--accent); }
.fx-ms-t { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 6px; min-width: 0; }
.fx-ms-t .cod { font-family: var(--f-id); font-size: 12px; font-weight: 600; color: var(--muted); }
.fx-ms-nome { font-weight: 700; color: var(--ink); }
.fx-ms-t small { flex-basis: 100%; font-size: 12px; color: var(--muted); line-height: 1.35; }
.fx-ms-op.coberta { cursor: default; }
.fx-ms-op.coberta .fx-ms-nome { color: var(--ink-2); font-weight: 600; }
.fx-ms-t small.fx-nota { color: var(--accent-ink); font-weight: 700; }
.fx-nada { margin: 10px; font-size: 13px; color: var(--muted); }

/* Celular: a folha de baixo (a mesma das Tratativas), quase da altura da tela; Onde e
   Problema em linhas de 56px, e a subtela da lista por cima de tudo. */
dialog.fx-folha { max-height: calc(100dvh - 12px); }
.fx-folha-corpo { gap: 14px; padding: 12px 16px 16px; }
.fx-linhas { display: flex; flex-direction: column; border: 1px solid var(--rule-2); border-radius: var(--r-md); overflow: hidden; }
.fx-linhas:empty { display: none; }
.fx-linha {
  display: flex; align-items: center; gap: 10px; width: 100%; min-height: 56px; padding: 0 10px 0 16px;
  border: 0; background: var(--surface); font: inherit; text-align: left; cursor: pointer; color: var(--ink);
}
.fx-linha + .fx-linha { border-top: 1px solid var(--rule); }
.fx-linha:hover { background: var(--surface-2); }
.fx-linha-rot { flex: none; font-size: 15px; font-weight: 800; }
.fx-linha-val { flex: 1 1 auto; min-width: 0; text-align: right; font-size: 14px; font-weight: 600; color: var(--ink-2); }
.fx-linha-seta { flex: none; color: var(--muted); }
.fx-folha .fx-pe { flex-wrap: wrap; padding: 10px 16px calc(10px + env(safe-area-inset-bottom)); }
.fx-folha .fx-motivo { flex-basis: 100%; order: -1; text-align: left; }
.fx-folha .fx-motivo:empty { display: none; }
.fx-folha .fx-limpar-tudo { min-height: 48px; }
.fx-folha .fx-aplicar { flex: 1 1 auto; min-height: 48px; }
.fx-sub { position: fixed; inset: 0; z-index: 2; display: flex; flex-direction: column; background: var(--surface); }
.fx-sub-topo { flex: none; display: flex; align-items: center; gap: 4px; padding: 4px 8px 4px 4px; border-bottom: 1px solid var(--rule); }
.fx-sub-topo h2 { flex: 1 1 auto; font-size: var(--t-lg); letter-spacing: -.02em; }
.fx-sub > .fx-sec { flex: 1 1 auto; min-height: 0; padding: 12px 16px 0; }
.fx-sub .fx-sec-cab { display: none; }
.fx-sub .fx-ms-lista { flex: 1 1 auto; min-height: 0; max-height: none; padding: 0 0 8px; border: 0; }
.fx-sub .fx-ms-op { min-height: 48px; font-size: 16px; }
.fx-sub .fx-ms-op input { width: 22px; height: 22px; }
.fx-sub .fx-busca { font-size: 16px; }
.fx-sub-pe { flex: none; padding: 10px 16px calc(10px + env(safe-area-inset-bottom)); border-top: 1px solid var(--rule); }
.fx-pronto { width: 100%; min-height: 48px; }
@media (max-width: 767px) {
  .fx-chips { gap: 6px; }
  .fx-chip-b { padding: 4px 6px 4px 12px; gap: 4px; }
  .fx-chip.ativo .fx-chip-b { padding-right: 4px; }
  .fx-fita { grid-template-columns: repeat(6, minmax(0, 1fr)); }
  .fx-op { grid-column: span 2; }
  .fx-op:nth-child(n+4) { grid-column: span 3; }
  .fx-c-longo { display: none; }
  .fx-c-curto { display: block; }
  .fx-compacta-b { padding-left: 14px; }
  .fx-c-filtrar { width: 44px; padding: 0; }
  .fx-c-filtrar > span { display: none; }
}

/* ==========================================================================
   A entrada animada do Resumo (app.js, palcoDaAnimacao): os cartões entram em
   sequência (--atraso), as barras crescem da base depois que o cartão entra, e os números
   contam (o valor final reserva a largura: nada pula). Só transform e opacity. As classes
   só existem quando o desenho anima — nunca com movimento reduzido nem com a aba escondida.
   ========================================================================== */
@keyframes anima-entra { from { opacity: 0; transform: translateY(8px); } }
@keyframes anima-cx { from { transform: scaleX(0); } }
@keyframes anima-cy { from { transform: scaleY(0); } }
@keyframes anima-surge { from { opacity: 0; } }
.anima-entra { animation: anima-entra .3s var(--atraso, 0ms) cubic-bezier(.2, .7, .3, 1) both; }
.anima-cresce :is(.alvo-barra > i, .stack, .barra-l .b > i, .funil-e .b > i, .evo-b > i) {
  transform-origin: 0 50%; animation: anima-cx .5s calc(var(--atraso, 0ms) + 300ms) cubic-bezier(.2, .8, .3, 1) both;
}
.anima-cresce :is(.notas .b > i, .graf-barras) { animation: anima-cy .5s calc(var(--atraso, 0ms) + 300ms) cubic-bezier(.2, .8, .3, 1) both; }
.anima-cresce .notas .b > i { transform-origin: 50% 100%; }
@media (max-width: 720px) {
  .anima-cresce .notas .b > i { animation-name: anima-cx; transform-origin: 0 50%; }
}
.anima-cresce .graf-totais { animation: anima-surge .15s calc(var(--atraso, 0ms) + 750ms) ease-out both; }
.anima-cresce.tarde :is(.alvo-barra > i, .stack, .barra-l .b > i, .funil-e .b > i, .evo-b > i, .notas .b > i, .graf-barras) { animation-delay: var(--atraso, 0ms); }
.anima-cresce.tarde .graf-totais { animation-delay: calc(var(--atraso, 0ms) + 450ms); }

/* ==========================================================================
   O pódio completo (montarPodio): o degrau provisório (ainda medindo), com fundo claro
   e borda tracejada; o vazio, com o traço e o porquê; a frase embaixo. No degrau, a seta
   curta ("▲ 3") no Resumo e a 360; a longa ("+3 posições") no Ranking largo.
   ========================================================================== */
/* Os números que contam (app.js, numeroQueConta): o valor final reserva a largura e o
   que conta fica por cima, preso à esquerda dela — nada se desloca a cada quadro. */
.conta { display: inline-grid; justify-items: stretch; text-align: left; font-variant-numeric: tabular-nums; }
.conta > span { grid-area: 1 / 1; }
.conta-fim { visibility: hidden; }
.rk-mov-curto { display: none; }
.rs-rk .rk-mov-longo { display: none; }
.rs-rk .rk-mov-curto { display: inline; }
.rk-deg-sinais { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 4px; }
.rk-deg .rk-mov { white-space: nowrap; }
.rk-empate { font-size: var(--t-xs); font-weight: 700; color: var(--ink-2); }
.rk-loja .rk-empate { margin-left: 6px; vertical-align: 1px; }
.rk-deg.provisoria .rk-degrau, .rk-deg-1.provisoria .rk-degrau {
  background: var(--surface-2); color: var(--ink-2); border: 1.5px dashed var(--rule-3); box-shadow: none;
}
.rk-prov {
  display: flex; flex-direction: column; align-items: center; padding: 3px 4px; border-radius: var(--r-xs);
  background: var(--neu-soft); color: var(--neu-ink); font-size: var(--t-xs); line-height: 1.3; text-align: center;
}
.rk-prov b { font-weight: 800; }
.rk-deg.vazio .rk-degrau, .rk-deg-1.vazio .rk-degrau {
  background: transparent; color: var(--muted); border: 1.5px dashed var(--rule-2); box-shadow: none;
}
.rk-deg.vazio .rk-deg-nps .rk-num { color: var(--muted-2); }
.rk-vazio-motivo { max-width: 15ch; font-size: var(--t-xs); line-height: 1.35; color: var(--muted); }
.rk-explica {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 6px 12px;
  max-width: 640px; margin: 14px auto 0; text-align: center;
}
.rk-explica p { margin: 0; font-size: var(--t-sm); line-height: 1.5; color: var(--ink-2); }
@media (max-width: 520px) {
  .rk-deg .rk-mov-longo, .rk-deg .rk-deg-meta, .rk-prov-resp { display: none; }
  /* "ainda medindo" numa linha só no degrau de ~95px a 360. */
  .rk-prov { padding-inline: 2px; }
  .rk-deg .rk-mov-curto { display: inline; }
  .rk-deg .rk-mov { white-space: nowrap; padding-inline: 7px; border-radius: var(--r-full); }
  .rk-deg-nps .rk-num, .rk-deg-1 .rk-deg-nps .rk-num { font-size: 28px; }
}

/* ---- o ranking no Resumo (cardRankingResumo): o bloco de 720px no eixo do cartão — o
   título, o pódio, a lista e o link alinhados nas mesmas bordas. ---- */
.rs-rk-bloco { max-width: 720px; margin: 0 auto; padding: 16px 18px 18px; }
.rs-rk-cab { display: flex; flex-direction: column; gap: 2px; margin-bottom: 6px; }
.rs-rk-cab h2 { font-size: var(--t-lg); letter-spacing: -.02em; }
.rs-rk-cab .sub { margin: 0; font-size: var(--t-sm); color: var(--muted); }
.rs-rk .rk-palco { max-width: none; }
.rs-rk-lista { list-style: none; margin: 18px 0 0; padding: 0; border-top: 1px solid var(--rule); }
.rs-rk-item {
  position: relative; display: grid; grid-template-columns: 2.6rem minmax(0, 1fr) auto 3.6rem; align-items: center;
  column-gap: 12px; min-height: 48px; padding: 4px 6px; border-bottom: 1px solid var(--rule);
}
.rs-rk-item > * { grid-area: auto; align-self: center; }
.rs-rk-item:hover { background: var(--surface-2); }
.rs-rk-item.minha, .rs-rk-item.minha:hover { background: var(--accent-soft); }
.rs-rk-item.minha .loja .nm { font-weight: 800; }
.rs-rk-item .rk-loja { font-size: var(--t-sm); }
.rs-rk-nps { text-align: right; }
.rs-rk-nps b { font-size: 18px; font-weight: 800; letter-spacing: -.02em; font-variant-numeric: tabular-nums; color: var(--ink); }
.rs-rk-nps.pos b { color: var(--prom-ink); }
.rs-rk-nps.mid b { color: var(--neu-ink); }
.rs-rk-nps.neg b { color: var(--det-ink); }
.rs-rk-mov { display: flex; justify-content: flex-end; }
.rs-rk-item .estica::after { content: ""; position: absolute; inset: 0; }
.rs-rk-item .estica:focus-visible { outline: none; }
.rs-rk-item .estica:focus-visible::after { outline: 2px solid var(--accent); outline-offset: -2px; }
.rs-rk-item:has(.estica):hover .loja .nm { color: var(--accent); text-decoration: underline; }
.rs-rk-reticencias { display: block; min-height: 32px; padding: 0; line-height: 32px; text-align: center; color: var(--muted); font-weight: 800; }
.rs-rk-medindo {
  display: flex; align-items: center; justify-content: center; flex-wrap: wrap; min-height: 44px; margin: 6px 0 0;
  font-size: var(--t-sm); font-weight: 700; color: var(--ink-2); text-decoration: none;
}
a.rs-rk-medindo .rs-rk-ver-l { color: var(--accent); white-space: pre; }
a.rs-rk-medindo:hover .rs-rk-ver-l { text-decoration: underline; }
/* As lojas com menor NPS, abaixo do topo: onde o gestor de uma rede grande vai agir primeiro. */
.rs-rk-piores { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--rule); }
.rs-rk-subtit { margin: 0 0 4px; font-size: var(--t-sm); font-weight: 800; color: var(--ink-2); }
.rs-rk-pe { display: flex; justify-content: flex-end; margin-top: 12px; }
.rs-rk-pe .rs-rk-ver { min-height: 44px; text-decoration: none; }
.rk-explica .btn { min-height: 44px; }
/* A entrada do Resumo espera o pódio entrar na tela: até lá, invisível (só quando o
   recorte mudou; com o mesmo, ele já nasce no lugar). */
.rk-espera :is(.rk-palco, .rk-explica, .rs-rk-lista, .rs-rk-medindo) { opacity: 0; }
.rk-anima .rs-rk-item { animation: rk-surge .3s calc(360ms + var(--atraso, 0ms)) cubic-bezier(.2, .7, .3, 1) both; }
.rk-anima :is(.rk-explica, .rs-rk-medindo) { animation: rk-surge .3s .7s cubic-bezier(.2, .7, .3, 1) both; }
@media (max-width: 520px) {
  .rs-rk-bloco { padding: 14px 12px 14px; }
  .rs-rk-item { grid-template-columns: 2.2rem minmax(0, 1fr) auto 3.2rem; column-gap: 8px; padding-inline: 2px; }
  .rs-rk-pe { justify-content: stretch; }
  .rs-rk-pe .rs-rk-ver { flex: 1 1 auto; }
}
@media (prefers-reduced-motion: reduce) {
  .rk-espera :is(.rk-palco, .rk-explica, .rs-rk-lista, .rs-rk-medindo) { opacity: 1; }
  .anima-entra, .anima-cresce * { animation: none !important; }
  /* O brilho do esqueleto também para: ele corria sem fim enquanto a parte chegava. */
  .skel i { animation: none; }
}

/* ==========================================================================
   O bloco recolhível (app.js, recolhivel): o cabeçalho inteiro é o botão (≥ 52px), com a
   seta que gira; recolhido, ele mostra o resumo, aberto, o subtítulo. O corpo abre e
   fecha em 200 ms pela altura da linha da grade (0fr ↔ 1fr), e fechado ele some também
   para o teclado e o leitor de tela (visibility). Com movimento reduzido, a regra geral
   deixa tudo instantâneo.
   ========================================================================== */
.rec > .rec-topo { display: flex; align-items: stretch; gap: 0; padding: 0; flex-wrap: nowrap; }
.card.rec > .rec-topo { border-bottom: 1px solid var(--rule); transition: border-color .2s; }
.card.rec:not(.aberto) > .rec-topo { border-bottom-color: transparent; }
.rec-h { flex: 1 1 auto; min-width: 0; display: flex; font: inherit; letter-spacing: normal; }
.rec-cab {
  flex: 1 1 auto; min-width: 0; min-height: 52px; display: flex; align-items: center; gap: 12px;
  padding: 12px 18px; border: 0; border-radius: inherit; background: transparent; color: var(--ink);
  font: inherit; text-align: left; cursor: pointer;
}
.rec-cab:hover .rec-tit { color: var(--accent); }
.rec-cab:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.rec-txt { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.rec-tit { font-size: var(--t-lg); font-weight: 700; letter-spacing: -.02em; line-height: 1.22; }
.rec-sub { font-size: var(--t-sm); color: var(--muted); line-height: 1.4; }
.rec-resumo { font-size: var(--t-sm); font-weight: 700; color: var(--ink-2); line-height: 1.4; font-variant-numeric: tabular-nums; }
.rec.aberto > .rec-topo .rec-resumo, .rec:not(.aberto) > .rec-topo .rec-sub { display: none; }
.rec-seta { flex: none; color: var(--muted); transition: transform .2s; }
.rec.aberto > .rec-topo .rec-seta { transform: rotate(180deg); }
.rec > .rec-topo > :not(.rec-h):not(.rec-cab) { align-self: center; margin-right: 12px; }
.rec-corpo { display: grid; grid-template-rows: 1fr; transition: grid-template-rows .2s ease; }
.rec:not(.aberto) > .rec-corpo { grid-template-rows: 0fr; visibility: hidden; transition: grid-template-rows .2s ease, visibility 0s .2s; }
.rec-in { min-height: 0; min-width: 0; }
.rec:not(.aberto) > .rec-corpo > .rec-in, .rec.rec-anim > .rec-corpo > .rec-in { overflow: hidden; }
.rec-in > .body { padding: 18px; min-width: 0; }
.rec-in > .flush { padding: 0; }
/* O grupo (os indicadores no celular): uma barra própria acima dos três cartões. */
.rec-grupo { margin-bottom: var(--s4); }
.rec-grupo > .rec-topo { background: var(--surface); border: 1px solid var(--rule); border-radius: var(--r-lg); box-shadow: var(--sh-1); }
.rec-grupo > .rec-corpo > .rec-in > .topo-painel { margin: 12px 0 0; }
/* O "Ver as outras N lojas" do ranking: uma linha de link com a seta, e a lista embaixo. */
.rec-link > .rec-topo { border-top: 1px solid var(--rule); margin-top: 12px; }
.rec-link .rec-cab { justify-content: center; min-height: 48px; padding: 8px 6px; }
.rec-link .rec-txt { flex: 0 1 auto; }
.rec-link .rec-tit { font-size: var(--t-sm); font-weight: 800; letter-spacing: 0; color: var(--accent); }
.rec-link .rec-seta { color: var(--accent); }
.rec-link .rs-rk-lista { margin-top: 0; }
/* O ranking do Resumo: o cabeçalho alinhado ao bloco de 720px, sem o fio. */
.rs-rank > .rec-topo { border-bottom: 0 !important; }
.rs-rank > .rec-topo .rec-cab { max-width: 720px; margin-inline: auto; }
.rs-rank .rs-rk-bloco { padding-top: 0; }
/* "O que mais aparece" recolhido ocupa a linha, e "Onde acontece" (o detalhe dele) sai. */
.grid.c2.rec-so { grid-template-columns: minmax(0, 1fr); }
.grid.c2.rec-so > .onde { display: none; }
.grid.c2 > .card.rec:not(.aberto) { height: auto; }
@media (max-width: 520px) {
  .rec-cab { padding-inline: 15px; }
  .rs-rank .rs-rk-bloco { padding-top: 0; }
}

/* A barra de filtros do celular: um botão só, numa linha (o texto quebra dentro dele se
   não couber, sem reticências), o número de filtros fora do padrão e o × de limpar. */
.fx-cel { display: none; }
.fx-bc {
  flex: 1 1 auto; min-width: 0; min-height: 48px; display: flex; align-items: center; gap: 10px;
  padding: 6px 12px 6px 14px; border: 1px solid var(--rule-2); border-radius: var(--r-md);
  background: var(--surface); color: var(--ink); box-shadow: var(--sh-1);
  font: inherit; font-size: 14px; font-weight: 700; line-height: 1.3; text-align: left; cursor: pointer;
}
.fx-bc.ativo { border-color: var(--accent-line); background: var(--accent-soft); color: var(--accent-ink); }
.fx-bc-ic { flex: none; color: var(--accent); }
.fx-bc-txt { flex: 1 1 auto; min-width: 0; }
.fx-bc-n {
  flex: none; min-width: 22px; height: 22px; padding: 0 6px; border-radius: var(--r-full);
  display: inline-grid; place-items: center; background: var(--accent); color: #fff; font-size: 12px; font-weight: 800;
}
.fx-bc .seta { flex: none; color: var(--muted); }
.fx-bc-limpar {
  flex: none; width: 48px; min-height: 48px; display: grid; place-items: center; padding: 0;
  border: 1px solid var(--rule-2); border-radius: var(--r-md); background: var(--surface); color: var(--ink-2); cursor: pointer;
}
.fx-bc-limpar:hover { color: var(--det-ink); border-color: var(--det-line); }
@media (max-width: 767px) {
  .fx-cel { display: flex; gap: 8px; align-items: stretch; }
  .fx > .fx-chips { display: none; }
}
/* As partes que chegam depois do primeiro desenho moram num invólucro (.rs-alvo): a
   grade de "O que mais aparece" é o último filho dele e perdia a margem de baixo. */
.rs-alvo > .grid.c2 { margin-bottom: var(--s4); }
/* A 360-400 o resumo padrão ("30 dias · Toda a rede · Todos os problemas") cabe numa linha
   com 13px; com filtros e o × ao lado, o texto quebra dentro do botão, sem reticências. */
@media (max-width: 400px) { .fx-bc { font-size: 13px; gap: 8px; padding-left: 12px; } }

/* ==========================================================================
   Riscos (db/034): Configurar › Riscos e Plataforma › Riscos padrão. Uma coluna
   de 960px, centrada (a 1440 as margens ficam iguais), com o teste de um
   comentário, um cartão por grupo e o editor no padrão de Categorias de problema
   (modal largo, fita) — no celular, em folha de tela cheia.
   ========================================================================== */
.rk-col { width: 100%; max-width: 960px; margin-inline: auto; display: flex; flex-direction: column; gap: var(--s4); }
.rk-col > .card, .rk-col > .banner { margin: 0; }
.rk-teste textarea { width: 100%; min-height: 84px; }
.rk-teste-acao { display: flex; justify-content: flex-end; margin-top: var(--s2); }
.rk-res { display: flex; flex-direction: column; gap: 4px; margin-top: var(--s2); font-size: var(--t-md); color: var(--ink); }
.rk-res:empty { display: none; }
.rk-ign, .rk-nada { color: var(--muted); }
.rk-efeito { color: var(--ink-2); font-size: var(--t-sm); }
.rk-grupo > header { align-items: flex-start; }
.rk-tit { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.rk-selos { display: flex; flex-wrap: wrap; gap: 6px; }
.rk-grupo > .body { display: flex; flex-direction: column; gap: 6px; }
.rk-regras { font-size: 13.5px; color: var(--ink-2); line-height: 1.5; }
.rk-pal, .rk-marcas { font-size: var(--t-sm); color: var(--muted); }
.rk-alarme { margin: 4px 0 0; }
.rk-rodape { display: flex; flex-wrap: wrap; gap: var(--s2); }
.rk-dica { font-size: var(--t-xs); color: var(--muted); line-height: 1.45; }
.rk-erro { color: var(--det-ink); font-size: var(--t-xs); font-weight: 700; }
.rk-erro:empty { display: none; }
.rk-fixo { font-size: var(--t-sm); color: var(--ink-2); }

/* O editor: as regras em duas colunas no largo; as palavras e exceções embaixo. */
.modal.rk-editor .form { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.rk-sec { display: flex; flex-direction: column; gap: 8px; padding-top: var(--s3); border-top: 1px solid var(--rule); }
.rk-sec h4 { font-size: 14px; letter-spacing: -.01em; }
.rk-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.rk-chip-it { display: inline-flex; max-width: 100%; }
.rk-chip {
  display: inline-flex; align-items: center; gap: 2px; min-height: 32px; max-width: 100%;
  padding: 4px 12px; border-radius: var(--r-full); border: 1px solid var(--rule-2);
  background: var(--surface-3); color: var(--ink-2); font: inherit; font-size: 13px; font-weight: 700;
  overflow-wrap: anywhere; text-align: left;
}
button.rk-chip { cursor: pointer; }
button.rk-chip:hover, button.rk-chip[aria-expanded="true"] { border-color: var(--rule-3); color: var(--ink); background: var(--surface); }
.rk-chip.rede { background: var(--surface); border: 1.5px solid var(--accent-line); color: var(--accent-ink); padding-right: 2px; }
.rk-chip.off { text-decoration: line-through; color: var(--muted); background: var(--surface); border-style: dashed; }
.rk-x {
  flex: none; width: 28px; height: 28px; border: 0; border-radius: 50%; background: none; color: inherit;
  display: inline-flex; align-items: center; justify-content: center; cursor: pointer;
}
.rk-x:hover { background: var(--accent-soft); }
.rk-menu {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px; padding: 8px 10px;
  border: 1px solid var(--rule-2); border-radius: var(--r-md); background: var(--surface-2); font-size: var(--t-sm);
}
.rk-menu > span { flex: 1 1 14rem; color: var(--ink-2); }
.rk-novo { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 260px) auto; gap: 8px; align-items: start; }
.rk-novo input { min-width: 0; }
.rk-pe { margin-top: 2px; }
.rk-previa { display: flex; flex-direction: column; gap: 8px; font-size: var(--t-sm); color: var(--ink-2); }
.rk-exemplos { margin: 0; padding-left: 18px; display: flex; flex-direction: column; gap: 4px; overflow-wrap: anywhere; }
.rk-hist ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.rk-hist li { display: flex; flex-direction: column; gap: 2px; font-size: var(--t-sm); color: var(--ink-2); overflow-wrap: anywhere; }
.rk-hist-em { font-size: var(--t-xs); color: var(--muted); }

/* A tratativa: quem classificou, e "Não é risco" / "Marcar risco" na linha do risco. */
.tk-risco-quem { display: flex; flex-direction: column; gap: 4px; font-size: 13px; color: var(--muted); line-height: 1.45; }
.tk-risco-quem > p { overflow-wrap: anywhere; }
.tk-risco-acoes { display: flex; flex-wrap: wrap; gap: 0 18px; }
.tk-risco-acoes .linkline { color: var(--accent-ink); font-size: 13px; min-height: 36px; }
.rk-grupos { border: 0; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 6px; }
.rk-grupos legend { font-size: 12.5px; font-weight: 600; color: var(--ink-2); margin-bottom: 4px; padding: 0; }
.rk-chk { font-size: var(--t-sm); color: var(--ink-2); }
.rk-sugestoes { display: flex; flex-wrap: wrap; gap: 6px; }
.rk-sug { white-space: normal; text-align: left; }
.linkline.rk-ir { color: var(--accent-ink); }

@media (max-width: 620px) {
  .modal.rk-editor .form { grid-template-columns: minmax(0, 1fr); }
  .rk-novo { grid-template-columns: minmax(0, 1fr); }
  .rk-rodape > .btn { flex: 1 1 100%; }
}
/* No celular o editor é uma folha de tela cheia: as regras e as palavras não cabem
   nos 92% da folha comum, e o "Salvar" fica sempre no rodapé à vista. */
@media (max-width: 520px) {
  .modal.rk-editor {
    height: calc(100dvh - var(--kb, 0px)); max-height: calc(100dvh - var(--kb, 0px)); border-radius: 0;
  }
  .modal.rk-editor > .body { flex: 1; }
}
/* Todo alvo da tela com 44px em qualquer ponteiro (a 768 e a 1440 também): Editar,
   Testar, o chip, o × e o menu do chip, "Não é risco" e "Marcar risco". */
.rk-chip { min-height: 44px; }
.rk-chip.rede { padding-block: 0; }
.rk-x { width: 44px; height: 44px; }
.btn.rk-editar, .rk-teste-acao .btn, .rk-menu .btn, .tk-risco-acoes .linkline { min-height: 44px; }
/* No dedo, também os demais botões da tela e do editor. */
@media (pointer: coarse) {
  .rk-col .btn, .rk-editor .btn, .rk-sug, .linkline.rk-ir { min-height: 44px; }
  .rk-chk { min-height: 44px; }
}

/* Importar por planilha (O-01). O diálogo reaproveita o modal; aqui só o corpo dele: as
   colunas, os dois botões, o arquivo escolhido e o relatório da conferência. Todo botão
   com 44px, e nada com largura fixa: a 360 os botões descem um por linha. */
.imp .imp-colunas { font-size: var(--t-sm); color: var(--muted); margin: 0 0 var(--s3); }
.imp .imp-acoes { display: flex; flex-wrap: wrap; gap: var(--s2); }
.imp .imp-acoes .btn { min-height: 44px; }
.imp .imp-arq { display: block; margin-top: var(--s2); font-size: var(--t-sm); color: var(--ink-2); overflow-wrap: anywhere; }
.imp .imp-res { margin-top: var(--s3); }
.imp .imp-resumo { font-size: 15px; font-weight: 700; color: var(--ink-2); margin: 0 0 var(--s2); }
.imp .imp-resumo.bom { color: var(--prom-ink); }
.imp .imp-resumo.ruim { color: var(--det-ink); }
.imp .imp-nota { font-size: var(--t-sm); color: var(--muted); margin: 0 0 var(--s2); }
.imp .imp-erros { list-style: none; margin: var(--s2) 0; padding: 0; border-top: 1px solid var(--rule); }
.imp .imp-erros li { padding: 9px 0; border-bottom: 1px solid var(--rule); font-size: var(--t-sm); color: var(--ink-2); overflow-wrap: anywhere; }
.imp .imp-frase { display: block; color: var(--det-ink); }
.imp .imp-frase i { font-style: normal; font-weight: 600; }
/* Importar vendas: o relatório em grupos (com erro, sem convite por motivo, avisos), cada um com as
   primeiras linhas e "Mostrar mais". Depois de importar, o diálogo fica com o resultado e o
   Baixar links; o que serve para escolher o arquivo sai de cena. */
.imp .imp-tit { font-size: var(--t-sm); font-weight: 700; color: var(--ink-2); margin: var(--s4) 0 0; }
.imp .imp-grupo.ruim .imp-tit { color: var(--det-ink); }
.imp .imp-grupo .imp-erros { margin-top: var(--s1, 4px); }
/* O foco que vai para a lista quando "Mostrar mais" termina é só para o leitor de tela: sem moldura. */
.imp .imp-erros:focus { outline: none; }
.imp .imp-motivo, .imp .imp-aviso { display: block; color: var(--muted); }
.imp .imp-aviso { color: var(--neu-ink); }
.imp .imp-aviso i { font-style: normal; font-weight: 600; }
.imp .imp-mais { min-height: 44px; margin-top: var(--s2); }
.imp .imp-links { display: flex; flex-direction: column; align-items: flex-start; gap: var(--s2); margin: var(--s3) 0; }
.imp .imp-links .btn { min-height: 44px; }
.imp .imp-links .imp-nota { margin: 0; }
.imp.imp-fim .imp-colunas, .imp.imp-fim .imp-acoes, .imp.imp-fim .imp-arq,
.imp.imp-fim > footer .acao-extra, .imp.imp-fim > footer > .btn.ghost { display: none; }
@media (max-width: 520px) {
  .imp .imp-links .btn { width: 100%; }
}
.empty-acao > .btn-row { margin-left: 0; justify-content: center; }

/* Configurar › Registro de alterações (só leitura). A frase da alteração em destaque e,
   embaixo dela, o detalhe ("Antes: 09:00 · Agora: 08:00") mais apagado; quem fez vem na
   coluna Quem, com o papel ao lado, e no cartão do celular depois de "por". */
.rg-barra select { flex: 0 1 280px; min-height: 44px; }
.rg-frase { white-space: normal; }
.rg-txt { display: block; color: var(--ink); overflow-wrap: anywhere; }
.rg-det { display: block; margin-top: 2px; font-size: 12.5px; color: var(--muted); overflow-wrap: anywhere; }
.rg-papel { color: var(--muted); }
.rg-quem { overflow-wrap: anywhere; }
.rg-nota { margin: var(--s3) 0 0; }
.rg-erro { align-items: center; flex-wrap: wrap; }
.rg-erro .btn { min-height: 44px; }
/* "Criar o convite padrão" e "Copiar o de outra empresa", lado a lado e, sem espaço, um sobre o outro. */
.empty-acao .acoes-linha { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; }

/* ==========================================================================
   Avisos (db/041): a lista do que a rotina avisou e a escolha de quais avisos receber.
   Alvos de 44px em qualquer ponteiro, e nada que passe de 360px de largura.
   ========================================================================== */
.av-lista { list-style: none; margin: 0; padding: 0; }
.av-item { padding: var(--s3) 0; border-top: 1px solid var(--rule); display: flex; flex-direction: column; align-items: flex-start; gap: 6px; }
.av-item:first-child { border-top: 0; padding-top: 0; }
.av-item.novo .av-assunto { color: var(--ink); }
.av-topo { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; }
.av-quando, .av-so-tela { font-size: var(--t-xs); color: var(--muted); }
.av-quando { font-variant-numeric: tabular-nums; }
.av-assunto { font-weight: 600; color: var(--ink-2); overflow-wrap: anywhere; }
.av-detalhe { max-width: 100%; }
.av-detalhe > summary {
  display: inline-flex; align-items: center; min-height: 44px; padding: 0 2px; cursor: pointer;
  font-size: var(--t-sm); font-weight: 600; color: var(--accent);
}
.av-texto { margin: 2px 0 6px; white-space: pre-line; overflow-wrap: anywhere; color: var(--ink-2); font-size: var(--t-sm); max-width: 62ch; }
.av-abrir { min-height: 44px; }
.av-prefs { display: flex; flex-direction: column; gap: var(--s3); }
.av-pref .chk { min-height: 44px; font-size: var(--t-sm); color: var(--ink-2); font-weight: 600; }
.av-pref .chk input { width: 22px; height: 22px; }
.av-pref .chk-ajuda { margin-left: 29px; margin-top: -6px; }
\ No newline at end of file

/* Mensagens do Resumo: enviadas, respostas e inválidas (total) e a lista por loja. */
.card-msg .kpis-msg { margin: 0; }
.card-msg .kpi .v.msg-inv, .msg-inv { color: var(--det-ink); }
.card-msg .kpi .v.msg-inv { font-weight: 800; }
td.msg-inv { font-weight: 800; }
.msg-det { margin-top: 14px; }
.msg-det > summary { min-height: 44px; display: flex; align-items: center; font-weight: 700; }
.msg-seg { margin: 4px 0 10px; flex-wrap: wrap; }
.msg-seg button { min-height: 44px; }
.msg-mais { margin-top: 10px; min-height: 44px; }

/* O pódio vivo do Resumo (proposta A, dono, 11/10/2026): medalhas, degraus de ouro, prata e bronze, confete no 1º e
   a lista que entra uma a uma. Desde 12/10 a tela de Ranking usa o mesmo pódio. */
.rk .rk-faixa-coroa { display: none; }
.rk .rk-palco { position: relative; padding-top: 10px; border-radius: var(--r-md);
  background: radial-gradient(80% 70% at 50% 100%, rgba(232, 181, 0, .14), transparent 70%); }
.rk-medalha { display: block; font-size: 32px; line-height: 1; margin-bottom: 2px; }
.rk .rk-deg-1 .rk-medalha { font-size: 42px; }
.rk .rk-deg-1:not(.provisoria):not(.vazio) .rk-degrau { background: linear-gradient(180deg, #F5C518, #E0A800); color: var(--ink);
  border-color: transparent; box-shadow: 0 10px 24px rgba(224, 168, 0, .25); }
.rk .rk-deg-2:not(.provisoria):not(.vazio) .rk-degrau { background: linear-gradient(180deg, #D3D8E1, #AEB5C2); color: var(--ink); border-color: transparent; }
.rk .rk-deg-3:not(.provisoria):not(.vazio) .rk-degrau { background: linear-gradient(180deg, #E3AE80, #C98A52); color: var(--ink); border-color: transparent; }
.rk-confete { position: absolute; inset: 0; pointer-events: none; overflow: hidden; display: none; z-index: 1; }
.rk-anima .rk-confete { display: block; }
.rk-confete i { position: absolute; top: -12px; width: 7px; height: 11px; border-radius: 2px; opacity: 0;
  animation: rk-confete .7s calc(520ms + var(--d, 0ms)) ease-in both; }
@keyframes rk-confete { 0% { opacity: 1; transform: translateY(0) rotate(0); } 100% { opacity: 0; transform: translateY(190px) rotate(420deg); } }
.rk-anima .rk-medalha { animation: rk-medalha .5s calc(var(--rk-d, 0ms) + 320ms) cubic-bezier(.3, 1.6, .5, 1) both; }
@keyframes rk-medalha { from { opacity: 0; transform: translateY(-34px) scale(.6); } }
.rk-anima .rs-rk-item { animation: rk-linha .38s calc(480ms + var(--atraso, 0ms)) ease both; }
@keyframes rk-linha { from { opacity: 0; transform: translateX(-14px); } }
@media (max-width: 520px) { .rk-medalha { font-size: 26px; } .rk .rk-deg-1 .rk-medalha { font-size: 34px; } }
@media (prefers-reduced-motion: reduce) { .rk-anima .rk-medalha, .rk-anima .rs-rk-item, .rk-confete i { animation: none; } .rk-confete { display: none !important; } }

/* O cartão "Mensagens" (dono, 12/10/2026): o caminho, as faixas "de cada 10", as inválidas e a barra por loja. */
.msg-caminho { display: grid; grid-template-columns: 1fr 34px 1fr 34px 1fr; align-items: stretch; }
.msg-etapa { display: flex; flex-direction: column; gap: 2px; padding: 14px 16px; border-radius: var(--r-md); background: var(--surface-3); min-width: 0; }
.msg-etapa.env { background: var(--accent-soft); }
.msg-etapa.resp { background: var(--prom-soft); }
.msg-ic { font-size: 24px; line-height: 1.1; }
.msg-n { font-size: 30px; font-weight: 800; letter-spacing: -.035em; line-height: 1.1; margin-top: 4px; font-variant-numeric: tabular-nums lining-nums; color: var(--ink); }
.msg-etapa.env .msg-n { color: var(--accent-ink); }
.msg-etapa.resp .msg-n { color: var(--prom-ink); }
.msg-t { font-weight: 700; font-size: var(--t-sm); color: var(--ink); }
.msg-etapa small { font-size: var(--t-xs); font-weight: 600; color: var(--muted); }
.msg-seta { position: relative; display: grid; place-items: center; color: var(--muted); font-size: 20px; }
.msg-seta i { position: absolute; left: 4px; font-style: normal; font-size: 13px; opacity: 0; }
.msg-faixa { display: flex; align-items: center; justify-content: space-between; gap: 10px 16px; flex-wrap: wrap; margin-top: 12px;
  padding: 12px 16px; border-radius: var(--r-md); background: var(--prom-soft); }
.msg-faixa.entrega { background: var(--accent-soft); margin-top: 14px; }
.msg-faixa p { margin: 0; font-size: 17px; font-weight: 800; color: var(--ink); line-height: 1.3; }
.msg-faixa.resposta .msg-faixa-n { color: var(--prom-ink); }
.msg-faixa.entrega .msg-faixa-n { color: var(--accent-ink); }
.msg-blocos { display: flex; gap: 4px; }
.msg-blocos i { width: 18px; height: 26px; border-radius: 6px; background: var(--surface); }
.msg-faixa.resposta .msg-blocos i.on { background: var(--prom); }
.msg-faixa.entrega .msg-blocos i.on { background: var(--accent); }
.msg-perda { display: flex; align-items: center; gap: 8px 10px; flex-wrap: wrap; margin-top: 12px; padding: 12px 16px;
  border-radius: var(--r-md); background: var(--det-soft); color: var(--det-ink); font-weight: 700; font-size: var(--t-sm); }
.msg-perda b { font-size: 20px; font-variant-numeric: tabular-nums; }
.msg-chip { background: var(--surface); border: 1px solid var(--det-line); border-radius: var(--r-full); padding: 3px 10px; font-size: 12px; }
.msg-ok { margin: 12px 0 0; font-size: var(--t-sm); color: var(--prom-ink); font-weight: 700; }
.card-msg .msg-det { margin-top: 16px; }
.msg-leg { display: flex; flex-wrap: wrap; gap: 6px 14px; margin: 8px 0 10px; font-size: 12px; font-weight: 700; color: var(--ink-2); }
.msg-leg span { display: inline-flex; align-items: center; gap: 6px; }
.msg-leg i { width: 12px; height: 12px; border-radius: 4px; display: inline-block; }
.msg-lojas-l { list-style: none; margin: 10px 0 0; padding: 0; }
.msg-loja { padding: 12px 0; border-top: 1px solid var(--rule); }
.msg-loja-cab { display: flex; justify-content: space-between; align-items: baseline; flex-wrap: wrap; gap: 4px 14px; margin-bottom: 8px; font-size: var(--t-sm); }
.msg-loja-n { font-size: 12px; font-weight: 600; color: var(--muted); }
.msg-loja-n b { font-size: 14px; color: var(--ink); font-variant-numeric: tabular-nums; }
.msg-loja-n b.cor-r { color: var(--prom-ink); }
.msg-loja-n b.cor-i { color: var(--det-ink); }
.msg-barra { display: flex; height: 14px; border-radius: var(--r-full); overflow: hidden; background: var(--surface-3); }
.msg-barra i, .msg-leg i { display: block; height: 100%; }
.msg-barra i.r, .msg-leg i.r { background: var(--prom); }
.msg-barra i.e, .msg-leg i.e { background: var(--accent); }
.msg-barra i.v, .msg-leg i.v { background: var(--det); }
.msg-leg i { height: 12px; }
.msg-det[open] .msg-barra { transform-origin: 0 50%; animation: anima-cx .6s cubic-bezier(.2, .8, .3, 1) both; }
@media (max-width: 720px) {
  .msg-caminho { grid-template-columns: minmax(0, 1fr); }
  .msg-seta { height: 28px; transform: rotate(90deg); }
  .msg-faixa p { font-size: 16px; }
}
@media (prefers-reduced-motion: no-preference) {
  .msg-anima .msg-etapa { animation: anima-entra .45s cubic-bezier(.2, .7, .3, 1) both; }
  .msg-anima .msg-etapa.env { animation-delay: .2s; }
  .msg-anima .msg-etapa.resp { animation-delay: .4s; }
  .msg-anima .msg-seta i { animation: msg-voa 1.4s ease-in-out .5s 2 both; }
  .msg-anima .msg-seta:last-of-type i { animation-delay: .9s; }
  .msg-anima .msg-blocos i.on { animation: msg-acende .35s ease calc(.7s + var(--j) * 70ms) both; }
  .msg-anima .msg-perda { animation: anima-entra .45s ease .9s both; }
}
@keyframes msg-voa { 0% { opacity: 0; transform: translateX(0); } 20% { opacity: 1; } 80% { opacity: 1; } 100% { opacity: 0; transform: translateX(20px); } }
@keyframes msg-acende { from { transform: scale(.4); opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .msg-det[open] .msg-barra { animation: none; } }

/* "O que mais aparece" e "Onde acontece" no estilo novo do Resumo (dono, 12/10/2026). */
.prob-linha { display: flex; align-items: center; gap: 12px; min-width: 0; }
.prob-linha > .cell-2 { flex: 1; min-width: 0; }
.prob-ic { flex: none; width: 40px; height: 40px; border-radius: 50%; display: grid; place-items: center; font-size: 19px; line-height: 1;
  background: var(--det-soft); }
.prob-barra { display: block; height: 6px; max-width: 340px; margin-top: 6px; border-radius: var(--r-full); background: var(--surface-3); overflow: hidden; }
.prob-barra > i { display: block; height: 100%; border-radius: var(--r-full); background: var(--det); transform-origin: 0 50%; }
.card-prob td.r.num.strong { font-size: 20px; font-weight: 800; color: var(--det-ink); }
.anima-cresce .prob-barra > i { animation: anima-cx .6s calc(var(--atraso, 0ms) + 300ms) cubic-bezier(.2, .8, .3, 1) both; }
.onde-frase { margin: 0 0 14px; padding: 10px 14px; border-radius: var(--r-md); background: var(--det-soft); color: var(--ink);
  font-size: var(--t-sm); font-weight: 600; line-height: 1.4; }
.onde-frase b { color: var(--det-ink); }
.onde .barra-l .b > i { background: var(--det); }
@media (max-width: 720px) { .prob-ic { width: 34px; height: 34px; font-size: 16px; } .card-prob td.r.num.strong { font-size: 17px; } }

/* NPS por semana com a régua das zonas e o pino; a distribuição das notas com o rosto (dono, 12/10/2026). */
.evo-b.evo-regua { background: linear-gradient(90deg, var(--det) 0 50%, var(--neu) 50% 75%, #7BC96F 75% 87.5%, var(--prom) 87.5%); }
.evo-b i.evo-pino { top: 50%; bottom: auto; width: 18px; height: 18px; margin: -9px 0 0 -9px; border-radius: 50%; background: var(--surface);
  border: 3px solid var(--ink); box-shadow: 0 1px 3px rgba(19, 19, 34, .25); }
.evo-emo { font-size: 16px; margin-right: 6px; vertical-align: -1px; }
.anima-cresce .evo-b i.evo-pino { animation: nps-pino .8s calc(var(--atraso, 0ms) + 300ms + var(--j, 0) * 80ms) cubic-bezier(.2, .8, .3, 1) both; }
.notas .k { display: flex; flex-direction: column; align-items: center; gap: 2px; }
.k-emo { font-size: 16px; line-height: 1; }
.evo-l { grid-template-columns: 92px minmax(0, 1fr) 100px; }
@media (max-width: 380px) { .evo-l { grid-template-columns: 76px minmax(0, 1fr) 88px; } }
@media (max-width: 720px) { .notas .k { flex-direction: row; gap: 6px; } .k-emo { font-size: 15px; } }
@media (max-width: 720px) {
  /* No celular a régua da semana ganha a largura toda, embaixo do rótulo e do número. */
  .evo-l { grid-template-columns: minmax(0, 1fr) auto; gap: 6px 10px; }
  .evo-l .evo-b { grid-column: 1 / -1; grid-row: 2; margin: 2px 9px 6px; }
  .evo-k small { display: inline; margin-left: 6px; }
}

/* O funil com o ícone de cada etapa e a perda em vermelho; o Controle por unidade com a barra P/N/D (12/10/2026). */
.funil-ic { display: inline-block; width: 22px; margin-right: 6px; text-align: center; }
.funil-e .b { height: 22px; }
.funil-e .b > i { background: linear-gradient(90deg, var(--accent), var(--accent-2)); }
.funil-perda { color: var(--det-ink); font-weight: 600; }
.uni-pnd { display: flex; height: 6px; width: 96px; margin: 5px 0 0 auto; border-radius: var(--r-full); overflow: hidden; background: var(--surface-3); }
.uni-pnd i { display: block; height: 100%; }
.uni-pnd i.p { background: var(--prom); } .uni-pnd i.n { background: var(--neu); } .uni-pnd i.d { background: var(--det); }
.uni-emo { margin-right: 5px; font-size: 15px; vertical-align: -1px; }

/* Ordenar pelo título da coluna (dono, 12/10/2026). No celular, a fileira "Ordenar por". */
th.th-ordenavel { padding: 0; }
.th-ord { display: inline-flex; align-items: center; gap: 5px; width: 100%; min-height: 40px; padding: 10px 12px; font: inherit;
  font-weight: inherit; letter-spacing: inherit; text-transform: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
th.r .th-ord { justify-content: flex-end; }
.th-ord:hover { color: var(--ink); background: var(--surface-3); }
.th-ord:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.th-seta { font-size: 10px; color: var(--muted); opacity: .75; }
th[aria-sort="ascending"] .th-ord, th[aria-sort="descending"] .th-ord { color: var(--accent-ink); }
th[aria-sort="ascending"] .th-seta, th[aria-sort="descending"] .th-seta { color: var(--accent-ink); opacity: 1; }
.tbl-ordem { display: none; }
@media (max-width: 720px) {
  .tbl-ordem { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; padding: 10px 15px; border-bottom: 1px solid var(--rule); }
  .tbl-ordem-rot { font-size: 12px; font-weight: 700; color: var(--muted); margin-right: 2px; }
  .tbl-ordem-b { font: inherit; font-size: 12px; font-weight: 700; min-height: 36px; padding: 6px 10px; border-radius: var(--r-full);
    border: 1px solid var(--rule-2); background: var(--surface); color: var(--ink-2); cursor: pointer; }
  .tbl-ordem-b.on { background: var(--accent-soft); border-color: var(--accent-line); color: var(--accent-ink); }
}

/* O painel de Tratativas com as propostas aprovadas (1A, 2, 3B e 4; dono, 12/10/2026). */
.tk-kpis .tk-kpi { position: relative; border-radius: var(--r-md); }
.tk-kpi-ic { display: block; font-size: 22px; line-height: 1.1; margin-bottom: 2px; }
.tk-kpi-ag { background: var(--neu-soft); } .tk-kpi-ag .v { color: var(--neu-ink); }
.tk-kpi-tempo { background: var(--accent-soft); } .tk-kpi-tempo .v { color: var(--accent-ink); }
.tk-kpi-obrig { background: var(--surface-3); }
.tk-kpi-ret { display: grid; grid-template-columns: auto minmax(0, 1fr); column-gap: 14px; align-content: start; }
.tk-kpi-ret > :not(.ret-anel) { grid-column: 2; }
.tk-kpi-ret > .ret-anel { grid-row: 1 / span 6; align-self: center; width: 96px; height: 96px; }
.tk-kpi-ret.erro { background: var(--det-soft); } .tk-kpi-ret.atencao { background: var(--neu-soft); } .tk-kpi-ret.ok { background: var(--prom-soft); }
.tk-velha { display: inline-flex !important; align-items: center; gap: 6px; width: max-content; max-width: 100%; margin-top: 6px;
  padding: 3px 10px; border-radius: var(--r-full); background: var(--surface); border: 1px solid var(--det-line); color: var(--det-ink) !important; font-weight: 800; }
.tk-velha i { flex: none; width: 8px; height: 8px; border-radius: 50%; background: var(--det); }
@media (prefers-reduced-motion: no-preference) {
  .tk-velha i { animation: tk-pulsa 2s infinite; }
  .tk-kpi .ret-anel-cheio { animation: ret-anel 1s .2s cubic-bezier(.2, .8, .3, 1) both; }
  .tk-st-q .tk-st-b i { animation: anima-cx .7s .2s cubic-bezier(.2, .8, .3, 1) both; transform-origin: 0 50%; }
  .tk-rl .ret-anel-cheio { animation: ret-anel 1s .2s cubic-bezier(.2, .8, .3, 1) both; }
}
@keyframes tk-pulsa { 0% { box-shadow: 0 0 0 0 rgba(244, 45, 94, .45); } 70% { box-shadow: 0 0 0 8px rgba(244, 45, 94, 0); } 100% { box-shadow: 0 0 0 0 rgba(244, 45, 94, 0); } }
@media (max-width: 720px) { .tk-kpi-ret > .ret-anel { width: 80px; height: 80px; } }

.tk-st-quadros { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 10px; }
@media (max-width: 620px) { .tk-st-quadros { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.tk-st-q { width: 100%; height: 100%; display: flex; flex-direction: column; align-items: center; gap: 1px; padding: 12px 8px; text-align: center;
  font: inherit; border: 0; border-radius: var(--r-md); cursor: pointer; }
.tk-st-q:hover { filter: brightness(.97); }
.tk-st-q.ag { background: var(--neu-soft); color: var(--neu-ink); }
.tk-st-q.at { background: var(--accent-soft); color: var(--accent-ink); }
.tk-st-q.ok { background: var(--prom-soft); color: var(--prom-ink); }
.tk-st-q.nao { background: var(--surface-3); color: var(--ink-2); }
.tk-st-ic { font-size: 22px; line-height: 1.2; }
.tk-st-n { font-size: 28px; font-weight: 800; letter-spacing: -.03em; font-variant-numeric: tabular-nums; }
.tk-st-t { font-size: 12px; font-weight: 800; }
.tk-st-q small { font-size: 11px; font-weight: 600; opacity: .85; line-height: 1.3; }
.tk-st-b { display: block; align-self: stretch; height: 6px; margin-top: 8px; border-radius: var(--r-full); background: rgba(255, 255, 255, .85); overflow: hidden; }
.tk-st-b i { display: block; height: 100%; border-radius: var(--r-full); }
.tk-dia-frase { margin: 0 0 12px; font-size: 16px; font-weight: 800; color: var(--ink); }
.tk-dia-frase > span { color: var(--prom-ink); }

.tk-rl-lista { list-style: none; margin: 0; padding: 16px 18px; display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 12px; }
.tk-rl { position: relative; display: flex; align-items: center; gap: 12px; padding: 12px 14px; border: 1px solid var(--rule); border-radius: var(--r-md); }
.tk-rl.erro { background: radial-gradient(110% 90% at 0 0, rgba(244, 45, 94, .10), transparent 60%); }
.tk-rl.atencao { background: radial-gradient(110% 90% at 0 0, rgba(240, 162, 2, .14), transparent 60%); }
.tk-rl.ok { background: radial-gradient(110% 90% at 0 0, rgba(0, 161, 112, .12), transparent 60%); }
.tk-rl .ret-anel { width: 78px; height: 78px; }
.tk-rl-txt { min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.tk-rl-nome { font-weight: 700; font-size: var(--t-sm); }
.tk-rl-txt small { font-size: 12px; font-weight: 600; color: var(--muted); }
.tk-rl-txt small.tk-rl-atr { color: var(--det-ink); font-weight: 800; }

.tk-prob-nome { display: flex; align-items: center; gap: 10px; }
.tk-prob-nome .prob-ic { width: 36px; height: 36px; font-size: 17px; }
.tk-prob-num b { color: var(--det-ink); font-size: 18px; }
.tk-prob-barra i, .tk-loja-barra i { background: var(--det) !important; }
.tk-lojas .tk-loja:first-child .tk-loja-qtd { color: var(--det-ink); }
.tk-rl-lista { grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
.tk-rl-txt { flex: 1; text-align: left; }
.tk-rl-nome .loja { display: inline; }
.tk-rl-nome .linkline { text-align: left; }
@media (max-width: 720px) {
  /* O retorno com o anel na linha inteira: em meia largura o texto quebrava a cada palavra. */
  .tk-kpis .tk-kpi-ret { grid-column: 1 / -1; }
}

/* "Loja ou região" na barra das Tratativas (dono, 12/10/2026). */
.tk-onde select { min-height: 40px; max-width: 280px; padding: 8px 34px 8px 12px; border-radius: var(--r-md); font: inherit; font-size: var(--t-sm); }

/* Comentários no estilo novo (dono, 12/10/2026): a fita de notas com o rosto, o rosto em cada nota, o filtro de lugar. */
.filtros-nota { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 14px; }
.vb-notas button { display: inline-flex; align-items: center; gap: 6px; }
.vb-rosto { font-size: 16px; line-height: 1; }
.vb-notas button.on.vb-nota-detrator { background: var(--det-soft); color: var(--det-ink); }
.vb-notas button.on.vb-nota-neutro { background: var(--neu-soft); color: var(--neu-ink); }
.vb-notas button.on.vb-nota-promotor { background: var(--prom-soft); color: var(--prom-ink); }
.vb-nota-cel { white-space: nowrap; }
.vb-nota-cel .vb-rosto { margin-right: 6px; vertical-align: -2px; }
td.comentario { font-size: 15px; line-height: 1.5; color: var(--ink); }
.tk-onde .rotulo { white-space: nowrap; }
.vb-notas { max-width: 100%; overflow-x: auto; scrollbar-width: none; }
.vb-notas button { white-space: nowrap; }
@media (max-width: 420px) { .vb-notas button { padding-inline: 10px; } }
@media (max-width: 480px) { .vb-suf { display: none; } }

/* Os filtros das Tratativas no desenho do Resumo (dono, 12/10/2026): os chips na barra e, no computador, o painel de
   filtros no meio da tela (no celular continua a folha de baixo). */
.tk-fx { flex: 1 1 auto; min-width: 0; }
.tk-fx .fx-chips { flex-wrap: wrap; }
@media (min-width: 721px) {
  dialog.folha-filtros { inset: 0; margin: auto; width: min(520px, calc(100vw - 32px)); max-height: min(86vh, 760px);
    border-radius: 16px; box-shadow: 0 24px 60px rgba(19, 19, 34, .28); }
}

/* Tratativas: o botão único de filtros no computador e o Onde do Resumo dentro do painel (dono, 12/10/2026). */
.tk-fx-um { display: flex; gap: 8px; align-items: stretch; min-width: 0; max-width: 760px; }
.tk-fx-um .fx-bc { flex: 1 1 auto; min-width: 0; }
.tk-fx-um .fx-bc-txt { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tk-folha-onde .fx-ms-lista { max-height: 280px; }

/* Convites enviados com o topo B e a lista 1 (dono, 12/10/2026). */
.cv-kpis .cv-q { position: relative; border-radius: var(--r-md); }
.cv-q-ic { display: block; font-size: 22px; line-height: 1.1; margin-bottom: 2px; }
.cv-q-prog { background: var(--surface-3); }
.cv-q-env { background: var(--accent-soft); } .cv-q-env .v { color: var(--accent-ink); }
.cv-q-resp { background: var(--prom-soft); display: grid; grid-template-columns: auto minmax(0, 1fr); column-gap: 12px; align-content: start; }
.cv-q-resp .v { color: var(--prom-ink); }
.cv-q-resp > :not(.ret-anel) { grid-column: 2; }
.cv-q-resp > .ret-anel { grid-row: 1 / span 6; align-self: center; width: 76px; height: 76px; }
.cv-q-nao { background: var(--det-soft); } .cv-q-nao .v { color: var(--det-ink); }
.cv-q-av { background: #F1ECFF; } .cv-q-av .v { color: #5B3FD6; }
.cv-q[aria-pressed="true"] { box-shadow: inset 0 0 0 2px var(--accent); }
@media (prefers-reduced-motion: no-preference) { .cv-q .ret-anel-cheio { animation: ret-anel 1s .2s cubic-bezier(.2, .8, .3, 1) both; } }
.cv-tl-cx { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.cv-tl { display: flex; align-items: center; max-width: 230px; }
.cv-tl i { flex: none; width: 11px; height: 11px; border-radius: 50%; background: var(--rule-2); }
.cv-tl b { flex: 1 1 auto; height: 3px; min-width: 10px; background: var(--rule-2); }
.cv-tl i.on, .cv-tl b.on { background: var(--accent); }
.cv-tl i.ok, .cv-tl b.ok { background: var(--prom); }
.cv-tl i.x { background: var(--det); }
@media (prefers-reduced-motion: no-preference) { .cv-tl i { animation: msg-acende .35s ease calc(var(--k, 0) * 80ms) both; } }
.cv-tl-t { font-size: 12px; font-weight: 600; color: var(--ink-2); line-height: 1.35; }
.cv-tl-t b { font-weight: 800; }
.cv-tl-t.ok { color: var(--prom-ink); } .cv-tl-t.x { color: var(--det-ink); } .cv-tl-t.espera { color: var(--neu-ink); }
.cv-rosto { margin-right: 6px; vertical-align: -2px; }
@media (max-width: 720px) { .cv-q-resp { grid-column: 1 / -1; } .cv-tl { max-width: 260px; } }
/* Os tons dos quadros de Convites com a precedência da regra dos números (.kpis.cv-kpis .kpi). */
.kpis.cv-kpis .kpi.cv-q-prog { background: var(--surface-3); }
.kpis.cv-kpis .kpi.cv-q-env { background: var(--accent-soft); }
.kpis.cv-kpis .kpi.cv-q-resp { background: var(--prom-soft); }
.kpis.cv-kpis .kpi.cv-q-nao { background: var(--det-soft); }
.kpis.cv-kpis .kpi.cv-q-av { background: #F1ECFF; }
.kpis.cv-kpis .kpi.cv-q:hover { filter: brightness(.98); }
.kpis.cv-kpis .cv-q-resp .ret-anel-fundo { stroke: var(--surface); }
td:has(> .cv-rosto) { white-space: nowrap; }
td:has(> .cv-rosto) > * { vertical-align: middle; }

/* Mensagens com o quarto quadro e o problema por loja; a tela Telefones a corrigir (dono, 13/10/2026). */
.msg-caminho { grid-template-columns: 1fr 30px 1fr 30px 1fr 30px 1fr; }
.msg-etapa.cheg { background: #E2F3F8; }
.msg-etapa.cheg .msg-n { color: #0B6A84; }
@media (prefers-reduced-motion: no-preference) {
  .msg-anima .msg-etapa.cheg { animation-delay: .4s; }
  .msg-anima .msg-etapa.resp { animation-delay: .6s; }
  .msg-anima .msg-seta:nth-of-type(2) i { animation-delay: .7s; }
}
.msg-ver { margin-left: auto; background: var(--surface); color: var(--det-ink); border: 1px solid var(--det-line); }
.msg-ver svg { margin-left: 2px; }
.msg-loja-prob { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 4px 12px; margin-top: 8px;
  font-size: 12px; font-weight: 600; color: var(--det-ink); }
.tf-kpis .tf-q { border-radius: var(--r-md); text-align: left; }
.tf-q-ic { display: block; font-size: 22px; line-height: 1.1; margin-bottom: 2px; }
.tf-q-sub { display: block; font-size: var(--t-xs); font-weight: 600; color: var(--muted); margin-top: 2px; }
.kpis.tf-kpis .kpi.tf-q-tot { background: var(--det-soft); } .tf-q-tot .v { color: var(--det-ink); }
.kpis.tf-kpis .kpi.tf-q-sem { background: var(--neu-soft); } .tf-q-sem .v { color: var(--neu-ink); }
.kpis.tf-kpis .kpi.tf-q-falha { background: var(--surface-3); }
.tf-q[aria-pressed="true"] { box-shadow: inset 0 0 0 2px var(--accent); }
.tf-frase { margin: 4px 0 14px; padding: 12px 16px; border-radius: var(--r-md); background: var(--accent-soft); color: var(--ink);
  font-weight: 700; font-size: var(--t-sm); }
.tf-tel { font-variant-numeric: tabular-nums; font-weight: 700; color: var(--det-ink); white-space: nowrap; }
.tf-mot { font-size: var(--t-sm); color: var(--ink-2); }
@media (max-width: 980px) { .msg-caminho { grid-template-columns: 1fr 26px 1fr; row-gap: 10px; } .msg-seta:nth-of-type(2) { display: none; } }
@media (max-width: 720px) { .msg-caminho { grid-template-columns: minmax(0, 1fr); } .msg-seta:nth-of-type(2) { display: grid; } .msg-ver { margin-left: 0; } }
.kpis.tf-kpis { gap: 12px; }
.tf-outras { margin: -4px 0 14px; font-size: var(--t-sm); color: var(--muted); }

/* Mensagens: Taxa de entrega e Taxa de resposta (dono, 13/10/2026). */
.msg-taxas { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; margin-top: 14px; }
.msg-taxa { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: 4px 16px; padding: 14px 16px;
  border-radius: var(--r-md); background: var(--accent-soft); }
.msg-taxa.resposta { background: var(--prom-soft); }
.msg-taxa-cab { display: flex; flex-direction: column; }
.msg-taxa-nome { font-weight: 800; font-size: 15px; color: var(--ink); }
.msg-taxa-cab small { font-size: var(--t-xs); font-weight: 600; color: var(--muted); }
.msg-taxa-v { grid-row: 1 / span 2; grid-column: 2; font-size: 34px; font-weight: 800; letter-spacing: -.035em; line-height: 1;
  font-variant-numeric: tabular-nums lining-nums; color: var(--accent-ink); }
.msg-taxa.resposta .msg-taxa-v { color: var(--prom-ink); }
.msg-taxa p { grid-column: 1; margin: 0; font-size: var(--t-sm); font-weight: 600; color: var(--ink-2); }
.msg-taxa p strong { color: var(--ink); font-weight: 800; }
.msg-taxa .msg-blocos { grid-column: 1 / -1; margin-top: 6px; }
.msg-taxa .msg-blocos i { flex: 1 1 0; max-width: 26px; }
.msg-taxa.entrega .msg-blocos i.on { background: var(--accent); }
.msg-taxa.resposta .msg-blocos i.on { background: var(--prom); }
@media (max-width: 720px) { .msg-taxas { grid-template-columns: minmax(0, 1fr); } .msg-taxa-v { font-size: 30px; } }
@media (max-width: 720px) {
  .msg-caminho { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
  .msg-caminho .msg-seta { display: none !important; }
  .msg-etapa { padding: 12px 14px; }
  .msg-etapa .msg-n { font-size: 26px; }
}
@media (max-width: 720px) { .kpis.tf-kpis .kpi.tf-q-tot { grid-column: 1 / -1; } }
.tf-outras .linkline { color: var(--accent-ink); font-weight: 700; }

/* Mensagens: as réguas das taxas (C) e o funil de barras (B), escolhidos pelo dono em 13/10/2026. */
.msg-reguas { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
.msg-regua { padding: 16px; border-radius: var(--r-md); background: var(--surface-3); min-width: 0; }
.msg-regua-topo { display: flex; justify-content: space-between; align-items: flex-start; gap: 10px; }
.msg-regua-topo small { display: block; font-size: var(--t-xs); font-weight: 600; color: var(--muted); }
.msg-regua-v { text-align: right; }
.msg-regua-v b { display: block; font-size: 32px; font-weight: 800; letter-spacing: -.035em; line-height: 1; font-variant-numeric: tabular-nums lining-nums; }
.msg-regua.entrega .msg-regua-v b { color: #0B6A84; }
.msg-regua.resposta .msg-regua-v b { color: var(--prom-ink); }
.msg-zona { display: inline-block; margin-top: 6px; font-size: 12px; font-weight: 800; padding: 2px 9px; border-radius: var(--r-full); }
.msg-zona.ok { background: var(--prom-soft); color: var(--prom-ink); }
.msg-zona.at { background: var(--neu-soft); color: var(--neu-ink); }
.msg-zona.ruim { background: var(--det-soft); color: var(--det-ink); }
.msg-reg { position: relative; display: flex; height: 10px; margin: 34px 0 6px; }
.msg-reg > span { height: 100%; }
.msg-reg .z-ruim { background: #FFC9D6; border-radius: 99px 0 0 99px; }
.msg-reg .z-at { background: #FDE3A7; }
.msg-reg .z-ok { background: #B6EBD3; border-radius: 0 99px 99px 0; }
.msg-pino { position: absolute; top: -9px; width: 4px; height: 28px; margin-left: -2px; border-radius: 3px; background: var(--ink); }
.msg-pino::after { content: attr(data-e); position: absolute; top: -28px; left: 50%; transform: translateX(-50%); font-size: 19px; font-style: normal; }
.msg-eixo { position: relative; height: 14px; font-size: 11px; font-weight: 700; color: var(--muted); }
.msg-eixo span { position: absolute; transform: translateX(-50%); }
.msg-eixo span:first-child { transform: none; }
.msg-eixo span:last-child { transform: translateX(-100%); }
.msg-regua p { margin: 10px 0 0; font-size: var(--t-sm); font-weight: 600; color: var(--ink-2); line-height: 1.45; }
.msg-regua p strong { color: var(--ink); font-weight: 800; }
.msg-funil { display: grid; gap: 10px; margin-top: 18px; }
.msg-f { display: grid; grid-template-columns: 170px minmax(0, 1fr) 72px; gap: 14px; align-items: center; }
.msg-f-r { font-size: var(--t-sm); font-weight: 700; color: var(--ink-2); line-height: 1.25; }
.msg-f-r small { display: block; font-size: 11px; font-weight: 600; color: var(--muted); margin-left: 24px; }
.msg-f-b { height: 22px; border-radius: 7px; background: var(--surface-3); overflow: hidden; }
.msg-f-b i { display: block; height: 100%; border-radius: 7px; transform-origin: 0 50%; }
.msg-f.prog .msg-f-b i { background: #B9B9CC; }
.msg-f.env .msg-f-b i { background: var(--accent); }
.msg-f.cheg .msg-f-b i { background: #0E8AA8; }
.msg-f.resp .msg-f-b i { background: var(--prom); }
.msg-f-v { text-align: right; font-size: 16px; font-weight: 800; font-variant-numeric: tabular-nums; color: var(--ink); }
.msg-perda { gap: 10px 14px; margin-top: 18px; }
.msg-perda-ic { font-size: 20px; }
.msg-perda-tx { flex: 1 1 320px; font-weight: 600; color: var(--ink-2); line-height: 1.45; }
.msg-perda-tx b { color: var(--det-ink); font-size: 16px; }
@media (prefers-reduced-motion: no-preference) {
  .msg-anima .msg-regua { animation: anima-entra .45s cubic-bezier(.2, .7, .3, 1) both; }
  .msg-anima .msg-regua.resposta { animation-delay: .15s; }
  .msg-anima .msg-pino { animation: msg-pino 1.1s cubic-bezier(.2, .8, .2, 1) .35s both; }
  .msg-anima .msg-f-b i { animation: anima-cx .9s cubic-bezier(.2, .8, .2, 1) both; }
  .msg-anima .msg-f.env .msg-f-b i { animation-delay: .15s; }
  .msg-anima .msg-f.cheg .msg-f-b i { animation-delay: .3s; }
  .msg-anima .msg-f.resp .msg-f-b i { animation-delay: .45s; }
}
@keyframes msg-pino { from { left: 0; opacity: 0; } }
@media (max-width: 720px) {
  .msg-reguas { grid-template-columns: minmax(0, 1fr); }
  .msg-f { grid-template-columns: 112px minmax(0, 1fr) 54px; gap: 10px; }
  .msg-f-r small { margin-left: 0; }
  .msg-regua-v b { font-size: 28px; }
}

/* Indicadores por loja (dono, 13/10/2026). */
.ind-rede { display: grid; grid-template-columns: minmax(0, 1.1fr) minmax(0, 2fr); gap: 12px; margin-bottom: 14px; }
.ind-grupo { background: var(--surface); border: 1px solid var(--rule); border-radius: 16px; padding: 14px 16px; min-width: 0; }
.ind-grupo h3 { margin: 0 0 10px; font-size: 13px; font-weight: 700; color: var(--muted); }
.ind-lin { display: flex; flex-wrap: wrap; gap: 10px 18px; align-items: flex-end; }
.ind-it b { display: block; font-size: 24px; font-weight: 800; letter-spacing: -.03em; font-variant-numeric: tabular-nums lining-nums; color: var(--ink); line-height: 1.15; }
.ind-it > span { font-size: 12px; font-weight: 700; color: var(--ink-2); }
.ind-it.nps b { font-size: 34px; }
.ind-it.nps.z-ok b, .ind-nps.z-ok { color: var(--prom-ink); }
.ind-it.nps.z-at b, .ind-nps.z-at { color: var(--neu-ink); }
.ind-it.nps.z-ruim b, .ind-nps.z-ruim { color: var(--det-ink); }
.ind-it.p b, .ind-p { color: var(--prom-ink); } .ind-it.ne b, .ind-ne { color: var(--neu-ink); } .ind-it.d b, .ind-d { color: var(--det-ink); }
.ind-p, .ind-ne, .ind-d { font-weight: 700; }
.ind-it.env b { color: var(--accent-ink); } .ind-it.cheg b, .ind-it.tx-e b { color: #0B6A84; } .ind-it.resp b, .ind-it.tx-r b { color: var(--prom-ink); }
.ind-sep { width: 1px; align-self: stretch; background: var(--rule); }
.ind-zona { display: inline-block; margin-left: 6px; font-size: 11px; font-weight: 800; padding: 1px 8px; border-radius: var(--r-full); vertical-align: 1px; }
.ind-zona.ok { background: var(--prom-soft); color: var(--prom-ink); }
.ind-zona.at { background: var(--neu-soft); color: var(--neu-ink); }
.ind-zona.ruim { background: var(--det-soft); color: var(--det-ink); }
.ind-acoes { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.ind-nps { font-weight: 800; font-size: 16px; white-space: nowrap; }
.ind-mix { display: flex; width: 86px; height: 6px; margin: 5px 0 0 auto; border-radius: var(--r-full); overflow: hidden; background: var(--surface-3); }
.ind-mix i { display: block; height: 100%; }
.ind-mix .p { background: var(--prom); } .ind-mix .n { background: var(--neu); } .ind-mix .d { background: var(--det); }
.ind-tx { font-weight: 800; white-space: nowrap; }
.ind-tx i { display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-right: 6px; vertical-align: 1px; background: var(--rule-2); }
.ind-tx i.z-ok { background: var(--prom); } .ind-tx i.z-at { background: var(--neu); } .ind-tx i.z-ruim { background: var(--det); }
.card-ind td.ind-cg, .card-ind th:nth-child(6), .card-ind th:nth-child(10) { border-left: 1px solid var(--rule); }
.card-ind tr.ind-grupos th { border: 0; padding: 12px 6px 0; text-align: center; font-size: 12px; font-weight: 800; color: var(--ink-2); }
.card-ind tr.ind-grupos th span { display: block; padding-bottom: 6px; border-bottom: 2px solid var(--rule-2); }
.card-ind tr.ind-grupos th.g-cli span { border-color: #B6EBD3; } .card-ind tr.ind-grupos th.g-msg span { border-color: #C9C9FB; }
.card-ind tr.ind-grupos th.g-tx span { border-color: #BFE3EE; }
.card-ind tr.ind-grupos th:nth-child(n) { border-left: 0; }
.card-ind tfoot td { font-weight: 800; background: var(--surface-3); padding: 12px 10px; }
.ind-nota { margin: 10px 2px 0; font-size: 12px; color: var(--muted); line-height: 1.5; }
@media (max-width: 980px) { .ind-rede { grid-template-columns: minmax(0, 1fr); } }
@media (max-width: 720px) { .card-ind tr.ind-grupos, .card-ind tfoot { display: none; } .ind-mix { margin-left: 0; } }

/* Convites enviados com o cartão Mensagens e a fileira "Mostrar na lista" (dono, 13/10/2026). */
.msg-meio { display: grid; grid-template-columns: minmax(0, 1fr) 230px; gap: 16px; align-items: stretch; }
.msg-meio .msg-funil { margin-top: 18px; }
.msg-av { margin-top: 18px; display: flex; flex-direction: column; gap: 2px; padding: 14px 16px; border-radius: var(--r-md); background: #F1ECFF; }
.msg-av-ic { font-size: 22px; }
.msg-av b { font-size: 30px; font-weight: 800; letter-spacing: -.035em; color: #5B3FD6; font-variant-numeric: tabular-nums; line-height: 1.1; }
.msg-av-t { font-weight: 800; font-size: var(--t-sm); color: var(--ink); }
.msg-av small { font-size: var(--t-xs); font-weight: 600; color: var(--muted); }
.msg-av-ver { margin-top: auto; align-self: flex-start; background: var(--surface); color: #5B3FD6; border: 1px solid #D8CCFF; }
.cv-mostrar { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin: 14px 0; }
.cv-mostrar-rot { font-size: var(--t-sm); font-weight: 700; color: var(--muted); margin-right: 2px; }
.cv-chip { font: inherit; font-size: var(--t-sm); font-weight: 700; min-height: 40px; padding: 7px 14px; border-radius: var(--r-full);
  border: 1px solid var(--rule-2); background: var(--surface); color: var(--ink-2); cursor: pointer; }
.cv-chip b { margin-left: 6px; color: var(--ink); font-variant-numeric: tabular-nums; }
.cv-chip.on { background: var(--ink); border-color: var(--ink); color: #fff; }
.cv-chip.on b { color: #fff; }
.cv-chip:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
@media (max-width: 720px) { .msg-meio { grid-template-columns: minmax(0, 1fr); } .cv-mostrar-rot { width: 100%; } }
@media (min-width: 721px) {
  .ind-rede { grid-template-columns: max-content minmax(0, 1fr); }
  .card-ind th, .card-ind td { padding-left: 7px; padding-right: 7px; }
  .card-ind thead tr:not(.ind-grupos) th { font-size: 10.5px; letter-spacing: 0; }
  .card-ind td:first-child { white-space: nowrap; }
  .card-ind td:first-child .cod { margin-right: 4px; }
  .ind-mix { width: 60px; }
}
@media (min-width: 721px) {
  .card-ind th.th-ordenavel { padding: 0; }
  .card-ind .th-ord { padding: 8px 6px; gap: 3px; }
}
@media (min-width: 981px) { .ind-lin { gap: 8px 14px; } .ind-it b { font-size: 22px; } .ind-it.nps b { font-size: 32px; } }
.ind-lin { align-items: flex-start; }
.ind-it > span:not(.ind-zona) { display: block; }
.ind-it .ind-zona { display: table; margin: 4px 0 0; }

/* Problemas relatados: as lojas de cada problema (dono, 13/10/2026). */
.cat-loja-b { position: relative; z-index: 2; white-space: nowrap; }
.cat-loja-b .seta { transition: transform .2s ease; }
.cat-loja-b[aria-expanded="true"] .seta { transform: rotate(180deg); }
tr.cat-lojas > td { background: var(--surface-2, #FAFAFC); padding: 6px 16px 14px 32px; }
.cat-lojas-l { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.cat-lojas-l li { display: grid; grid-template-columns: minmax(180px, 280px) minmax(0, 1fr) 170px; gap: 12px; align-items: center; }
.cat-lojas-n { font-weight: 700; font-size: var(--t-sm); color: var(--ink); }
.cat-lojas-bar { height: 10px; border-radius: var(--r-full); background: var(--surface-3); overflow: hidden; }
.cat-lojas-bar i { display: block; height: 100%; border-radius: var(--r-full); background: var(--det); transform-origin: 0 50%; }
.cat-lojas-v { text-align: right; font-size: var(--t-sm); }
.cat-lojas-v b { font-variant-numeric: tabular-nums; color: var(--det-ink); }
.cat-lojas-v small { display: block; font-size: 11px; font-weight: 600; color: var(--muted); }
@media (prefers-reduced-motion: no-preference) {
  .cat-lojas-bar i { animation: anima-cx .6s cubic-bezier(.2, .8, .3, 1) calc(var(--j, 0) * 60ms) both; }
}
@media (max-width: 720px) {
  tr.cat-lojas > td { padding: 4px 12px 12px; display: block; }
  .cat-lojas-l li { grid-template-columns: minmax(0, 1fr) auto; }
  .cat-lojas-bar { grid-column: 1 / -1; grid-row: 2; }
}

/* A tratativa avulsa (dono, 13/10/2026). */
.tag.tk-avulsa { background: #F1ECFF; color: #5B3FD6; font-weight: 800; }
.tk-faixa-avulsa { margin: 0 0 14px; padding: 12px 14px; border-radius: var(--r-md); background: #F1ECFF; font-size: var(--t-sm); color: var(--ink-2); line-height: 1.5; }
.tk-faixa-avulsa > b { color: var(--ink); }
.tk-faixa-avulsa ul { margin: 6px 0 0; padding-left: 18px; }
.tk-faixa-avulsa p { margin: 6px 0 0; font-size: 12px; color: var(--muted); }

/* Clientes: o cadastro do cliente e a apuração mensal (dono, 14/10/2026). */
.cli-topo { margin: 0 0 10px; }
.cli-fatos { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 14px 22px; margin: 0; }
.cli-fatos dt { font-size: var(--t-xs); font-weight: 700; color: var(--muted); }
.cli-fatos dd { margin: 3px 0 0; font-weight: 700; color: var(--ink); }
.cli-emails { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 8px; }
.cli-emails li { background: var(--surface-3); border-radius: var(--r-full); padding: 6px 12px; font-size: var(--t-sm); font-weight: 600; }
.apu-mes { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 0 0 14px; }
.apu-mes input[type="month"] { font: inherit; font-weight: 700; padding: 8px 12px; border: 1px solid var(--rule-2); border-radius: var(--r-md); background: var(--surface); color: var(--ink); }
.apu-parcial { font-size: var(--t-xs); font-weight: 700; color: var(--neu-ink); background: var(--neu-soft); padding: 4px 10px; border-radius: var(--r-full); }
.apu-resumo { display: flex; flex-wrap: wrap; gap: 10px 26px; padding: 16px 18px; margin: 0 0 14px; background: var(--surface); border: 1px solid var(--rule); border-radius: 16px; }
.apu-it b { display: block; font-size: 24px; font-weight: 800; letter-spacing: -.03em; font-variant-numeric: tabular-nums; color: var(--ink); }
.apu-it span { font-size: 12px; font-weight: 700; color: var(--ink-2); }
.apu-it.ativas b { color: var(--accent-ink); }
.apu-it.total b { color: var(--prom-ink); }
.apu-total { color: var(--prom-ink); }
.apu-lojas { width: 100%; border-collapse: collapse; font-size: var(--t-sm); }
.apu-lojas th { font-size: 11px; font-weight: 800; color: var(--muted); text-align: left; padding: 6px 8px; border-bottom: 1px solid var(--rule-2); }
.apu-lojas td { padding: 8px; border-bottom: 1px solid var(--rule); }
.apu-lojas th.r, .apu-lojas td.r { text-align: right; }
.apu-lojas tr.off td { color: var(--muted); }
.apu-lojas-cx { overflow-x: auto; }
.apu-mes { flex-wrap: nowrap; }
.apu-mes input[type="month"] { width: auto; flex: 0 1 220px; min-width: 0; min-height: 40px; }
.apu-mes .btn { flex: none; min-height: 40px; }
@media (max-width: 520px) { .apu-mes { flex-wrap: wrap; } .apu-parcial { flex-basis: 100%; } }
.cli-emps { display: grid; gap: 12px; }
.cli-emp { border: 1px solid var(--rule); border-radius: 14px; padding: 14px 16px; background: var(--surface); }
.cli-emp.off { opacity: .7; }
.cli-emp-cab { display: flex; justify-content: space-between; align-items: flex-start; gap: 10px; }
.cli-emp-cab b { display: block; font-size: 15px; }
.cli-emp-cab small { display: block; color: var(--muted); font-size: 12px; font-weight: 600; margin-top: 2px; }
.cli-emp-end { margin: 8px 0 0; font-size: var(--t-sm); color: var(--ink-2); }
.cli-filiais { margin-top: 10px; }
.cli-filiais > summary { cursor: pointer; font-weight: 700; font-size: var(--t-sm); color: var(--accent-ink); min-height: 32px; display: flex; align-items: center; }
.cli-filiais ul { list-style: none; margin: 6px 0 0; padding: 0; display: grid; gap: 6px; }
.cli-filiais li { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; padding: 6px 0; border-top: 1px solid var(--rule); font-size: var(--t-sm); }
.cli-filiais li small { color: var(--muted); font-weight: 600; }
.cli-filiais li.off { color: var(--muted); }
