/* 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 pelo toggle de Minha conta (localStorage).
   Passo 8 do rascunho 21: todo token do Pico que o app usa tem valor stone aqui — sem isso o dark
   do Pico vaza fundos azulados (card/modal, code, switch, tooltip). Contrastes medidos em
   tests_navegador/navegador_rascunho21_tema.py. */
:root[data-theme=dark] {
        --bg: #171614;
        --surface: #201f1c;
        --ink: #ece9e4;
        --ink-2: #b8b3ad;
        --muted: #96918a; /* 5,3:1 sobre --surface (o #8a857d dava 4,50) */
        --line: #35322d;
        --primary: #14b8a6;
        --primary-soft: #123b37;
        --chart-bar: #3f7f79; /* 3,9:1 sobre --bg (o #2f5f5b dava 2,5) */

        /* 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-color: var(--ink);
        --pico-h1-color: var(--ink);
        --pico-h2-color: var(--ink);
        --pico-h3-color: var(--ink);
        --pico-h4-color: var(--ink-2);
        --pico-h5-color: var(--ink-2);
        --pico-h6-color: var(--ink-2);
        --pico-text-selection-color: rgba(20, 184, 166, 0.3);
        --pico-secondary-background: #57534e;
        --pico-secondary-border: #57534e;
        --pico-secondary-hover-background: #6b665f;
        --pico-secondary-hover-border: #6b665f;
        --pico-contrast-background: var(--ink);
        --pico-contrast-border: var(--ink);
        --pico-contrast-inverse: var(--bg);
        --pico-mark-background-color: var(--primary-soft);
        --pico-mark-color: var(--ink);
        --pico-code-background-color: #2a2825;
        --pico-code-color: var(--ink-2);
        --pico-table-row-stripped-background-color: rgba(236, 233, 228, 0.04);
        --pico-card-background-color: var(--surface);
        --pico-card-border-color: var(--line);
        --pico-card-sectioning-background-color: var(--surface);
        --pico-modal-overlay-background-color: rgba(0, 0, 0, 0.7);
        --pico-progress-background-color: var(--line);
        --pico-switch-background-color: #57534e;
        --pico-switch-checked-background-color: var(--pico-primary-background);
        --pico-tooltip-background-color: var(--ink);
        --pico-tooltip-color: var(--bg);
        --pico-form-element-background-color: var(--bg);
        --pico-form-element-color: var(--ink);
        --pico-form-element-selected-background-color: #35322d;
        --pico-form-element-active-background-color: var(--bg);
        /* borda do campo é o indicador do componente: 3,4:1 sobre --surface (a --line dava 1,4) */
        --pico-form-element-border-color: #78716c;
        --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;
}

/* link dentro do aviso acompanha a cor do próprio aviso (success/warning/error) e continua
   sublinhado, em todos os estados — as regras globais de link (Pico) davam verde num aviso amarelo */
:is(.mensagens, ul.errorlist) li a:is(:link, :visited, :hover, :active, :focus, :focus-visible) {
    color: inherit;
    text-decoration-line: underline;
    text-decoration-color: currentColor;
}

/* 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): "+ Modelo", "+ Campanha" 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;
}

/* tutorial do Painel (SPEC 14, D5/D6): banner final no padrão verde de sucesso e botões-link em POST */
.banner-sucesso {
    background: #ddf3dd;
    color: #086108;
    border: 1px solid #0ca30c;
    border-radius: 6px;
    padding: 0.75rem 1rem;
    margin-bottom: 1rem;
}

.form-tutorial {
    display: inline;
    margin: 0;
}

.link-botao {
    display: inline;
    width: auto;
    margin: 0;
    padding: 0;
    border: 0;
    background: none;
    color: inherit;
    font: inherit;
    text-decoration: underline;
    cursor: pointer;
}

/* notificação com ação (Decisão C do rascunho 18, ui-padroes §8): o banner verde inteiro é o botão,
   mesma anatomia do `.banner-pendencia`; o `<form>` que o envolve não soma margem */
.form-banner {
    margin: 0 0 1rem;
}

/* `.conteudo .form-banner >` vence o teto de 14rem do botão de submit padrão */
.banner-sucesso.banner-acao,
.conteudo .form-banner > .banner-acao {
    display: block;
    width: 100%;
    max-width: none;
    text-align: left;
    border-radius: 4px;
    padding: 0.5rem 0.75rem;
    margin: 0;
    font-size: 0.9375rem;
    font-weight: normal;
    cursor: pointer;
}

/* o Pico pinta botão em hover/foco com a cor primária: o banner mantém o verde e escurece de leve
   (sem hex novo); o foco visível é um contorno verde no lugar do anel do Pico */
.banner-sucesso.banner-acao:is(:hover, :focus, :active) {
    background: #ddf3dd;
    color: #086108;
    border-color: #0ca30c;
}

.banner-sucesso.banner-acao:hover {
    filter: brightness(0.95);
}

.banner-sucesso.banner-acao:focus-visible {
    box-shadow: none;
    outline: 2px solid #0ca30c;
    outline-offset: 2px;
}

/* 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;
}

/* quebra por palavra (Decisão D do rascunho 19): `anywhere` reduzia o min-content e partia palavra
   que cabia na linha de baixo; token sem espaço que precise partir leva `[data-token]` */
table.tabela-campos td {
    overflow-wrap: break-word;
}

/* o seletor da célula entra para vencer a especificidade de `table.tabela-campos td` */
[data-token],
table.tabela-campos td[data-token] {
    overflow-wrap: anywhere;
}

/* Decisão A do rascunho 19: o Valor é mais um campo da tabela campo/valor — alinhado à esquerda
   como os demais; a mono fica. A coluna `.num` das listas segue à direita. */
table.tabela-campos td.num {
    text-align: left;
}

