/* Gerimos — único override sobre o Pico classless.
   Normativo: docs/ui-padroes.md (dimensões/comportamento) e docs/identidade-visual.md (tokens). */

@font-face {
    font-family: "IBM Plex Sans";
    font-weight: 600;
    src: url("../fonts/ibm-plex-sans-600.196e3cbc5fee.woff2") format("woff2");
    font-display: swap;
}

@font-face {
    font-family: "IBM Plex Mono";
    font-weight: 500;
    src: url("../fonts/ibm-plex-mono-500.b1c8a895f5fd.woff2") format("woff2");
    font-display: swap;
}

/* :root:not(...) espelha a especificidade dos temas do Pico — :root puro perde a cascata */
:root:not([data-theme=dark]) {
    --bg: #f5f5f4;
    --surface: #ffffff;
    --ink: #1c1917;
    --ink-2: #44403c;
    --muted: #66605a;
    --line: #d6d3d0;
    --primary: #0f766e;
    --primary-soft: #e0f0ee;
    --chart-bar: #8ac3bd;

    /* primária do Pico = teal da marca (links, botões, focus) */
    --pico-primary: var(--primary);
    --pico-primary-background: var(--primary);
    --pico-primary-border: var(--primary);
    --pico-primary-underline: var(--primary);
    --pico-primary-hover: #0c5f59;
    --pico-primary-hover-background: #0c5f59;
    --pico-primary-hover-border: #0c5f59;
    --pico-primary-hover-underline: #0c5f59;
    --pico-primary-inverse: #ffffff;
    --pico-primary-focus: rgba(15, 118, 110, 0.3);

    /* formulários nos neutros quentes da identidade (nada de azulado) */
    --pico-background-color: var(--bg);
    --pico-form-element-background-color: var(--surface);
    --pico-form-element-border-color: var(--line);
    --pico-form-element-placeholder-color: var(--muted);
    --pico-form-element-active-border-color: var(--primary);
    --pico-form-element-focus-color: var(--pico-primary-focus);
    --pico-muted-color: var(--muted);
    --pico-muted-border-color: var(--line);
}

/* Light é o padrão (data-theme="light" no <html>); dark só via toggle dev.
   TODO: oferecer dark mode como opção do usuário em Minha conta. */
:root[data-theme=dark] {
        --bg: #171614;
        --surface: #201f1c;
        --ink: #ece9e4;
        --ink-2: #b8b3ad;
        --muted: #8a857d;
        --line: #35322d;
        --primary: #14b8a6;
        --primary-soft: #123b37;
        --chart-bar: #2f5f5b;

        /* botões sólidos mantêm petróleo com texto branco (identidade §Paleta dark) */
        --pico-primary: var(--primary);
        --pico-primary-underline: var(--primary);
        --pico-primary-hover: #2dd4bf;
        --pico-primary-hover-underline: #2dd4bf;
        --pico-primary-background: #0f766e;
        --pico-primary-border: #0f766e;
        --pico-primary-hover-background: #0c5f59;
        --pico-primary-hover-border: #0c5f59;
        --pico-primary-inverse: #ffffff;
        --pico-primary-focus: rgba(20, 184, 166, 0.35);

        --pico-background-color: var(--bg);
        --pico-form-element-background-color: var(--bg);
        --pico-form-element-border-color: var(--line);
        --pico-form-element-placeholder-color: var(--muted);
        --pico-form-element-active-border-color: var(--primary);
        --pico-form-element-focus-color: var(--pico-primary-focus);
        --pico-muted-color: var(--muted);
        --pico-muted-border-color: var(--line);
}

/* ---------- base ---------- */

html {
    background: var(--bg);
    /* mata o escalonamento responsivo do Pico (§1 do ui-padroes): 1rem = 16px em
       qualquer viewport e em qualquer tema (o var --pico-font-size não cobre o dark) */
    font-size: 16px;
}

body {
    background: var(--bg);
    color: var(--ink);
    font-size: 0.9375rem;
}

h1, h2, h3, .wordmark {
    font-family: "IBM Plex Sans", sans-serif;
    font-weight: 600;
    color: var(--ink);
}

h1 { font-size: 1.375rem; }
h2 { font-size: 1rem; }

/* Dinheiro em Plex Mono tabular (identidade), mas sem nada que o destaque além da família:
   tamanho herdado da tabela e peso do corpo. O peso 500 fica no KPI de card, onde o destaque é
   o ponto (rodada 7, Passo 2 — o dono lia a coluna de valores como "fonte de outro app"). */
td.num, .valor {
    font-family: "IBM Plex Mono", monospace;
    font-variant-numeric: tabular-nums;
}

.valor {
    font-weight: 500;
}

/* "Não registrado"/"Indisponível" é texto, não dinheiro: fora do monoespaçado da coluna .num */
td.num .sem-termos {
    font-family: "IBM Plex Sans", sans-serif;
}

.wordmark {
    color: var(--ink);
    text-decoration: none;
    font-size: 1.375rem;
}

.wordmark .ponto {
    color: var(--primary);
}

footer {
    padding: 1rem 1.5rem;
    color: var(--muted);
    font-size: 0.9375rem;
    text-align: center;
}

/* divisória do footer recuada das bordas (§4) — mesmo tratamento em todas as telas */
footer small {
    display: block;
    max-width: 720px;
    margin: 0 auto;
    padding-top: 1rem;
    border-top: 1px solid var(--line);
}

.mensagens,
ul.errorlist,
.mensagens.erro {
    list-style: none;
    padding: 0;
    margin: 0 0 1rem;
}

/* mesmo padrão de notificação da app também para erros de formulário (allauth/Django) */
.mensagens li,
ul.errorlist li,
.mensagens.erro li {
    list-style: none;
    background: var(--primary-soft);
    color: var(--ink);
    border: 1px solid var(--line);
    border-radius: 4px;
    padding: 0.5rem 0.75rem;
    margin-bottom: 0.5rem;
    font-size: 0.9375rem;
}

/* sucesso some sozinho após 6s (rascunho §3); erro/warning ficam até o usuário resolver */
.mensagens li.success {
    background: #ddf3dd;
    color: #086108;
    border-color: #0ca30c;
    animation: sumir-banner 0.4s ease 6s forwards;
}

.mensagens li.error {
    background: #fbe1e1;
    color: #a02020;
    border-color: #d03b3b;
}

.mensagens li.warning {
    background: #fdf3d7;
    color: #7a5a00;
    border-color: #fab219;
}

/* texto de erro avulso fora de .mensagens (verificador, aceite público) — mesmo tom de status */
.erro {
    color: #a02020;
}

/* botão de ação secundária (Cancelar, +Adicionar) — contorno, sem competir com o CTA primário */
.secundario {
    background: var(--surface);
    color: var(--ink-2);
    border: 1px solid var(--line);
}

.secundario:hover {
    border-color: var(--primary);
    color: var(--primary);
}

/* link de ação de seção (Decisão C): "+ Template", "+ Cobrança eventual" etc — sublinhado em
   --primary, sem borda/fundo; substitui .secundario nessas ações. Aplica a <a> e <button> dentro
   de .secao-cabecalho, que já alinha título à esquerda e ação à direita (space-between). */
.acao-secao {
    all: unset;
    cursor: pointer;
    color: var(--primary);
    text-decoration: underline;
}

.acao-secao:hover,
.acao-secao:focus-visible {
    color: var(--pico-primary-hover);
}

.acao-secao:focus-visible {
    outline: 2px solid var(--primary);
    outline-offset: 2px;
}

.banner-aviso {
    background: var(--primary-soft);
    border: 1px solid var(--line);
    border-radius: 6px;
    padding: 0.75rem 1rem;
}

/* confirmação de salvamento — some sozinha após alguns segundos (sem JS) */
.banner-ok {
    background: var(--primary-soft);
    border: 1px solid var(--line);
    border-radius: 6px;
    padding: 0.5rem 0.75rem;
    margin-bottom: 1rem;
    animation: sumir-banner 0.4s ease 4s forwards;
}

