/* Identidade visual neutra do webapp. Todas as cores, fontes, espaços, raios,
 * bordas e sombras ficam neste único bloco :root; o restante do arquivo e os
 * templates usam só var(--...). Para trocar a marca, edite apenas este bloco.
 *
 * Contraste WCAG AA (texto normal ≥ 4,5:1; texto grande e bordas de controle ≥ 3:1):
 *   --cor-texto sobre --cor-superficie ............ 14,7:1
 *   --cor-texto sobre --cor-fundo ................. 13,5:1
 *   --cor-texto-suave sobre --cor-superficie ...... 7,0:1  (sobre o fundo: 6,4:1)
 *   --cor-primaria (links) sobre --cor-superficie . 7,4:1  (sobre o fundo: 6,7:1)
 *   --cor-texto-primaria sobre --cor-primaria ..... 7,4:1  (hover: 10,0:1)
 *   --cor-texto sobre --cor-secundaria ............ 12,3:1 (hover: 10,5:1)
 *   --cor-texto-desabilitado sobre --cor-desabilitado 4,6:1
 *   --cor-borda-controle sobre --cor-superficie ... 4,5:1  (fundo 4,2:1; secundária 3,8:1)
 *   --cor-foco sobre --cor-superficie e o fundo ... 7,4:1 e 6,7:1
 *   Semáforo, texto sobre o fundo do estado: ok 6,6:1; atenção 7,3:1; erro 6,5:1
 *   Indicador do semáforo sobre o fundo do estado: ok 4,5:1; atenção 3,8:1; erro 4,5:1
 *   --cor-erro sobre --cor-superficie ............. 7,9:1
 *   Avisos flutuantes, chips, contadores e o segmentado reaproveitam os pares acima
 *   (texto sobre superfície ou secundária; texto-primária sobre primária).
 * --cor-borda é só divisória decorativa (cartões, tabelas); controles usam
 * --cor-borda-controle. --cor-esqueleto é decorativa (placeholder sem texto).
 * O semáforo nunca depende só da cor: sempre traz texto. */
:root {
    --reserva-editor: 29rem;  /* altura que o editor de recorte deixa para o resto da tela */
    --largura-campo-numero: 5rem;  /* campos numéricos ao lado dos controles do editor */
    --largura-rotulo-curto: 5rem;  /* rótulos Brilho e Saturação do editor */
    --cor-primaria: #1d5a85;
    --cor-primaria-hover: #154666;
    --cor-texto-primaria: #ffffff;
    --cor-secundaria: #e6ebef;
    --cor-secundaria-hover: #d3dbe1;
    --cor-fundo: #f3f5f7;
    --cor-superficie: #ffffff;
    --cor-superficie-suave: #f6f8f9;
    --cor-texto: #1b2a33;
    --cor-texto-suave: #4d5b64;
    --cor-borda: #d5dde0;
    --cor-borda-controle: #6b7882;
    --cor-foco: #1d5a85;
    --cor-desabilitado: #e9ecee;
    --cor-texto-desabilitado: #5f6b73;
    --cor-ok: #2b7a3f;
    --cor-ok-texto: #1d5e30;
    --cor-ok-fundo: #e1f0e4;
    --cor-atencao: #a36f00;
    --cor-atencao-texto: #6b4800;
    --cor-atencao-fundo: #fcf0d2;
    --cor-erro: #9a2424;
    --cor-erro-indicador: #c0392b;
    --cor-erro-fundo: #fbe3e3;
    --cor-progresso-fundo: #dfe5e8;
    --cor-imagem-fundo: #000000;
    --cor-vazio-borda: #8a959c;
    --cor-modal-fundo: rgba(0, 0, 0, .45);
    --cor-sombra: rgba(27, 42, 51, .08);
    --cor-sombra-forte: rgba(27, 42, 51, .25);
    --cor-esqueleto: #e3e8eb;
    /* Linhas de alinhamento das prévias do editor: ciano translúcido, visível na pele, no
     * fundo preto do recorte e nos dentes; são guias, sem texto, então dispensam contraste AA. */
    --cor-linha-alinhamento: rgba(0, 200, 235, .8);

    --fonte-familia: system-ui, "Segoe UI", sans-serif;
    --fonte-base: 1rem;
    --fonte-pequena: .9rem;
    --fonte-menor: .85rem;
    --fonte-minima: .7rem;
    --fonte-titulo: 1.5rem;
    --fonte-titulo-editor: 1.15rem;  /* título do editor de recorte no modal, numa linha só */
    --fonte-peso-forte: 600;
    --fonte-altura-linha: 1.45;

    --espaco-1: .25rem;
    --espaco-2: .5rem;
    --espaco-3: .75rem;
    --espaco-4: 1rem;
    --espaco-5: 1.5rem;
    --espaco-6: 2rem;

    --raio-pequeno: .25rem;
    --raio-medio: .5rem;
    --raio-pilula: 999px;

    --borda-largura: 1px;
    --borda: var(--borda-largura) solid var(--cor-borda);
    --borda-controle: var(--borda-largura) solid var(--cor-borda-controle);
    --borda-destaque: .3rem solid var(--cor-ok);
    --borda-vazio: var(--borda-largura) dashed var(--cor-vazio-borda);
    --foco-contorno: 2px solid var(--cor-foco);
    --foco-afastamento: 2px;

    --sombra-cartao: 0 1px 2px var(--cor-sombra);
    --sombra-modal: 0 .5rem 2rem var(--cor-sombra-forte);
    --sombra-flutuante: 0 .25rem 1rem var(--cor-sombra-forte);

    /* Camadas: barra de ações presa, menus abertos e avisos por cima de tudo. */
    --camada-barra: 10;
    --camada-menu: 20;
    --camada-aviso: 30;
    --largura-aviso: 24rem;
    --largura-menu: 14rem;
    --miniatura-historico: 40px;
    --largura-motivo: 28rem;
    --largura-cartao-dia: 16rem;
    --altura-progresso: .375rem;
    /* Carregamento global (carregamento.js): véu da tela inteira e do bloco travado. */
    --cor-carregamento-fundo: rgba(27, 42, 51, .3);
    --cor-carregamento-bloco: rgba(255, 255, 255, .6);
    --tamanho-spinner: 1em;
    --tamanho-spinner-camada: 1.75rem;
    --espessura-spinner: .15em;

    /* Página do paciente: as 8 categorias em três linhas (rosto 3:4, intraorais e oclusais
     * 4:3) cabem em 1440x900 sem rolagem. --reserva-paciente (21rem = 336px) estima o que fica
     * fora das fotos: corpo e topo ~150 + cabeçalho e ações ~44 + alertas numa linha ~26 +
     * margens ~16 + legenda e respiro das três linhas ~3 x 28 + espaço entre linhas ~16.
     * As fotos repartem o resto: rosto 1,25 x a altura intraoral (mesma largura de coluna
     * do template final) + 2 x intraoral = 3,25 partes. Em 900px: intraoral ~173px, rosto
     * ~217px; medido no Chromium a 1440x900, a grade termina ~70px acima do pé da janela
     * (folga para uma segunda linha de alertas). Ajuste se a verificação mostrar rolagem. */
    --reserva-paciente: 21rem;
    --altura-quadro-intraoral: clamp(6rem, calc((100vh - var(--reserva-paciente)) / 3.25), 22rem);
    --altura-quadro-rosto: calc(var(--altura-quadro-intraoral) * 1.25);
    --sombra-sobre-foto: 0 1px 3px var(--cor-sombra-forte);

    /* Conferência em etapas (docs/WEBAPP.md, "Fluxo em etapas"): cada etapa de fotos mostra uma
     * linha só, grande e sem rolagem. --reserva-etapa (32rem = 512px) estima o que fica fora das
     * fotos: corpo e topo ~150 + cabeçalho ~44 + alertas ~26 + barra de etapas ~56 + aviso de
     * pendências ~56 + legenda ~28 + Voltar/Próxima ~56 + barra de conferência ~64 + margens ~32.
     * --reserva-lateral-etapa (20rem) é o rótulo do grupo, o "Desfazer" e o respiro do corpo.
     * A largura de cada quadro é a menor entre a altura disponível (na proporção da categoria)
     * e a sua parte da largura da linha. */
    --reserva-etapa: 32rem;
    --reserva-lateral-etapa: 20rem;
    --altura-etapa: clamp(10rem, calc(100vh - var(--reserva-etapa)), 48rem);
    --largura-etapa: calc(min(100vw, var(--largura-maxima)) - var(--reserva-lateral-etapa));
    /* Etapa 4: a grade 2 x 4 com o fluxo em volta; a conta é a de --template-coluna. */
    --reserva-template-etapa: 30rem;

    /* Template do paciente: a grade 2 x 4 cabe sem rolagem a partir de 1366x768.
     * --reserva-template (19rem = 304px) é a altura fora da grade: respiro do corpo 24+24 +
     * topo ~70 e margem 16 + respiro do main 16+16 e margem 16 + barra de ações ~63 e margem 16
     * + respiro da grade 16+16. --reserva-lateral-template (7rem) é o mesmo na largura: corpo
     * 24+24 + main 16+16 + grade 16+16. Não há rodapé; o pé da página é o respiro do corpo. */
    --reserva-template: 19rem;
    --reserva-lateral-template: 7rem;
    --espaco-template: var(--espaco-2);
    /* Largura w das colunas da grade 2 x 4 (a conta está na regra .template). */
    --template-coluna: min(calc((100vh - var(--reserva-template) - var(--espaco-template)) * 12 / 25),
        calc((min(100vw, var(--largura-maxima)) - var(--reserva-lateral-template) - 3 * var(--espaco-template)) / 4));
    --template-coluna-oclusal: var(--template-coluna);

    /* Painel "Todas as fotos": à direita, por cima da grade e abaixo dos menus abertos. */
    --largura-painel-revisao: 40vw;
    --miniatura-revisao: 7rem;
    /* Etapa Extras: miniaturas em grade, 8 por linha a 1440 px (coluna mínima de 9rem com o
     * espaço-2 entre elas); 36 fotos ficam em cerca de duas telas. */
    --miniatura-extras: 9rem;
    --camada-painel: 15;
    --duracao-painel: .2s;

    /* Modais Trocar foto, Revisar foto e Trocar categoria: quadros de altura fixa (trocar a
     * opção não faz a tela pular), proporção do esqueleto enquanto a foto grande carrega,
     * miniaturas da tira e a coluna do formulário do Revisar. Em 1440x900 o Trocar foto cabe
     * no modal (92vh): título ~60 + quadros 46vh (~414) + legenda ~24 + tira ~130 + rodapé ~60. */
    --altura-foto-modal: 46vh;
    --altura-foto-revisao: 60vh;
    --proporcao-retrato: 3 / 4;
    --proporcao-paisagem: 4 / 3;
    --miniatura-troca: 5.5rem;
    --borda-selecao-largura: .2rem;
    --largura-coluna-revisao: 24rem;
    --alvo-galeria: 44px;  /* área mínima de clique das setas */
    --meio-galeria: 50%;

    /* Telas de formulário: coluna do título das seções, campo compacto e cartão do login. */
    --largura-texto-secao: 18rem;
    --largura-campo-compacto: 14rem;
    --largura-login: 24rem;

    /* Figuras sintéticas do padrão de enquadramento (desenho nosso, sem foto). */
    --largura-figura-enquadramento: 18rem;
    --altura-figura-enquadramento: 9rem;
    --altura-figura-enquadramento-compacta: 7rem;
    --largura-campo-zoom: 5rem;
    /* Miniaturas dos presets do template A4 (folhas do motor, quadros cinza, sem foto). */
    --altura-miniatura-paisagem: 5.5rem;
    --altura-miniatura-retrato: 7rem;
    --tamanho-seta: 2.25rem;
    --cor-figura-fundo: #dfe7ec;
    --cor-figura-pele: #e8c2a0;
    --cor-figura-pele-sombra: #d4a982;
    --cor-figura-cabelo: #5b4636;
    --cor-figura-roupa: #7d93a6;
    --cor-figura-traco: #3a2c22;
    --cor-figura-labio: #c97b7b;
    --cor-figura-boca: #5a2a2a;
    --cor-figura-gengiva: #e59a9a;
    --cor-figura-palato: #d98a8a;
    --cor-figura-dente: #fbf8f0;
    --cor-quadro-recorte: #1d5a85;
    --cor-fora-recorte: rgba(27, 42, 51, .45);
    --cor-nariz: #9a2424;

    /* Somente computador: abaixo disso a página rola na horizontal. */
    --largura-minima: 1280px;
    --largura-maxima: 96rem;
}