/* 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; }
}

/* indicador de requisição HTMX (ui-padroes §8): popover manual no topo, acima até de modal, aceso só
   depois de 300ms (modais.js). Discreto: superfície + spinner no primário, sem bloquear a tela. */
#indicador-htmx {
    inset: 0.75rem auto auto 50%;
    transform: translateX(-50%);
    margin: 0;
    display: none;
    align-items: center;
    gap: 0.5rem;
    padding: 0.25rem 0.75rem;
    background: var(--surface);
    color: var(--ink-2);
    border: 1px solid var(--line);
    border-radius: 999px;
    font-size: 0.875rem;
    pointer-events: none;
}

#indicador-htmx:popover-open {
    display: flex;
}

#indicador-htmx .spinner {
    width: 0.875rem;
    height: 0.875rem;
    border: 2px solid var(--line);
    border-top-color: var(--primary);
    border-radius: 50%;
    animation: girar 0.8s linear infinite;
}

@keyframes girar {
    to { transform: rotate(360deg); }
}

@media (prefers-reduced-motion: reduce) {
    #indicador-htmx .spinner { animation-duration: 2.4s; }
}

/* contêiner que recebe o foco depois do swap (tabindex="-1", modais.js): sem anel de foco no clique */
[tabindex="-1"]:focus:not(:focus-visible) {
    outline: none;
}

/* campos inseríveis no corpo do contrato (minuta): <button>, inserem por clique, Enter ou Espaço
   na posição do cursor — sem arraste (Passo 6 do rascunho 21) */
button.ph-chip {
    cursor: pointer;
    display: inline-block;
    width: auto;
    height: auto;
    min-height: 0;
    margin: 0 0 0.25rem;
    white-space: nowrap;
    background: var(--primary-soft);
    color: var(--primary);
    border: 1px solid var(--primary);
    border-radius: 999px;
    padding: 0.1rem 0.6rem;
    font-family: inherit;
    font-size: 0.8125rem;
    line-height: 1.5;
}

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

/* 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);
}
/* ---------- 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;
}

/* landing institucional (§4.2): coluna única de 960px, escala estendida só aqui */
body.landing .conteudo-publico { max-width: 960px; margin: 0 auto; padding: 0 1.5rem; }
.topo-landing {
    max-width: 960px;
    margin: 0 auto;
    padding: 2rem 1.5rem 0.5rem;
    display: flex;
    justify-content: space-between;
    align-items: baseline;
}
.topo-landing .wordmark { font-size: 1.75rem; }
.topo-landing .topo-acoes { color: var(--muted); }
.topo-landing a:not(.wordmark), .rodape-landing a, .landing-coluna p > a:only-child { display: inline-block; min-height: 24px; line-height: 24px; }
.landing-coluna section { padding: 2rem 0; border-top: 1px solid var(--line); }
.landing-coluna section:first-child { border-top: 0; }
.landing-coluna p, .landing-coluna li, .landing-coluna dd { max-width: none; }
.landing-coluna h1 { font-size: 2rem; }
.landing-coluna h2 { font-size: 1.375rem; }
/* corpo da landing (Decisão A): 17px no desktop, 16px abaixo de 768; só este escopo, o Pico segue global */
.landing-coluna :is(p, li, dd) { font-size: 1.0625rem; }
/* sem viúva/órfã: h2 e público equilibrados, parágrafos sem palavra sozinha na última linha. O h1 e
   as frases em negrito ocupam a coluna como o corpo (o `balance` encurtava a 1ª linha a ~60% — dono, 2026-10-01) */