/* banner persistente de pendência (Decisão M, ui-padroes §8): mesma cor da mensagem `warning`,
   mas não é flash — fica enquanto a pendência existir e o elemento inteiro é o gatilho da ação. */
.banner-pendencia {
    display: block;
    width: 100%;
    text-align: left;
    background: #fdf3d7;
    color: #7a5a00;
    border: 1px solid #fab219;
    border-radius: 4px;
    padding: 0.5rem 0.75rem;
    margin-bottom: 1rem;
    font-size: 0.9375rem;
    font-weight: normal;
    cursor: pointer;
}

.banner-pendencia:hover,
.banner-pendencia:focus-visible {
    background: #fbe9b8;
    color: #7a5a00;
    border-color: #fab219;
}

/* título do modal da cobrança com nome sem ponto de quebra: quebra no cabeçalho em vez de alargar o modal */
#modal-cobranca article > header strong {
    overflow-wrap: anywhere;
}

/* aviso amarelo só informativo (modal da cobrança): mesma cor do `.banner-pendencia`, sem o gesto de clique */
.banner-pendencia-info,
.banner-pendencia-info:hover {
    background: #fdf3d7;
    cursor: default;
}

/* tabela campo/valor do modal da cobrança: sem a regra de coluna variável (50% para o rótulo), o
   rótulo fica contido e o valor — nome, descrição, nome de modelo — ganha o resto e quebra */
table.tabela-campos th.curta {
    width: 10rem;
    white-space: normal;
}

table.tabela-campos td {
    overflow-wrap: anywhere;
}

/* aviso de template salvo sem placeholders (§ templates de contrato) — fica até o próximo swap */
.banner-atencao {
    border: 1px solid var(--line);
    border-left: 3px solid var(--muted);
    border-radius: 6px;
    padding: 0.5rem 0.75rem;
    margin-bottom: 1rem;
    color: var(--ink-2);
}

@keyframes sumir-banner {
    to { opacity: 0; height: 0; padding-block: 0; margin: 0; overflow: hidden; }
}

/* placeholders arrastáveis para o corpo do contrato (drag/click-to-insert) */
.ph-chip {
    cursor: grab;
    user-select: none;
    display: inline-block;
    background: var(--primary-soft);
    color: var(--primary);
    border: 1px solid var(--primary);
    border-radius: 999px;
    padding: 0.1rem 0.6rem;
    font-family: inherit;  /* tira o monoespaçado herdado de <code> */
    font-size: 0.8125rem;
}

.ph-chip:hover {
    background: var(--primary);
    color: var(--pico-primary-inverse);
}

.ph-chip:active {
    cursor: grabbing;
}

/* Automação (rodada 7, Decisão I): redação das notificações só para leitura, sob o checkbox do
   canal; canal desmarcado esmaece a própria redação — CSS puro, sem JS. */
.canal-regua .redacao {
    margin: 0 0 var(--pico-spacing) 1.75rem;
    padding-left: 0.75rem;
    border-left: 2px solid var(--line);
}
.canal-regua:not(:has(input[type=checkbox]:checked)) .redacao { opacity: 0.45; }

/* Contrato individual (Passo 9): "Salvar e enviar" só faz sentido gerando do template — anexar
   PDF já chega assinado, sem OTP por e-mail. CSS puro: o radio ativo decide, sem JS. */