/* Base e layout de computador (sem layout de celular). */
body {font: var(--fonte-base)/var(--fonte-altura-linha) var(--fonte-familia); color: var(--cor-texto);
    background: var(--cor-fundo); box-sizing: border-box; min-width: var(--largura-minima);
    max-width: var(--largura-maxima); margin: auto; padding: var(--espaco-5);}
header, article, main {background: var(--cor-superficie); padding: var(--espaco-4); margin-bottom: var(--espaco-4);
    border-radius: var(--raio-medio); box-shadow: var(--sombra-cartao);}
a {color: var(--cor-primaria);} a:hover {color: var(--cor-primaria-hover);}
:focus-visible {outline: var(--foco-contorno); outline-offset: var(--foco-afastamento);}
label {display: block;}
input, select, textarea, button {font: inherit; padding: var(--espaco-2); max-width: 100%;}
input:not([type=checkbox], [type=radio], [type=range]), select, textarea {color: var(--cor-texto);
    background: var(--cor-superficie); border: var(--borda-controle); border-radius: var(--raio-pequeno);}
.errorlist, [role=alert] {color: var(--cor-erro);}
pre {background: var(--cor-superficie-suave); padding: var(--espaco-2); border-radius: var(--raio-pequeno);}

/* Botões: secundário é o padrão de <button> e de .botao; .botao-primario marca a ação principal. */
button, .botao {display: inline-block; padding: var(--espaco-2) var(--espaco-3); cursor: pointer;
    border: var(--borda-controle); border-radius: var(--raio-pequeno); background: var(--cor-secundaria);
    color: var(--cor-texto); text-decoration: none; line-height: inherit;}
button:hover, .botao:hover {background: var(--cor-secundaria-hover); color: var(--cor-texto);}
.botao-primario {background: var(--cor-primaria); border-color: var(--cor-primaria);
    color: var(--cor-texto-primaria); font-weight: var(--fonte-peso-forte);}
.botao-primario:hover:not(:disabled) {background: var(--cor-primaria-hover); border-color: var(--cor-primaria-hover);
    color: var(--cor-texto-primaria);}
button:disabled, .botao[aria-disabled=true] {cursor: not-allowed; background: var(--cor-desabilitado);
    border-color: var(--cor-desabilitado); color: var(--cor-texto-desabilitado); font-weight: normal;}
.botao[aria-disabled=true] {pointer-events: none;}

/* Cartão: superfície com borda discreta. */
.cartao {background: var(--cor-superficie); border: var(--borda); border-radius: var(--raio-medio);
    box-shadow: var(--sombra-cartao); padding: var(--espaco-3);}

/* Semáforo: indicador colorido sempre acompanhado do texto do estado. */
.semaforo {display: inline-flex; align-items: center; gap: var(--espaco-2); font-weight: var(--fonte-peso-forte);
    padding: var(--espaco-1) var(--espaco-2); border-radius: var(--raio-pequeno); border: var(--borda-largura) solid;}
.semaforo-indicador {width: .75em; height: .75em; border-radius: var(--raio-pilula); background: currentColor;}
.semaforo.verde {background: var(--cor-ok-fundo); color: var(--cor-ok-texto); border-color: var(--cor-ok);}
.semaforo.verde .semaforo-indicador {background: var(--cor-ok);}
.semaforo.amarelo {background: var(--cor-atencao-fundo); color: var(--cor-atencao-texto); border-color: var(--cor-atencao);}
.semaforo.amarelo .semaforo-indicador {background: var(--cor-atencao);}
.semaforo.vermelho {background: var(--cor-erro-fundo); color: var(--cor-erro); border-color: var(--cor-erro-indicador);}
.semaforo.vermelho .semaforo-indicador {background: var(--cor-erro-indicador);}
.detalhe-conferido {display: block; font-size: var(--fonte-minima);}
.finalizado {border-left: var(--borda-destaque); padding-left: var(--espaco-3);}

/* Tabelas: cabeçalho em destaque, separadores discretos e zebra leve. */
table {width: 100%; border-collapse: collapse; margin: var(--espaco-2) 0 var(--espaco-4);}
caption {text-align: left; font-weight: var(--fonte-peso-forte); padding-bottom: var(--espaco-2);}
th, td {text-align: left; vertical-align: top; padding: var(--espaco-2) var(--espaco-3); border-bottom: var(--borda);}
thead th {background: var(--cor-secundaria); font-weight: var(--fonte-peso-forte);}
tbody tr:nth-child(even) {background: var(--cor-superficie-suave);}
td ul {margin: var(--espaco-1) 0 0; padding-left: var(--espaco-4);}

/* Motivos do semáforo na lista do dia: até 3 linhas compactas e o resto em <details>, para a
   linha do paciente ficar em cerca de 120 px com ele fechado (docs/WEBAPP.md). */
td ul.motivos {margin: 2px 0 0; padding-left: 0; list-style: none; font-size: 0.875rem; line-height: 1.25;}
td ul.motivos li {white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 32rem;}
.motivos-ocultos {font-size: 0.875rem;}
.motivos-ocultos > summary {cursor: pointer; line-height: 1.25; margin-top: 2px;}
.motivos-ocultos[open] ul.motivos li {white-space: normal; overflow: visible;}

/* Página Versões: uma linha compacta por versão (número, data e títulos), sem espaçamento de seção. */
.versao-linha {margin: 0; padding: 2px 0; font-size: 0.875rem; line-height: 1.25; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; max-width: 100%;}
.versoes-historico {margin-top: var(--espaco-2); font-size: 0.875rem;}
.versoes-historico > summary {cursor: pointer;}

/* Transição suave entre páginas, sem hx-boost: o navegador anima a troca de documento. */
@view-transition { navigation: auto; }

/* Barra superior única: produto, clínica, trilha, administração e usuário. */
.topo { display: flex; align-items: center; gap: var(--espaco-4); flex-wrap: wrap; }
.topo h1 { margin: 0; font-size: var(--fonte-titulo); }
.topo form { margin: 0; }
.topo .clinica { margin: 0; color: var(--cor-texto-suave); font-weight: var(--fonte-peso-forte); }
.topo .marca { color: inherit; text-decoration: none; }
/* O menu do usuário (com Sair) fica no canto superior direito. */
.topo .menu-usuario { margin-left: auto; }
/* Selo de versão: discreto, à direita, antes dos menus; âmbar com a fila à frente, verde em dia. */
.topo .selo-versao { margin-left: auto; white-space: nowrap; }
.topo .selo-versao ~ .menu-usuario { margin-left: 0; }
.selo-versao { margin: 0; padding: var(--espaco-1) var(--espaco-2); border-radius: var(--raio-pilula);
    font-size: var(--fonte-menor); color: var(--cor-texto-suave); background: var(--cor-superficie-suave); }
.selo-atrasado { color: var(--cor-atencao-texto); background: var(--cor-atencao-fundo); }
.selo-em-dia { color: var(--cor-ok-texto); background: var(--cor-ok-fundo); }

/* Trilha: Início > UNIDADE dd/mm/aaaa > Paciente X; o item atual não é link. */
.trilha ol { display: flex; flex-wrap: wrap; align-items: center; gap: var(--espaco-2); list-style: none; margin: 0; padding: 0; }
.trilha li + li::before { content: "›"; margin-right: var(--espaco-2); color: var(--cor-texto-suave); }
.trilha [aria-current=page] { font-weight: var(--fonte-peso-forte); }
/* Voltar (←) à tela pai, antes do primeiro item; não aumenta a altura do cabeçalho. */
.trilha ol { flex-wrap: nowrap; white-space: nowrap; }
.trilha li + li::before { display: inline-block; }
.trilha .trilha-item-voltar + li::before { content: none; }
.trilha-voltar { display: inline-flex; align-items: center; justify-content: center; min-width: 2rem; min-height: 2rem;
    margin: -0.25rem 0; border-radius: var(--raio-pilula); text-decoration: none; font-weight: var(--fonte-peso-forte); line-height: 1; }
.trilha-voltar:hover { background: var(--cor-superficie-suave); }
.trilha-voltar:focus-visible { outline: 2px solid currentColor; outline-offset: 2px; }

/* Menu "Mais ações" (e os menus do topo): <details> com a lista de ações por cima da página.
 * menus.js fecha ao clicar fora e com Esc. */
.menu-mais { position: relative; }
.menu-mais > summary { list-style: none; cursor: pointer; padding: var(--espaco-2) var(--espaco-3);
    border: var(--borda-controle); border-radius: var(--raio-pequeno); background: var(--cor-secundaria); }
.menu-mais > summary::-webkit-details-marker { display: none; }
.menu-mais > summary::after { content: " ▾"; }
.menu-mais > summary:hover { background: var(--cor-secundaria-hover); }
.menu-mais > ul { position: absolute; right: 0; top: calc(100% + var(--espaco-1)); z-index: var(--camada-menu);
    min-width: var(--largura-menu); list-style: none; margin: 0; padding: var(--espaco-2); display: flex;
    flex-direction: column; gap: var(--espaco-1); background: var(--cor-superficie); border: var(--borda);
    border-radius: var(--raio-medio); box-shadow: var(--sombra-flutuante); }
.menu-mais > ul a, .menu-mais > ul button { display: block; width: 100%; box-sizing: border-box; text-align: left;
    padding: var(--espaco-2) var(--espaco-3); border-radius: var(--raio-pequeno); }
.menu-mais > ul a:hover { background: var(--cor-secundaria); }

/* Barra de ações: a ação primária da tela sempre à vista, presa ao pé da janela. */
.barra-acoes { position: sticky; bottom: 0; z-index: var(--camada-barra); display: flex; flex-wrap: wrap;
    align-items: center; gap: var(--espaco-2); padding: var(--espaco-3) 0; background: var(--cor-superficie);
    border-top: var(--borda); }

/* Filtros numa linha só, aplicados ao mudar (hx-get + hx-trigger=change). */
.filtros-linha { display: flex; flex-wrap: nowrap; align-items: flex-end; gap: var(--espaco-3); margin: 0 0 var(--espaco-3); }
.filtros-linha label { display: flex; flex-direction: column; gap: var(--espaco-1); font-size: var(--fonte-pequena); }

/* Chip (rótulo curto, filtro ativo) e contador (número em pílula). */
.chip { display: inline-flex; align-items: center; gap: var(--espaco-1); padding: var(--espaco-1) var(--espaco-3);
    border: var(--borda-controle); border-radius: var(--raio-pilula); background: var(--cor-secundaria);
    color: var(--cor-texto); font-size: var(--fonte-pequena); text-decoration: none; }
.chip[aria-pressed=true], .chip[aria-current] { background: var(--cor-primaria); border-color: var(--cor-primaria);
    color: var(--cor-texto-primaria); }
.contador { display: inline-block; min-width: 1.5em; padding: 0 var(--espaco-2); border-radius: var(--raio-pilula);
    background: var(--cor-secundaria); color: var(--cor-texto); font-size: var(--fonte-menor); text-align: center;
    font-variant-numeric: tabular-nums; }