.landing-coluna :is(h2, .landing-publico) { text-wrap: balance; }
.landing-coluna :is(p, li, dd) { text-wrap: pretty; }
.landing-publico { color: var(--muted); }
.landing-coluna .landing-nota { font-size: 0.8125rem; }
.landing-coluna :is(ol, ul) { padding-left: 1.25rem; }
.rodape-landing { max-width: 960px; margin: 0 auto; padding: 0 1.5rem; }
.rodape-landing { text-align: center; }
.rodape-landing small { max-width: none; margin: 0; }
.rodape-landing address { font-style: normal; margin-top: 0.5rem; }
.rodape-landing address small { padding-top: 0; border-top: 0; }
@media (max-width: 767.98px) {
    .landing-coluna h1 { font-size: 1.75rem; }
    .landing-coluna :is(p, li, dd) { font-size: 1rem; }
}
/* camada visual v2 (Passo 13, §4.2): screenshots, fluxo, mock e reveals — só tokens, zero JS */
.landing-tela { margin: 1.5rem 0 0; }
.landing-tela img {
    display: block;
    max-width: 100%;
    height: auto;
    border: 1px solid var(--line); /* moldura neutra: o screenshot é claro nos dois temas */
    border-radius: 6px;
    background: var(--surface);
}
.landing-tela img { margin-inline: auto; } /* capturas centralizadas na coluna (dono, 2026-10-01) */
.landing-tela figcaption { margin-top: 0.5rem; font-size: 0.8125rem; color: var(--muted); text-align: center; }
/* "Criar conta" final: centralizado e um pouco mais largo que o botão padrão */
.landing-coluna .landing-cta { text-align: center; }
.landing-cta a[role=button] { padding-inline: 2.5rem; }
/* D8: o hero estoura a coluna de 960 até ~1140px; o respiro de 1rem cobre a barra de rolagem */
.landing-tela-hero {
    --vazamento: clamp(0px, (100vw - 960px) / 2 - 1rem, 114px);
    margin-inline: calc(-1 * var(--vazamento));
}
.landing-tela-hero img { width: 100%; }
/* S4: cinco passos numa linha do tempo vertical — número em Plex Mono, hairline ligando os passos */
.landing-coluna .landing-fluxo { list-style: none; padding-left: 0; counter-reset: fluxo; }
.landing-fluxo li {
    counter-increment: fluxo;
    position: relative;
    padding: 0 0 1.25rem 3rem;
    margin: 0;
}
.landing-fluxo li::before {
    content: counter(fluxo);
    position: absolute;
    left: 0;
    top: 0;
    width: 2rem;
    height: 2rem;
    display: grid;
    place-items: center;
    font-family: "IBM Plex Mono", monospace;
    font-size: 0.9375rem;
    color: var(--primary);
    background: var(--surface);
    border: 1px solid var(--primary);
    border-radius: 4px;
}
.landing-fluxo li:not(:last-child)::after {
    content: "";
    position: absolute;
    left: calc(1rem - 0.5px);
    top: 2.25rem;
    bottom: 0.25rem;
    border-left: 1px solid var(--line);
}
.landing-fluxo li strong { display: block; }
/* S5: mock de conversa neutro (D3) — balões nos tokens do Gerimos, sem logo, verde ou fundo de terceiro */
.landing-badge {
    display: inline-block;
    padding: 0.25rem 0.75rem;
    border: 1px solid var(--line);
    border-radius: 4px;
    background: var(--surface);
    color: var(--ink-2);
}
.landing-coluna .landing-badge { font-size: 0.8125rem; text-wrap: balance; }
.landing-conversa {
    max-width: 26rem;
    margin: 1.5rem auto 0; /* centralizado como as capturas (dono, 2026-10-01) */
    padding: 1rem;
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: 6px;
}
.landing-coluna .landing-balao {
    max-width: 85%;
    margin: 0;
    padding: 0.5rem 0.75rem;
    color: var(--ink);
    background: var(--primary-soft);
    border-radius: 6px 6px 6px 0;
    font-size: 0.9375rem;
}
/* S7: nota do fundador — foto pequena (≤128px, decisão C) ao lado da citação */
.landing-fundador {
    display: grid;
    grid-template-columns: 6rem 1fr;
    gap: 1.25rem;
    align-items: start;
    margin-top: 2rem;
}
.landing-fundador img { display: block; width: 6rem; height: auto; border-radius: 6px; border: 1px solid var(--line); }
.landing-fundador blockquote { margin: 0; padding-block: 0; }
.landing-fundador footer { margin-top: 0.5rem; padding: 0; text-align: left; font-size: 0.8125rem; color: var(--muted); }
@media (max-width: 767.98px) {
    .landing-fundador { grid-template-columns: 4rem 1fr; gap: 1rem; }
    .landing-fundador img { width: 4rem; }
}
/* reveals: scroll-driven, só opacity/transform, degradam para estático sem suporte ou com movimento reduzido */
@keyframes landing-revela { from { opacity: 0; transform: translateY(1rem); } }
@supports (animation-timeline: view()) {
    @media (prefers-reduced-motion: no-preference) {
        body.landing :is(.landing-tela:not(.landing-tela-hero), .landing-conversa) {
            animation: landing-revela linear both;
            animation-timeline: view();
            animation-range: entry 0% entry 60%;
        }
    }
}

/* 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;
}

/* aceite público (rascunho 24): "Ler contrato (PDF)" centralizado; as declarações têm texto de
   várias linhas, então a caixa alinha no topo e cresce a 24px (alvo de toque, ui-padroes §9) */
.aceite-ler {
    text-align: center;
}
.declaracoes-aceite p:has(input[type="checkbox"]) {
    align-items: flex-start;
}
.declaracoes-aceite input[type="checkbox"] {
    width: 1.5rem;
    height: 1.5rem;
}

.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;
    flex-wrap: wrap;              /* Copiar + "Ver código completo" + feedback não cabem em 360 lado a lado */
    align-items: center;
    gap: 0.75rem;
    margin-bottom: 1rem;
}

/* Código longo numa linha (Decisão N do rascunho 24): SHA-256 do aceite e .codigo-copiavel. Fechado,
   uma linha com reticências e sem rolagem; aberto pelo [data-expandir] (_expandir_codigo.html), o
   texto inteiro quebra no próprio elemento. Mesmo par de regras da .celula-expansivel .texto. */
.texto-numa-linha {
    display: block;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

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

.hash-rotulo {
    margin-bottom: 0.25rem;
}

.hash-linha code.hash {
    margin-bottom: 0.25rem;
}

/* disclosure, não link de ação: sem sublinhado (como o .expandir da célula); alvo >= 24px (WCAG
   2.5.8), 44px no celular (M5) */
.expandir-codigo,
.expandir-codigo:hover,
.expandir-codigo:focus-visible {
    text-decoration-line: none;
}

.expandir-codigo {
    display: inline-flex;
    align-items: center;
    min-height: 24px;
    white-space: nowrap;
}

.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 3 da SPEC do rascunho 14, D3; Decisão D do rascunho 18): 48px (`--vao-secao`), no lugar dos 16px
   do rascunho 11. Regra única, cobrada do título: margem superior que colapsa com a margem inferior
   do bloco anterior (tabela, `p`, `form`, gráfico, paginação: todos 1rem ou menos) e dá 3rem depois
   de qualquer um deles, em qualquer viewport. O 1rem da tabela mora no `.tabela-wrap` (não na
   `<table>`, presa dentro do overflow) para colapsar também. Título da abertura da página não
   ganha vão. Sem override por página. */
:root {
    --vao-secao: 3rem;
}

.conteudo h2,
.conteudo .secao-cabecalho {
    margin-top: 0;
}

.conteudo > h2:not(:first-child),
.conteudo > .secao-cabecalho:not(:first-child),
.conteudo > section:not(:first-child) > :is(h2, .secao-cabecalho):first-child {
    margin-top: var(--vao-secao);
}

.tabela-wrap > table:last-child {
    margin-bottom: 0;
}