.modal-corpo-contrato:has(#tipo-contrato-anexar:checked) ~ footer #botao-salvar-enviar { display: none; }
.redacao-texto { white-space: pre-line; }
/* o label de checkbox já é flex centrado (regra geral abaixo); na célula só perde a margem de
   campo, que empurrava o switch para cima da linha de base das vizinhas */
td.situacao label.switch-regua { margin-bottom: 0; }

/* input[type=file] nativo (botão azul em inglês do navegador) trocado por rótulo no tema —
   ver prepararCamposArquivo() em base.html/base_publica.html */
.campo-arquivo {
    display: inline-flex;
    align-items: center;
    gap: 0.75rem;
}

.campo-arquivo input[type="file"] {
    position: absolute;
    opacity: 0;
    width: 0;
}

.campo-arquivo .botao-arquivo {
    height: 3.125rem;
    display: inline-flex;
    align-items: center;
    padding: 0 1rem;
    border-radius: 6px;
    cursor: pointer;
}

.campo-arquivo .nome-arquivo {
    color: var(--muted);
}

.logo-preview {
    display: block;
    width: 160px;
    height: 60px;
    object-fit: contain;
    margin-bottom: 0.5rem;
}

/* miniatura do logo no resumo "Dados do prestador" — caixa de 48px de altura */
.logo-miniatura {
    height: 48px;
    width: 144px;
    object-fit: contain;
    vertical-align: middle;
    margin-right: 0.75rem;
}

/* recorte do logo (static/js/recorte-logo.js): o canvas é a própria moldura */
.recorte-logo canvas {
    display: block;
    width: 100%;
    max-width: 360px;
    margin-bottom: 0.5rem;
    border: 1px dashed var(--line);
    cursor: grab;
    touch-action: none;
}

/* ---------- formulários (§5) ---------- */

/* altura padrão de controle: input de texto, select e botão têm sempre 3.125rem (50px) — a
   altura natural do input do Pico. Garante linhas de filtro/ação alinhadas em qualquer browser
   (month/date/select variam de altura sem isso). Variante compacta sobrescreve com height. */
input:not([type="checkbox"], [type="radio"], [type="range"], [type="file"], [type="hidden"]),
select,
button {
    height: 3.125rem;
}

/* checkbox/radio sempre inline com o rótulo, nunca em linha própria */
form p:has(input[type="checkbox"]),
form p:has(input[type="radio"]),
label:has(input[type="checkbox"]) {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-bottom: 1rem;
}

form p:has(input[type="checkbox"]) label,
form p:has(input[type="radio"]) label {
    margin: 0;
}

form p:has(input[type="checkbox"]) input,
form p:has(input[type="radio"]) input,
label:has(input[type="checkbox"]) input {
    margin: 0;
    flex-shrink: 0;
}

/* par de campos curtos numa linha (ui-padroes §5, rodada 7): lado a lado enquanto couber, empilha
   no mobile. O checkbox do par ocupa a altura do input (3.125rem) + a margem dele, para centrar
   na mesma linha do campo de texto ao lado. */
.campos-par {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    column-gap: 1rem;
}
.campos-par > p {
    flex: 1 1 10rem;
    min-width: 0;
}
.campos-par > p:has(input[type="checkbox"]) {
    min-height: calc(3.125rem + var(--pico-spacing));
    padding-bottom: var(--pico-spacing);
}
/* o "?" do checkbox fica na ponta direita do par, no topo do corpo do modal (que rola e corta o
   que passa da borda): o balão abre PARA BAIXO e cresce para a esquerda, sem a animação do Pico
   (que o desloca -50% na horizontal), e só existe em hover/foco — invisível, ainda alargava o
   corpo do modal em 360px (mesma regra de td.acoes). */
.campos-par [data-tooltip]::after { left: auto; right: 0; bottom: auto; top: calc(100% + 0.5rem); }
.campos-par [data-tooltip]::before {
    left: auto;
    right: 0.25rem;
    bottom: auto;
    top: calc(100% - 0.15rem);
    border-top-color: transparent;
    border-bottom-color: var(--line);
}
.campos-par [data-tooltip]:is(:hover, :focus)::after,
.campos-par [data-tooltip]:is(:hover, :focus)::before { animation: none; transform: none; }
.campos-par [data-tooltip]:not(:hover, :focus)::after,
.campos-par [data-tooltip]:not(:hover, :focus)::before { display: none; }

/* ---------- esqueleto público (§4) ---------- */

/* svh, não dvh: com a barra de endereço recolhida o navegador móvel reporta dvh = viewport
   grande, o esqueleto fica mais alto que a tela e o footer cai abaixo da dobra mesmo com pouco
   conteúdo. svh = menor viewport possível — nunca ultrapassa o visível. */
body.publica {
    display: flex;
    flex-direction: column;
    min-height: 100svh;
}

body.publica > main {
    flex: 1;
}

.topo-publico {
    text-align: center;
    padding: 2rem 0 0.5rem;
}

.topo-publico .wordmark {
    font-size: 1.75rem;
}

.card-publico {
    max-width: 420px;
    margin: 0 auto;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: 6px;
    padding: 2rem;
}

/* SHA-256 (64 chars) do verificador quebra em qualquer ponto — o card é o mesmo do login */
.card-publico .hash {
    overflow-wrap: anywhere;
}

.card-publico h1 {
    font-size: 1.375rem;
}

.conteudo-publico > .mensagens {
    max-width: 420px;
    margin: 0 auto 1rem;
}

/* página pública de pagamento (/pagar/<token>/) — dentro do .card-publico */
.pagar-valor {
    font-size: 1.75rem;
    font-weight: 600;
    color: var(--ink);
    margin: 0.25rem 0;
}

/* aviso antifraude do checkout (ui-padroes §4.1) — reusa .banner-aviso, só espaçamento e escala */
.pagar-seguranca {
    margin-top: 1.5rem;
    font-size: 0.8125rem;
}

.pagar-seguranca p {
    margin: 0 0 0.5rem;
}

.pagar-seguranca ul {
    margin: 0;
    padding-left: 1.25rem;
}

.pagar-seguranca li {
    margin-bottom: 0.25rem;
}

.pagar-seguranca li:last-child {
    margin-bottom: 0;
}

.pix-qr {
    display: block;
    width: 100%;
    max-width: 220px;
    margin: 1rem auto;
    image-rendering: pixelated;  /* QR é bitmap: escalar sem suavizar mantém a leitura pela câmera */
}

/* código longo copiável (payload Pix, linha digitável) — texto, não campo (Decisão B, Passo 1) */
.codigo-rotulo {
    margin: 0 0 0.25rem;
    font-weight: 600;
}

.codigo-copiavel {
    font-family: "IBM Plex Mono", monospace;
    font-size: 0.875rem;
    overflow-wrap: anywhere;      /* payload Pix é uma palavra só: sem isso estoura a largura */
    user-select: all;             /* clique seleciona o código inteiro para a cópia manual */
    background: var(--bg);
    border: 1px solid var(--line);
    border-radius: 6px;
    padding: 0.5rem 0.75rem;
    margin: 0 0 0.75rem;
}

.codigo-acoes {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin-bottom: 1rem;
}

.codigo-acoes button {
    margin: 0;
    width: auto;
}

.codigo-feedback {
    color: var(--muted);
    font-size: 0.875rem;
}

.prosa-publica {
    max-width: 720px;
    margin: 0 auto;
}

.prosa-publica h2 {
    font-size: 1.125rem;
    margin-top: 1.5rem;
}

/* ---------- olhinho de mostrar senha (login/telas públicas) ---------- */

.campo-senha {
    position: relative;
    display: block;
    margin-bottom: 1rem;
}

.campo-senha input {
    margin-bottom: 0;
    padding-right: 2.75rem;
}

.olho-senha {
    position: absolute;
    inset: 0 0 0 auto;
    width: auto;
    height: 100%;
    margin: 0;
    padding: 0 0.75rem;
    display: flex;
    align-items: center;
    background: none;
    border: none;
    color: var(--muted);
    font-size: 1rem;
    cursor: pointer;
}

/* ---------- esqueleto logado (§3) ---------- */

.layout {
    display: flex;
    min-height: 100svh;   /* svh, não dvh — mesmo motivo do esqueleto público (footer sob a dobra) */
}

.sidebar {
    width: 220px;
    flex-shrink: 0;
    position: sticky;
    top: 0;
    height: 100dvh;
    overflow-y: auto;
    background: var(--surface);
    border-right: 1px solid var(--line);
    display: flex;
    flex-direction: column;
    padding: 1.25rem 1rem;
}

.sidebar nav ul, .sidebar-rodape {
    list-style: none;
    padding: 0;
    margin: 1.25rem 0 0;
}

/* espaço entre itens: hover de um item não encosta no highlight do item ativo (§3).
   align-items:stretch mata o `align-items:center` que o Pico põe em `nav ul` — sem isso os
   itens encolhem para a largura do texto e ficam centralizados na coluna. */
.sidebar nav ul {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 0.625rem;
}

.sidebar li {
    list-style: none;
    margin: 0;
    padding: 0;
}

/* nav logo abaixo do wordmark; Ajuda/Sair empurrados ao pé */
.sidebar-rodape {
    margin-top: auto;
    padding-top: 0.5rem;
}

.sidebar a, .sidebar .em-breve, .menu-usuario ul a {
    display: block;
    /* o Pico dá a todo `nav li a` uma margem vertical negativa (hit-area) que cancelava o padding
       no fluxo mas continuava pintando o fundo de `.ativo` além da caixa — sobrepunha o vizinho
       com o gap entre itens. Zera só a vertical; a horizontal segue negativa (Passo 2). */
    margin-block: 0;
    padding: 0.4rem 0.75rem;
    border-radius: 4px;
    color: var(--ink-2);
    text-decoration: none;
    font-size: 0.9375rem;
}

.sidebar a:hover,
.menu-usuario ul a:hover {
    background: var(--bg);
    color: var(--ink);
}

.sidebar a.ativo {
    background: var(--primary-soft);
    color: var(--primary);
}

.sidebar .em-breve {
    color: var(--muted);
}

/* rodapé (Autenticidade, Ajuda) fora do <nav>: sem a margem horizontal negativa do Pico o texto
   ficava 8px à direita da coluna dos itens de cima (Passo 6, 2026-09-18) */
.sidebar-rodape a, .sidebar-rodape .em-breve {
    margin-inline: -0.5rem;
}

.sidebar .wordmark {
    padding: 0 0.75rem;
    font-size: 1.75rem;
    text-align: center;
}

.area-principal {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    /* tooltips absolutos dos cards (::after) não geram scroll horizontal da página no mobile;
       clip não cria scroll-box nem força overflow-y (ao contrário de hidden). §9: sem scroll-x. */
    overflow-x: clip;
}

.topo {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.875rem 1.5rem;
    border-bottom: 1px solid var(--line);
    background: var(--surface);
}

.titulo-pagina-grupo {
    display: flex;
    align-items: center;
    gap: 0.35rem;
    flex: 1;
    min-width: 0;
}

.topo h1 {
    margin: 0;
    min-width: 0;
    font-size: 1.125rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* menu do usuário no header: <details> nativo, sem JS de posicionamento */
.menu-usuario {
    position: relative;
    margin: 0;
    padding: 0;
    border: 0;
    flex-shrink: 0;
}

.menu-usuario summary {
    display: inline-block;
    max-width: 14rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    vertical-align: bottom;
    color: var(--muted);
    font-size: 0.9375rem;
    cursor: pointer;
    padding: 0.25rem 0.5rem;
    border: 1px solid transparent;
    border-radius: 4px;
}

.menu-usuario summary:hover,
.menu-usuario[open] summary {
    border-color: var(--line);
    color: var(--ink);
}

/* Pico dá margin-bottom ao summary aberto (estilo acordeão) — aqui o menu é um
   dropdown absoluto, então esse espaço só empurra a altura do header. Zerar. */
.menu-usuario[open] summary {
    margin-bottom: 0;
}

.menu-usuario ul {
    position: absolute;
    right: 0;
    top: calc(100% + 0.25rem);
    z-index: 20;
    min-width: 10rem;
    margin: 0;
    padding: 0.25rem;
    list-style: none;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: 6px;
}

.menu-usuario li {
    list-style: none;
    margin: 0;
    padding: 0;
}

.badge-status {
    background: var(--primary-soft);
    color: var(--primary);
    border-radius: 4px;
    padding: 0.125rem 0.5rem;
    font-size: 0.8125rem;
}

.conteudo {
    flex: 1;
    width: 100%;
    max-width: 960px;
    margin-inline: auto;
    padding: 1.5rem;
}

/* Espaço entre seções (Passo 2 da SPEC do rascunho 11): 1rem — a distância medida entre o fim da
   tabela do Mercado Pago e o título Automação, que é a margem inferior da tabela do Pico. É uma
   regra só, cobrada do bloco que ANTECEDE o título; o título não soma margem superior (o `~ h2`
   do Pico dava 2.625rem depois de `p`/`form`/`table`, e 0 depois de `div`, então o mesmo layout
   variava de 16 a 59px). A faixa de paginação fecha a seção com a mesma folga. */
.conteudo h2,
.conteudo .secao-cabecalho {
    margin-top: 0;
}

/* `<section>` não soma folga própria (o Pico dá 1rem): o último bloco dela — tabela, parágrafo,
   faixa de paginação — já carrega o 1rem, e os dois juntos davam 32px entre seções do detalhe. */
.conteudo section {
    margin-bottom: 0;
}

/* barra de ações do topo da página (← voltar e atalhos) */
.acoes-topo {
    margin-bottom: 0.5rem;
}

/* Sumário de página (Minha conta, Passo 10 da SPEC UX ampliada): links âncora por seção, no
   corpo do texto (0.9375rem, §1) — não é nav de sidebar. */
.sumario {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem 1rem;
    font-size: 0.9375rem;
    margin-bottom: 1.5rem;
}

/* formulários usam a largura total do conteúdo — mesma da mensagem/tabela central (§2, §5).
   Inputs e textareas herdam essa largura; o botão de ação é que é limitado (abaixo). */
.conteudo form {
    max-width: 100%;
}

/* fieldset nasce com min-inline-size:min-content no UA — não encolhe abaixo do conteúdo.
   No mobile isso estourava o fieldset do cadastro segmentado (468px numa área de 328px) e o
   overflow-x:clip da .area-principal CORTAVA a coluna "Ações": o "✎ alterar" ficava fora da tela
   e sem rolagem. Zerando, o fieldset acompanha a largura e a rolagem volta para o .tabela-wrap. */
fieldset {
    min-inline-size: 0;
}

/* botão de ação padrão (Salvar, Gerar…): ocupa a linha mas com teto — nunca estica com a tela,
   encolhe no mobile. Mesmo teto do botão "Conectar". */
.conteudo form > button[type="submit"] {
    width: 100%;
    max-width: 14rem;
}

/* input + botão de ação na mesma linha (ex.: conectar Mercado Pago): a linha toda ocupa a largura do
   conteúdo; o input estica, o botão fica no seu tamanho natural (encolhe com a tela, não cresce). */
.input-com-botao {
    display: flex;
    gap: 0.5rem;
    align-items: start;
}

.input-com-botao input {
    flex: 1;
    margin-bottom: 0;
}

.input-com-botao button {
    width: auto;
    max-width: 14rem;
    flex-shrink: 0;
}

/* legendas de seção do formulário de cliente — destaque como as seções da ficha (h2) */
.conteudo form legend,
.conteudo form .legend-fieldset {
    font-family: "IBM Plex Sans", sans-serif;
    font-weight: 600;
    font-size: 1rem;
    color: var(--ink);
    padding: 0;
    margin-bottom: 0.5rem;
}

/* pessoas vinculadas: cada pessoa gravada é um <details> recolhível (abre pra editar) */
.linha-vinculado {
    border: 1px solid var(--line);
    border-radius: 6px;
    padding: 0.75rem 1rem;
    margin-bottom: 0.75rem;
    background: var(--surface);
}
.linha-vinculado > summary {
    cursor: pointer;
    font-weight: 600;
    color: var(--ink);
}
.linha-vinculado[open] > summary {
    margin-bottom: 0.5rem;
    padding-bottom: 0.5rem;
    border-bottom: 1px solid var(--line);
}
/* Modais (<dialog>): cabeçalho e rodapé FIXOS, rolagem só no corpo (ui-padroes §5.1).
   Pico faz o <article> inteiro rolar (overflow:auto + max-height) — o header e o footer
   somem junto com os campos. Aqui o article vira coluna flex: header/footer travados,
   e o filho do meio (o corpo) é o único que rola. Vale para todo dialog do app. */
dialog article {
    display: flex;
    flex-direction: column;
    overflow: hidden;
    /* dvh, não vh: no navegador móvel a barra de endereço não entra no 100vh e o footer fixo
       (Confirmar) cairia abaixo da dobra. Mesma unidade da sidebar. */
    height: calc(100dvh - var(--pico-spacing) * 2);
}
dialog article > header,
dialog article > footer {
    flex: 0 0 auto;
}
/* rodapé com dois botões (Voltar + Salvar/Avançar) numa linha só: o Pico dá width:100% a todo
   button[type=submit] e, com o footer em bloco, o submit caía para a linha de baixo do Voltar
   (Passo 11). Em flex, o secundário fica no tamanho do texto e o submit ocupa o resto; com um
   botão só, nada muda. As margens do Pico entre botões viram o gap. */
dialog article > footer {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}
dialog article > footer > :is(button, [role="button"]) {
    margin: 0;
}
/* rodapé com um botão só, dentro do wrapper focável de "desabilitado explicado" (§8, Passo 12):
   o <span> não herda o width:100% que o Pico dá a button — sem isso o "Enviar para assinatura"
   encolhia ao tamanho do texto assim que o contador ao lado saiu do rodapé. */
#lote-enviar-wrap {
    flex: 1 1 auto;
}
#lote-enviar-wrap button {
    width: 100%;
}
dialog article > *:not(header):not(footer) {
    flex: 1 1 auto;
    overflow-y: auto;
    min-height: 0;      /* deixa o corpo encolher e rolar dentro do flex */
}
/* o primeiro campo do corpo já cola no cabeçalho (nenhum elemento tem margin-top); o último
   filho, porém, costuma trazer margin-bottom próprio (ex: .linha-vinculado, <p>), o que deixava
   a borda inferior maior que a superior. Zera essa margem final para igualar as duas — regra
   vale para todo dialog do app. */
