/* ───────── Transição entre telas ─────────────────────────────────────────
 *
 * A lateral NÃO é mais redesenhada ao trocar de tela: o roteador
 * (js/roteador.js) substitui só o `<main>`, e o elemento da barra lateral é
 * literalmente o mesmo do início ao fim da sessão. Antes ela era destruída e
 * remontada a cada clique, e o `view-transition-name` só disfarçava isso.
 *
 * `@view-transition` continua aqui para o caso de uma navegação de verdade
 * acontecer — quando o roteador desiste e devolve o controle ao navegador.
 */
@view-transition { navigation: auto; }

@media (prefers-reduced-motion: reduce) {
  ::view-transition-group(*), ::view-transition-old(*), ::view-transition-new(*) {
    animation: none !important;
  }
}

/* `hidden` tem de vencer qualquer display: as telas de lista e ficha se
 * alternam por esse atributo, e uma regra de flex/grid o anularia em silêncio. */
[hidden] { display: none !important; }

:root {
  /* ─── Sistema visual portado do painel do Plano Pet ─────────────────────
   *
   * O azul é o mesmo de lá. O acento âmbar `--paw` (#F7C21B) do Plano Pet virou
   * LARANJA aqui — passou por verde no caminho, e o verde acabou reaproveitado
   * para o que ele realmente sabe dizer: estado positivo. Ver o bloco abaixo.
   */
  --azul: #2E63F2;          /* --vet       */
  --azul-forte: #1B47C4;    /* --vet-dark  */
  --azul-suave: #E9F0FE;    /* --vet-soft  */
  --azul-fundo: #F4F7FF;    /* --vet-softer*/

  /* ─── DUAS FAMÍLIAS, DOIS TRABALHOS ─────────────────────────────────────
   *
   * LARANJA é o ACENTO: ação e o lugar onde você está. Complementar do azul da
   * marca, então salta sem brigar.
   * VERDE é ESTADO POSITIVO: cliente, cadastro completo, parcela paga.
   *
   * Antes o verde fazia os dois papéis, e isso confundia "esta é a página
   * aberta" com "está tudo certo". Separados, cada cor só afirma uma coisa.
   *
   * ⚠️ A ARMADILHA DO LARANJA, medida: o tom comum (#F97316) com texto branco
   * dá 2,80:1 — quase metade do mínimo de 4,5. Laranja é uma das cores em que
   * o valor "bonito" é justamente o ilegível. Por isso o sólido aqui é escuro
   * (#C2410C, 5,18:1) e o claro só aparece com texto quase preto. */
  --laranja: #C2410C;        /* sólido, texto branco — 5,18:1 */
  --laranja-forte: #9A3412;  /* hover do sólido */
  --laranja-suave: #FFF1E7;
  --laranja-escuro: #7C2D12;

  --verde: #0E7C3E;          /* estado positivo, não acento */
  --verde-suave: #E6F6ED;
  --verde-escuro: #0A5C2E;
  /* O item ATIVO do menu vive sobre o azul escuro da lateral, então tem DOIS
   * contrastes a respeitar: a pílula contra o azul (para o item saltar) e o
   * texto contra a pílula (para ser lido). Medidos, em laranja:
   *
   *   #FB923C laranja 400   3,38 vs lateral    6,92 texto escuro
   *   #FDBA74 laranja 300   4,54               9,28   <- escolhido
   *   #FED7AA laranja 200   5,65              11,56   (lava demais, some)
   *
   * O arranjo é o mesmo do âmbar no Plano Pet, de onde este layout veio:
   * fundo claro e vibrante com texto escuro. NUNCA laranja sólido com texto
   * branco na pílula — seria o erro de 2,80:1 medido acima. */
  --acento-vivo: #FDBA74;
  --acento-tinta: #431407;

  /* Shell lateral, portado do Plano Pet */
  --lateral: var(--azul-forte);
  --lateral-texto: #CBD9FB;
  --lateral-hover: rgba(255, 255, 255, .10);
  --lateral-larg: 236px;

  --texto: #111318;         /* --ink   */
  --apagado: #5B6472;       /* --muted */
  /* Duas bordas, porque servem a coisas diferentes:
   * `--borda` separa (divisória de tabela, aresta de cartão) e pode ser leve.
   * `--borda-campo` CONTORNA um controle, e a WCAG 1.4.11 pede 3:1 para o
   * contorno ser percebido — a antiga dava 1,22:1 contra o branco, ou seja,
   * o campo praticamente não tinha forma. Esta dá 3,05:1. */
  --borda: #D3DCEC;
  --borda-campo: #8794AE;
  --erro: #C0261F;
  --atencao: #8A6400;       /* unico remanescente ambar: avisos */
  --atencao-fundo: #FFF6DA;
  --atencao-borda: #F0DFA8;

  --raio: 14px;
  --raio-pilula: 100px;
  --sombra: 0 8px 30px rgba(17, 19, 24, .08);
}
* { box-sizing: border-box; }
body {
  margin: 0; min-height: 100vh;
  font: 15px/1.55 Inter, -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
  background: var(--azul-fundo); color: var(--texto);
  -webkit-font-smoothing: antialiased;
}