.tabela-wrap {
    margin-bottom: var(--pico-spacing);
}

/* `<section>` não soma folga própria (o Pico dá 1rem): o último bloco dela já carrega a folga. */
.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é. */
/* wrapper de "desabilitado explicado" (§8) no rodapé: flex, para não somar a folga de linha do
   inline ao botão, e botão sem a margem do Pico — alinha com o irmão direto (mesmo top) */
dialog article > footer > span {
    display: flex;
}
dialog article > footer > span > :is(button, [role="button"]) {
    margin: 0;
}
/* envio de contrato (Passo 6 do rascunho 21): sem Cancelar (X/Esc fecham), o Enviar ocupa a
   largura útil do rodapé, dentro do wrapper de "desabilitado explicado" */
#modal-enviar-contrato footer > span {
    flex: 1 1 auto;
}
#modal-enviar-contrato footer > span > button {
    width: 100%;
}
/* minuta (Passo 6 do rascunho 21): Voltar e Ver prévia com a mesma largura, Salvar modelo com o
   resto sem dominar a linha; no celular, os dois secundários numa linha e o Salvar embaixo */
dialog article > footer.rodape-minuta {
    display: grid;
    grid-template-columns: 2fr 2fr 3fr;
}
/* :is com [role] vence o `button:not(:first-of-type)` do Pico, que somaria margem ao gap */
dialog article > footer.rodape-minuta > :is(button, [role="button"]) {
    min-width: 0;
    margin: 0;
}
/* rótulo de botão de rodapé nunca quebra dentro da caixa (a 360 o rodapé é que quebra em linhas) */
article > footer :is(button, [role="button"]) {
    white-space: nowrap;
}
@media (max-width: 767.98px) {
    article > footer {
        display: flex;
        flex-wrap: wrap;
        gap: 0.5rem;
    }
    article > footer > :is(button, [role="button"]) {
        flex: 1 1 auto;
        margin: 0;
    }
    dialog article > footer.rodape-minuta {
        grid-template-columns: 1fr 1fr;
    }
    dialog article > footer.rodape-minuta > [type="submit"] {
        grid-column: 1 / -1;
    }
}
#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;
    /* piso do editor: em tela baixa (360×740) os campos e a barra tomavam o corpo e o textarea
       encolhia a 0 — com o piso, quem rola é o corpo do modal (Passo 6 do rascunho 21) */
    min-height: 12rem;
}
#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;
}
/* Minuta com editor visual (Passo 3 da SPEC do editor, Decisões A/C/D): o Quill ocupa o lugar do
   textarea `corpo` (que segue no form, escondido e sincronizado) e imita o PDF — serifa, justificado,
   título e cláusula centrados em negrito. Sem prévia lateral: o editor é a prévia. Sem JS (sem
   `.com-editor`) ou no modo texto aparecem o textarea e a barra de marcação; a barra do editor e o
   link de alternar nascem `hidden` e o JS os revela. */
.minuta-editor {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-height: 0;
}
.com-editor .barra-texto,
.com-editor .ajuda-marcacao,
.com-editor .chips-campos,
.com-editor #modal-template-corpo textarea[name="corpo"],
[data-minuta-etapa]:not(.com-editor) :is(.editor-minuta, .barra-editor) {
    display: none;
}
.alternar-modo {
    font-size: 0.875rem;
}
/* Etapa 2 do modal de modelo (Passo 4 do rascunho 24, Decisão M; ui-padroes §5.1.2): o modal alarga
   só nesta etapa e as ferramentas cabem numa linha — formatação à esquerda, IA à direita —, deixando
   ao editor a maior parte da altura. O painel do ajuste com IA nasce recolhido. */
#modal-template article:has(> [data-minuta-etapa]) {
    max-width: min(1400px, 95dvw);
}
.minuta-ferramentas {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    margin-bottom: 0.5rem;
}
.minuta-ferramentas > .barra-formatacao {
    margin-bottom: 0;
}
.minuta-ia {
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem;
    margin-left: auto;
}
.minuta-ia button {
    width: auto;
    margin: 0;
    padding: 0.25rem 0.6rem;
}
.ajuste-ia {
    padding: 0.75rem;
    border: 1px solid var(--line);
    border-radius: var(--pico-border-radius);
}
.ajuste-ia p:last-child {
    margin-bottom: 0;
}
.ajuste-ia button {
    width: auto;
    margin: 0;
}
/* pedido, autorização e envio numa linha só; no celular (bloco abaixo) empilham */
.ajuste-ia:not([hidden]) {
    display: grid;
    grid-template-columns: 1fr auto auto;
    align-items: end;
    gap: 0 1rem;
}
.ajuste-ia > p,
.ajuste-ia input[type="text"] {
    margin-bottom: 0;
}
.ajuste-ia > p:has([type="checkbox"]) {
    align-self: center;
    padding-top: 1.5rem;
}
/* no celular a barra se desfaz na linha de ferramentas (`display: contents`): "Campo ▾", o alternar e a
   IA ocupam o resto da linha dos botões em vez de abrir uma linha cada */