/* Segmentado: filtro por links lado a lado; o atual leva aria-current. */
.segmentado { display: inline-flex; border: var(--borda-controle); border-radius: var(--raio-pequeno); overflow: hidden; }
.segmentado a { padding: var(--espaco-1) var(--espaco-3); color: var(--cor-texto); text-decoration: none;
    background: var(--cor-superficie); }
.segmentado a + a { border-left: var(--borda-controle); }
.segmentado a:hover { background: var(--cor-secundaria); color: var(--cor-texto); }
.segmentado a[aria-current] { background: var(--cor-primaria); color: var(--cor-texto-primaria);
    font-weight: var(--fonte-peso-forte); }

/* Avisos flutuantes (mensagens do Django), empilhados no canto inferior direito. avisos.js
 * mostra o Fechar e some com eles depois de 6 s, exceto os de erro. */
.avisos-flutuantes { position: fixed; right: var(--espaco-5); bottom: var(--espaco-5); z-index: var(--camada-aviso);
    display: flex; flex-direction: column; gap: var(--espaco-2); width: var(--largura-aviso); }
.aviso-flutuante { display: flex; align-items: flex-start; gap: var(--espaco-2); padding: var(--espaco-3);
    background: var(--cor-superficie); color: var(--cor-texto); border: var(--borda);
    border-left: var(--borda-destaque); border-left-color: var(--cor-primaria); border-radius: var(--raio-medio); box-shadow: var(--sombra-flutuante); }
.aviso-flutuante p { margin: 0; flex: 1; }
.aviso-flutuante.sucesso { border-left-color: var(--cor-ok); }
.aviso-flutuante.atencao { border-left-color: var(--cor-atencao); }
.aviso-flutuante.erro { border-left-color: var(--cor-erro-indicador); color: var(--cor-erro); }
.aviso-fechar { padding: 0 var(--espaco-2); line-height: inherit; background: none; border: 0; }

/* Esqueleto: placeholder com proporção fixa enquanto a imagem ou a região carrega. */
.esqueleto { display: block; width: 100%; aspect-ratio: var(--proporcao, 4 / 3); background: var(--cor-esqueleto);
    border-radius: var(--raio-pequeno); }

/* Tabela densa: mais linhas por tela, para caber o dia sem rolagem. */
.tabela-densa { font-size: var(--fonte-pequena); margin: 0; }
.tabela-densa th, .tabela-densa td { padding: var(--espaco-1) var(--espaco-2); vertical-align: middle; }

/* Histórico de decisões: uma linha por decisão, miniatura de 40 px (40 linhas em duas telas a 1440x900). */
.so-leitor { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.historico-tabela { width: 100%; border-collapse: collapse; background: var(--cor-superficie); }
.historico-tabela th { text-align: left; border-bottom: var(--borda-controle); }
.historico-tabela td { border-bottom: var(--borda); padding-block: 0; height: var(--miniatura-historico); }
.historico-quando { white-space: nowrap; font-variant-numeric: tabular-nums; }
.historico-miniatura { display: inline-flex; }
.historico-miniatura img { display: block; width: var(--miniatura-historico); height: var(--miniatura-historico);
    object-fit: cover; border-radius: var(--raio-pequeno); background: var(--cor-esqueleto); }
.historico-mudou > span { margin-right: var(--espaco-2); }
.historico-motivo { color: var(--cor-texto-suave); }
.historico-detalhes { display: inline-block; vertical-align: middle; font-size: var(--fonte-menor); }
.historico-detalhes summary { cursor: pointer; color: var(--cor-primaria); }
.historico-detalhes pre { margin: 0; max-width: var(--largura-motivo); overflow-x: auto; white-space: pre-wrap;
    background: var(--cor-superficie-suave); padding: var(--espaco-2); border-radius: var(--raio-pequeno); }
.paginacao { display: flex; align-items: center; gap: var(--espaco-3); margin-top: var(--espaco-3); }
.paginacao [aria-current] { font-weight: var(--fonte-peso-forte); }

.foto-confirmacao { max-width: 100%; max-height: 60vh; }

/* Trocar foto: a escolhida à esquerda e a opção selecionada à direita, do mesmo tamanho. */
.troca-foto { --proporcao: var(--proporcao-paisagem); }
.troca-foto.retrato { --proporcao: var(--proporcao-retrato); }
.comparacao-fotos { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--espaco-4); }
.comparacao-fotos h3 { margin: 0 0 var(--espaco-2); font-size: var(--fonte-base); }
.foto-grande { margin: 0; display: flex; flex-direction: column; gap: var(--espaco-1); }
.legenda-confianca { font-size: var(--fonte-menor); color: var(--cor-texto-suave); }
.contador-galeria { text-align: center; font-size: var(--fonte-menor); color: var(--cor-texto-suave);
    font-variant-numeric: tabular-nums; }
.seta-galeria { position: absolute; top: var(--meio-galeria); transform: translateY(calc(-1 * var(--meio-galeria)));
    min-width: var(--alvo-galeria); min-height: var(--alvo-galeria); padding: var(--espaco-2);
    background: var(--cor-secundaria); color: var(--cor-texto); font-size: var(--fonte-menor); }
.seta-galeria[hidden] { display: none; }
.seta-galeria.anterior { left: var(--espaco-2); }
.seta-galeria.proxima { right: var(--espaco-2); }
.seta-galeria:disabled { background: var(--cor-desabilitado); color: var(--cor-texto-desabilitado); cursor: default; }
.seta-galeria:focus-visible, [data-carrossel]:focus-visible { outline: var(--foco-contorno);
    outline-offset: calc(-1 * var(--foco-afastamento)); }
/* Quadro de altura fixa: trocar de foto só troca o conteúdo, sem a tela pular. O esqueleto
 * fica por baixo com a proporção da foto até ela carregar (paciente_modais.js o esconde). */
.quadro-foto { position: relative; height: var(--altura-foto-modal); background: var(--cor-fundo);
    border-radius: var(--raio-pequeno); display: flex; align-items: center; justify-content: center; overflow: hidden; }
.quadro-foto > .esqueleto { position: absolute; width: auto; height: 100%; max-width: 100%; }
.quadro-foto > .esqueleto[hidden] { display: none; }
.quadro-foto > img { position: relative; max-width: 100%; max-height: 100%; object-fit: contain; }
.quadro-foto > p { margin: 0; padding: var(--espaco-3); text-align: center; color: var(--cor-texto-suave); }
/* Tira com todas as outras fotos da categoria; a selecionada leva borda e o selo "Selecionada". */
.tira-miniaturas { margin-top: var(--espaco-3); }
.tira-miniaturas .dica-atalhos { margin: 0 0 var(--espaco-2); font-size: var(--fonte-menor); color: var(--cor-texto-suave); }
.tira-miniaturas ul { list-style: none; margin: 0; padding: var(--espaco-1); display: flex; flex-wrap: wrap; gap: var(--espaco-2); }
.miniatura-troca { position: relative; display: flex; flex-direction: column; align-items: center; gap: var(--espaco-1);
    padding: var(--espaco-1); border: var(--borda-controle); border-radius: var(--raio-pequeno);
    background: var(--cor-superficie); color: var(--cor-texto); text-decoration: none; }
.miniatura-troca:hover { background: var(--cor-secundaria); color: var(--cor-texto); }
.miniatura-troca img { display: block; height: var(--miniatura-troca); width: auto; aspect-ratio: var(--proporcao);
    object-fit: contain; background: var(--cor-esqueleto); border-radius: var(--raio-pequeno); }
.miniatura-troca[aria-current=true] { border-color: var(--cor-primaria);
    box-shadow: 0 0 0 var(--borda-selecao-largura) var(--cor-primaria); }
.miniatura-troca[aria-current=true]::before { content: "Selecionada"; position: absolute; top: var(--espaco-1);
    left: var(--espaco-1); padding: 0 var(--espaco-1); border-radius: var(--raio-pequeno); background: var(--cor-primaria);
    color: var(--cor-texto-primaria); font-size: var(--fonte-minima); }
.legenda-miniatura { font-size: var(--fonte-minima); color: var(--cor-texto-suave); font-variant-numeric: tabular-nums; }
/* "O OCR leu:": leituras sugeridas ao lado do campo de OS (leituras_ocr.js). */
.leituras-ocr { display: flex; flex-wrap: wrap; align-items: center; gap: var(--espaco-1); }
.leituras-ocr[hidden], .leituras-ocr [hidden] { display: none; }

.alertas a { white-space: nowrap; }

/* Todas as fotos para revisão: uma grade por categoria. */
.grupo-revisao h4 { margin: var(--espaco-4) 0 var(--espaco-2); }
.grade-revisao { list-style: none; padding: 0; margin: 0; display: grid; gap: var(--espaco-3);
    grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr)); }
.item-revisao { padding: var(--espaco-2); display: flex; flex-direction: column; gap: var(--espaco-2); }
.item-revisao p { margin: 0; font-size: var(--fonte-pequena); }
.miniatura-revisao { height: 9rem; background: var(--cor-fundo); display: flex; align-items: center; justify-content: center; }
.miniatura-revisao img { max-width: 100%; max-height: 100%; object-fit: contain; }

/* Separar fotos do paciente sem OS: o Shift + clique não seleciona o texto. */
.selecao-fotos .item-revisao label { display: flex; flex-direction: column; gap: var(--espaco-2); user-select: none; cursor: pointer; }
/* Fotos sem paciente do dia: legenda com o nome da câmera abaixo da miniatura. */
.legenda-foto { font-size: var(--fonte-pequena); color: var(--cor-texto-suave); overflow-wrap: anywhere; }
.foto-ampliada { margin: 0; display: flex; flex-direction: column; align-items: center; gap: var(--espaco-2); }
.foto-ampliada img { max-width: 100%; max-height: 74vh; object-fit: contain; background: var(--cor-imagem-fundo); }
.foto-ampliada figcaption { font-size: var(--fonte-pequena); color: var(--cor-texto-suave); }

/* Revisar foto (modal e página da foto): foto grande à esquerda e, à direita, o formulário
 * em coluna (categoria, paciente, motivo). */
.revisao-lado-a-lado { display: grid; grid-template-columns: minmax(0, 1fr) var(--largura-coluna-revisao);
    gap: var(--espaco-4); align-items: start; }
.revisao-lado-a-lado .quadro-revisao { height: var(--altura-foto-revisao); }
.coluna-revisao { display: flex; flex-direction: column; gap: var(--espaco-2); min-width: 0; }
.coluna-revisao p { margin: 0; font-size: var(--fonte-pequena); }
.campos-revisao { display: flex; flex-direction: column; gap: var(--espaco-3); margin: var(--espaco-2) 0; }
.campos-revisao select, .campos-revisao textarea { width: 100%; box-sizing: border-box; }
.campo-categoria [hidden] { display: none; }
/* Botões de categoria agrupados (Rosto, Intraorais, Oclusais, Outros). No Trocar categoria
 * cada um é um <label> com o radio real; no Revisar, um <button aria-pressed> ligado ao
 * <select>. A seleção traz o radio marcado ou o "✓", nunca só a cor. */
.grupos-categoria, .grupo-categoria { border: 0; margin: 0; padding: 0; min-width: 0; }
.grupos-categoria { display: flex; flex-direction: column; gap: var(--espaco-2); }
.grupos-categoria > legend { padding: 0; margin-bottom: var(--espaco-1); font-weight: var(--fonte-peso-forte); }
.grupo-categoria > legend { padding: 0; margin-bottom: var(--espaco-1); font-size: var(--fonte-menor); color: var(--cor-texto-suave); }
.botoes-grupo { display: flex; flex-wrap: wrap; gap: var(--espaco-1); }
.opcao-categoria { display: inline-flex; align-items: center; gap: var(--espaco-1); padding: var(--espaco-1) var(--espaco-2);
    border: var(--borda-controle); border-radius: var(--raio-pequeno); background: var(--cor-secundaria);
    color: var(--cor-texto); font-size: var(--fonte-pequena); cursor: pointer; }