dialog article > *:not(header):not(footer) > :last-child {
    margin-bottom: 0;
}

/* X no canto superior direito do header do modal (Decisão F, Passo 11) — injetado uma vez por
   dialog no showModal() (base.html). Header vira flex para o título ficar à esquerda e o X à
   direita; alvo de toque >= 24px mesmo com o glifo pequeno. */
dialog article > header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
}
.modal-fechar {
    all: unset;
    box-sizing: border-box;
    min-width: 24px;
    min-height: 24px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 1.25rem;
    line-height: 1;
    color: var(--muted);
    cursor: pointer;
    border-radius: 4px;
}
.modal-fechar:hover {
    color: var(--ink);
}

/* Modal de template de contrato: com o modal em altura de página, o textarea "corpo" cresce
   proporcionalmente pra preencher o espaço em vez de sobrar vazio embaixo. */
.modal-corpo-template {
    display: flex;
    flex-direction: column;
    min-height: 0;
}
#modal-template-corpo {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-height: 0;
}
#modal-template-corpo form {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-height: 0;
}
#modal-template-corpo form p:has(textarea) {
    display: flex;
    flex: 1 1 auto;
    min-height: 0;
}
#modal-template-corpo textarea {
    flex: 1 1 auto;
    resize: none;
}

/* "+ inserir": seletor de tipo + botão, alinhados numa linha compacta */
.inserir-pessoa {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
}
.inserir-pessoa select { width: auto; margin: 0; }
.inserir-pessoa button { width: auto; margin: 0; }

/* cabeçalhos de coluna ordenáveis (lista de clientes) */
th a.ord {
    color: inherit;
    text-decoration: none;
    cursor: pointer;
    white-space: nowrap;
}

th a.ord:hover { text-decoration: underline; }
th a.ord.ord-ativa { color: var(--primary); }

/* ---------- indicadores e gráfico (§7) ---------- */

.cards-indicadores {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 1rem;
    margin: 1rem 0;
}

.card-indicador {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: 6px;
    padding: 1rem;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
}

.card-indicador .rotulo {
    color: var(--muted);
    font-size: 0.8125rem;
}

.card-indicador .valor {
    font-size: 1.5rem;
    color: var(--ink);
}