@media (max-width: 767.98px) {
    .minuta-ferramentas {
        gap: 0.25rem;
    }
    .com-editor .minuta-ferramentas > .barra-editor:not([hidden]),
    [data-minuta-etapa]:not(.com-editor) .minuta-ferramentas > .barra-texto {
        display: contents;
    }
    .minuta-ia {
        display: contents;
    }
    .ajuste-ia:not([hidden]) {
        display: block;
    }
    .ajuste-ia > p {
        margin-bottom: 0.75rem;
    }
    .ajuste-ia > p:has([type="checkbox"]) {
        padding-top: 0;
    }
}
.barra-editor button.ql-active {
    background: var(--primary-soft);
    color: var(--primary);
    border-color: var(--primary);
}
/* 23 campos: a lista rola dentro do menu, sem passar da tela abaixo do gatilho */
.menu-campos {
    max-height: min(24rem, 60vh);
}
.barra-formatacao .menu-campos button {
    display: block;
    box-sizing: border-box;
    width: 100%;
    margin: 0;
    text-align: left;
    white-space: normal;
}
.editor-minuta {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-width: 0;
    min-height: 12rem;
    border: 1px solid var(--line);
    border-radius: var(--pico-border-radius);
    background: var(--surface);
    color: var(--ink);
}
.editor-minuta .ql-editor {
    flex: 1 1 auto;
    height: auto;
    padding: 0.75rem 1rem;
    font-family: "DejaVu Serif", Georgia, serif;
    font-size: 1rem;
    line-height: 1.4;
    text-align: justify;
}
.editor-minuta .ql-editor :is(h1, h2) {
    text-align: center;
    font-size: 1rem;
    font-weight: 700;
    color: var(--ink);
    margin: 0 0 0.6rem;
}
.editor-minuta .ql-editor p {
    margin: 0 0 0.6rem;
}
/* chip de campo no editor: mesmo desenho do `.ph-chip`/`.ph-previa`, sem edição por dentro;
   inline-block para o justificado do parágrafo não esticar os espaços do rótulo */
.ph-chip-editor {
    display: inline-block;
    line-height: 1.3;
    font-family: var(--pico-font-family);
    font-size: 0.8em;
    font-weight: 400;
    padding: 0 0.4em;
    border-radius: 999px;
    border: 1px solid var(--primary);
    background: var(--primary-soft);
    color: var(--primary);
    white-space: nowrap;
    user-select: all;
}
.ph-previa {
    font-family: var(--pico-font-family);
    font-size: 0.8em;
    padding: 0 0.4em;
    border-radius: 999px;
    border: 1px solid var(--primary);
    background: var(--primary-soft);
    color: var(--primary);
    white-space: nowrap;
}

/* "+ 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 .rotulo.gatilho-dica {
    align-self: flex-start;
    white-space: normal;
    /* área de toque de 24px (ui-padroes §9) sem crescer o card: a folga volta pela margem */
    padding-block: 3px;
    margin-block: -3px;
}

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

/* ---------- dica (popover `[data-aviso]`, `_dica.html`) ---------- */

/* Mecanismo único de dica do produto (Passo 4 da SPEC landing/UX): o balão de CSS-only (que só abria
   em hover/foco, não no toque, e era recortado por overflow) saiu; cards, "?" de título, barra
   parcial do gráfico e ações desabilitadas usam o popover posicionado por static/js/modais.js. */

: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, rótulo de card): botão sem o
   visual de botão do Pico, sublinhado pontilhado. O balão é o popover .aviso-balao posicionado por
   static/js/modais.js ([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 */
}
/* motivo de falha (Automação) é frase: quebra como o texto da célula */
td.motivo .gatilho-dica { white-space: normal; }

/* pill que só explica (span focável de _dica.html): cursor de ajuda; o pill-link segue pointer */
span.pill[data-aviso] { cursor: help; }

/* 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,
[data-aviso]:focus-visible {
    outline: 2px solid var(--primary);
    outline-offset: 2px;
}

.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 */
    /* herdaria peso/alinhamento do `th` quando a dica mora no cabeçalho (_dica.html) */
    font-family: var(--pico-font-family);
    font-weight: 400;
    text-align: left;
    text-transform: none;
    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);
}

/* fechado, o balão some mesmo onde o contêiner dá `display` aos filhos (rodapé de modal flexível:
   `dialog article > footer > span`) — sem isso o motivo da ação desabilitada aparecia fixo. */
.aviso-balao:not(:popover-open) {
    display: none;
}

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

/* marcador "?" de ajuda ao lado de um título (gatilho de `_dica.html`) */
.info-marca {
    cursor: help;
    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: gatilho `[data-aviso="esquerda"]` do balão do
   Gerimos (o <title> do SVG só abria o balão nativo escuro), que abre à esquerda da barra, apoiado
   na base. min-height: barra zerada ou baixa continua tocável (24px, ui-padroes §9). */
.gatilho-parcial {
    position: absolute;
    min-height: 24px;
}

.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;
}

/* Indicador de rolagem interna (ui-padroes §9): conteúdo cortado à direita esmaece na borda —
   sinal de que há mais colunas. `.rola-mais` vem de static/js/rolagem.js só com overflow real e
   sai no fim da rolagem. A máscara é só alfa (o `black` não é cor de tela); popover de dica fica
   na camada superior, fora dela. No celular, tabela com Ações grudada troca o fade pela sombra
   da coluna grudada (bloco mobile). */
.rola-mais {
    mask-image: linear-gradient(to left, transparent, black 2.5rem);
}

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%;
}

/* Comunicações em Configurações (rascunho 23, Passo 3): duas colunas de texto livre disputavam a folga
   (100% cada) e "Como sai" ficava com ~94px. Comunicação fixa em 22%, "Como sai" leva o resto. */
#tabela-comunicacoes table :is(td, th):first-child {
    width: 22%;
}

/* Nome de cliente (ou de tenant, no staff) em toda tabela (D13 do rascunho 21; antes só Pessoas,
   Passo 6 dos rascunhos 17/18): coluna variável (absorve a folga, regra acima), numa linha só; o
   que não cabe vira reticências — `max-width: 0` faz a célula ceder à tabela em vez de alargá-la,
   então o .tabela-wrap nunca rola. Empilhada no mobile, `.tabela-empilhavel`/`.tabela-empilhada`
   voltam a quebrar. Nome completo no `title`. Nota/erro em `<small>` sob o nome quebra normal. */
td.nome {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 0;
}