.opcao-categoria:hover { background: var(--cor-secundaria-hover); color: var(--cor-texto); }
.opcao-categoria input { margin: 0; }
.opcao-categoria:has(input:checked), .opcao-categoria[aria-pressed=true] { background: var(--cor-primaria);
    border-color: var(--cor-primaria); color: var(--cor-texto-primaria); }
.opcao-categoria:has(input:checked):hover, .opcao-categoria[aria-pressed=true]:hover { background: var(--cor-primaria-hover);
    color: var(--cor-texto-primaria); }
.opcao-categoria[aria-pressed=true]::before { content: "✓"; }
.opcao-categoria:has(input:focus-visible) { outline: var(--foco-contorno); outline-offset: var(--foco-afastamento); }
.opcao-categoria:has(input:disabled) { cursor: not-allowed; }
.outras-categorias > summary { cursor: pointer; padding: var(--espaco-1) 0; color: var(--cor-primaria); }
.outras-categorias[open] > summary { margin-bottom: var(--espaco-1); }
.outras-categorias > .grupo-categoria + .grupo-categoria { margin-top: var(--espaco-2); }
/* O motivo cresce com o texto até 4 linhas; depois, rolagem vertical. */
textarea[data-crescer] { field-sizing: content; box-sizing: border-box; resize: none; overflow-y: auto;
    min-height: calc(1lh + 1rem + 2px); max-height: calc(4lh + 1rem + 2px); }

/* Página do paciente (docs/WEBAPP.md): cabeçalho e ações numa linha, alertas curtos logo
 * abaixo e a grade única das 8 categorias no formato do template final. */
.topo-paciente { display: flex; align-items: center; justify-content: space-between; gap: var(--espaco-3);
    margin-bottom: var(--espaco-2); }
.cabecalho-paciente { display: flex; align-items: center; flex-wrap: wrap; gap: var(--espaco-2) var(--espaco-3); min-width: 0; }
.cabecalho-paciente h2 { margin: 0; font-size: var(--fonte-titulo); }
.cabecalho-paciente p { margin: 0; }
.cabecalho-paciente .chip { border-color: var(--cor-borda); }
.cabecalho-paciente .chip-alerta { background: var(--cor-erro-fundo); color: var(--cor-erro); border-color: var(--cor-erro-indicador); }
/* Chip da documentação: "Documentação de 8 incompleta: falta ..." pode ser longo e quebra linha. */
.cabecalho-paciente #chip-documentacao { max-width: 100%; white-space: normal; overflow-wrap: anywhere; }
.estado-conferencia { color: var(--cor-texto-suave); font-size: var(--fonte-pequena); }
/* Menu "Mais ações" no topo; a conferência fica na barra presa ao pé (.barra-conferencia).
 * Quebra linha para não estourar a largura em 1280px. */
.barra-paciente { position: static; flex-wrap: wrap; padding: 0; border-top: 0; background: none; }
.barra-paciente form, .barra-paciente p { margin: 0; }
.barra-paciente p { font-size: var(--fonte-pequena); }
.menu-mais > ul form { margin: 0; }
/* Barra de conferência: anterior, posição e próximo, presa ao pé da janela, em todas as etapas. */
.barra-conferencia { justify-content: center; gap: var(--espaco-4); margin-top: var(--espaco-4);
    padding: var(--espaco-3) var(--espaco-4); background: var(--cor-superficie); border: var(--borda);
    box-shadow: var(--sombra-cartao); }
.barra-conferencia form { margin: 0; }
.barra-conferencia .botao { text-decoration: none; }
.barra-conferencia .conferencia-desabilitado { cursor: not-allowed; background: var(--cor-desabilitado);
    color: var(--cor-texto-desabilitado); border-color: var(--cor-borda); }
.barra-conferencia a:focus-visible, .barra-conferencia button:focus-visible {
    outline: var(--foco-contorno); outline-offset: var(--foco-afastamento); }
.posicao-conferencia { min-width: 5rem; text-align: center; font-variant-numeric: tabular-nums;
    font-weight: var(--fonte-peso-forte); color: var(--cor-texto); }
.alertas-paciente { display: flex; flex-wrap: wrap; gap: 0 var(--espaco-5); margin: 0 0 var(--espaco-2);
    padding-left: 0; list-style: disc inside; font-size: var(--fonte-pequena); }
.alertas-paciente li { display: list-item; }
.informar-os, .selecao-fotos { margin-bottom: var(--espaco-3); }

/* Grade única: duas colunas (rótulo do grupo e fichas). Cada <section> some do layout
 * (display: contents) e vira uma linha; as fichas da linha ficam centralizadas, então as
 * oclusais (mesma altura e proporção das intraorais) ficam com a largura de um quadro
 * intraoral, centradas abaixo deles. */
.grade-paciente { display: grid; grid-template-columns: max-content minmax(0, 1fr) max-content; align-items: center;
    gap: var(--espaco-2) var(--espaco-3); margin-bottom: var(--espaco-3); }
.grupo-escala { display: contents; }
.grupo-escala > h3 { margin: 0; font-size: var(--fonte-pequena); color: var(--cor-texto-suave); text-align: right; }
/* Terceira coluna: "Desfazer alterações do grupo", um botão por grupo de zoom da linha. */
.desfazer-grupo { display: flex; flex-direction: column; gap: var(--espaco-1); }
.grupo-sem-posicao { color: var(--cor-texto-suave); font-size: var(--fonte-menor); }
.categorias-paciente { list-style: none; padding: 0; margin: 0; display: flex; justify-content: center;
    gap: var(--espaco-3); }
.categoria-paciente { --proporcao: 4 / 3; display: flex; flex-direction: column; gap: var(--espaco-1);
    padding: var(--espaco-1); width: calc(var(--altura-quadro-intraoral) * 4 / 3); box-sizing: content-box; }
.grupo-escala[data-grupo=rosto] .categoria-paciente { --proporcao: 3 / 4; width: calc(var(--altura-quadro-rosto) * 3 / 4); }
/* O quadro tem a proporção do recorte e a foto o preenche; o esqueleto fica por baixo
 * até a imagem chegar. */
.quadro-categoria { position: relative; width: 100%; aspect-ratio: var(--proporcao);
    border-radius: var(--raio-pequeno); overflow: hidden; background: var(--cor-fundo); }
.quadro-categoria > .esqueleto { position: absolute; inset: 0; height: 100%; aspect-ratio: auto; }
.quadro-categoria img { position: relative; display: block; width: 100%; height: 100%; object-fit: cover; }
.foto-editavel { display: block; width: 100%; height: 100%; cursor: zoom-in; }
.quadro-categoria.vazio { display: flex; align-items: center; justify-content: center; border: var(--borda-vazio);
    box-sizing: border-box; background: var(--cor-superficie-suave); }
.sem-foto { margin: 0 0 var(--espaco-6); padding: 0 var(--espaco-2); text-align: center; font-size: var(--fonte-menor);
    color: var(--cor-texto-suave); }
/* Trocar foto e Editar recorte: botões compactos sobre a foto. Aparecem no hover e no foco
 * do cartão; com opacity (não display) o Tab continua chegando neles e os revela. */
.acoes-foto { position: absolute; left: var(--espaco-1); right: var(--espaco-1); bottom: var(--espaco-1);
    justify-content: center; gap: var(--espaco-1); opacity: 0; transition: opacity .15s; }
.categoria-paciente:hover .acoes-foto, .categoria-paciente:focus-within .acoes-foto,
.quadro-categoria.vazio .acoes-foto { opacity: 1; }
.acoes-foto .botao, .acoes-foto button { padding: 0 var(--espaco-2); font-size: var(--fonte-menor);
    box-shadow: var(--sombra-sobre-foto); }
.acoes-foto button:disabled { background: var(--cor-desabilitado); }
/* Conferência em etapas: barra dinâmica (atual destacada, contagem e pendências), aviso
 * não bloqueante das pendências e Voltar/Próxima (ou Finalizar, só no template). */
.fluxo-paciente { display: flex; flex-direction: column; gap: var(--espaco-2); margin-bottom: var(--espaco-3); }
.barra-etapas ol { display: flex; flex-wrap: wrap; gap: var(--espaco-2); list-style: none;
    margin: 0; padding: 0; }
.barra-etapas li { flex: 1 1 12rem; }
.passo-etapa { display: flex; flex-wrap: wrap; align-items: center; gap: var(--espaco-1) var(--espaco-2);
    padding: var(--espaco-2) var(--espaco-3); border: var(--borda); border-radius: var(--raio-medio);
    background: var(--cor-superficie); color: var(--cor-texto); text-decoration: none; font-size: var(--fonte-pequena); }
.passo-etapa:hover { background: var(--cor-secundaria); }
.passo-etapa:focus-visible { outline: var(--foco-contorno); outline-offset: var(--foco-afastamento); }
.passo-etapa.atual { border-color: var(--cor-primaria); background: var(--cor-primaria); color: var(--cor-texto-primaria); }
.numero-etapa { display: inline-flex; align-items: center; justify-content: center; width: 1.6rem; height: 1.6rem;
    border-radius: var(--raio-pilula); border: var(--borda-controle); font-weight: var(--fonte-peso-forte); }
.passo-etapa.atual .numero-etapa { border-color: var(--cor-texto-primaria); }
/* Estados (views.estados_etapas), combináveis: verde = sem pendência, cinza = pendência em etapa
 * anterior, destaque = etapa aberta. O cinza só parece desabilitado: continua clicável. Completa
 * e cinza juntos ficam verdes e esmaecidos; o destaque vence os dois. */
.passo-etapa.estado-completa { border-color: var(--cor-ok); background: var(--cor-ok-fundo); color: var(--cor-ok-texto); }
.passo-etapa.estado-cinza { opacity: .55; }
.passo-etapa.estado-cinza:not(.estado-completa):not(.atual) { background: var(--cor-desabilitado); }
.passo-etapa.estado-cinza:hover, .passo-etapa.estado-cinza:focus-visible { opacity: 1; }
.passo-etapa.estado-atual { opacity: 1; border-color: var(--cor-atencao); border-width: .15rem; font-weight: var(--fonte-peso-forte); }
/* Etapa aberta (atual) em cada combinação: sem pendência fica clara com texto escuro; com pendência
 * (cinza) mantém o fundo escuro da etapa atual com texto claro, nunca o fundo claro do cinza. */
.passo-etapa.atual.estado-completa { background: var(--cor-ok-fundo); color: var(--cor-ok-texto); }
.passo-etapa.atual.estado-completa .numero-etapa { border-color: var(--cor-ok-texto); }
/* Seletor de arquivo nativo escondido: o rótulo em português (label for) abre o seletor e segue focável. */
.input-oculto { position: absolute; width: 1px; height: 1px; opacity: 0; overflow: hidden; }
.campo-compacto:focus-within .botao { outline: var(--foco-contorno); outline-offset: var(--foco-afastamento); }
.ver-tudo-acao, .ver-tudo-topo { margin: var(--espaco-2) 0 0; }
.nome-etapa { font-weight: var(--fonte-peso-forte); }
.contagem-etapa { font-variant-numeric: tabular-nums; }
.chip-pendencias { background: var(--cor-atencao-fundo); color: var(--cor-atencao-texto); border-color: var(--cor-atencao); }
.chip-sem-pendencias { background: var(--cor-ok-fundo); color: var(--cor-ok-texto); border-color: var(--cor-ok); }
.aviso-pendencias { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 var(--espaco-3);
    padding: var(--espaco-2) var(--espaco-3); border-left: .3rem solid var(--cor-atencao);
    background: var(--cor-atencao-fundo); color: var(--cor-atencao-texto); font-size: var(--fonte-pequena); }
.aviso-pendencias p { margin: 0; }
.aviso-pendencias ul { display: flex; flex-wrap: wrap; gap: 0 var(--espaco-4); margin: 0; padding-left: 0;
    list-style: disc inside; }