/* ---------- tooltip (hover/focus) ---------- */

[data-tooltip] {
    position: relative;
    cursor: help;
    border-bottom: 1px dotted var(--muted);
}

[data-tooltip]:focus-visible {
    outline: 2px solid var(--primary);
    outline-offset: 2px;
}

/* balão + caret: ::after é o balão, ::before vira a setinha (Pico usa ambos p/ o balão dele).
   Ancorado à esquerda (cresce p/ a direita) — não corta no card mais à esquerda nem no mobile. */
[data-tooltip]::after,
[data-tooltip]::before {
    position: absolute;
    left: 0;
    z-index: 10;
    opacity: 0;
    pointer-events: none;
    transform: translateY(0.2rem);
    transition: opacity 0.15s ease, transform 0.15s ease;
}

[data-tooltip]::after {
    content: attr(data-tooltip);
    bottom: calc(100% + 0.5rem);
    width: max-content;
    max-width: 15rem;
    padding: 0.5rem 0.7rem;
    border-radius: 6px;
    background: var(--surface);
    color: var(--ink);
    border: 1px solid var(--line);
    border-left: 3px solid var(--primary);
    /* fonte e peso do balão são os do corpo, nunca os do gatilho: o "?" de Evolução (12 meses) vive
       num `h2` (Plex Sans 600) e o balão herdava a família do título. */
    font-family: var(--pico-font-family);
    font-size: 0.75rem;
    font-weight: 400;
    line-height: 1.4;
    text-align: left;
    white-space: normal;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.14);
}

/* nas duas últimas colunas (Ações e a que a antecede, ex.: Contrato em /clientes/) o balão cresce
   para a esquerda: ancorado à esquerda, ele passava da borda da tabela (74px em /clientes/) e
   fazia o `.tabela-wrap` rolar na horizontal. */
td:nth-last-child(-n+2) [data-tooltip]::after { left: auto; right: 0; }
td:nth-last-child(-n+2) [data-tooltip]::before { left: auto; right: 0.75rem; }
/* em célula de tabela o balão invisível (opacity 0) ainda ocupa layout e alarga o scrollWidth da
   célula: só existe em hover/foco. */
td [data-tooltip]:not(:hover, :focus)::after,
td [data-tooltip]:not(:hover, :focus)::before,
th [data-tooltip]:not(:hover, :focus)::after,
th [data-tooltip]:not(:hover, :focus)::before { display: none; }
/* no cabeçalho não há linha acima: o balão abriria para fora do `.tabela-wrap` e seria recortado
   pelo overflow — abre PARA BAIXO, sobre as linhas (mesma virada de .campos-par). */
th [data-tooltip]::after { bottom: auto; top: calc(100% + 0.5rem); }
th [data-tooltip]::before {
    bottom: auto;
    top: calc(100% - 0.15rem);
    border-top-color: transparent;
    border-bottom-color: var(--line);
}
/* o Pico anima o balão (deslize de ~4rem no `::after`) por 0.2s: em célula de tabela isso alargava o
   `scrollWidth` do `.tabela-wrap` por alguns frames (56px na coluna Contrato de /clientes/) e a
   barra de rolagem piscava. Em célula/cabeçalho o balão já nasce no lugar — sem animação e sem
   `transform`; o `overflow-x: hidden` global esconderia o sintoma e cortaria a ajuda. */
:is(td, th) [data-tooltip]:is(:hover, :focus)::after,
:is(td, th) [data-tooltip]:is(:hover, :focus)::before { animation: none; transform: none; }

/* caret triangular apontando pra baixo, junto à borda esquerda do balão */
[data-tooltip]::before {
    content: "";
    left: 0.75rem;
    bottom: calc(100% + 0.15rem);
    border: 5px solid transparent;
    border-top-color: var(--line);
    /* o Pico dá fundo escuro e padding ao ::before (balão dele): sem zerar, o caret virava um
       retângulo cheio em vez de triângulo (achado no Passo 8, valia para todo tooltip). */
    padding: 0;
    background: none;
    border-radius: 0;
}

[data-tooltip]:hover::after,
[data-tooltip]:hover::before,
[data-tooltip]:focus::after,
[data-tooltip]:focus::before {
    opacity: 1;
    transform: translateY(0);
}

:root[data-theme=dark] [data-tooltip]::after,
:root[data-theme=dark] .aviso-balao {
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5);
}

/* gatilho de balão em texto (valor do plano, dia de vencimento ajustado): botão sem o visual de
   botão do Pico, sublinhado pontilhado como o [data-tooltip]. O balão é o popover .aviso-balao
   posicionado pelo script de base.html ([data-aviso]), que escapa do recorte do .tabela-wrap. */
.gatilho-dica,
.acao-desabilitada {
    all: unset;
}

.gatilho-dica {
    cursor: help;
    border-bottom: 1px dotted var(--muted);
    white-space: nowrap; /* "R$ 250,00" não quebra dentro do gatilho em 360px */
}

/* ação visível e indisponível (aditivo, Decisão I): focável para ler o motivo no balão */
.acao-desabilitada {
    color: var(--muted);
    cursor: not-allowed;
}

.gatilho-dica:focus-visible,
.acao-desabilitada:focus-visible {
    outline: 2px solid var(--primary);
    outline-offset: 2px;
}

/* o único lápis do produto (alterar vencimento): SVG inline que herda a cor do link */
.lapis svg {
    vertical-align: -0.2em;
}

.aviso-balao {
    position: fixed;
    inset: auto;
    margin: 0;
    max-width: min(15rem, calc(100vw - 1rem));
    white-space: normal; /* herdaria o nowrap da célula e cortaria a mensagem */
    padding: 0.5rem 0.7rem;
    border-radius: 6px;
    background: var(--surface);
    color: var(--ink);
    border: 1px solid var(--line);
    border-left: 3px solid var(--primary);
    font-size: 0.75rem;
    line-height: 1.4;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.14);
}

.evolucao h2 {
    margin-bottom: 0.75rem;
}

/* marcador "?" de ajuda ao lado de um título (dispara o [data-tooltip]) */
.info-marca {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.1rem;
    height: 1.1rem;
    border-radius: 50%;
    border-bottom: 0;
    background: var(--line);
    color: var(--muted);
    font-size: 0.6875rem;
    font-weight: 600;
    vertical-align: middle;
}

.grafico-evolucao {
    width: 100%;
    height: auto;
    display: block;
}

/* SVG + gatilho HTML da barra parcial: o gatilho é posicionado em % do viewBox desta caixa */
.grafico-evolucao-caixa {
    position: relative;
    margin-bottom: 1rem; /* fecha a seção Evolução com o mesmo 1rem das tabelas */
}

/* span transparente sobre a barra do mês corrente: dá o [data-tooltip] do Gerimos no hover/foco
   (o <title> do SVG só abria o balão nativo escuro). min-height: barra zerada continua clicável. */
.gatilho-parcial {
    position: absolute;
    min-height: 0.5rem;
    border-bottom: 0;
}

/* última barra: balão à esquerda dela, apoiado na base — fica dentro da caixa do gráfico, que no
   mobile rola na horizontal e recortaria um balão acima/à direita. Caret aponta para a barra. */
.gatilho-parcial::after {
    left: auto;
    /* encostado na barra (Passo 3 da rodada 7): 5px = a metade visível do caret, que ocupa
       exatamente essa folga — antes eram 8px, com um vão vazio entre o balão e a barra. */
    right: calc(100% + 5px);
    bottom: 0;
}

.gatilho-parcial::before {
    left: auto;
    right: calc(100% - 5px);  /* border-box de 10px: a ponta cai na borda da barra */
    bottom: 0.75rem;
    border-top-color: transparent;
    border-left-color: var(--line);
}