td.nome small {
    white-space: normal;
}

/* no celular a lista longa rola dentro do .tabela-wrap (§9): reticências ali reduziam o nome a
   "Mari…"; o nome volta a quebrar por palavra, como antes da D13 (que mede só o desktop) */
@media (max-width: 767.98px) {
    td.nome {
        white-space: normal;
        max-width: none;
        min-width: 9rem;
    }
}

/* Pessoas tem cinco colunas em ~57rem úteis a 1440 px: Contatos e Endereço a 9rem (reticências +
   expansor) deixam um nome de ~50 caracteres inteiro ao lado do CPF */
section.qualificacao {
    --coluna-texto: 9rem;
}

/* 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;
}

/* expansor +/− é controle de disclosure, não link de ação: sem sublinhado em nenhum estado (o
   `.acao-secao` de que herda o estilo sublinha). Foco visível vem do `.acao-secao:focus-visible`. */
.celula-expansivel .expandir,
.celula-expansivel .expandir:hover,
.celula-expansivel .expandir:focus,
.celula-expansivel .expandir:focus-visible,
.celula-expansivel .expandir[aria-expanded="true"] {
    text-decoration-line: none;
}

.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;
}

/* Ajustes no modal da cobrança (Passo 6 do rascunho 21): Efeito e Motivo expansíveis lado a lado
   com Data e Autor; com os 14rem padrão a tabela passava 15 px do corpo quando a barra vertical do
   corpo rolava. 12rem cabe a 1280 com a barra; o texto integral segue no expansor. */
.ajustes-cobranca {
    --coluna-texto: 12rem;
}

/* 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;
}

.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 que vira botão (Falha do lote → tenta de novo a linha): tira altura, borda e margem do
   botão do Pico; cor vem do pill-<status>. */
button.pill {
    height: auto;
    width: auto;
    margin: 0;
    border: 0;
    line-height: inherit;
    cursor: pointer;
}
button.pill:hover {
    text-decoration: underline;
}

/* Alvos de toque (U3/M5, ui-padroes §9): todo interativo tem área efetiva >= 24x24px em qualquer
   viewport; no celular, pill, ação de linha e paginação sobem a 44px. A área cresce sem mexer no
   visual nem no fluxo: padding vertical em elemento inline não altera a linha; pill ganha um
   `::after` transparente centrado (o `top`/`bottom` em % é da própria pill, `position: relative`);
   o "?" de ajuda pinta o círculo só no content-box e devolve a folga com margem negativa.
   `--alvo-toque` é o piso de cada elemento — o bloco mobile o sobe para 44px onde vale M5. */
/* `label`/`span`/`.acoes-topo` (Passo 7: aceite dos Termos, "Esqueceu sua senha?", tarifas nos
   Termos, "← clientes"); `td a.acao-secao`: "dia 10" do vencimento e "Cancelar" de Minha conta */
:where(td, th, p, small, li, label, span, .acoes-topo) > a:where(:not([class])), th a.ord, a.recebi,
td a.acao-secao, .gatilho-dica, .menu-acoes-gatilho {
    padding-block: 6px;
}

/* Decisão J do rascunho 24 (Passo 3): link inline não empurra a linha com o padding, mas botão é caixa
   atômica — o "Ações" e o "R$"/"Termos" de balão levavam a linha da tabela de Contratos de 39,5 a
   52,5px. A margem negativa devolve a folga: o alvo continua com 34px, a linha fica na altura padrão. */
td button:is(.gatilho-dica, .menu-acoes-gatilho) {
    margin-block: -6px;
}

/* rótulo de campo em bloco tem 22,5px: a folga invisível de 2px o leva a 24 sem mexer no fluxo
   (o campo abaixo está a mais de 2px); rótulo com link fica sem ela, que cobriria o link */
label[for]:not(:has(a)) {
    position: relative;
}

/* aceite dos Termos a 360: o link da linha de baixo cobria a folga do de cima (linha de 22,5px) */
label[for]:has(a) {
    line-height: 1.75;
}

label[for]:not(:has(a))::after {
    content: "";
    position: absolute;
    inset: -2px 0;
}

a.pill, button.pill, span.pill[data-aviso] {
    --alvo-toque: 24px;
}

a.pill, span.pill[data-aviso] {
    position: relative;
}

a.pill::after, span.pill[data-aviso]::after {
    content: "";
    position: absolute;
    inset: min(0px, calc(50% - var(--alvo-toque) / 2)) 0;
}

/* no botão o `::after` contaria como texto vazando da caixa (scrollHeight): a folga vem de borda
   transparente fora do fundo (`background-clip`), devolvida pela margem negativa — o botão já
   não tem borda visível (`border: 0` acima). 0.12rem = o padding vertical da `.pill`. */
button.pill {
    --folga-toque: max(0px, calc((var(--alvo-toque) - 1lh - 0.12rem) / 2));
    border-block: var(--folga-toque) solid transparent;
    margin-block: calc(-1 * var(--folga-toque));
    background-clip: padding-box;
}

.info-marca {
    box-sizing: content-box;
    /* 1.1rem + 2×4px > 24px com folga: com 3px dava 23,6px e a medição arredondava para 23 */
    padding: 4px;
    margin: -4px;
    background-clip: content-box;
}

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

/* contorno por sombra, não por borda: a borda somava 2px à pill "Inativo"/"Sem contrato" e a linha que a
   tinha ficava mais alta que as vizinhas (Decisão J do rascunho 24) */