.navegacao-etapas { display: flex; align-items: center; justify-content: space-between; gap: var(--espaco-3); }
.navegacao-etapas .botao { text-decoration: none; }
.navegacao-etapas form, .navegacao-etapas p { margin: 0; }
.navegacao-etapas:has(.acoes-finalizacao) { flex-wrap: wrap; }
.acoes-finalizacao { display: grid; gap: var(--espaco-3); max-width: 100%; }
.acoes-finalizacao textarea { width: 100%; box-sizing: border-box; }
.navegacao-etapas .conferencia-desabilitado { cursor: not-allowed; background: var(--cor-desabilitado);
    color: var(--cor-texto-desabilitado); border-color: var(--cor-borda); }
.posicao-etapa { color: var(--cor-texto-suave); font-size: var(--fonte-pequena); font-variant-numeric: tabular-nums; }
/* Fotos grandes: o quadro tem a proporção do recorte e a foto inteira aparece (contain). */
.fluxo-paciente .grade-paciente { margin-bottom: 0; }
.fluxo-paciente .categoria-paciente { width: min(calc(var(--altura-etapa) * 4 / 3),
    calc((var(--largura-etapa) - 2 * var(--espaco-3)) / 3)); }
.fluxo-paciente[data-etapa-slug="extraorais"] .categoria-paciente { width: min(calc(var(--altura-etapa) * 3 / 4),
    calc((var(--largura-etapa) - 2 * var(--espaco-3)) / 3)); }
.fluxo-paciente[data-etapa-slug="oclusais"] .categoria-paciente { width: min(calc(var(--altura-etapa) * 4 / 3),
    calc((var(--largura-etapa) - var(--espaco-3)) / 2)); }
.fluxo-paciente .quadro-categoria { background: var(--cor-imagem-fundo); }
.fluxo-paciente .quadro-categoria.vazio { background: var(--cor-superficie-suave); }
.fluxo-paciente .quadro-categoria img { object-fit: contain; }
.fluxo-paciente .template { --template-coluna: min(calc((100vh - var(--reserva-template-etapa) - var(--espaco-template)) * 12 / 25),
        calc((min(100vw, var(--largura-maxima)) - var(--reserva-lateral-template) - 3 * var(--espaco-template)) / 4));
    --template-coluna-oclusal: var(--template-coluna); }
/* Legenda em uma linha: nome curto, estado do recorte e o chip "+N outras". */
.legenda-categoria { display: flex; align-items: center; gap: var(--espaco-1); margin: 0; min-width: 0;
    font-size: var(--fonte-menor); white-space: nowrap; }
/* O nome não encolhe; se faltar espaço, o estado do recorte é que ganha reticências. */
.nome-categoria { flex: 0 0 auto; font-weight: var(--fonte-peso-forte); }
.estado-recorte { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; text-align: right;
    color: var(--cor-texto-suave); }
/* Recorte ao vivo: selo enquanto o worker recorta e, com falha, o erro e "Tentar de novo". */
.estado-recorte.recortando { color: var(--cor-atencao-texto); font-weight: var(--fonte-peso-forte); }
.erro-recorte { margin: var(--espaco-1) 0 0; font-size: var(--fonte-menor); color: var(--cor-erro); white-space: normal; }
.tentar-recorte button { font-size: var(--fonte-menor); }
.chip-outras { flex: 0 0 auto; padding: 0 var(--espaco-2); font-size: var(--fonte-minima); border-color: var(--cor-borda); }

/* Painel "Todas as fotos": sem JavaScript é uma seção no fim da página; com a classe
 * js-painel no <html> (paciente_modais.js) vira um painel fixo à direita, fechado até
 * ganhar a classe aberto. visibility tira o painel fechado da ordem do Tab. */
.painel-revisao { margin-top: var(--espaco-4); }
.painel-topo { display: flex; align-items: center; justify-content: space-between; gap: var(--espaco-3); }
.painel-topo h3 { margin: 0; }
.painel-revisao > p { margin: var(--espaco-2) 0; font-size: var(--fonte-pequena); }
.painel-dica { color: var(--cor-texto-suave); }
.js-painel .painel-revisao { position: fixed; top: 0; right: 0; bottom: 0; z-index: var(--camada-painel);
    width: var(--largura-painel-revisao); box-sizing: border-box; margin: 0; padding: 0 var(--espaco-4) var(--espaco-4);
    overflow-y: auto; background: var(--cor-superficie); border-left: var(--borda); box-shadow: var(--sombra-modal);
    transform: translateX(100%); visibility: hidden;
    transition: transform var(--duracao-painel), visibility var(--duracao-painel); }
.js-painel .painel-revisao.aberto { transform: none; visibility: visible; }
/* O próprio aside rola; o cabeçalho cobre toda a largura, inclusive o recuo lateral. */
.js-painel .painel-cabecalho { position: sticky; top: 0; z-index: 1; background: var(--cor-superficie);
    margin: 0 calc(-1 * var(--espaco-4)); padding: var(--espaco-4); }
/* Grupos por categoria lado a lado; cada um quebra as próprias miniaturas em linhas. */
.grupos-revisao { display: flex; flex-wrap: wrap; align-items: flex-start; gap: var(--espaco-3) var(--espaco-5); }
.painel-revisao .grupo-revisao h4 { margin: var(--espaco-2) 0; font-size: var(--fonte-pequena); }
.painel-revisao .grade-revisao { display: flex; flex-wrap: wrap; gap: var(--espaco-2); }
.painel-revisao .item-revisao { width: var(--miniatura-revisao); padding: var(--espaco-1); gap: var(--espaco-1); }
.painel-revisao .item-revisao p { font-size: var(--fonte-menor); }
/* Placeholder de proporção fixa: a miniatura em data-src chega sem a tela pular. */
.painel-revisao .miniatura-revisao { width: 100%; height: auto; aspect-ratio: 4 / 3; background: var(--cor-esqueleto);
    border-radius: var(--raio-pequeno); overflow: hidden; }
.legenda-revisao { display: flex; flex-wrap: wrap; align-items: center; gap: var(--espaco-1); }
.painel-revisao .chip { padding: 0 var(--espaco-2); font-size: var(--fonte-minima); border-color: var(--cor-borda); }
.painel-revisao .origem { color: var(--cor-texto-suave); overflow-wrap: anywhere; }
/* Escolhida: borda verde e o chip "Escolhida" (a cor nunca vem sozinha). */
.item-revisao.escolhida { border-color: var(--cor-ok); box-shadow: inset 0 0 0 var(--borda-largura) var(--cor-ok); }
.painel-revisao .chip-escolhida { background: var(--cor-ok-fundo); color: var(--cor-ok-texto); border-color: var(--cor-ok); }
.acao-compacta { padding: 0 var(--espaco-2); font-size: var(--fonte-menor); text-align: center; }

/* Etapa Extras em lote: por categoria, ações presas no topo do grupo e a grade de miniaturas
 * com a caixa de seleção no canto (o resto da miniatura abre o modal de revisão). */
.grupo-extras + .grupo-extras { margin-top: var(--espaco-3); }
.grupo-extras form { margin: 0; }
.acoes-grupo-extras { position: sticky; top: 0; z-index: 1; display: flex; flex-wrap: wrap; align-items: center;
    gap: var(--espaco-2); padding: var(--espaco-2) 0; background: var(--cor-superficie); }
.acoes-grupo-extras h4 { margin: 0 var(--espaco-2) 0 0; }
.troca-extras { display: inline-flex; align-items: center; gap: var(--espaco-1); }
/* No painel estreito, as ações rolam com as fotos e o seletor quebra linha. */
.painel-revisao .acoes-grupo-extras { position: static; }
.painel-revisao .troca-extras { flex-wrap: wrap; max-width: 100%; }
.painel-revisao .troca-extras select { min-width: 0; max-width: 100%; }
.grade-extras { list-style: none; padding: 0; margin: 0; display: grid; gap: var(--espaco-2);
    grid-template-columns: repeat(auto-fill, minmax(var(--miniatura-extras), 1fr)); }
.miniatura-extra { position: relative; }
.miniatura-extra .miniatura-revisao { height: auto; aspect-ratio: 4 / 3; background: var(--cor-esqueleto);
    border-radius: var(--raio-pequeno); overflow: hidden; }
.caixa-extra { position: absolute; top: var(--espaco-1); left: var(--espaco-1); z-index: 1; display: flex;
    padding: var(--espaco-1); background: var(--cor-superficie); border-radius: var(--raio-pequeno);
    box-shadow: var(--sombra-sobre-foto); cursor: pointer; user-select: none; }
.miniatura-extra:has(:checked) .miniatura-revisao { box-shadow: 0 0 0 var(--borda-selecao-largura) var(--cor-primaria); }
.miniatura-extra .chip { position: absolute; right: var(--espaco-1); bottom: var(--espaco-1); padding: 0 var(--espaco-2);
    font-size: var(--fonte-minima); background: var(--cor-atencao-fundo); color: var(--cor-atencao-texto);
    border-color: var(--cor-atencao); }

/* Erros do dia (sempre recolhida ao abrir a página do dia). */
.erros-do-dia > summary { cursor: pointer; font-weight: var(--fonte-peso-forte); padding: var(--espaco-2) 0; }
.acoes { display: flex; flex-wrap: wrap; gap: var(--espaco-2); align-items: center; }

/* Modal: fundo escurecido, cabeçalho com o título e rodapé com as ações. */
dialog.modal { width: min(64rem, 94vw); max-height: 92vh; border: 0; border-radius: var(--raio-medio);
    padding: var(--espaco-4) var(--espaco-5); background: var(--cor-superficie); color: var(--cor-texto);
    box-shadow: var(--sombra-modal); }
dialog.modal::backdrop { background: var(--cor-modal-fundo); }
dialog.modal-editor { width: 90vw; height: 90vh; height: 90dvh; max-width: none; max-height: 90vh; max-height: 90dvh;
    overflow: hidden; box-sizing: border-box; }
dialog.modal-editor[open] { display: flex; flex-direction: column; }
dialog.modal-editor #modal-conteudo { flex: 1 1 auto; min-height: 0; height: 100%; overflow: hidden; }
#modal-titulo { margin: 0 0 var(--espaco-3); padding-bottom: var(--espaco-3); border-bottom: var(--borda);
    font-size: var(--fonte-titulo); }
.modal-rodape { justify-content: flex-end; margin-top: var(--espaco-4); padding-top: var(--espaco-3); border-top: var(--borda); }
.troca-categoria-corpo { display: flex; flex-wrap: wrap; gap: var(--espaco-4); align-items: flex-start; }
.troca-categoria-corpo img { max-width: 100%; height: auto; }
.troca-categoria-corpo form { flex: 1; min-width: 0; }
/* Rodapé dos modais: Cancelar e, à direita, a ação primária (que mostra o andamento do envio,
 * carregamento.js). Ação secundária extra vai para a esquerda. */
.modal-rodape .acao-esquerda { order: -1; margin-right: auto; }
/* Vincular fotos: radios dos pacientes do dia lado a lado. Sem JavaScript (classe
 * sem-js), o conteúdo do dialog aparece na própria página, sem Cancelar. */
dialog.modal-vincular { width: min(40rem, 94vw); }
.modal-vincular fieldset { display: flex; flex-wrap: wrap; gap: var(--espaco-2) var(--espaco-4); }
dialog.modal-vincular.sem-js { display: block; position: static; width: auto; max-height: none; margin: var(--espaco-4) 0;
    box-shadow: none; border: var(--borda); }
.modal-vincular.sem-js [data-cancelar] { display: none; }