.grafico-evolucao .barra-evolucao { fill: var(--chart-bar); }
/* mês corrente em andamento: barra mais clara + rótulo "parcial" — lê como parcial, não vazia */
.grafico-evolucao .barra-evolucao.parcial { fill: var(--chart-bar); opacity: 0.45; }
.grafico-evolucao .marca-parcial { fill: var(--muted); font-size: 10px; }
.grafico-evolucao .linha-max { stroke: var(--line); stroke-dasharray: 3 3; }
.grafico-evolucao text {
    fill: var(--muted);
    font-family: "IBM Plex Mono", monospace;
    font-variant-numeric: tabular-nums;
}
/* ---------- tabelas (§6) ---------- */

.tabela-wrap {
    overflow-x: auto;
}

table {
    font-size: 0.9375rem;
}

/* Pico dá 1rem de padding lateral por célula — 32px por coluna, 192px numa tabela de 6 colunas,
   que saíam da única coluna de texto (Cliente). 0.5rem é o mesmo passo de espaçamento do resto. */
td, th {
    padding-inline: 0.5rem;
}

/* Colunas curtas encolhem ao conteúdo (width:1% + nowrap); coluna sem classe é variável e
   absorve a folga da tabela. `<th>` e `<td>` da mesma coluna levam a mesma classe — é isso que
   mantém cabeçalho e corpo alinhados (Decisão E, SPEC de UX/Contratos pós-teste). A regra
   genérica anterior (seletor negativo pela extinta classe "principal", com layout fixo) foi
   removida por regressão: pegava quase todas as tabelas (quase nenhuma marcava a coluna
   especial) e, com layout fixo e nowrap, conteúdo largo transbordava a célula (2026-09-10). */
td.num, th.num,
td.data, th.data,
td.situacao, th.situacao,
td.acoes, th.acoes,
td.curta, th.curta {
    white-space: nowrap;
    width: 1%;
}

td.num, th.num {
    text-align: right;
}

td.data, th.data,
td.curta, th.curta {
    text-align: left;
}

/* Exceção localizada à regra "dinheiro à direita" (rascunho 11, Passo 8): Valor de Sua assinatura
   Gerimos e Tarifa das tarifas do Mercado Pago são centralizados, cabeçalho e células juntos, mantendo
   a tipografia `.num` (Plex Mono tabular). As demais colunas de dinheiro seguem à direita. */
td.num.centro, th.num.centro {
    text-align: center;
}

/* coluna variável (sem classe curta): absorve a folga da tabela. Sem isso o navegador soma o
   max-content de cada coluna e a tabela cresce além do `.tabela-wrap` (a coluna de texto livre
   é, sozinha, o que sobra da conta). */
table :is(td, th):not(.num):not(.data):not(.situacao):not(.acoes):not(.curta) {
    width: 100%;
}

/* Nome em Pessoas (detalhe do cliente, Passo 11): continua a coluna variável (absorve a folga,
   regra acima), mas nunca quebra em duas linhas — ao lado de Contatos e Endereço, duas células
   expansíveis de 14rem cada, um nome comum reflui e desalinha a altura da linha. */
td.nome, th.nome {
    white-space: nowrap;
}

/* Ações centralizada em toda tabela (rodada 7, Decisão D) — padrão único, não mais exceção da
   coluna Cobrar. E sem `font-size` próprio: a célula de ação herda o 0.9375rem da tabela, que é
   o tamanho único de célula (Decisão C); o 0.8125rem miúdo anterior destoava das vizinhas. */
td.acoes, th.acoes {
    text-align: center;
}

td.situacao, th.situacao {
    white-space: nowrap;
    width: 1%;
}

/* Motivo (falhas da Automação) é a segunda coluna de texto livre da tabela: com duas colunas
   variáveis o Chromium dá a folga toda à primeira (Cliente) e o motivo caía a uma palavra por
   linha. O mínimo garante 2–3 linhas; empilhada no mobile, 12rem ainda cabe em 360. */
td.motivo, th.motivo {
    min-width: 12rem;
}

td.acoes > a {
    margin-left: 0.5rem;
}

/* Texto livre longo em célula de largura definida (e-mail e endereço em Pessoas, Passo 4 do
   rascunho 11). 14rem é a medida única desta coluna (16rem espremia a coluna Nome em duas linhas
   a 1440px: seis colunas dividem os ~57rem úteis da tabela); fechado, uma linha com reticências; aberto
   (botão .expandir, aria-expanded), o conteúdo integral quebra DENTRO da célula — a largura não
   muda, só a altura da linha, então a página não alarga. `anywhere` quebra e-mail sem espaço. */
:root {
    --coluna-texto: 14rem;
}

.celula-expansivel {
    display: flex;
    align-items: baseline;
    gap: 0.5rem;
    width: var(--coluna-texto);
}

/* Competência de /pagamentos/ (Passo 5 do rascunho 11): 9rem de texto (o maior rótulo previsto,
   "09/2026 – 11/2026", mede ~125px, ~8rem) + gap + botão (3rem). Texto maior trunca e expande sem
   alargar a coluna — quem absorve a folga da tabela é o nome do cliente. */
.celula-expansivel.celula-competencia {
    width: 12.5rem;
}

.celula-expansivel .texto {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.celula-expansivel .texto[data-aberto] {
    overflow: visible;
    white-space: normal;
    overflow-wrap: anywhere;
}

.celula-expansivel .expandir {
    flex: none;
    white-space: nowrap;
    /* largura própria: "+" e "−" ocupam o mesmo espaço, e o texto não reflui ao alternar */
    box-sizing: border-box;
    width: 3rem;
    /* alvo de toque >= 24px (WCAG 2.5.8) mesmo com o símbolo em uma linha só; centralizado nos
       dois estados (fechado "+", aberto "−") — sem isso o glifo ficava colado à esquerda do botão */
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 1.5rem;
}

/* célula Ações com um form/button (Minha conta: Cancelar), em vez de link — mesma altura de
   linha da tabela, não o botão de página inteira. */
td.acoes form {
    display: inline;
}

td.acoes button {
    width: auto;
    margin: 0;
}

/* Extensão de teste no console staff: campos empilhados. Em linha, os quatro controles (nowrap da
   coluna Ações) faziam a tabela passar do `.tabela-wrap` no desktop. */
td.acoes .form-extensao {
    display: grid;
    gap: 0.25rem;
    text-align: left;
    min-width: 12rem;
}

td.acoes .form-extensao :is(input, button) {
    margin: 0;
}

/* Planos Gerimos (Minha conta, Passo 4): a faixa da carteira atual vai em negrito na linha inteira,
   dinheiro incluído — exceção registrada em ui-padroes §6 à regra "`.num` sem peso próprio"; só
   vale aqui, e a linha também se identifica por texto. */
tr.faixa-atual :is(td, th) {
    font-weight: 600;
}

/* baixa manual ("Recebi") faz rede (MP) + SMTP em série dentro da request — sem feedback,
   o clique parecia travado e convidava ao duplo clique. */
a.recebi.htmx-request {
    opacity: .5;
    pointer-events: none;
    font-size: 0;
}

a.recebi.htmx-request::after {
    content: "confirmando…";
    font-size: 0.9375rem;
}

/* o primeiro item não leva o separador: com a coluna centralizada, a margem só à esquerda
   descentraria o conteúdo dentro da célula. */
td.acoes > :first-child {
    margin-left: 0;
}

/* Menu de ações (Passo 2 da SPEC do rascunho 11, D8): linha com mais de uma ação mostra o gatilho
   "Ações" e o menu num `popover` nativo — camada superior, fora do recorte do `.tabela-wrap`.
   Posição, foco e fechamento por Escape/clique fora: `static/js/modais.js`. Ação única fica direta
   e "Cobrar" nunca entra em menu. */
.menu-acoes-gatilho {
    all: unset;
    cursor: pointer;
    color: var(--primary);
    text-decoration: underline;
}

.menu-acoes-gatilho:hover,
.menu-acoes-gatilho:focus-visible {
    color: var(--pico-primary-hover);
}

.menu-acoes-gatilho:focus-visible {
    outline: 2px solid var(--primary);
    outline-offset: 2px;
}

.menu-acoes-gatilho::after {
    content: "";
    display: inline-block;
    margin-left: 0.3em;
    border: 0.3em solid transparent;
    border-top-color: currentColor;
    border-bottom-width: 0;
    vertical-align: 0.1em;
}

.menu-acoes {
    position: fixed;
    inset: auto;
    margin: 0;
    padding: 0.25rem;
    min-width: 9rem;
    max-width: min(20rem, calc(100vw - 1rem));
    max-height: calc(100vh - 1rem);
    overflow-y: auto;
    text-align: left;
    white-space: normal;
    background: var(--surface);
    color: var(--ink);
    border: 1px solid var(--line);
    border-radius: 6px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.14);
}