.pill-inativo {
    box-shadow: inset 0 0 0 1px 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: resumo (primeiros nomes) fechado, nomes completos abertos (D12) */
.celula-expansivel .texto .completo {
    display: none;
}

.celula-expansivel .texto[data-aberto] .completo {
    display: inline;
}

.celula-expansivel .texto[data-aberto] .resumo {
    display: none;
}

/* 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. */
/* no modal a ação de seção não desce de linha (360px): o título quebra, "Ajustar" fica à direita */
dialog .secao-cabecalho {
    flex-wrap: nowrap;
}

dialog .secao-cabecalho > .acao-secao {
    flex-shrink: 0;
}

.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", "+ Campanha", "+ Modelo" — 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: 767.98px) {
    .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;
    }

    .expandir-codigo {
        min-height: 44px;
    }

    .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.
       Cobrar inclusive (paliativo F1 do plano mobile, fim da X9): ~145px a 390, o resto da linha
       rola por baixo dela até a lista de extrato. */
    td.acoes, th.acoes {
        position: sticky;
        right: 0;
        border-left: 1px solid var(--line);
    }

    /* com Ações grudada o fade cobriria a ação: o indicador vira a sombra na borda esquerda dela,
       onde o conteúdo some por baixo */
    .rola-mais:has(> table td.acoes) {
        mask-image: none;
    }

    .rola-mais > table :is(td, th).acoes {
        box-shadow: -0.75rem 0 0.75rem -0.5rem var(--muted);
    }

    /* Pessoas do detalhe: cada linha vira um cartão rótulo/valor (sem rolagem horizontal); o
       cabeçalho continua no DOM (só fora da tela). */
    .tabela-empilhavel thead {
        position: absolute;
        width: 1px;
        height: 1px;
        overflow: hidden;
        clip-path: inset(50%);
    }

    .tabela-empilhavel, .tabela-empilhavel tbody, .tabela-empilhavel tr {
        display: block;
    }

    .tabela-empilhavel tr {
        padding-block: 0.5rem;
        border-bottom: 1px solid var(--line);
    }

    .tabela-empilhavel tbody td {
        display: grid;
        grid-template-columns: 5.5rem minmax(0, 1fr);
        gap: 0.5rem;
        width: auto;
        border: 0;
        white-space: normal;
        overflow-wrap: anywhere;
        max-width: none; /* td.nome desktop: reticências com max-width 0 */
        overflow: visible;
    }

    .tabela-empilhavel tbody td::before {
        content: attr(data-label);
        font-weight: 600;
    }

    .tabela-empilhavel .celula-expansivel {
        width: 100%;
    }

    /* alvo de toque: os links de ação tinham 15–18px de altura (WCAG 2.5.8 pede 24 no mínimo).
       Pill "Automatizada" e ícone de exaurida da coluna Cobrar são links com caixa própria: fora. */
    td.acoes > a:not(.pill, .info-marca), .acoes.cobrar a:not(.pill, .info-marca), td a.ord, th a.ord {
        display: inline-block;
        padding-block: 0.75rem;
    }

    /* M5: no celular a ação de linha tem 44px também na largura ("Abrir" tinha 32) — `min-width`
       só alarga o que é mais estreito, centralizando o rótulo; o gatilho "Ações" e a pill crescem
       pela altura invisível (padding inline / `::after`), a paginação pelo padding. */
    td.acoes > a:not(.pill, .info-marca), .acoes.cobrar a:not(.pill, .info-marca) {
        min-width: 46px; /* 44 + folga: em posição fracionária "E-mail" media 43 */
        text-align: center;
    }

    /* 46 como a ação de linha direta (`td.acoes > a`, 0.75rem): na tabela do celular a folga é layout
       (a célula grudada da linha seguinte cobriria a sobra), e com 10px a linha só com "Ações" ficava
       4px mais baixa que a das demais tabelas (Decisão J do rascunho 24) */
    td button.menu-acoes-gatilho {
        padding-block: 0.75rem;
        margin-block: 0;
    }

    /* 46 = 44 + folga do arredondamento (a borda de 43,4px media 41). Na tabela a área invisível
       vira layout: a linha seguinte (célula grudada de Ações, posicionada) pintava por cima da
       sobra da pill e o toque caía nela — a pill ganha margem, o botão perde a margem negativa. */
    td :is(a.pill, button.pill) {
        --alvo-toque: 46px;
    }

    td a.pill {
        margin-block: 12.5px;
    }

    td button.pill {
        margin-block: 0;
    }

    /* "i" de exaurida na coluna Cobrar: 44px de alvo; a folga à esquerda cobre o vão até a pill
       (a da direita sairia do `.tabela-wrap`, que corta), a vertical entra no layout da linha */
    td .info-marca {
        padding: 14px 4px 14px 24px;
        margin: 0 -4px 0 -24px;
    }

    .paginacao-controles > :is(a, button) {
        min-width: 44px;
        min-height: 44px;
        justify-content: center;
    }

    /* com quatro botões de 44px, "Página X de Y" só quebra em duas linhas onde a faixa não cabe
       (seleção de clientes no modal, corpo de 266px a 360) — nunca rola */
    .paginacao-controles > span {
        white-space: normal;
        text-align: center;
    }

    /* 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;
    }

    /* o overflow faz da seção um BFC: a margem do título não colapsa para fora, então o vão
       (`--vao-secao`) passa a ser da própria seção */
    .conteudo > section.evolucao:not(:first-child) {
        margin-top: var(--vao-secao);
    }

    .conteudo > section.evolucao:not(:first-child) > h2:first-child {
        margin-top: 0;
    }

    /* idem embaixo: o 1rem do gráfico ficaria preso dentro do BFC e somaria ao vão seguinte */
    .conteudo > section.evolucao {
        margin-bottom: var(--pico-spacing);
    }

    .evolucao .grafico-evolucao-caixa {
        margin-bottom: 0;
    }

    /* 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;
        max-width: none; /* td.nome desktop: reticências com max-width 0 */
        overflow: visible;
    }

    .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 */
    }
}