/* Editor de recorte: fundo branco, quadro e grade em cinza escuro (pedido do dono, 30/10/2026). */
/* A altura do canvas vem só do CSS (o JS lê clientWidth/clientHeight a cada draw(), inclusive no
 * resize, e converte o arraste por getBoundingClientRect). --reserva-editor (29rem = 464px) é o que
 * fica fora do canvas na página avulsa, para a tela caber sem rolagem vertical: medido no Chrome
 * (03/11/2026), com 27rem a página passava 24px em 1366x768 e em 1920x1080 (cabeçalho, trilha,
 * título com Categoria anterior/Próxima, controles em duas linhas e rodapé); 29rem dá ~8px de folga.
 * Em 1366x768 (área útil ~673px) sobram ~210px de canvas; em 1080p (~985px), ~520px. Ajuste o valor se
 * a verificação visual mostrar rolagem ou espaço sobrando. */
.canvas-editor { display: block; width: 100%; height: 65vh; touch-action: none; background: var(--cor-superficie);
    border: var(--borda); }
.editor-recorte-canvas { min-height: 0; height: max(12rem, calc(100vh - var(--reserva-editor))); max-height: max(12rem, calc(100vh - var(--reserva-editor)));
    height: max(12rem, calc(100dvh - var(--reserva-editor))); max-height: max(12rem, calc(100dvh - var(--reserva-editor))); }
.canvas-editor:focus-visible { outline: var(--foco-contorno); outline-offset: calc(-1 * var(--foco-afastamento)); }
/* Placeholder: o quadro da foto já tem a altura final e fica cinza até a original chegar,
 * então a tela não pula quando a foto e o quadro aparecem. */
.moldura-foto { display: flex; flex-direction: column; min-width: 0; min-height: 0; }
.moldura-foto.carregando .canvas-editor { background: var(--cor-esqueleto); }
/* Título com a troca de categoria e a legenda dos atalhos na mesma linha. */
.editor-topo { display: flex; align-items: center; gap: var(--espaco-2); margin: 0 0 var(--espaco-2);
    padding-bottom: var(--espaco-2); border-bottom: var(--borda); }
.editor-topo #modal-titulo { flex: 1 1 auto; min-width: 0; margin: 0; padding: 0; border: 0; }
.nav-categorias { display: flex; gap: var(--espaco-2); }
.nav-categorias .botao, .atalhos-editor > summary { padding: var(--espaco-1) var(--espaco-3); font-size: var(--fonte-menor); }
.atalhos-editor { position: relative; }
.atalhos-editor > summary { list-style: none; cursor: pointer; border: var(--borda-controle); border-radius: var(--raio-pequeno);
    background: var(--cor-secundaria); }
.atalhos-editor > summary::-webkit-details-marker { display: none; }
.atalhos-editor > summary::after { content: " ▾"; }
.atalhos-editor > summary:hover { background: var(--cor-secundaria-hover); }
.legenda-atalhos { position: absolute; right: 0; top: calc(100% + var(--espaco-1)); z-index: var(--camada-menu);
    width: var(--largura-aviso); padding: var(--espaco-3); font-size: var(--fonte-menor); background: var(--cor-superficie);
    border: var(--borda); border-radius: var(--raio-medio); box-shadow: var(--sombra-flutuante); }
.legenda-atalhos dl { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: var(--espaco-1) var(--espaco-3); margin: 0; }
.legenda-atalhos dd { margin: 0; }
.legenda-atalhos kbd { font-family: inherit; padding: 0 var(--espaco-1); border: var(--borda-controle);
    border-radius: var(--raio-pequeno); background: var(--cor-superficie-suave); }
/* Foto com o quadro na área principal e os controles logo abaixo dela; à direita, a prévia do
 * resultado e, abaixo dela, os recortes ativos das outras fotos do grupo de escala. */
body:has(main .editor-recorte) { padding: var(--espaco-3); }
main:has(.editor-recorte) { padding: var(--espaco-2); margin-bottom: var(--espaco-2); }
body:has(main .editor-recorte) > header { margin-bottom: var(--espaco-2); padding: var(--espaco-2); }
.area-editor { display: grid; grid-template-columns: minmax(0, 1fr) var(--largura-coluna-previas);
    --largura-coluna-previas: min(24vw, calc((100dvh - 18rem) * var(--proporcao) / 2));
    gap: var(--espaco-3); align-items: start; }
.area-editor:has([data-pilha="intraorais"]) {
    --largura-coluna-previas: min(24vw, calc((100dvh - 22rem) * var(--proporcao) / 3)); }
.area-editor:has(.previas-lado > :nth-child(2)) { --largura-coluna-previas: clamp(28rem, 34vw, 32rem); }
.lateral-editor { display: flex; flex-direction: column; gap: var(--espaco-1); min-height: 0; min-width: 0; }
.coluna-previas { --previa-largura: 100%; }
.coluna-previas:has(.previas-lado > :nth-child(2)) { --previa-largura: calc((100% - var(--espaco-1)) / 2); }
.quadro-previa { margin: 0; display: flex; flex-direction: column; align-items: center; min-width: 0; }
/* Todas as prévias da coluna (canvas ao vivo, recortes do grupo e a frente ao lado do perfil) usam
 * o mesmo quadro: --previa-largura e a proporção do recorte aberto (--proporcao, do
 * .area-editor). A imagem fica inteira dentro (object-fit: contain), então formatos diferentes não
 * distorcem e dá para comparar. */
.previa-recorte { display: block; box-sizing: border-box; width: var(--previa-largura);
    height: auto; aspect-ratio: var(--proporcao);
    max-width: 100%; background: var(--cor-imagem-fundo); object-fit: contain; border: var(--borda); }
.previa-recorte.vazia { display: flex; align-items: center; justify-content: center; padding: var(--espaco-2);
    text-align: center; font-size: var(--fonte-minima); color: var(--cor-texto-suave); background: var(--cor-fundo);
    border: var(--borda-vazio); }
/* Linhas de alinhamento: SVG por cima da prévia (o JS o prende à área da imagem dentro do quadro),
 * sem alterar o recorte. O toggle as esconde em todas as prévias; sem JS, o :has faz o mesmo. */