/* o JS posiciona depois de abrir; até lá o menu não pisca no canto */
.menu-acoes:popover-open:not([data-posicionado]) {
    visibility: hidden;
}

:root[data-theme=dark] .menu-acoes {
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5);
}

/* item = linha inteira clicável (alvo de toque de 2.75rem no mobile); a margem lateral de
   `td.acoes a` e o `inline-block` do mobile não valem aqui */
.menu-acoes > :is(a, button) {
    all: unset;
    display: block;
    box-sizing: border-box;
    padding: 0.5rem 0.75rem;
    border-radius: 4px;
    color: var(--primary);
    cursor: pointer;
    white-space: nowrap;
}

.menu-acoes > :is(a, button):is(:hover, :focus-visible) {
    background: var(--primary-soft);
}

.menu-acoes > :is(a, button):focus-visible {
    outline: 2px solid var(--primary);
    outline-offset: -2px;
}

.menu-acoes > .acao-desabilitada {
    color: var(--muted);
    cursor: not-allowed;
}

/* formulário dentro do menu (extensão de teste no console staff): o `form` mantém a grade própria */
.menu-acoes > .form-extensao {
    padding: 0.5rem 0.75rem;
}

/* id da mensagem na Meta (wamid.…) é uma palavra só de ~60 caracteres: quebra em qualquer ponto
   para o relatório de notificações caber em 360px sem rolagem horizontal. */
td.comprovante {
    overflow-wrap: anywhere;
}

.pill {
    display: inline-block;
    border-radius: 999px;
    padding: 0.06rem 0.6rem;
    font-size: 0.8125rem;
}

/* Pills comparáveis (mesma coluna de status: Ativo/Inativo, Situação do contrato, Status da
   cobrança/fatura) têm a mesma largura, centradas (Passo 11) — escopado às colunas de status
   (`.curta`/`.situacao`), não a todo `.pill` do app: a "Automatizada" da coluna Cobrar
   (`td.acoes.cobrar`) é um selo isolado, não uma família de status comparável, e não deve herdar
   essa largura. O rótulo mais comprido em célula de tabela é "Não confirmado" (14 caracteres,
   notificações da cobrança) — min-width cobre esse caso com folga e o texto menor ("Pago",
   "Ativo") centraliza dentro do mesmo retângulo, em vez de pills de tamanhos díspares na coluna. */
td.curta .pill, td.situacao .pill {
    min-width: 7.5rem;
    text-align: center;
}

/* pill que vira link (status "Pago" → comprovante do provedor): mantém a cor do status, sem o
   sublinhado/azul de link do Pico. */
a.pill {
    text-decoration: none;
    cursor: pointer;
}
a.pill:hover {
    text-decoration: underline;
}

.pill-ativo {
    background: var(--primary-soft);
    color: var(--primary);
}

.pill-inativo {
    border: 1px solid var(--line);
    color: var(--muted);
}

/* status fixos da identidade visual (Pago/Pendente/Atrasado) — cor não muda com o tema,
   mesmo padrão hardcoded de .mensagens li.success/.error (contraste AA já conferido) */
.pill-pago {
    background: #ddf3dd;
    color: #086108;
}

.pill-pendente {
    background: #fdf3d7;
    color: #7a5a00;
}

.pill-atrasado {
    background: #fbe1e1;
    color: #a02020;
}

tr.inativo td {
    color: var(--muted);
}

/* ---------- toggle da sidebar ---------- */

/* ☰ só no mobile (abre o drawer); sem colapso de sidebar no desktop por enquanto */
.menu-btn {
    display: none;
    align-items: center;
    justify-content: center;
    width: 2.25rem;
    height: 2.25rem;
    border: 1px solid var(--line);
    border-radius: 4px;
    color: var(--ink);
    cursor: pointer;
    flex-shrink: 0;
}

.backdrop {
    display: none;
}

/* texto secundário (dica, rótulo auxiliar) — classe já usada nos templates */
.muted {
    color: var(--muted);
}

/* coluna Alunos da lista de clientes: um nome por linha, sem quebrar o nome */
.alunos span {
    display: block;
    white-space: nowrap;
}

/* cabeçalho de seção com controle à direita (por-página, período) */
.secao-cabecalho {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
}

/* estado + ação numa linha só (Mercado Pago em Configurações): botão/link direto, sem <form> de
   busca por perto — sem isso herdam a largura 100% padrão do Pico e quebram para a linha de baixo
   mesmo com espaço sobrando. flex-wrap do pai acima já resolve o encaixe em telas estreitas. */
.secao-cabecalho > a[role="button"],
.secao-cabecalho > button {
    width: auto;
    max-width: none;
    flex-shrink: 0;
    margin: 0;
}

.controle-listagem {
    margin: 0;
    font-size: 0.875rem;
}

.controle-listagem label {
    color: var(--muted);
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
}

.controle-listagem select {
    width: auto;
    height: auto;  /* variante compacta — fora da altura padrão de controle (§5) */
    margin: 0;
    padding: 0.15rem 1.75rem 0.15rem 0.5rem;
}

/* busca da lista de clientes: input estica, o seletor de "por página" fica no seu tamanho (§5) */
.secao-cabecalho form:has(input[type="search"]) {
    display: flex;
    align-items: center;
    gap: 1rem;
    flex-wrap: wrap;
    /* preenche a largura da seção: o input estica e "Mostrar" encosta na direita (§5) */
    flex: 1;
}

.secao-cabecalho form:has(input[type="search"]) input[type="search"] {
    flex: 1;
    min-width: 12rem;
    margin: 0;
}

/* botão de ação dentro do form de busca ("+ Template"): sem a margem inferior do Pico, que o
   align-items:center contava na caixa e deixava o botão 8px acima do centro da busca (Passo 11) */
.secao-cabecalho form:has(input[type="search"]) button {
    margin: 0;
}

/* ação de criar de página de lista (§6.1): "+ Cliente", "+ Cobrança eventual", "+ Template" — o
   mesmo botão sólido do "Filtrar", não link. `.acao-secao` segue valendo em seção de detalhe e
   modal. Altura: o <a role="button"> não entra na regra de controle (§5) e, como âncora, não
   centraliza o texto sozinho numa altura fixa. */
.acao-criar {
    height: 3.125rem;
    display: inline-flex;
    align-items: center;
}

/* botão "Filtrar" (pagamentos) e a ação de criar: na mesma linha dos seletores, tamanho de
   controle — não o botão de ação padrão full-width (§5), que quebraria a linha por ser largo demais. */
.secao-cabecalho form:has(input[type="search"]) :is(button[type="submit"], .acao-criar) {
    width: auto;
    max-width: none;
    padding-inline: 1.25rem;
    flex-shrink: 0;
    margin: 0;
}

/* filtros de pagamentos: Situação/Competência têm rótulo em cima — alinhar tudo pela base
   deixa os quatro controles (busca, select, mês, Filtrar) na mesma linha e mesma altura */
/* o :has repete o do bloco genérico acima para ganhar dele na especificidade */
.secao-cabecalho form.filtros-pagamentos:has(input[type="search"]) {
    align-items: flex-end;
}

.filtros-pagamentos {
    margin-bottom: 1rem;  /* respiro que os margins zerados dos controles davam antes */
}

.filtros-pagamentos label {
    margin: 0;
}

/* Passo 9 (Decisão K): o filtro de signatários perdeu o <label> visível (só aria-label) — sem o
   rótulo em cima, o select precisa das mesmas medidas que os rotulados, senão herda o width:100%
   do Pico e empurra o "+ Template" para a linha de baixo. */