/* Termos comerciais da geração (13B, T4): o modo de preço esconde o que não vale nele. */
#termos-contrato[data-modo="titular"] .so-dependente,
#termos-contrato[data-modo="titular"] .so-pessoas,
#termos-contrato[data-modo="dependente"] .so-titular,
#termos-contrato[data-modo="dependente"] .so-pessoas,
#termos-contrato[data-modo="personalizado"] .so-dependente { display: none; }

/* "+ Signatário" (13B, Passo 5): datas lado a lado até em 360px; com "Alterar valores" em
   personalizado, o rodapé troca "Enviar" por "Revisar valores" (a revisão por pessoa vem antes). */
.campos-par.datas-lote > p { flex-basis: 0; }
#lote-revisar { display: none; }
article:has(#termos-contrato[data-modo="personalizado"] [name="alterar_termos"]:checked) #lote-revisar { display: inline-block; }
article:has(#termos-contrato[data-modo="personalizado"] [name="alterar_termos"]:checked) #lote-enviar { display: none; }
.revisao-lote td input { margin-bottom: 0; min-width: 7rem; }

/* Aditivo encadeado sob o contrato-base (Passo 11 da SPEC 13B): recuo e rótulo na célula de situação */
tr.aditivo td.situacao { padding-left: 1.5rem; }
.rotulo-aditivo { display: block; font-size: 0.8em; color: var(--muted); }

.barra-formatacao { display: flex; flex-wrap: wrap; gap: .25rem; margin-bottom: .5rem; }
.barra-formatacao button { width: auto; margin: 0; padding: .25rem .6rem; }

/* `<p class="erro" role="alert">` vazio à espera do JS (ex.: `#automacao-erro`) não ocupa o fluxo: a margem
   dele colapsava com a do título seguinte e encurtava o `--vao-secao` para 32px. Com texto, volta a aparecer. */
.conteudo p.erro:empty {
    display: none;
}

/* "Reenviar" com escolha de canal (D11 do rascunho 21): o aviso da nova rodada só aparece com
   uma opção que abre rodada nova marcada — antes do envio, sem JS. */
.opcoes-reenvio label { display: block; margin-bottom: 0.5rem; }
.aviso-nova-rodada { display: none; }
#form-trocar-canal:has([data-nova-rodada]:checked) .aviso-nova-rodada { display: block; }

/* Acabamento do editor da minuta (Passo 4 da SPEC do editor): o `snow` do Quill traz hex próprios (#ccc,
   #06c, #444) e mede botões em pixels; aqui tudo volta aos tokens da identidade. A barra é a
   `.barra-formatacao` (botões `.secundario` com ícone SVG inline em `currentColor`) e quebra em linhas
   no celular; o editor tem piso de 12rem (o corpo do modal rola, não o editor encolhe). */
.barra-editor.ql-toolbar.ql-snow {
    border: 0;
    padding: 0;
    font-family: inherit;
}
.barra-editor.ql-toolbar.ql-snow button {
    float: none;
    width: auto;
    height: auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: .25rem .6rem;
    border: 1px solid var(--pico-secondary-border, var(--line));
    cursor: pointer;
}
.barra-editor.ql-toolbar.ql-snow button svg { float: none; width: 16px; height: 16px; }
.barra-editor.ql-toolbar.ql-snow button.ql-active,
.barra-editor.ql-toolbar.ql-snow button.ql-active:hover,
.barra-editor.ql-toolbar.ql-snow button.ql-active:focus {
    background: var(--primary-soft);
    color: var(--primary);
    border-color: var(--primary);
}
.barra-editor.ql-toolbar.ql-snow button:not(.ql-active):hover,
.barra-editor.ql-toolbar.ql-snow button:not(.ql-active):focus { color: var(--primary); }
.editor-minuta.ql-container.ql-snow {
    border: 1px solid var(--line);
    height: auto;
    font-family: inherit;
}
.editor-minuta .ql-editor.ql-blank::before { color: var(--muted); }
.editor-minuta .ql-editor { min-height: 12rem; }

/* "Ajustar com IA" (Passo 8 da SPEC do editor e IA): diff por parágrafo, atual | proposto; empilhado no celular */
.ajuste-ia, #ajuste-ia-resultado:not(:empty) { margin-bottom: 0.5rem; }
.diff-minuta { border: 1px solid var(--line); border-radius: 6px; margin-bottom: 0.75rem; }
.diff-linha { display: grid; grid-template-columns: 1fr 1fr; border-bottom: 1px solid var(--line); }
.diff-linha:last-child { border-bottom: 0; }
.diff-lado { padding: 0.4rem 0.6rem; min-width: 0; overflow-wrap: anywhere; }
.diff-lado :is(p, h1, h2) { margin: 0; font-size: inherit; }
.diff-rotulo { display: block; color: var(--muted); }
.diff-linha.diff-igual { color: var(--muted); }
.diff-removido .diff-lado:first-child { background: #fbe3e3; }
.diff-adicionado .diff-lado:last-child { background: #ddf3dd; }
.diff-alterado .diff-lado:first-child { background: #fbe3e3; }
.diff-alterado .diff-lado:last-child { background: #ddf3dd; }
@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) :is(.diff-removido .diff-lado:first-child, .diff-alterado .diff-lado:first-child) { background: #4a2323; }
    :root:not([data-theme="light"]) :is(.diff-adicionado .diff-lado:last-child, .diff-alterado .diff-lado:last-child) { background: #23422a; }
}
:root[data-theme="dark"] :is(.diff-removido .diff-lado:first-child, .diff-alterado .diff-lado:first-child) { background: #4a2323; }
:root[data-theme="dark"] :is(.diff-adicionado .diff-lado:last-child, .diff-alterado .diff-lado:last-child) { background: #23422a; }
@media (max-width: 640px) { .diff-linha { grid-template-columns: 1fr; } }