/* Centrar é EXCEÇÃO, e a exceção é o login.
 *
 * Era ao contrário: o body nascia `display: grid; place-items: center` e as
 * telas do sistema desligavam isso por JavaScript (`body.classList.add('app')`).
 * Bastou essa linha cair numa refatoração para a página inteira voltar a ser
 * centralizada e encolhida ao conteúdo — barra lateral descolada da esquerda,
 * faixa vazia de 360px, tabela esticada. Regra que depende de JS para não
 * quebrar o layout quebra o layout mais cedo ou mais tarde. */
body.login { display: grid; place-items: center; }
h1, h2, h3, .topo .marca { font-family: Nunito, Inter, system-ui, sans-serif; letter-spacing: -.01em; }
.cartao { background: #fff; padding: 2rem; border-radius: var(--raio); width: min(380px, 92vw); box-shadow: var(--sombra); }
h1 { margin: 0 0 1.5rem; font-size: 1.4rem; font-weight: 800; }
h1 span { color: var(--azul); }
label { display: block; margin: .9rem 0 .3rem; font-size: .82rem; font-weight: 600; color: var(--apagado); }
input { width: 100%; padding: .65rem .8rem; border: 1px solid var(--borda-campo); border-radius: 10px; font-size: 1rem; font-family: inherit; background: #fff; transition: border-color .15s, box-shadow .15s; }
/* O foco é anel, não contorno do sistema: o contorno some contra a borda
 * escura do campo e quem navega por teclado perde o lugar. */
input:focus, select:focus, textarea:focus {
  outline: none; border-color: var(--azul);
  box-shadow: 0 0 0 3px rgba(46, 99, 242, .22);
}
/* Botão e link também precisam dizer onde está o foco. */
button:focus-visible, a:focus-visible, .btn:focus-visible {
  outline: 2px solid var(--azul); outline-offset: 2px;
}
.lateral button:focus-visible, .lateral a:focus-visible { outline-color: var(--acento-vivo); }
button {
  width: 100%; margin-top: 1.4rem; padding: .72rem 1.2rem; border: 0;
  border-radius: var(--raio-pilula); background: var(--azul); color: #fff;
  font-size: 1rem; font-weight: 700; font-family: inherit; cursor: pointer;
  transition: background .15s, transform .05s;
}
button:hover:not(:disabled) { background: var(--azul-forte); }
button:active:not(:disabled) { transform: translateY(1px); }
button:disabled { opacity: .55; cursor: progress; }
button.secundario { background: var(--azul-suave); color: var(--azul-forte); }
button.secundario:hover:not(:disabled) { background: #dbe6fd; }
/* O acento do sistema: ação. Laranja, complementar do azul da marca. */
button.acento { background: var(--laranja); }
button.acento:hover:not(:disabled) { background: var(--laranja-forte); }
.erro { margin: 1rem 0 0; color: var(--erro); font-size: .88rem; }
dl { display: grid; grid-template-columns: auto 1fr; gap: .5rem 1rem; margin: 0; }
dt { font-size: .82rem; font-weight: 600; color: var(--apagado); }
dd { margin: 0; }

/* ───────── Shell: barra lateral fixa + conteudo ──────────────────────────
 *
 * Portado do painel do Plano Pet (~/projetos/plano-pet/frontend). Antes daqui o
 * Core usava barra no TOPO; a lateral cabe mais item sem apertar, e o sistema
 * vai crescer (agendamento, PJ, onboarding ainda nao existem).
 *
 * `position: sticky` e deliberado la e aqui: a navegacao some ao rolar uma
 * lista de 23 mil pessoas, e recuperar o menu custa um scroll de volta a cada
 * acao.
 */
.app { display: flex; min-height: 100vh; }

.lateral {
  /* âncora da transição: o navegador entende que é o MESMO elemento entre
   * páginas e não a redesenha — fim do flash da navegação. */
  view-transition-name: lateral;
  width: var(--lateral-larg); flex: 0 0 var(--lateral-larg);
  background: var(--lateral); color: #fff;
  display: flex; flex-direction: column;
  position: sticky; top: 0; height: 100vh;
}
.lateral-marca { padding: 20px 18px 18px; border-bottom: 1px solid rgba(255,255,255,.08); }
/* A logo oficial é BRANCA sobre transparente, que é exatamente o que uma
 * lateral escura pede — não precisa de pílula branca por trás, como o
 * placeholder "MS" precisava. Largura fixa e altura automática: a proporção é
 * da marca, não do meu palpite. */
.lateral-logo { display: block; width: 148px; height: auto; }
.lateral-sub {
  margin-top: .45rem; font-size: .68rem; color: var(--lateral-texto);
  text-transform: uppercase; letter-spacing: .16em; font-weight: 600;
}

.lateral-nav { display: flex; flex-direction: column; gap: 2px; padding: 12px 10px; flex: 1; overflow-y: auto; }
.lateral-link {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 12px; border-radius: 9px;
  color: var(--lateral-texto); text-decoration: none; font-size: .88rem; font-weight: 500;
}
.lateral-link:hover { background: var(--lateral-hover); color: #fff; }
/* O item aberto. Laranja claro com tinta quase preta — ver os números no topo. */
.lateral-link.ativo { background: var(--acento-vivo); color: var(--acento-tinta); font-weight: 700; }
.lateral-icone { width: 19px; height: 19px; flex: none; opacity: .9; }
.lateral-link.ativo .lateral-icone { opacity: 1; }

.lateral-rodape { padding: 14px 16px; border-top: 1px solid rgba(255,255,255,.08); }
.lateral-quem { font-size: .8rem; color: var(--lateral-texto); margin-bottom: 8px; }
.lateral-rodape button {
  width: 100%; margin: 0; padding: .45rem .7rem; font-size: .82rem; font-weight: 600;
  background: rgba(255,255,255,.10); color: #fff; border: 1px solid rgba(255,255,255,.16);
  border-radius: 9px;
}
.lateral-rodape button:hover:not(:disabled) { background: rgba(255,255,255,.18); }

/* Em tela estreita a lateral vira barra no topo — o mesmo arranjo do Plano Pet,
 * porque quem atende usa tablet no balcao. */
@media (max-width: 860px) {
  .app { flex-direction: column; }
  .lateral { width: 100%; flex: none; height: auto; position: static; }
  .lateral-nav { flex-direction: row; overflow-x: auto; padding: 8px; }
  .lateral-link { white-space: nowrap; }
  .lateral-rodape { display: flex; align-items: center; gap: 12px; }
  .lateral-quem { margin: 0; flex: 1; }
  .lateral-rodape button { width: auto; }
}

main.conteudo { view-transition-name: conteudo; flex: 1; min-width: 0; padding: 26px 30px 44px; }
.pagina-titulo { font-family: Nunito, Inter, system-ui, sans-serif; font-size: 1.5rem; font-weight: 800; margin: 0 0 18px; letter-spacing: -.02em; }
.painel { background: #fff; border: 1px solid var(--borda); border-radius: var(--raio); padding: 1.35rem; margin-bottom: 1.25rem; box-shadow: var(--sombra); }
.painel h2 { margin: 0 0 1rem; font-size: 1.05rem; font-weight: 800; }
.linha { display: flex; gap: .6rem; align-items: center; flex-wrap: wrap; }
.linha > input, .linha > select { width: auto; flex: 1; min-width: 200px; }
.linha button { width: auto; margin: 0; padding: .65rem 1.1rem; }

table { width: 100%; border-collapse: collapse; font-size: .9rem; }
th { text-align: left; font-size: .76rem; text-transform: uppercase; letter-spacing: .04em; color: var(--apagado); padding: .55rem .6rem; border-bottom: 1px solid var(--borda); }
td { padding: .6rem; border-bottom: 1px solid #f0f2f7; }
tbody tr { cursor: pointer; }
tbody tr:hover { background: var(--azul-fundo); }
.vazio { padding: 2rem; text-align: center; color: var(--apagado); }

.selo { display: inline-block; padding: .12rem .5rem; border-radius: 20px; font-size: .74rem; font-weight: 700; }
.selo.cliente { background: var(--verde-suave); color: var(--verde-escuro); }
/* Ex-cliente saiu do laranja para o azul suave: e um ESTADO, nao um alerta. */
.selo.ex_cliente { background: var(--azul-suave); color: var(--azul-forte); }
.selo.prospecto { background: #EEF1F7; color: var(--apagado); }
.selo.pend { background: #FDECEC; color: #A81E18; }
.selo.migrado { background: #EEF1F7; color: var(--apagado); }

/* Faixa de pendências: informa, não bloqueia. Some sozinha quando completa. */
.pendencias { margin: 0 0 1rem; padding: .7rem .9rem; background: var(--atencao-fundo); border: 1px solid var(--atencao-borda); border-radius: 10px; font-size: .86rem; color: var(--atencao); }
.pendencias b { font-weight: 700; }

/* O ESCOPO do modal de novo exame. Duas seções valem para a REDE inteira, duas
 * são só do parceiro: a faixa diz com palavras, a borda repete com cor para o
 * olho que só varre o modal. Azul é o que é de todos; laranja, "onde você está"
 * (este parceiro) — a mesma divisão de papéis das duas famílias de cor acima. */
.escopo { margin: 0 0 1rem; padding: .2rem .9rem .9rem; border-left: 4px solid var(--borda); border-radius: 6px; }
.escopo-rede { border-left-color: var(--azul); background: var(--azul-fundo); }
.escopo-parceiro { border-left-color: var(--laranja); background: var(--laranja-suave); }
.escopo-faixa { margin: .7rem 0 0; font-size: .74rem; font-weight: 700; letter-spacing: .04em; color: var(--apagado); }

.grade { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 0 1rem; }
.campo label { margin-top: .8rem; }
.campo.faltando input { border-color: var(--erro); background: #fff7f7; }
.campo.faltando label::after { content: ' • obrigatório'; color: var(--erro); font-weight: 700; }
fieldset { border: 1px solid var(--borda); border-radius: 12px; padding: .2rem 1rem 1rem; margin: 1.2rem 0 0; }
fieldset.faltando { border-color: var(--erro); background: #fff7f7; }
legend { font-size: .8rem; font-weight: 700; color: var(--apagado); padding: 0 .4rem; }
.aviso-campo { margin: .3rem 0 0; font-size: .8rem; color: var(--atencao); }
.acoes { display: flex; gap: .6rem; margin-top: 1.4rem; }
.acoes button { width: auto; margin: 0; padding: .65rem 1.3rem; }
.link { background: none; border: 0; color: var(--azul); font-weight: 600; cursor: pointer; padding: 0; text-decoration: underline; width: auto; margin: 0; }

/* ───────── Modal e toast (portados junto com modal.js / toast.js) ─────── */
.ov { position: fixed; inset: 0; background: rgba(16,24,40,.5); display: none; align-items: center; justify-content: center; z-index: 50; padding: 20px; }
.ov.on { display: flex; }
.modal { background: #fff; border-radius: var(--raio); max-width: 560px; width: 100%; max-height: 90vh; overflow: auto; box-shadow: 0 20px 50px rgba(0,0,0,.3); }
.modal .mh { padding: 16px 20px; border-bottom: 1px solid var(--borda); display: flex; align-items: center; }
.modal .mh h3 { font-size: 1rem; flex: 1; margin: 0; }
.modal .mb { padding: 18px 20px; }
.modal .mf { padding: 13px 20px; border-top: 1px solid var(--borda); display: flex; justify-content: flex-end; gap: 10px; }
.iconbtn { border: 0; background: none; cursor: pointer; color: #7b8499; font-size: .95rem; padding: 4px 8px; border-radius: 6px; width: auto; margin: 0; }
.iconbtn:hover { background: var(--azul-suave); color: var(--texto); }

/* .btn é a classe que modal.js gera nos botões do rodapé. */
.btn { width: auto; margin: 0; border: 1px solid var(--borda); background: #fff; color: var(--texto); padding: .5rem 1.05rem; border-radius: var(--raio-pilula); font-size: .86rem; font-weight: 700; font-family: inherit; cursor: pointer; }
.btn:hover { background: var(--azul-fundo); border-color: #cfdaf0; }
.btn.pri { background: var(--azul); border-color: var(--azul); color: #fff; }
.btn.pri:hover { background: var(--azul-forte); border-color: var(--azul-forte); }
/* Laranja = o acento do sistema: ação. Verde ficou reservado a ESTADO. */
.btn.acento { background: var(--laranja); border-color: var(--laranja); color: #fff; }
.btn.acento:hover { background: var(--laranja-forte); border-color: var(--laranja-forte); }
.btn.danger { color: var(--erro); border-color: #F3C9C9; }
.btn.pri.danger { background: var(--erro); border-color: var(--erro); color: #fff; }

.toast { position: fixed; bottom: 22px; left: 50%; transform: translateX(-50%); background: var(--texto); color: #fff; padding: 11px 22px; border-radius: var(--raio-pilula); font-size: .84rem; z-index: 99; opacity: 0; transition: .25s; pointer-events: none; }
.toast.on { opacity: 1; }

.modal label { margin-top: .9rem; }
.modal select, .modal input { width: 100%; padding: .6rem .75rem; border: 1px solid var(--borda-campo); border-radius: 10px; font-size: .95rem; font-family: inherit; }
select { padding: .65rem .8rem; border: 1px solid var(--borda-campo); border-radius: 10px; font-size: 1rem; background: #fff; font-family: inherit; }


/* ───────── Carregando ────────────────────────────────────────────────────
 *
 * Existe porque, sem ele, a tabela ficava VAZIA entre o primeiro quadro e a
 * chegada dos dados — e tabela vazia já significa uma coisa neste sistema
 * ("nenhum resultado"). O círculo diz a verdade: ainda estou buscando.
 */
.carregando {
  display: flex; align-items: center; justify-content: center; gap: .7rem;
  padding: 2.4rem 1rem; color: var(--apagado); font-size: .88rem;
}
.carregando::before {
  content: ''; width: 20px; height: 20px; flex: none;
  border: 2.5px solid var(--azul-suave); border-top-color: var(--azul);
  border-radius: 50%; animation: girar .7s linear infinite;
}
/* O círculo entra com atraso: buscas rápidas terminam antes de ele aparecer, e
 * um círculo que pisca por 80ms comunica menos que nada — comunica instabilidade. */
.carregando { animation: aparecer .2s var(--curva) .18s both; }
@keyframes aparecer { from { opacity: 0; } }
@keyframes girar { to { transform: rotate(360deg); } }

/* Dentro de uma tabela o círculo precisa ocupar a linha inteira. */
td.carregando { display: table-cell; text-align: center; }
td.carregando::before { display: inline-block; vertical-align: -4px; margin-right: .6rem; }

@media (prefers-reduced-motion: reduce) {
  .carregando::before { animation-duration: 2s; }
}

/* A lateral já existe no HTML de cada página, então o primeiro quadro tem o
 * shell inteiro no lugar. Enquanto o JS não preenche o menu, estes blocos
 * seguram a altura — sem eles o conteúdo saltava quando os itens apareciam. */
.lateral-nav.esqueleto::after {
  content: ''; display: block; height: 240px;
  background: linear-gradient(var(--lateral-hover) 0 0) no-repeat;
  background-size: 100% 37px; border-radius: 9px; opacity: .5;
}

/* ───────── A tabela ROLA, não se espreme ─────────────────────────────────
 *
 * As colunas quebravam no meio do dado: um CPF virava "047.986.846-" numa
 * linha e "86" na outra; "1 pendência(s)" partia entre a palavra e o número.
 * Dado quebrado ao meio é pior que dado fora da vista — quem lê tem de
 * remontar de cabeça.
 *
 * SEM `@media`, de propósito. A primeira tentativa prendeu isto a
 * `max-width: 900px` e não resolveu: quem espreme a tabela não é a largura da
 * JANELA, é a do CONTEÚDO — numa janela de 1024px sobram 715px depois dos
 * 236px da lateral, e a tabela já quebra enquanto a regra dorme. Amarrar a
 * medida errada é o mesmo que não ter regra.
 *
 * Assim a rolagem aparece exatamente quando não cabe, em qualquer janela:
 * acima de 620px de espaço a tabela é mais larga que o mínimo e não há barra
 * nenhuma. `min-width` é o que força — sem ele a tabela obedece ao pai e volta
 * a se espremer.
 */
.painel { overflow-x: auto; }
/* `min-width` sozinho não resolvia: dentro de 620px as colunas continuavam
 * espremendo e o CPF seguia partido. Escolher UMA largura mínima é adivinhar —
 * ela depende do nome mais longo da base, que ninguém controla.
 *
 * `nowrap` ataca a causa: nenhuma célula parte o próprio valor. A tabela passa
 * a ter a largura natural do seu conteúdo e o `overflow-x` acima cuida do
 * resto. Linha sempre de uma altura só, como no painel do Plano Pet.
 *
 * O `min-width` fica só para a tabela VAZIA não encolher e desalinhar os
 * cabeçalhos quando a busca não devolve nada. */
.painel table { min-width: 620px; }
.painel th, .painel td { white-space: nowrap; }

/* Entre 900 e 1100 o espaço é apertado mas cabe: só o respiro diminui. */
@media (max-width: 1100px) {
  main.conteudo { padding: 20px 18px 36px; }
  .painel { padding: 1.1rem; }
}

/* No celular o cabeçalho comia 315px dos 812 da tela antes de mostrar um dado
 * sequer — quase 40% da altura para dizer o nome do sistema. */
@media (max-width: 640px) {
  .lateral-marca { padding: 12px 14px; }
  .lateral-logo { width: 28px; height: 28px; font-size: .82rem; }
  .lateral-nome { font-size: .95rem; }
  .lateral-rodape { padding: 8px 14px; }
  .pagina-titulo { font-size: 1.25rem; margin-bottom: 12px; }
  main.conteudo { padding: 14px 14px 30px; }
  /* O botão de ação não precisa dividir linha com a busca num vão de 375px. */
  .linha > input, .linha > select { min-width: 0; flex: 1 1 100%; }
}

/* ───────── Segunda via: boleto e PIX ─────────────────────────────────── */
.parcela-pagto { padding: .2rem 0; }
.divisor-pagto { border: 0; border-top: 1px solid var(--borda); margin: 1rem 0; }
.qr-pix { border: 1px solid var(--borda); border-radius: 10px; background: #fff; flex: none; }
/* O modal de pagamento tem tabela nenhuma, mas herda `.painel`? Não — ele vive
 * no overlay. Aqui só o respiro entre os blocos de boleto e de PIX. */
.parcela-pagto .linha { gap: .5rem; }

/* ═════════ Passagem de design: texto, botões e movimento ═══════════════════
 *
 * A direção deste painel é CLAREZA OPERACIONAL: é uma ferramenta usada o dia
 * inteiro sobre 23 mil pessoas. Nada decorativo disputa espaço com o dado; o
 * contraste codifica significado (em aberto × pago, vencida × a vencer); o
 * movimento só confirma ação e orienta entre telas. Precisão, não intensidade.
 */

/* ───────── Números alinham ───────────────────────────────────────────────
 *
 * Data e dinheiro em coluna precisam de algarismo de largura fixa. Sem isto,
 * "R$ 119,90" e "R$ 29,90" desalinham a vírgula e o olho tem de reler cada
 * linha para comparar. É a diferença entre varrer uma coluna e soletrá-la.
 */
.numerico { font-variant-numeric: tabular-nums; }
td.numerico, th.numerico { white-space: nowrap; }

/* Margem negativa é FATO, não alarme: no Premium ela é intencional. Cor de
 * atenção, não de erro — erro pediria correção de uma decisão de produto. */
.margem-negativa { color: var(--atencao); font-weight: 700; }

/* Procedimento que nunca foi precificado neste plano (Tarefa 12, achado
 * Crítico). Itálico e apagado para não se confundir de relance com uma linha
 * de "R$ 0,00" de verdade — "sem preço" não é grátis. Clicar abre o mesmo
 * modal de sempre, para definir o preço pela primeira vez. */
.sem-preco td { color: var(--apagado); font-style: italic; }

/* ───────── Hierarquia do texto ───────────────────────────────────────────
 *
 * `.quem` é texto de APOIO: CPF sob o nome, status cru, carimbo de leitura.
 * Estava do mesmo tamanho do conteúdo, então competia com ele. Menor e mais
 * claro — mas ainda em 5,98:1, acima do mínimo de 4,5.
 */
.quem { font-size: .82rem; color: var(--apagado); line-height: 1.45; }
.painel h3 {
  font-family: Nunito, Inter, system-ui, sans-serif; font-weight: 800;
  font-size: .95rem; letter-spacing: .01em;
  margin: 1.6rem 0 .5rem; padding-top: 1.2rem; border-top: 1px solid var(--borda);
}
.painel h3:first-of-type { border-top: 0; padding-top: 0; }
dl + h3 { margin-top: 1.4rem; }
dt { line-height: 1.9; }
dd { line-height: 1.9; font-variant-numeric: tabular-nums; }

/* ───────── Botão dentro da linha da tabela ──────────────────────────────
 *
 * Os botões de boleto e PIX ficavam no TOPO da ficha, valendo para o contrato
 * inteiro. Agora vivem na linha da parcela a que pertencem — que é onde a
 * decisão acontece: quem atende está olhando uma parcela específica quando
 * resolve mandar o boleto dela.
 *
 * Miúdos de propósito: são 12 linhas na tela, e botão de tamanho normal em
 * cada uma transformaria a tabela numa parede de pílulas.
 */
td.pagto { white-space: nowrap; text-align: right; }
.btn-mini {
  padding: .26rem .7rem; font-size: .78rem; font-weight: 700;
  border-radius: var(--raio-pilula); line-height: 1.5;
  text-decoration: none; display: inline-block;
}
a.btn-mini { color: var(--azul-forte); border-color: var(--borda); }
a.btn-mini:hover { background: var(--azul-suave); border-color: #cfdaf0; }
.btn-mini + .btn-mini { margin-left: .3rem; }

/* ───────── Movimento ─────────────────────────────────────────────────────
 *
 * Três momentos, e só três: a troca de tela, o retorno de um clique, e a
 * entrada do modal. Micro-animação espalhada em tudo vira ruído numa
 * ferramenta de trabalho — o olho aprende a ignorar, e aí ela deixa de
 * comunicar quando importa.
 */

/* A CURVA DA CASA. `cubic-bezier(.32,.72,0,1)` começa rápido e desacelera
 * muito no fim — é o que faz um movimento parecer que PAROU em vez de ter
 * sido interrompido. `ease` e `ease-out` do navegador desaceleram cedo demais
 * e deixam a sensação de arrasto. */
:root { --curva: cubic-bezier(.32, .72, 0, 1); }

/* 1. Troca de tela. A lateral é âncora e NÃO se move; só o conteúdo troca.
 *    Sem isto o menu inteiro pisca a cada clique, e o olho perde o lugar.
 *
 *    A saída é curta e só desaparece: quem está indo embora não deve chamar
 *    atenção. A entrada é a que se sente — mais longa, com um deslocamento
 *    pequeno o bastante para orientar sem parecer que a página caiu no lugar. */
/* Duracoes CURTAS de proposito. A rede ja custa uns 600ms numa troca de tela;
 * somar 260ms de animacao em cima disso e o que fazia parecer arrastado.
 * 170ms ainda le como movimento — abaixo de ~120ms o olho ve um corte. */
::view-transition-old(conteudo) { animation: sai .09s linear both; }
::view-transition-new(conteudo) { animation: entra .17s var(--curva) both; }
::view-transition-old(lateral), ::view-transition-new(lateral) { animation: none; }
@keyframes sai   { to   { opacity: 0; } }
@keyframes entra { from { opacity: 0; transform: translateY(6px); } }

/* 2. O clique responde. 60ms é abaixo do limiar de percepção consciente: não
 *    se vê a animação, sente-se que o botão cedeu. */
button, .btn { transition: background-color .15s ease, border-color .15s ease, box-shadow .15s ease, transform .06s ease; }
button:active:not(:disabled), .btn:active { transform: translateY(1px); }
/* Só o botão PRINCIPAL levanta ao passar o mouse. Se todos levantassem, a tela
 * inteira ficaria inquieta e o gesto deixaria de significar "este é o caminho". */
button:not(.secundario):not(.btn):hover:not(:disabled), .btn.pri:hover, .btn.acento:hover {
  box-shadow: 0 3px 10px rgba(17, 19, 24, .16);
}

/* 3. O modal entra de onde veio, em vez de aparecer pronto. */
.ov { transition: opacity .18s var(--curva); opacity: 0; }
.ov.on { opacity: 1; }
.ov.on .modal { animation: sobe .18s var(--curva) both; }
@keyframes sobe { from { opacity: 0; transform: translateY(12px) scale(.98); } }

/* 4. Troca DENTRO da página — lista ↔ ficha. Essas telas se alternam por
 *    `hidden`, e a troca era um corte seco: a ficha aparecia pronta, sem dizer
 *    de onde veio. É a navegação mais frequente do sistema. */
#tela-ficha:not([hidden]), #tela-lista:not([hidden]), #painel-form:not([hidden]) {
  animation: entra .16s var(--curva) both;
}

/* A linha da tabela reage sem deslocar nada: só a cor muda. */
tbody tr { transition: background-color .12s var(--curva); }

/* Quem pediu menos movimento recebe menos movimento — em tudo, não só aqui. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

/* ───────── Marca no login ────────────────────────────────────────────────
 *
 * A logo oficial é branca sobre transparente, e o cartão de login é branco.
 * Em vez de pedir uma segunda versão da marca, o cartão ganha uma faixa azul
 * no topo — que é o fundo para o qual a logo foi desenhada. Sangra até as
 * bordas do cartão, então o raio tem de ser o mesmo, só em cima.
 */
.login-marca {
  margin: -2rem -2rem 1.6rem; padding: 1.7rem 2rem 1.5rem;
  background: var(--azul-forte);
  border-radius: var(--raio) var(--raio) 0 0;
  text-align: center;
}
.login-marca img { display: block; width: 168px; height: auto; margin: 0 auto; }
.login-marca span {
  display: block; margin-top: .5rem; font-size: .68rem; font-weight: 600;
  color: var(--lateral-texto); text-transform: uppercase; letter-spacing: .16em;
}
/* O cartão passa a ter conteúdo sangrado; sem isto a faixa vaza pelos cantos. */
.cartao { overflow: hidden; }

/* O aviso de que o pedido ainda está a caminho. A tela já mostra o resultado
 * pedido — este selo é o que impede isso de virar afirmação: já pedi, ainda
 * não confirmaram. Sem ele, um POST que falhasse deixaria a tela mentindo. */
.salvando {
  display: inline-block; margin-left: .5rem; padding: .05rem .5rem;
  border-radius: var(--raio-pilula); font-size: .7rem; font-weight: 700;
  background: var(--laranja-suave); color: var(--laranja-escuro);
  animation: pulsar 1.1s var(--curva) infinite;
}
@keyframes pulsar { 50% { opacity: .45; } }

/* Faixa de abas do painel de credenciado. */
.abas {
  display: flex;
  gap: .25rem;
  border-bottom: 1px solid var(--borda);
  margin: .5rem 0 1rem;
}
.abas .aba {
  background: none;
  border: none;
  border-bottom: 2px solid transparent;
  padding: .6rem 1rem;
  font-weight: 600;
  color: var(--apagado);
  cursor: pointer;
  width: auto;
}
.abas .aba:hover { color: var(--texto); }
/* Laranja porque o acento do sistema é ação (estilo.css:139). Verde está
 * reservado a ESTADO, e a aba corrente não é um estado do dado — é onde a
 * pessoa está. */
.abas .aba.corrente {
  color: var(--laranja);
  border-bottom-color: var(--laranja);
}

/* Financeiro: chamado cujo agendamento foi cancelado. Pagar um deles é pagar por
 * atendimento que não aconteceu, depois de o dinheiro já ter voltado ao paciente:
 * a linha inteira salta aos olhos, não só o selo. */
tr.chamado-cancelado td { background: #FDECEC; }
tr.chamado-cancelado td:first-child { box-shadow: inset 4px 0 0 var(--erro); }