.filtros-pagamentos > select {
    width: auto;
    margin-bottom: 0;
    flex-shrink: 0;
}

.filtros-pagamentos label > select,
.filtros-pagamentos label > input {
    margin-bottom: 0;
}

/* Situação/Competência não precisam esticar como o campo de busca — largura próxima do
   conteúdo devolve espaço pro input de busca (§5) */
.filtros-pagamentos label > select,
.filtros-pagamentos label > input[type="month"] {
    display: block;  /* select/input são inline-block por padrão; só o width:100% do Pico
                         forçava a quebra pro rótulo ficar em cima — width menor perde isso */
}

.filtros-pagamentos label > select {
    width: 9rem;
}

.filtros-pagamentos label > input[type="month"] {
    width: 8.5rem;
}

/* faixa de paginação comum (`_paginacao.html`, Decisão H/Passo 3): navegação centralizada na
   faixa e "Mostrar" encostado à direita (grid 1fr controles 1fr); quebra em duas linhas no
   mobile em vez de rolar a página (§9). Vale para toda tabela paginada, inclusive o Painel e a
   seleção do "+ Signatário" (modal). */
/* filtro de período + paginação no mesmo rodapé (Painel → Contratos vencendo, Passo 12): o
   filtro fica em cima, a faixa de paginação embaixo — cada um já centraliza o próprio conteúdo. */
.rodape-lista .controle-listagem {
    margin-bottom: 0.5rem;
}

.paginacao-lista {
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    gap: 0.5rem 1rem;
    margin-block: 0.75rem 1rem;
    font-size: 0.875rem;
}

.paginacao-controles {
    grid-column: 2;
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.paginacao-controles > span {
    color: var(--muted);
    white-space: nowrap;
}

.paginacao-controles > a,
.paginacao-controles > button {
    width: auto;
    height: auto;  /* variante compacta — fora da altura padrão de controle (§5), igual ao link */
    margin: 0;
    padding: 0.3rem 0.5rem;
    display: inline-flex;
    align-items: center;
    line-height: 1;
    text-decoration: none;
    background: var(--surface);
    color: var(--primary);
    border: 1px solid var(--line);
    border-radius: var(--pico-border-radius);
}

.paginacao-controles > a:hover {
    border-color: var(--primary);
}

.paginacao-controles > a:focus-visible {
    outline: 2px solid var(--primary);
    outline-offset: 2px;
}

/* destino indisponível: botão nativo desabilitado, sem o esmaecido de 50% do Pico */
.paginacao-controles > button:disabled {
    opacity: 1;
    color: var(--muted);
    background: transparent;
    cursor: not-allowed;
}

.paginacao-lista .controle-listagem {
    grid-column: 3;
    justify-self: end;
    margin: 0;
}

/* ficha de cadastro do cliente (rascunho §5) */
.dados-cadastro {
    display: grid;
    grid-template-columns: minmax(8rem, max-content) 1fr;
    gap: 0.35rem 1rem;
    margin: 0;
}

.dados-cadastro dt {
    color: var(--muted);
}

.dados-cadastro dd {
    margin: 0;
    overflow-wrap: anywhere;
    min-width: 0;
}

.recomendacoes-senha {
    font-size: 0.875rem;
    margin-bottom: 1rem;
}

/* ---------- mobile (§9) ---------- */

@media (max-width: 768px) {
    .menu-btn {
        display: flex;
    }

    .sidebar {
        position: fixed;
        inset: 0 auto 0 0;
        width: 260px;
        height: 100dvh;
        z-index: 15;
        transform: translateX(-100%);
        transition: transform 0.2s ease;
    }

    body:has(.nav-toggle:checked) .sidebar {
        transform: translateX(0);
    }

    body:has(.nav-toggle:checked) .backdrop {
        display: block;
        position: fixed;
        inset: 0;
        z-index: 14;
        background: rgba(0, 0, 0, 0.4);
    }

    .topo {
        padding: 0.75rem 1rem;
        flex-wrap: wrap;
    }

    .conteudo, .conteudo-publico {
        padding: 1rem;
    }

    .card-publico {
        padding: 1.5rem;
    }

    .cards-indicadores {
        grid-template-columns: 1fr;
    }

    /* header numa linha só: com wrap, o nome do tenant caía sozinho numa segunda linha e o
       header comia ~90px de altura fixa. O nome trunca com reticências. */
    .topo {
        flex-wrap: nowrap;
    }

    .menu-usuario summary {
        max-width: min(9rem, 20vw);
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

    /* a tabela é ~2x mais larga que a tela: a coluna de ações — que é o que se faz na tela —
       ficava atrás de uma rolagem sem indicação. Grudada à direita, fica sempre alcançável.
       Fora .cobrar (WhatsApp/E-mail/Recebi): 215px grudados sobrariam 113px pro conteúdo. */
    td.acoes:not(.cobrar), th.acoes:not(.cobrar) {
        position: sticky;
        right: 0;
        border-left: 1px solid var(--line);
    }

    /* alvo de toque: os links de ação tinham 15–18px de altura (WCAG 2.5.8 pede 24 no mínimo). */
    td.acoes > a, .acoes.cobrar a, td a.ord, th a.ord {
        display: inline-block;
        padding-block: 0.75rem;
    }

    /* o SVG do gráfico escala junto com a largura: a 328px sobravam 72px de altura e os rótulos
       de eixo caíam para ~5px efetivos (§7 pede eixo legível). Largura mínima + rolagem mantém a
       escala legível — mesmo recurso do .tabela-wrap. */
    .evolucao {
        overflow-x: auto;
    }

    /* 44rem: a 34rem a escala ficava em 0.6 e o rótulo de eixo (13px) caía para ~8px — ainda
       ilegível. Aqui a escala é ~0.77 e o eixo sai em ~10px. Na caixa (não no SVG): o gatilho
       da barra parcial é posicionado em % dela e precisa acompanhar a mesma largura. */
    .grafico-evolucao-caixa {
        min-width: 44rem;
    }

    /* PDF embutido não renderiza em navegador móvel — fica o link "Abrir contrato (PDF)" */
    .pdf-embed {
        display: none;
    }

    /* API key + "Reconectar" lado a lado sobravam ~130px pro input — apertado pra colar uma
       key longa. Empilha, como os campos normais do form já fazem por serem block-level. */
    .input-com-botao {
        flex-direction: column;
        align-items: stretch;
    }

    /* em coluna, o `flex: 1` do input vira base 0 na ALTURA e o encolhe abaixo dos 3.125rem (§5) */
    .input-com-botao input {
        flex: none;
    }

    .input-com-botao button {
        width: 100%;
        max-width: none;
    }

    /* faixa de paginação: sem largura pra três colunas lado a lado — quebra em duas linhas,
       controles centralizados na primeira, "Mostrar" encostado à direita na segunda (Passo 3) */
    .paginacao-lista {
        grid-template-columns: 1fr;
    }

    .paginacao-controles {
        grid-column: 1;
        justify-self: center;
    }

    .paginacao-lista .controle-listagem {
        grid-column: 1;
        justify-self: end;
    }

    /* tabela empilhada (Automação, Passo 9 da rodada 7): Configurações cabe no 360 sem rolagem
       interna — cada linha vira um bloco e cada célula leva o rótulo da coluna (`data-rotulo`).
       Só onde há poucas linhas: numa lista longa a rolagem com Ações grudada (§9) lê melhor. */
    .tabela-empilhada thead {
        display: none;
    }

    .tabela-empilhada tr {
        display: block;
        border-bottom: 1px solid var(--line);
    }

    .tabela-empilhada :is(td, th) {
        display: block;
        width: auto;
        white-space: normal;
        text-align: left;
        border-bottom: 0;
        padding-block: 0.25rem;
    }

    .tabela-empilhada td.acoes {
        position: static;
        border-left: 0;
    }

    .tabela-empilhada td[data-rotulo]::before {
        content: attr(data-rotulo) ": ";
        color: var(--muted);
        font-family: "IBM Plex Sans", sans-serif;  /* o rótulo de td.num não herda a mono */
    }
}