.previa-com-linhas { position: relative; display: block; width: 100%; max-width: 100%; }
.linhas-alinhamento { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; overflow: visible; }
.linhas-alinhamento line { stroke: var(--cor-linha-alinhamento); stroke-width: 1; vector-effect: non-scaling-stroke; }
.lateral-editor.sem-linhas .linhas-alinhamento,
.lateral-editor:has(#linhas-alinhamento:not(:checked)) .linhas-alinhamento { display: none; }
.toggle-linhas { display: flex; align-items: center; gap: var(--espaco-1); font-size: var(--fonte-menor); }
.toggle-linhas input { margin: 0; }
/* Perfil: a prévia e a frente lado a lado, do mesmo tamanho. */
.previas-lado { display: flex; gap: var(--espaco-1); align-items: flex-start; justify-content: center; }
.previas-lado .quadro-previa { flex: 0 0 auto; width: var(--previa-largura); }
.previas-lado .previa-recorte { width: 100%; }
/* Recortes do grupo (e, nas intraorais, as três prévias frente, direita e esquerda) um em cima do
 * outro, centralizados na coluna e com o mesmo alinhamento horizontal. */
.grupo-recortes { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: var(--espaco-2); }
.grupo-recortes li { display: flex; flex-direction: column; align-items: center; min-width: 0; }
.grupo-recortes span, .quadro-previa figcaption { font-size: var(--fonte-menor); text-align: center; }
.editor-recorte p { margin: var(--espaco-2) 0; }
/* Controles abaixo da foto, em duas colunas: giro e tamanho; depois brilho e saturação. Cada
 * controle deslizante tem o campo numérico ao lado; o do tamanho ocupa o resto da coluna (largo). */
.coluna-editor { min-width: 0; min-height: 0; display: flex; flex-direction: column; overflow: hidden;
    padding: var(--espaco-1); }
.controles-editor { min-width: 0; margin-top: var(--espaco-1); font-size: var(--fonte-menor); }
.controles-editor button { padding: 0 var(--espaco-2); font-size: var(--fonte-menor); }
.controles-editor form { margin: 0; }
/* As frações descontam o espaço entre colunas; a subgrade compartilha as duas alturas. */
.grade-controles { display: grid; grid-template-columns: 65fr 35fr; grid-template-rows: repeat(2, 1fr);
    gap: var(--espaco-2) var(--espaco-5); min-width: 0; }
.coluna-controles { display: grid; grid-row: span 2; grid-template-rows: subgrid; min-width: 0;
    align-items: start; }
.controle-giro, .controle-escala { min-width: 0; display: flex; flex-direction: column; gap: var(--espaco-1); }
.controle-cor { min-width: 0; display: flex; align-items: center; gap: var(--espaco-2); }
.controle-cor > label { flex: 0 0 var(--largura-rotulo-curto); }
.controle-cor > .linha-controle { flex: 1 1 auto; }
.linha-controle { display: flex; align-items: center; gap: var(--espaco-2); min-width: 0; }
.linha-controle input[type=range] { flex: 1 1 auto; width: auto; min-width: 0; }
.linha-controle input[type=number] { flex: 0 0 auto; width: var(--largura-campo-numero); box-sizing: border-box;
    padding: var(--espaco-1); text-align: right; }
.editor-recorte .dica-zoom { margin: 0; font-size: var(--fonte-menor); color: var(--cor-texto-suave); }
@media (max-width: 899px) {
    .grade-controles { grid-template-columns: minmax(0, 1fr); grid-template-rows: auto; }
    .coluna-controles { grid-row: auto; grid-template-rows: auto; gap: var(--espaco-2); }
}
/* Rodapé: "Voltar ao recorte do sistema" à esquerda, como ação de risco com confirmação;
 * mensagens no meio; Cancelar, Salvar e próxima categoria e Salvar (primária) à direita. */
.editor-recorte .modal-rodape { flex-wrap: nowrap; margin-top: var(--espaco-1); padding-top: var(--espaco-2); gap: var(--espaco-2); }
.mensagens-editor { flex: 1 1 auto; min-width: 0; font-size: var(--fonte-menor); }
.editor-recorte .mensagens-editor p { margin: 0; }
.botao-risco, .confirmacao-risco button { color: var(--cor-erro); border-color: var(--cor-erro); background: var(--cor-superficie); }
.botao-risco:hover, .confirmacao-risco button:hover { color: var(--cor-erro); background: var(--cor-erro-fundo); }
.confirmar-risco { position: relative; }
.confirmar-risco > summary { list-style: none; }
.confirmar-risco > summary::-webkit-details-marker { display: none; }
.confirmacao-risco { position: absolute; left: 0; bottom: calc(100% + var(--espaco-1)); z-index: var(--camada-menu);
    width: var(--largura-aviso); padding: var(--espaco-3); background: var(--cor-superficie); border: var(--borda);
    border-radius: var(--raio-medio); box-shadow: var(--sombra-flutuante); }
.editor-recorte .confirmacao-risco p { margin: 0 0 var(--espaco-2); }

/* Modal do editor (sem rolagem em 1366x768, 1440x900 e 1920x1080, inclusive oclusais): o editor é
 * uma coluna flex com a área (foto e lateral) e o rodapé; a área encolhe para o rodapé caber. Na
 * coluna esquerda, o título, a foto original e, logo abaixo, os controles; na direita, o toggle das
 * linhas, a prévia e as miniaturas do grupo, todas com a largura da coluna (que já cabe nas três
 * intraorais empilhadas). O resto é dividido por flex/grid (1fr, min-height: 0) em relação aos 90dvh
 * do modal, sem altura fixa em px; a foto encolhe para caber. */
dialog.modal-editor .editor-recorte { display: flex; flex-direction: column; }
dialog.modal-editor .editor-recorte, dialog.modal-editor .area-editor { height: 100%; min-height: 0; }
dialog.modal-editor .area-editor { flex: 1 1 0; grid-template-columns: minmax(0, 1fr) var(--largura-coluna-previas);
    grid-template-rows: minmax(0, 1fr); align-items: stretch; overflow: hidden; }
dialog.modal-editor .coluna-editor > * { flex: 0 0 auto; }
dialog.modal-editor .coluna-editor > .moldura-foto { flex: 1 1 0; min-height: 0; }
dialog.modal-editor .coluna-editor .canvas-editor { flex: 1 1 0; min-height: 0; height: auto; max-height: none; }
dialog.modal-editor .editor-topo { margin-bottom: var(--espaco-1); padding-bottom: var(--espaco-1); }
dialog.modal-editor .editor-topo #modal-titulo { font-size: var(--fonte-titulo-editor); }
dialog.modal-editor .controles-editor { margin-top: var(--espaco-1); font-size: var(--fonte-menor); }
dialog.modal-editor .grade-controles { gap: var(--espaco-1) var(--espaco-4); }
dialog.modal-editor .controles-editor button { padding: 0 var(--espaco-2); font-size: var(--fonte-menor); }
dialog.modal-editor .linha-controle input[type=number] { padding: 0 var(--espaco-1); }
dialog.modal-editor .modal-rodape { margin-top: var(--espaco-1); padding-top: var(--espaco-2); gap: var(--espaco-2); }
dialog.modal-editor .lateral-editor { height: 100%; max-height: none; min-height: 0; overflow: hidden; }
dialog.modal-editor .previas-lado .quadro-previa { flex: 0 0 auto; }
dialog.modal-editor .grupo-recortes { flex: 0 1 auto; min-height: 0; overflow: hidden; display: grid;
    grid-template-columns: minmax(0, 1fr); justify-items: center; align-content: start; gap: var(--espaco-1); }
dialog.modal-editor .grupo-recortes li { min-height: 0; min-width: 0; width: 100%; display: flex; flex-direction: column;
    align-items: center; gap: 2px; overflow: hidden; }
dialog.modal-editor .grupo-recortes .previa-recorte { max-height: 100%; max-width: 100%; object-fit: contain; }
dialog.modal-editor .grupo-recortes span { flex: 0 0 auto; text-align: center; font-size: var(--fonte-minima); }

/* Tela Início: quadro compacto da clínica, filtros e um grupo por data com os cartões
 * das unidades lado a lado (unidades de um dia numa linha; oito datas em cerca de duas
 * telas a 1440x900). */
.faixa-organizar { display: flex; flex-wrap: wrap; align-items: center; gap: var(--espaco-3); margin: 0 0 var(--espaco-3);
    padding: var(--espaco-2) var(--espaco-3); background: var(--cor-superficie-suave); border: var(--borda);
    border-radius: var(--raio-medio); font-size: var(--fonte-pequena); }
.faixa-organizar form { margin: 0; }
.acao-inicio { display: flex; align-items: center; gap: var(--espaco-3); margin: 0 0 var(--espaco-3); }
.estado-organizacao { color: var(--cor-texto-suave); }
.quadro-entrada { flex-basis: 100%; }
.quadro-entrada p { margin: 0; }
.pastas-entrada { list-style: none; margin: var(--espaco-2) 0; padding: 0; }
.pastas-entrada li { display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
    gap: var(--espaco-3); padding: var(--espaco-1) 0; }
.erro-organizacao { color: var(--cor-erro); }
.worker-ativo { color: var(--cor-texto-suave); font-size: .85em; margin: 0; }
.grupo-data + .grupo-data { margin-top: var(--espaco-4); }
.grupo-data h2 { margin: 0 0 var(--espaco-2); font-size: var(--fonte-base); }
.cartoes-dias { list-style: none; padding: 0; margin: 0; display: grid; gap: var(--espaco-3);
    grid-template-columns: repeat(auto-fill, minmax(var(--largura-cartao-dia), 1fr)); }
.cartao-dia { display: flex; flex-direction: column; gap: var(--espaco-2); padding: var(--espaco-2) var(--espaco-3); }
.cartao-dia h3 { margin: 0; font-size: var(--fonte-base); }
.cartao-dia .lote-extra { font-size: var(--fonte-menor); font-weight: normal; }
.cartao-dia .chip-clinica { align-self: flex-start; }
.chips-contagem { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: var(--espaco-1); }
.chips-contagem .chip { padding: 0 var(--espaco-2); font-size: var(--fonte-menor); border-color: var(--cor-borda);
    font-variant-numeric: tabular-nums; }
.chips-contagem .chip-alerta { background: var(--cor-atencao-fundo); color: var(--cor-atencao-texto);
    border-color: var(--cor-atencao); }
.linha-progresso { display: flex; align-items: center; gap: var(--espaco-2); font-size: var(--fonte-menor);
    color: var(--cor-texto-suave); white-space: nowrap; font-variant-numeric: tabular-nums; }
.cartao-dia .botao, .cartao-dia button { align-self: flex-start; padding: var(--espaco-1) var(--espaco-3); }
/* Envio de fotos: seleção e progresso usam os componentes comuns da tela. */
.upload-fotos { margin-bottom: var(--espaco-5); }
.upload-zona { border: var(--borda-vazio); border-radius: var(--raio-medio); padding: var(--espaco-4); }
.upload-zona.arrastando { background: var(--cor-secundaria); outline: var(--foco-contorno); }
.upload-lista { list-style: none; padding: 0; }
.upload-arquivo { margin-bottom: var(--espaco-2); overflow-wrap: anywhere; }
.upload-arquivo p { margin: var(--espaco-2) 0; }
.upload-arquivo progress { flex: 1; }
.upload-fotos [data-erros-upload]:empty { display: none; }
progress.progresso { width: 100%; height: var(--altura-progresso); appearance: none; border: 0;
    border-radius: var(--raio-pilula); background: var(--cor-progresso-fundo); overflow: hidden; }
progress.progresso::-webkit-progress-bar { background: var(--cor-progresso-fundo); border-radius: var(--raio-pilula); }
progress.progresso::-webkit-progress-value { background: var(--cor-ok); border-radius: var(--raio-pilula); }
progress.progresso::-moz-progress-bar { background: var(--cor-ok); border-radius: var(--raio-pilula); }

/* Página do dia: cabeçalho numa linha (unidade e data, status, contagens e progresso), que
 * quebra em linhas inteiras se faltar largura, e a barra de ações com "Conferir próximo paciente". */
.cabecalho-dia { display: flex; align-items: center; flex-wrap: wrap; gap: var(--espaco-2) var(--espaco-3);
    margin-bottom: var(--espaco-2); }
.cabecalho-dia h2 { margin: 0; font-size: var(--fonte-titulo); white-space: nowrap; }
.cabecalho-dia .linha-progresso { flex: 1 1 var(--largura-campo-compacto); min-width: var(--largura-campo-compacto); }
.chip-status-dia { padding: 0 var(--espaco-2); font-size: var(--fonte-menor); border-color: var(--cor-borda); }
.chip-status-dia.em_revisao { background: var(--cor-atencao-fundo); color: var(--cor-atencao-texto); border-color: var(--cor-atencao); }
.chip-status-dia.finalizado { background: var(--cor-ok-fundo); color: var(--cor-ok-texto); border-color: var(--cor-ok); }
.barra-progresso { flex: 1; height: var(--altura-progresso); border-radius: var(--raio-pilula);
    background: var(--cor-progresso-fundo); overflow: hidden; }
.barra-progresso > span { display: block; height: 100%; background: var(--cor-ok); border-radius: var(--raio-pilula); }
.barra-dia { padding: var(--espaco-2) 0; margin-bottom: var(--espaco-2); }
/* "Mais ações" do dia: logo depois da primária, com o popover alinhado à esquerda do botão e por cima da
 * tabela; itens de formulário ocupam a linha toda e o estado do ZIP vem em texto curto. */
.barra-dia .estado-dia { font-size: var(--fonte-pequena); color: var(--cor-texto-suave); }
.menu-acoes-dia > ul { left: 0; right: auto; }
.menu-acoes-dia .menu-estado { display: block; padding: 0 var(--espaco-3) var(--espaco-1);
    font-size: var(--fonte-menor); color: var(--cor-texto-suave); }
.menu-acoes-dia .menu-estado-erro { color: var(--cor-erro); }
.menu-acoes-dia > ul button:disabled { cursor: not-allowed; }
/* Pacientes do dia: título e filtro de status numa linha só, tabela logo abaixo. */
#pacientes-do-dia > h3 { margin: var(--espaco-2) 0; }
#pacientes-do-dia .filtros-linha { align-items: center; margin-bottom: var(--espaco-2); }
.segmentado .contador { margin-left: var(--espaco-1); }
.segmentado a[aria-current] .contador { background: var(--cor-superficie); color: var(--cor-texto); }

/* Telas de administração e formulários (configurações, importar, finalizar, limpeza). */
.titulo-tela { display: flex; align-items: center; gap: var(--espaco-3); }
.titulo-tela h2 { margin: var(--espaco-2) 0; }
.descricao-tela { margin: 0 0 var(--espaco-3); color: var(--cor-texto-suave); }
.chip-avancado { background: var(--cor-atencao-fundo); color: var(--cor-atencao-texto); border-color: var(--cor-atencao); }
.saiba-mais { margin: 0 0 var(--espaco-3); font-size: var(--fonte-pequena); }
.saiba-mais > summary { cursor: pointer; color: var(--cor-primaria); }
.saiba-mais > p { margin: var(--espaco-2) 0 0; max-width: var(--largura-motivo); color: var(--cor-texto-suave); }
.helptext { font-size: var(--fonte-menor); color: var(--cor-texto-suave); }
/* Seção de configuração: título e uma frase à esquerda, campos à direita. */
.secao-config { display: grid; grid-template-columns: var(--largura-texto-secao) minmax(0, 1fr); gap: var(--espaco-5);
    padding: var(--espaco-4) 0; border-top: var(--borda); }
.secao-config-texto h3 { margin: 0 0 var(--espaco-1); font-size: var(--fonte-base); }
.secao-explicacao { margin: 0; font-size: var(--fonte-pequena); color: var(--cor-texto-suave); }
.secao-config-campos { display: flex; flex-direction: column; gap: var(--espaco-1); }
.secao-config-campos input { width: var(--largura-campo-compacto); }
/* Exportação: formato e template A4 juntos, compactos para caber em 1440x900 sem rolagem. */
.formulario-exportacao .secao-config { padding: var(--espaco-3) 0; }
#id_template_orientacao { display: flex; gap: var(--espaco-4); }
.presets-template { display: flex; flex-wrap: wrap; gap: var(--espaco-2); margin: 0; padding: 0; border: 0; }
.presets-template legend { padding: 0; margin-bottom: var(--espaco-1); }
.opcao-preset { display: flex; flex-direction: column; gap: var(--espaco-1); padding: var(--espaco-2);
    border: var(--borda); border-radius: var(--raio-medio); cursor: pointer; }
.opcao-preset:has(input:checked) { box-shadow: 0 0 0 var(--borda-selecao-largura) var(--cor-primaria); }
.opcao-preset:has(input:focus-visible) { outline: var(--foco-contorno); outline-offset: var(--foco-afastamento); }
.opcao-preset-nome { font-size: var(--fonte-pequena); }
.secao-config-campos .opcao-preset input { width: auto; }
.miniatura-preset { display: none; gap: var(--espaco-1); }
.formulario-exportacao:has([name=template_orientacao][value=paisagem]:checked) .miniatura-preset[data-orientacao=paisagem],
.formulario-exportacao:has([name=template_orientacao][value=retrato]:checked) .miniatura-preset[data-orientacao=retrato] { display: flex; }
.miniatura-preset[data-orientacao=paisagem] .miniatura-folha { height: var(--altura-miniatura-paisagem); width: auto; }
.miniatura-preset[data-orientacao=retrato] .miniatura-folha { height: var(--altura-miniatura-retrato); width: auto; }
.miniatura-folha .folha { fill: var(--cor-superficie); stroke: var(--cor-borda-controle); stroke-width: 24; }
.miniatura-folha .cabecalho { fill: var(--cor-borda); }
.miniatura-folha .quadro { fill: var(--cor-esqueleto); stroke: var(--cor-vazio-borda); stroke-width: 12; }
/* Padrão de enquadramento: um cartão por grupo, figura sintética com o quadro por cima. */
.so-leitor { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.cartoes-enquadramento { display: grid; grid-template-columns: repeat(auto-fill, minmax(var(--largura-figura-enquadramento), 1fr));
    gap: var(--espaco-4); }
.cartao-enquadramento { position: relative; display: flex; flex-direction: column; gap: var(--espaco-2); padding: var(--espaco-3); }
.cartao-enquadramento h4 { margin: 0; font-size: var(--fonte-base); }
.figura-enquadramento { width: 100%; height: auto; max-height: var(--altura-figura-enquadramento); aspect-ratio: 4 / 3;
    object-fit: contain; border-radius: var(--raio-medio); }
.secao-enquadramento { padding: var(--espaco-3) 0; }
/* Compacta somente esta seção no computador, preservando os controles e a proporção das figuras. */
.secao-enquadramento-compacta { padding: var(--espaco-1) 0; }
.secao-enquadramento-compacta .cartoes-enquadramento { gap: var(--espaco-2); }
.secao-enquadramento-compacta .cartao-enquadramento { gap: var(--espaco-1); padding: var(--espaco-2); }
.secao-enquadramento-compacta .figura-enquadramento { max-height: var(--altura-figura-enquadramento-compacta); }
.figura-fundo { fill: var(--cor-figura-fundo); }
.figura-pele { fill: var(--cor-figura-pele); }
.figura-pele-sombra { fill: var(--cor-figura-pele-sombra); }
.figura-cabelo { fill: var(--cor-figura-cabelo); }
.figura-roupa { fill: var(--cor-figura-roupa); }
.figura-traco { fill: var(--cor-figura-traco); }
.figura-linha { fill: none; stroke: var(--cor-figura-traco); stroke-width: 2; stroke-linecap: round; }
.figura-boca { fill: var(--cor-figura-boca); }
.figura-labio { fill: var(--cor-figura-labio); }
.figura-boca-interna { fill: var(--cor-figura-boca); }
.figura-gengiva { fill: var(--cor-figura-gengiva); }
.figura-palato { fill: var(--cor-figura-palato); }
.figura-dente { fill: var(--cor-figura-dente); stroke: var(--cor-figura-pele-sombra); }
.ponto-nariz { fill: var(--cor-nariz); }
.fora-recorte { fill: var(--cor-fora-recorte); }
.quadro-sistema { fill: none; stroke: var(--cor-texto); stroke-width: 1.5; stroke-dasharray: 6 4; }
.quadro-recorte { fill: none; stroke: var(--cor-quadro-recorte); stroke-width: 3; }
.centro-recorte { fill: var(--cor-quadro-recorte); }
.resumo-enquadramento, .distancia-nariz { margin: 0; font-size: var(--fonte-pequena); }
.distancia-nariz { font-weight: var(--fonte-peso-forte); }
/* Alcance da troca do padrão (modal) e progresso da aplicação aos pacientes em aberto. */
.opcoes-alcance { display: grid; gap: var(--espaco-3); margin: var(--espaco-3) 0; padding: 0; border: 0; }
.opcao-alcance { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: var(--espaco-1) var(--espaco-2); }
.opcao-alcance .helptext { grid-column: 2; max-width: var(--largura-motivo); }
.progresso-enquadramento p { margin: var(--espaco-2) 0 var(--espaco-1); font-size: var(--fonte-pequena); }
.progresso-enquadramento progress { width: 100%; }
.controles-enquadramento { display: flex; flex-wrap: wrap; align-items: flex-start; gap: var(--espaco-3) var(--espaco-4); }
.setas-enquadramento { display: grid; grid-template-columns: repeat(3, var(--tamanho-seta));
    grid-template-areas: ". cima ." "esquerda . direita" ". baixo ."; gap: var(--espaco-1); margin: 0; padding: 0; border: 0; }
.setas-enquadramento legend { padding: 0; font-size: var(--fonte-pequena); }
.setas-enquadramento button { width: var(--tamanho-seta); height: var(--tamanho-seta); padding: 0; }
.seta-cima { grid-area: cima; } .seta-baixo { grid-area: baixo; }
.seta-esquerda { grid-area: esquerda; } .seta-direita { grid-area: direita; }
.campo-zoom, .campo-formato { display: flex; flex-direction: column; gap: var(--espaco-1); font-size: var(--fonte-pequena); }
.campo-zoom input { width: var(--largura-campo-zoom); }
/* Formulário compacto: os campos lado a lado, quebrando em linhas. */
.campos-compactos { display: flex; flex-wrap: wrap; gap: var(--espaco-3) var(--espaco-4); margin-bottom: var(--espaco-2); }
.campo-compacto { display: flex; flex-direction: column; gap: var(--espaco-1); width: var(--largura-campo-compacto);
    font-size: var(--fonte-pequena); }
.campo-compacto input, .campo-compacto select { width: 100%; box-sizing: border-box; }
/* Resumo em contagens: rótulo pequeno sobre o número. */
.resumo-tela h3, .depois h3, .simulacao h3 { margin: var(--espaco-3) 0 var(--espaco-2); font-size: var(--fonte-base); }
.resumo-contagens { display: flex; flex-wrap: wrap; gap: var(--espaco-3); margin: 0 0 var(--espaco-3); }
.resumo-contagens > div { padding: var(--espaco-2) var(--espaco-4); background: var(--cor-superficie-suave);
    border: var(--borda); border-radius: var(--raio-medio); }
.resumo-contagens dt { font-size: var(--fonte-menor); color: var(--cor-texto-suave); }
.resumo-contagens dd { margin: 0; font-size: var(--fonte-titulo); font-weight: var(--fonte-peso-forte);
    font-variant-numeric: tabular-nums; }
.depois ul { margin: 0 0 var(--espaco-3); padding-left: var(--espaco-5); }
.tabela-limpeza { margin-bottom: var(--espaco-3); }

/* Login: cartão centralizado com o nome do produto. */
.cartao-login { width: var(--largura-login); margin: var(--espaco-6) auto; padding: var(--espaco-5); }
.cartao-login h2 { margin: 0 0 var(--espaco-3); }
.cartao-login input:not([type=hidden]) { width: 100%; box-sizing: border-box; }
.cartao-login button { width: 100%; }
.campo-login { margin: 0 0 var(--espaco-3); }
.produto-login { margin: 0 0 var(--espaco-2); font-size: var(--fonte-titulo); font-weight: var(--fonte-peso-forte);
    color: var(--cor-primaria); }

/* Barra de ações no topo da tela (template do paciente): presa ao alto, não ao pé. */
.barra-topo { top: 0; bottom: auto; border-top: 0; border-bottom: var(--borda); margin-bottom: var(--espaco-4); }
.barra-topo h2 { margin: 0 auto 0 0; font-size: var(--fonte-titulo); }

/* Cada folha usa as caixas percentuais calculadas pelo motor A4. */
.template-pagina { margin-block: var(--espaco-4); break-inside: avoid; }
.template-pagina[data-orientacao="paisagem"] { page: template-paisagem; }
.template-pagina[data-orientacao="retrato"] { page: template-retrato; }
.template-numeracao { text-align: center; color: var(--cor-texto-suave); }
.template { position: relative; container-type: inline-size; margin-inline: auto;
    background: var(--cor-superficie); }
.template-cabecalho { position: absolute; display: flex; flex-direction: column;
    border-bottom: var(--borda-vazio); font-size: 1.6cqw; line-height: 1.35; }
.template-cabecalho strong { font-size: 2.16cqw; }
.template-cabecalho span:last-child { font-size: 1.37cqw; }
.template-quadro { position: absolute; min-width: 0; min-height: 0; box-sizing: border-box;
    display: flex; align-items: center; justify-content: center; }
.template-quadro img { width: 100%; height: 100%; object-fit: contain; display: block; }
.template-quadro[data-alinhamento="fim"] img { object-position: center bottom; }
.template-quadro[data-alinhamento="inicio"] img { object-position: center top; }
.template-vazio { border: var(--borda-vazio); color: var(--cor-texto-suave); font-size: 1.37cqw; text-align: center; }
/* Carregamento global (carregamento.js; docs/webapp/carregamento.md). A camada é um <dialog>
 * aberto com showModal: fica acima de tudo, deixa o resto inerte e o ::backdrop faz o véu. */
dialog.carregamento-camada { position: fixed; inset: 0; width: 100%; height: 100%; max-width: none; max-height: none;
    margin: 0; padding: 0; border: 0; background: transparent; cursor: progress; }
dialog.carregamento-camada[open] { display: grid; place-items: center; }
dialog.carregamento-camada::backdrop { background: var(--cor-carregamento-fundo); }
dialog.carregamento-camada:focus { outline: none; }
.carregamento-indicador { display: flex; align-items: center; gap: var(--espaco-3); padding: var(--espaco-3) var(--espaco-5);
    background: var(--cor-superficie); color: var(--cor-texto); border: var(--borda); border-radius: var(--raio-medio);
    box-shadow: var(--sombra-modal); }
.carregamento-indicador p { margin: 0; font-weight: var(--fonte-peso-forte); }
.carregamento-indicador .carregamento-spinner { width: var(--tamanho-spinner-camada); height: var(--tamanho-spinner-camada);
    color: var(--cor-primaria); }
.carregamento-spinner { display: inline-block; flex: none; width: var(--tamanho-spinner); height: var(--tamanho-spinner);
    vertical-align: -.15em; box-sizing: border-box; border: var(--espessura-spinner) solid currentColor;
    border-right-color: transparent; border-radius: var(--raio-pilula); animation: carregamento-girar .8s linear infinite; }
@keyframes carregamento-girar { to { transform: rotate(360deg); } }
@keyframes carregamento-pulsar { 50% { opacity: .55; } }
/* Botão ocupado: desabilitado, mas com a cara da ação (a primária continua primária). */
.botao-ocupado, button.botao-ocupado:disabled, .botao.botao-ocupado[aria-disabled=true] { cursor: progress; }
.botao-primario.botao-ocupado:disabled, .botao-primario.botao-ocupado[aria-disabled=true] {
    background: var(--cor-primaria); border-color: var(--cor-primaria); color: var(--cor-texto-primaria);
    font-weight: var(--fonte-peso-forte); }
.botao-ocupado .carregamento-spinner { margin-right: var(--espaco-1); }
/* data-carregamento="local": só o cartão fica velado e inerte. */
.bloco-carregando { position: relative; cursor: progress; }
.bloco-carregando::after { content: ""; position: absolute; inset: 0; border-radius: inherit;
    background: var(--cor-carregamento-bloco); }
.bloco-carregando > .carregamento-local { position: absolute; top: var(--espaco-4); left: 50%;
    transform: translateX(-50%); z-index: 1; }
/* Sem animação de giro para quem pede menos movimento: anel pontilhado parado, com pulso lento. */
@media (prefers-reduced-motion: reduce) {
    .carregamento-spinner { animation: carregamento-pulsar 2s ease-in-out infinite; border-style: dotted;
        border-right-color: currentColor; }
}
/* Uma folha por página impressa, na orientação definida pelo motor. */
@page template-paisagem { size: A4 landscape; margin: 0; }
@page template-retrato { size: A4 portrait; margin: 0; }
@media print { body { min-width: 0; padding: 0; } main { padding: 0; margin: 0; box-shadow: none; }
    header, .avisos-flutuantes { display: none; } .nao-imprimir { display: none; }
    .template-pagina { margin: 0; break-after: page; }
    .template-pagina:last-of-type { break-after: auto; }
    .template-numeracao { display: none; }
    .template { width: 100% !important; } }
