/* ==========================================================================
   Algir — CSS do site público
   --------------------------------------------------------------------------
   Servido direto de public/, sem build (CLAUDE.md, §§6 e 25).
   Não usar @vite aqui: o deploy do público não depende de npm run build.

   Todos os valores visuais moram nos tokens abaixo. "Muda um, muda todos"
   acontece editando :root — sem tela de configuração (§6).

   --------------------------------------------------------------------------
   MOBILE-FIRST (§29)

   O CSS base descreve a tela estreita. Media query só ACRESCENTA a partir
   daí — nunca o contrário, que geraria sobrescrita e CLS.

   Breakpoints (min-width), repetidos literalmente por toda parte:

       sm   40rem   640px    celular deitado
       md   48rem   768px    tablet
       lg   64rem   1024px   desktop
       xl   80rem   1280px   desktop largo

   Custom property NÃO funciona dentro de @media — `@media (min-width:
   var(--bp-md))` é inválido em CSS. Por isso os valores acima são repetidos
   à mão. É limitação da linguagem, não descuido.
   ========================================================================== */

:root {
    /* ---- Cor: marca -------------------------------------------------------
       Azul, uma paleta só para o site e para o sistema (§57).

       Até a §56 eram duas: vinho e dourado no site, azul no painel. O cliente
       pediu a mesma cor nos dois — e é a decisão certa: quem clica em "Área
       restrita" no site e cai numa tela de outra cor duvida por um instante se
       chegou no lugar certo. A troca não custa ranqueamento; o Google lê o
       HTML, não a paleta (§2).

       ⚠️ **Dois papéis para o azul**, e trocá-los quebra a acessibilidade —
       exatamente como acontecia com o dourado:

         --color-primary     #0a4ee4  → FUNDO de botão. Branco sobre ele mede
                                        6.51:1. Como texto sobre fundo escuro
                                        mede 2.38:1 e reprova.
         --color-accent-light #a1b9ed → o azul quando precisa ser TEXTO sobre
                                        o escuro (8.86:1 sobre #001647).

       Contraste MEDIDO sobre branco:
         primary 6.51 · primary-hover 9.34 · text 16.29 · text-muted 5.33
       Sobre o azul-escuro #001647:
         branco 17.42 · text-on-dark-muted 11.20 · accent-light 8.86
       Ao trocar qualquer cor, MEDIR de novo. */
    --color-primary: #0a4ee4;
    --color-primary-hover: #0840bd;
    --color-primary-weak: #0a4ee4;

    --color-accent: #0a4ee4;
    --color-accent-text: #0a4ee4;
    --color-accent-hover: #0840bd;
    --color-accent-light: #a1b9ed;

    /* O azul-escuro das superfícies grandes: rodapé, seções escuras, painel
       de números e o trilho do sistema. NÃO é o `primary`: um painel inteiro
       no azul vivo de botão cansa a vista e rouba o destaque do próprio
       botão. */
    --color-dark: #001647;

    /* ---- Cor: neutros -----------------------------------------------------
       Cinzas puros. Antes eram quentes, puxados para o vinho; ao lado do azul
       o cinza morno amarela e faz a marca parecer desbotada. */
    --color-bg: #ffffff;
    --color-surface: #fafafa;
    --color-surface-strong: #f0f0f0;
    --color-border: #e5e5e5;
    --color-border-strong: #d4d4d4;
    --color-text: #202020;
    --color-text-muted: #6b6b6b;
    --color-text-inverse: #ffffff;
    --color-text-on-dark-muted: #c3d0e8;

    /* ---- Cor: semântica --------------------------------------------------- */
    --color-success: #1c6b3f;
    /* Verde VIVO, só para ícone de ação (§105): o de texto é escuro de
       propósito (6.51:1 para texto), mas num ícone de 17px ele lê como
       cinza. Ícone é elemento de interface, e o mínimo é 3:1 (WCAG 1.4.11):
       #16a34a mede 3,30:1 sobre o branco e 3,16:1 sobre a superfície — passa
       como ícone e REPROVA como texto, que exige 4,5:1. Nunca para texto. */
    --color-success-vivo: #16a34a;
    --color-warning: #8a5a00;
    --color-danger: #a32020;
    /* ---- Tipografia -------------------------------------------------------
       Pilha do sistema: zero requisição, zero CLS de troca de fonte e nenhum
       CDN de terceiro (§§6 e 11). Fonte própria, se entrar, entra
       auto-hospedada com font-display: swap e size-adjust. */
    --font-sans: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue",
        Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji";

    --font-mono: ui-monospace, SFMono-Regular, "Cascadia Mono", Consolas,
        "Liberation Mono", monospace;

    --text-xs: 0.8125rem;
    --text-sm: 0.875rem;
    --text-base: 1rem;
    --text-lg: 1.125rem;
    --text-xl: 1.375rem;
    --text-2xl: 1.75rem;
    --text-3xl: 2.25rem;
    --text-4xl: 3rem;
    --text-5xl: 3.75rem;

    --leading-tight: 1.15;
    --leading-snug: 1.35;
    --leading-normal: 1.6;

    --weight-normal: 400;
    --weight-medium: 500;
    --weight-semibold: 600;
    --weight-bold: 700;

    --tracking-wide: 0.1em;
    --tracking-tight: -0.035em;

    /* ---- Espaçamento (escala de 4px) ------------------------------------ */
    --space-1: 0.25rem;
    --space-2: 0.5rem;
    --space-3: 0.75rem;
    --space-4: 1rem;
    --space-5: 1.25rem;
    --space-6: 1.5rem;
    --space-8: 2rem;
    --space-10: 2.5rem;
    --space-12: 3rem;
    --space-16: 4rem;
    --space-20: 5rem;

    /* Respiro vertical entre seções — o que dá ritmo à página. */
    --secao-y: var(--space-12);

    /* ---- Forma ----------------------------------------------------------- */
    --radius-sm: 6px;
    --radius: 10px;
    --radius-lg: 20px;
    --radius-full: 9999px;

    /* A sombra é tingida com o azul-escuro da marca, não cinza puro: sombra
       neutra sobre fundo colorido lê como sujeira. */
    --shadow-sm: 0 1px 2px rgb(0 22 71 / 0.06);
    --shadow: 0 6px 24px rgb(0 22 71 / 0.08);
    --shadow-lg: 0 18px 48px rgb(0 22 71 / 0.16);

    /* ---- Layout ---------------------------------------------------------- */
    --container: 74rem;
    --measure: 62ch;
    --tap-target: 44px;

    /* Altura de uma linha do rodapé fixo do celular (§83). A barra de
       "Mais ações" se desloca por múltiplos dela conforme o rodapé tem
       paginação, seleção, as duas ou nenhuma. */
    --rodape-linha: 52px;

    /* ---- Ícones (Lucide) --------------------------------------------------
       Espelham os defaults de resources/views/components/icon.blade.php.
       Mudou um, muda o outro. */
    --icon-size: 20px;
    --icon-stroke: 2;

    /* ---- Movimento --------------------------------------------------------
       Curva e duração únicas: movimento inconsistente lê como descuido. */
    --transicao: 180ms cubic-bezier(0.22, 0.61, 0.36, 1);

    /* ---- Foco (acessibilidade) -------------------------------------------- */
    --focus-ring: 2px solid var(--color-accent);
    --focus-offset: 2px;
}

/* ==========================================================================
   Base
   ========================================================================== */

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
    margin: 0;
    background: var(--color-bg);
    color: var(--color-text);
    font-family: var(--font-sans);
    font-size: var(--text-base);
    line-height: var(--leading-normal);
    -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4 {
    line-height: var(--leading-tight);
    text-wrap: balance;
    margin: 0 0 var(--space-4);
    font-weight: var(--weight-bold);
    /* Espaçamento fechado: título folgado lê como composição antiga. */
    letter-spacing: var(--tracking-tight);
}

/* Um H1 por página (§27, item 9). Tela estreita primeiro. */
h1 { font-size: var(--text-4xl); }
h2 { font-size: var(--text-2xl); }
h3 { font-size: var(--text-lg); }

p { margin: 0 0 var(--space-4); max-width: var(--measure); }

a { color: var(--color-primary-weak); text-underline-offset: 0.15em; }
a:hover { color: var(--color-primary); }

img, svg { max-width: 100%; height: auto; }

:focus-visible { outline: var(--focus-ring); outline-offset: var(--focus-offset); }

/* Respeita quem pediu menos movimento no sistema operacional. Vale para o
   contador de números e para o movimento dos cartões. */
@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
    }
}

/* md — 768px */
@media (min-width: 48rem) {
    :root { --secao-y: var(--space-20); }
    h1 { font-size: var(--text-5xl); }
    h2 { font-size: var(--text-4xl); }
    h3 { font-size: var(--text-xl); }
}

/* ==========================================================================
   Utilitários
   ========================================================================== */

.container {
    width: 100%;
    max-width: var(--container);
    margin-inline: auto;
    padding-inline: var(--space-5);
}

.tap { min-width: var(--tap-target); min-height: var(--tap-target); }

.scroll-x { overflow-x: auto; -webkit-overflow-scrolling: touch; }

.sr-only {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0;
}

.icon { display: inline-block; vertical-align: -0.15em; flex: none; }

/* ==========================================================================
   Seções — o fundo é o que separa um bloco do outro
   ========================================================================== */

.secao { padding-block: var(--secao-y); }

.secao--claro { background: var(--color-bg); }
.secao--suave { background: var(--color-surface); }

.secao--escuro {
    background: var(--color-dark);
    color: var(--color-text-inverse);
}

.secao--escuro h2,
.secao--escuro h3 { color: var(--color-text-inverse); }

.secao--escuro p { color: var(--color-text-on-dark-muted); }

.secao--escuro a { color: var(--color-accent-light); }

/* ---- Etiqueta acima do título ----------------------------------------- */

.etiqueta {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    margin-bottom: var(--space-4);
    padding: var(--space-1) var(--space-3);
    font-size: var(--text-xs);
    font-weight: var(--weight-semibold);
    letter-spacing: var(--tracking-wide);
    text-transform: uppercase;
    color: var(--color-accent-text);
    background: color-mix(in srgb, var(--color-accent) 10%, transparent);
    border-radius: var(--radius-full);
}

.secao--escuro .etiqueta {
    color: var(--color-accent-light);
    background: color-mix(in srgb, var(--color-accent-light) 16%, transparent);
}

/* ==========================================================================
   Cabeçalho
   --------------------------------------------------------------------------
   MOBILE-FIRST: a base descreve a gaveta; o menu em linha só aparece a
   partir de 1024px, onde os seis itens mais o botão cabem de fato.

   Medido antes: em 375px o menu quebrava em TRÊS linhas, o cabeçalho ia a
   228px de altura e empurrava o H1 para fora da primeira tela.

   Abre por checkbox + label, sem JavaScript: navegação que depende de script
   some quando o script falha (§29).
   ========================================================================== */

.cabecalho {
    position: sticky;
    top: 0;
    z-index: 10;
    background: color-mix(in srgb, var(--color-bg) 92%, transparent);
    backdrop-filter: blur(8px);
    /* Ouro. É borda, não texto — o dourado pode aqui (§40). */
    border-bottom: 2px solid var(--color-accent);
}

.cabecalho__interno {
    display: flex;
    align-items: center;
    gap: var(--space-4);
    padding-block: var(--space-3);
}

.cabecalho__marca {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    margin-right: auto;
    min-height: var(--tap-target);
    font-size: var(--text-lg);
    font-weight: var(--weight-bold);
    letter-spacing: -0.02em;
    color: var(--color-primary);
    text-decoration: none;
}

.cabecalho__marca .icon { color: var(--color-accent); }

/* ---- Botão da gaveta -------------------------------------------------- */

.cabecalho__hamburguer {
    display: grid;
    place-items: center;
    color: var(--color-primary);
    cursor: pointer;
    border-radius: var(--radius-sm);
}

.cabecalho__hamburguer:hover { background: var(--color-surface); }

/* Os dois ícones ocupam a MESMA célula da grade: assim o botão não muda de
   tamanho ao trocar de estado, e nada ao redor se desloca. */
.cabecalho__abrir,
.cabecalho__fechar { grid-area: 1 / 1; }

.cabecalho__fechar { display: none; }

.cabecalho__gatilho:checked ~ .cabecalho__interno .cabecalho__abrir { display: none; }
.cabecalho__gatilho:checked ~ .cabecalho__interno .cabecalho__fechar { display: block; }

/* ---- Gaveta ----------------------------------------------------------- */

.cabecalho__nav {
    display: none;
    position: absolute;
    left: 0;
    right: 0;
    top: 100%;
    flex-direction: column;
    align-items: stretch;
    gap: var(--space-1);
    padding: var(--space-3) var(--space-5) var(--space-5);
    background: var(--color-bg);
    border-bottom: 1px solid var(--color-border);
    box-shadow: var(--shadow-lg);
}

.cabecalho__gatilho:checked ~ .cabecalho__interno .cabecalho__nav { display: flex; }

.cabecalho__nav a:not(.botao) {
    display: flex;
    align-items: center;
    min-height: var(--tap-target);
    padding-inline: var(--space-2);
    font-size: var(--text-base);
    font-weight: var(--weight-medium);
    color: var(--color-text);
    text-decoration: none;
    border-radius: var(--radius-sm);
    transition: color var(--transicao), background var(--transicao);
}

.cabecalho__nav a:not(.botao):hover {
    color: var(--color-accent-text);
    background: var(--color-surface);
}

.cabecalho__nav .botao { margin-top: var(--space-3); }

/* lg — 1024px: cabe em linha, a gaveta deixa de existir */
@media (min-width: 64rem) {
    .cabecalho__hamburguer { display: none; }

    .cabecalho__nav {
        display: flex;
        position: static;
        flex-direction: row;
        align-items: center;
        gap: var(--space-1) var(--space-5);
        padding: 0;
        background: none;
        border: 0;
        box-shadow: none;
    }

    .cabecalho__nav a:not(.botao) {
        padding-inline: 0;
        font-size: var(--text-sm);
    }

    .cabecalho__nav a:not(.botao):hover { background: none; }

    /* O botão do cabeçalho é compacto, a pedido do cliente.
       -------------------------------------------------------------------
       O `.botao` padrão tem 44px e texto de 16 — medida de landing page,
       onde ele é o DESTINO. Repetido numa barra de navegação, ao lado de
       links de 14px, ele domina a faixa inteira.

       É o mesmo raciocínio das §§57 e 79, que já encolheram os botões do
       painel: o tamanho de um botão vem do papel dele na tela, não de haver
       um só tamanho de botão.

       ⚠️ Só no DESKTOP. Na gaveta do celular ele é item de menu, tocado com
       o dedo, e ali os 44px da §29 continuam valendo — que é o estado base,
       fora desta media query. */
    .cabecalho__nav .botao {
        margin-top: 0;
        min-height: 2.25rem;
        padding: 0 var(--space-4);
        font-size: var(--text-sm);
    }

    /* O salto no hover é enfeite de landing page. Numa barra fixa, com o
       menu ao lado, ele faz a linha tremer a cada passada de mouse (§79). */
    .cabecalho__nav .botao:hover { transform: none; }
}

/* ==========================================================================
   Botões
   ========================================================================== */

.botao,
.formulario__enviar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    min-height: var(--tap-target);
    padding: var(--space-3) var(--space-6);
    font: inherit;
    font-weight: var(--weight-semibold);
    text-decoration: none;
    border: 1px solid transparent;
    border-radius: var(--radius);
    cursor: pointer;
    transition: background var(--transicao), transform var(--transicao), box-shadow var(--transicao);
}

.botao:hover,
.formulario__enviar:hover:not([disabled]) { transform: translateY(-2px); }

.botao--principal,
.formulario__enviar {
    color: var(--color-text-inverse);
    background: var(--color-primary);
    box-shadow: var(--shadow-sm);
}

.botao--principal:hover,
.formulario__enviar:hover:not([disabled]) {
    color: var(--color-text-inverse);
    background: var(--color-primary-hover);
    box-shadow: var(--shadow);
}

/* Sobre a seção escura o bordô sumiria — ali o botão inverte: fundo branco
   com texto bordô, e o hover volta ao marsala com branco. */
.secao--escuro .botao--principal {
    color: var(--color-primary);
    background: var(--color-text-inverse);
}

.secao--escuro .botao--principal:hover {
    color: var(--color-text-inverse);
    background: var(--color-primary-hover);
}

.botao--secundario {
    color: var(--color-primary);
    background: transparent;
    border-color: var(--color-border-strong);
}

.botao--secundario:hover {
    color: var(--color-primary);
    background: var(--color-surface);
}

.secao--escuro .botao--secundario {
    color: var(--color-text-inverse);
    border-color: color-mix(in srgb, var(--color-text-inverse) 40%, transparent);
}

.secao--escuro .botao--secundario:hover {
    color: var(--color-text-inverse);
    background: color-mix(in srgb, var(--color-text-inverse) 10%, transparent);
}

/* ==========================================================================
   Hero — texto à esquerda, mídia à direita
   --------------------------------------------------------------------------
   Em tela estreita empilha, e o TEXTO vem primeiro: o H1 é o que precisa
   aparecer sem rolagem, e é ele que o robô lê na primeira resposta (§5).
   ========================================================================== */

.hero {
    padding-block: var(--space-10) var(--secao-y);
    background:
        radial-gradient(ellipse 70% 55% at 12% -10%, color-mix(in srgb, var(--color-accent) 7%, transparent), transparent),
        var(--color-bg);
}

.hero__grade {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--space-10);
    align-items: center;
}

.hero__texto { max-width: 40rem; }

.hero h1 {
    margin-bottom: var(--space-5);
    letter-spacing: var(--tracking-tight);
    /* Evita a última linha órfã do título. Onde não houver suporte, o
       título simplesmente quebra como sempre quebrou. */
    text-wrap: balance;
}

.hero__chamada {
    font-size: var(--text-lg);
    line-height: var(--leading-snug);
    color: var(--color-text-muted);
    max-width: var(--measure);
}

.hero__acoes {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-3);
    margin-top: var(--space-8);
}

/* ---- Selos de credibilidade abaixo das ações -------------------------- */

/* Ficam entre a chamada e os botões: qualificam a promessa do texto, e
   depois do botão ninguém mais lê — quem ia clicar já clicou. Por isso
   também perderam a borda superior, que ali fechava um rodapé de bloco. */
.hero__selos {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2) var(--space-5);
    margin: var(--space-6) 0 0;
    padding: 0;
    list-style: none;
}

.hero__selos li {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    font-size: var(--text-sm);
    font-weight: var(--weight-medium);
    color: var(--color-text-muted);
}

.hero__selos .icon { color: var(--color-accent-text); }

/* ---- Mídia ------------------------------------------------------------ */

.hero__midia { position: relative; }

/* Moldura deslocada atrás da mídia: dá profundidade sem nenhuma imagem
   extra, logo sem custo de LCP. */
.hero__midia::before {
    content: "";
    position: absolute;
    inset: var(--space-5) calc(var(--space-5) * -1) calc(var(--space-5) * -1) var(--space-5);
    border: 1px solid var(--color-border-strong);
    border-radius: var(--radius-lg);
    pointer-events: none;
}

.hero__midia > * {
    position: relative;
    display: block;
    width: 100%;
    /* aspect-ratio fixa a caixa antes de a mídia chegar — é o que mantém o
       CLS em zero junto com width/height no <img> (§5). */
    aspect-ratio: 4 / 3;
    object-fit: cover;
    background: var(--color-surface);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
}

/* Marcador enquanto não existe foto real. A §3 proíbe banco de imagem:
   contorno honesto é melhor que foto genérica, que derruba o E-E-A-T. */
.midia-vazia {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--space-3);
    overflow: hidden;
    padding: var(--space-8);
    text-align: center;
    color: var(--color-text-muted);
    background: var(--color-surface-strong);
    border: 1px dashed var(--color-border-strong);
    /* Sem sombra: marcador não pode se passar por conteúdo. */
    box-shadow: none;
}

.midia-vazia .icon { color: var(--color-primary-hover); }

.midia-vazia__texto {
    max-width: 30ch;
    font-size: var(--text-sm);
    line-height: var(--leading-snug);
}

.midia-vazia__forma {
    position: absolute;
    right: -3rem;
    bottom: -3rem;
    width: 12rem;
    height: 12rem;
    border: 1px solid var(--color-border-strong);
    border-radius: 50%;
}

/* md — 768px */
@media (min-width: 48rem) {
    .hero { padding-block: var(--space-16) var(--secao-y); }
    .hero__chamada { font-size: var(--text-xl); line-height: var(--leading-snug); }
}

/* lg — 1024px */
@media (min-width: 64rem) {
    .hero__grade {
        grid-template-columns: 1.05fr 0.95fr;
        gap: var(--space-16);
    }
}

/* Abertura só com o H1 (página sem bloco de hero): menos respiro, senão
   sobra uma faixa vazia entre o menu e o conteúdo.

   Declarado DEPOIS das media queries acima de propósito: mesma
   especificidade, e quem vem por último vence — antes delas, o padding do
   md sobrescrevia isto em silêncio. */
/* A abertura sem bloco de destaque é CENTRADA e menor (§90).
   -------------------------------------------------------------------------
   Medido na referência: H1 de 30px, centrado, com a linha de apoio logo
   abaixo, também centrada e em 16px.

   O H1 do site tem o tamanho de uma landing page, onde ele é a manchete que
   segura a primeira tela. Numa tela de formulário ele não é a manchete — é a
   etiqueta do que vem embaixo, e o que precisa de atenção são os campos.
   Mesmo raciocínio das §§57, 79 e 89 para os botões: o tamanho vem do papel
   do elemento na tela, não de haver um só tamanho. */
.hero--simples {
    /* Respiro de baixo quase zerado: quem fecha a distância até a linha de
       apoio é o bloco seguinte, que traz o próprio recuo. Antes sobravam os
       dois somados, e título e subtítulo pareciam de seções diferentes. */
    padding-block: var(--space-8) var(--space-2);
    text-align: center;
}

.hero--simples h1 {
    margin-bottom: 0;
    font-size: 1.875rem;
    line-height: 1.2;

    /* Azul, a pedido do cliente. Mede 9.38:1 sobre o branco — é o
       `--color-primary`, e a §27 já o tinha medido como cor de TEXTO sobre
       claro. O `--color-accent` é o mesmo tom, mas o papel dele é fundo de
       botão e anel de foco; usar o token pelo papel, e não pela cor, é o que
       impede a próxima troca de paleta de reprovar sem ninguém ver (§40). */
    color: var(--color-primary);
}

.hero--simples .hero__texto { margin-inline: auto; }

/* ==========================================================================
   Bloco de destaque: etiqueta + título + texto de um lado, mídia do outro
   ========================================================================== */

.destaque__grade {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--space-8);
    align-items: center;
}

.destaque__texto p { color: inherit; }

.destaque__lista {
    display: grid;
    gap: var(--space-3);
    margin: var(--space-6) 0 0;
    padding: 0;
    list-style: none;
}

.destaque__lista li {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: var(--space-3);
    align-items: start;
}

.destaque__lista .icon { color: var(--color-accent); margin-top: 0.28rem; }

.destaque__acao { margin-top: var(--space-8); }

/* Texto corrido longo — documento legal, artigo. A largura de leitura é
   o que separa "documento" de "parede de texto". */
.texto-longo { max-width: var(--measure); }
.texto-longo p { margin-bottom: var(--space-4); }
.texto-longo p:last-child { margin-bottom: 0; }

.secao--escuro .destaque__lista .icon { color: var(--color-accent-light); }

/* Espaço da mídia. NÃO recebe imagem de banco: a §3 proíbe — foto tem de ser
   real, de perícia e de equipamento de medição. Até existir, mostra o
   contorno do espaço e o que vai ali. */
.destaque__midia {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    aspect-ratio: 4 / 3;
    overflow: hidden;
    background: var(--color-surface-strong);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow);
}

.destaque__midia img,
.destaque__midia video {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.destaque__vazio {
    display: grid;
    justify-items: center;
    gap: var(--space-2);
    padding: var(--space-6);
    text-align: center;
    color: var(--color-primary);
}

.destaque__vazio .icon { width: 32px; height: 32px; opacity: 0.55; }

.destaque__vazio span {
    font-size: var(--text-sm);
    font-weight: var(--weight-medium);
    max-width: 24ch;
}

/* lg — 1024px: a partir daqui os lados existem de fato */
@media (min-width: 64rem) {
    .destaque__grade {
        grid-template-columns: 1fr 1fr;
        gap: var(--space-16);
    }

    /* Alterna o lado da mídia. É o que dá ritmo quando vários destaques se
       seguem — a alternância é a informação, não enfeite. */
    .destaque--invertido .destaque__midia { order: -1; }
}

/* ==========================================================================
   Números — painel escuro com padrão geométrico desenhado em CSS
   --------------------------------------------------------------------------
   Pontos, anéis e círculos, sem imagem e sem degradê de cor. Os pontos são
   radial-gradient de PARADA DURA (1.5px sólido → transparente em 1.6px), o
   que desenha ponto, não borrão. Os anéis são borda com raio 50%.

   Custo zero de requisição e nada que dispute banda com o LCP (§5).

   O VALOR sai no HTML. O JavaScript apenas anima o que já está lá (§34).
   ========================================================================== */

.numeros {
    position: relative;
    /* Cria contexto de empilhamento: assim o z-index -1 das decorações fica
       atrás do conteúdo mas à frente do fundo do próprio painel. */
    isolation: isolate;
    overflow: hidden;
    padding: var(--space-10) var(--space-6);
    color: var(--color-text-inverse);
    background: var(--color-dark);
    /* Sem raio: o painel encosta nas duas bordas da tela (fullBleed no
       BlockType), e canto arredondado só faz sentido em caixa solta. */
}

.numeros__padrao {
    position: absolute;
    inset: 0;
    z-index: -1;
    background-image: radial-gradient(circle, rgb(255 255 255 / 0.10) 1.5px, transparent 1.6px);
    background-size: 38px 38px;
}

/* Dois anéis — os "arcos e círculos". Saem parcialmente da caixa de
   propósito: anel inteiro e centralizado vira alvo de tiro. */
.numeros__padrao::before,
.numeros__padrao::after {
    content: "";
    position: absolute;
    border-radius: 50%;
}

.numeros__padrao::before {
    top: -13rem;
    right: -7rem;
    width: 32rem;
    height: 32rem;
    border: 2px solid color-mix(in srgb, var(--color-accent) 32%, transparent);
}

.numeros__padrao::after {
    bottom: -11rem;
    left: -7rem;
    width: 22rem;
    height: 22rem;
    border: 1px solid color-mix(in srgb, var(--color-text-inverse) 16%, transparent);
}

/* Disco cheio, bem discreto, para o padrão não ficar só de contornos. */
.numeros::after {
    content: "";
    position: absolute;
    z-index: -1;
    right: -5rem;
    bottom: -7rem;
    width: 16rem;
    height: 16rem;
    border-radius: 50%;
    background: color-mix(in srgb, var(--color-primary-hover) 35%, transparent);
}

.numeros__cabecalho {
    max-width: 44rem;
    margin-bottom: var(--space-8);
}

.numeros__cabecalho h2 {
    margin: 0;
    color: var(--color-text-inverse);
}

/* Sobre o azul-escuro o azul claro alcança 8.86:1 — aqui ele pode ser texto. */
.numeros .etiqueta {
    color: var(--color-accent-light);
    background: color-mix(in srgb, var(--color-accent-light) 16%, transparent);
}

.numeros__lista {
    display: grid;
    /* minmax(0, 1fr) e não 1fr: 1fr equivale a minmax(auto, 1fr), e um rótulo
       longo empurra a coluna — as quatro caixas saem de larguras diferentes.
       Medido em 375px: 118px e 152px em vez de metade cada. */
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-4);
    margin: 0;
    padding: 0;
    list-style: none;
}

/* Itens centrados, a pedido do cliente. Com o ícone em disco no topo de
   cada um, o alinhamento à esquerda deixava o disco, o número e o rótulo
   em três larguras diferentes — e o que se lê primeiro numa faixa de
   números é justamente o alinhamento entre eles. */
.numeros__item {
    text-align: center;
    align-items: center;
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    padding-right: var(--space-4);
}

.numeros__icone {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    margin-bottom: var(--space-2);
    color: var(--color-accent-light);
    background: color-mix(in srgb, var(--color-accent) 20%, transparent);
    border-radius: var(--radius-full);
}

.numeros__valor {
    font-size: var(--text-3xl);
    font-weight: var(--weight-bold);
    line-height: 1;
    letter-spacing: var(--tracking-tight);
    /* Largura de dígito fixa: sem isso o número treme durante a animação. */
    font-variant-numeric: tabular-nums;
}

.numeros__rotulo {
    font-size: var(--text-sm);
    line-height: var(--leading-snug);
    color: var(--color-text-on-dark-muted);
}

/* sm — 640px */
@media (min-width: 40rem) {
    .numeros { padding: var(--space-12) var(--space-10); }
}

/* md — 768px */
@media (min-width: 48rem) {
    .numeros { padding: var(--space-16) var(--space-12); }
    .numeros__lista { grid-template-columns: repeat(4, minmax(0, 1fr)); }
    .numeros__valor { font-size: var(--text-4xl); }
}

/* ==========================================================================
   Cartões — com movimento ao passar o mouse
   ========================================================================== */

.cartoes--apos-texto { margin-top: var(--space-10); }

.cartoes {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--space-5);
    margin: 0;
    padding: 0;
    list-style: none;
}

.cartao {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-6);
    text-align: center;
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
    transition: transform var(--transicao), box-shadow var(--transicao), border-color var(--transicao);
}

/* focus-within junto de hover: quem navega por teclado vê o mesmo destaque. */
.cartao:hover,
.cartao:focus-within {
    transform: translateY(-4px);
    border-color: color-mix(in srgb, var(--color-accent) 45%, var(--color-border));
    box-shadow: var(--shadow-lg);
}

.cartao__icone {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    color: var(--color-primary);
    background: color-mix(in srgb, var(--color-primary) 8%, transparent);
    border-radius: var(--radius);
    transition: background var(--transicao), color var(--transicao);
}

.cartao:hover .cartao__icone,
.cartao:focus-within .cartao__icone {
    color: var(--color-text-inverse);
    background: var(--color-accent);
}

.cartao h3 { margin: 0; }
.cartao p { max-width: 32ch; }
.cartao p { margin: 0; font-size: var(--text-sm); color: var(--color-text-muted); }

.cartao__link {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    margin-top: auto;
    padding-top: var(--space-2);
    font-size: var(--text-sm);
    font-weight: var(--weight-semibold);
    color: var(--color-accent-text);
    text-decoration: none;
}

.cartao__link .icon { transition: transform var(--transicao); }
.cartao:hover .cartao__link .icon { transform: translateX(3px); }

/* sm — 640px */
@media (min-width: 40rem) {
    .cartoes { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* lg — 1024px */
@media (min-width: 64rem) {
    .cartoes { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* ==========================================================================
   FAQ — cartões numerados, com a introdução ao lado
   --------------------------------------------------------------------------
   Continua <details> nativo: abre sem uma linha de JavaScript e a resposta
   está no HTML mesmo fechada — é isso que dá lastro ao schema FAQPage (§16).

   A apresentação mudou de lista corrida para cartões: acordeão empilhado sem
   separação vira parede de texto e ninguém percorre até o fim.
   ========================================================================== */

.faq {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--space-8);
    align-items: start;
}

.faq__intro h2 { margin-bottom: 0; }

.faq__lista {
    display: grid;
    gap: var(--space-3);
}

.faq__cartao {
    /* O cartão precisa contrastar com a seção que o envolve, e a seção pode
       ser clara ou suave — por isso o fundo do cartão troca junto. */
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    transition: border-color var(--transicao), box-shadow var(--transicao);
}

.faq__cartao[open] {
    border-color: var(--color-border-strong);
    box-shadow: var(--shadow-sm);
}

.secao--suave .faq__cartao { background: var(--color-bg); }

.faq__pergunta {
    display: flex;
    align-items: center;
    gap: var(--space-4);
    min-height: var(--tap-target);
    padding: var(--space-4) var(--space-5);
    font-weight: var(--weight-semibold);
    cursor: pointer;
    /* Some com o triângulo padrão; o chevron abaixo é quem indica o estado. */
    list-style: none;
}

.faq__pergunta::-webkit-details-marker { display: none; }

.faq__numero {
    flex: none;
    width: 1.75rem;
    font-size: var(--text-sm);
    font-weight: var(--weight-bold);
    font-variant-numeric: tabular-nums;
    color: var(--color-accent-text);
}

.faq__texto {
    flex: 1;
    line-height: var(--leading-snug);
    transition: color var(--transicao);
}

.faq__pergunta:hover .faq__texto { color: var(--color-accent-text); }

.faq__pergunta .icon {
    flex: none;
    color: var(--color-primary-hover);
    transition: transform var(--transicao);
}

.faq__cartao[open] .faq__pergunta .icon { transform: rotate(90deg); }

/* Recuo alinhado ao texto da pergunta, não ao número. */
.faq__resposta {
    padding: 0 var(--space-5) var(--space-5) calc(var(--space-5) + 1.75rem + var(--space-4));
}

.faq__resposta p {
    margin: 0;
    color: var(--color-text-muted);
}

/* md — 768px */
@media (min-width: 48rem) {
    .faq {
        grid-template-columns: minmax(0, 19rem) minmax(0, 1fr);
        gap: var(--space-12);
    }
}

/* lg — 1024px */
@media (min-width: 64rem) {
    /* A introdução acompanha a rolagem da lista, que costuma ser longa. */
    .faq__intro {
        position: sticky;
        top: 6rem;
    }
}

/* ==========================================================================
   Depoimentos
   ========================================================================== */

.depoimentos--apos-texto { margin-top: var(--space-8); }

.depoimentos {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--space-5);
}

.depoimento {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
    margin: 0;
    padding: var(--space-6);
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    transition: transform var(--transicao), box-shadow var(--transicao);
}

.depoimento:hover { transform: translateY(-3px); box-shadow: var(--shadow); }

.depoimento .icon { color: var(--color-accent); opacity: 0.5; }
.depoimento blockquote { margin: 0; }
.depoimento blockquote p { margin: 0; }

.depoimento figcaption { font-size: var(--text-sm); font-weight: var(--weight-semibold); }

.depoimento__papel {
    display: block;
    font-weight: var(--weight-normal);
    color: var(--color-text-muted);
}

/* md — 768px */
@media (min-width: 48rem) {
    .depoimentos { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ==========================================================================
   Chamada final
   ========================================================================== */

.cta { text-align: center; }
.cta__titulo { margin-bottom: var(--space-3); }
.cta p { margin-inline: auto; }

.cta__acoes {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--space-3);
    margin-top: var(--space-8);
}

/* ==========================================================================
   Página de formulário — UM cartão largo e centrado (§88)
   --------------------------------------------------------------------------
   ⚠️ Isto SUBSTITUI o desenho de duas colunas. Antes o formulário dividia a
   faixa com uma coluna de apoio ("Prefere falar direto?" e "O que acontece
   depois"); o cliente pediu o formato da referência, e a coluna era
   exatamente o que impedia o cartão de ocupar a largura.

   Medido na referência com viewport de verdade (1265px): cartão de **992px**
   dentro de um invólucro de 1024. É por isso que o teto aqui é 62rem — o
   número saiu de medição, não de gosto.

   ⚠️ Medir com o painel do navegador recolhido devolve viewport 0 e números
   plausíveis e todos errados (§72). A primeira leitura desta mesma página deu
   "form: 0px".

   Os canais diretos continuam no RODAPÉ (§48), e os passos foram para a tela
   do protocolo — onde eles respondem à pergunta em vez de prometer.
   ========================================================================== */

.form-pagina {
    max-width: 62rem;
    margin-inline: auto;
}

/* A seção do formulário vem logo abaixo de um H1 que já se apresentou.
   Com o respiro cheio de seção, a linha de apoio caía longe demais do
   título e os dois deixavam de se ler como um par. */
.secao:has(> .container > .form-pagina) { padding-block-start: var(--space-2); }

/* Centrada e no mesmo corpo do texto, como na referência — era 18px e
   alinhada à esquerda, o que a desencontrava do título logo acima. */
.form-pagina__abertura {
    margin-inline: auto;
    margin-bottom: var(--space-6);
    font-size: var(--text-base);
    line-height: var(--leading-snug);
    color: var(--color-text-muted);
    max-width: var(--measure);
    text-align: center;
}
.passos {
    display: grid;
    gap: var(--space-4);
    margin: 0;
    padding: 0;
    list-style: none;
    counter-reset: passo;
}

.passos li {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    gap: var(--space-3);
    align-items: start;
    font-size: var(--text-sm);
    color: var(--color-text-muted);
}

.passos__numero {
    display: grid;
    place-items: center;
    width: 1.75rem;
    height: 1.75rem;
    font-size: var(--text-xs);
    font-weight: var(--weight-bold);
    color: var(--color-text-inverse);
    background: var(--color-primary);
    border-radius: var(--radius-full);
}

/* ==========================================================================
   Formulários (§7.1)
   ========================================================================== */

.formulario { max-width: 46rem; margin-top: var(--space-8); }

/* Dentro da página de formulário ele vira cartão e não precisa de recuo
   próprio: quem dá o respiro é o cartão. */
.formulario--cartao {
    max-width: none;
    margin-top: 0;
    padding: var(--space-6);
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
}

/* ---- Agrupamento por assunto -------------------------------------------
   fieldset/legend e não <div>+<h3>: leitor de tela anuncia a legenda ao
   entrar em cada campo do grupo, o que dá contexto a quem não vê a tela. */

.formulario__grupo {
    margin: 0 0 var(--space-6);
    padding: 0;
    border: 0;
    /* fieldset nasce com `min-width: min-content`, e isso impede o grid de
       dentro de encolher — o conteúdo estoura em tela estreita. */
    min-width: 0;
}

.formulario__grupo:last-of-type { margin-bottom: var(--space-4); }

.formulario__grupo legend {
    /* `display: block` tira a legend do posicionamento especial que o
       navegador dá a ela, sem perder a semântica.

       NÃO usar `float: left` aqui, que é a receita que se vê por aí: uma
       legend flutuada com largura total não deixa espaço nenhum para o
       grid seguinte, que colapsa para zero. Medido: a grade de campos
       ficou com 0px de largura e as colunas com 75px. */
    display: block;
    width: 100%;
    margin-bottom: var(--space-4);
    padding: 0 0 var(--space-2);
    font-size: var(--text-xs);
    font-weight: var(--weight-semibold);
    letter-spacing: var(--tracking-wide);
    text-transform: uppercase;
    color: var(--color-text-muted);
    border-bottom: 1px solid var(--color-border);
}

.formulario__grade {
    display: grid;
    grid-template-columns: 1fr;
    gap: 0 var(--space-4);
}

/* sm — 640px */
@media (min-width: 40rem) {
    .formulario__grade { grid-template-columns: repeat(2, minmax(0, 1fr)); }

    /* ⚠️ Serve para campo de valor curto — o CNAE, o tipo de inscrição.
       NÃO serve mais para o estado: desde que ele passou a mostrar o nome
       por extenso, "Rio Grande do Norte" não cabe em 9rem, e o que a
       pessoa leria é "Rio Grande do N…". */
    .formulario__campo--estreito { max-width: 9rem; }
}

.formulario__campo {
    display: flex;
    flex-direction: column;

    /* Enxuto, a pedido do cliente. Eram 8px entre rótulo e campo e 16px entre
       linhas; agora são 5 e 10.

       ⚠️ O que ENCOLHEU foi o vazio, nunca o alvo: o campo continua com 40px
       (44 no dedo) e a fonte continua em 16px, que é o que impede o Safari do
       iPhone de dar zoom ao focar (§41). Espaço é o que se corta primeiro
       quando um formulário parece grande; alvo de toque e legibilidade, não. */
    gap: 0.3125rem;
    margin-bottom: 0.625rem;
}

/* O rótulo desce para 13px e ganha peso. Ele é etiqueta, não texto: precisa
   dizer o que é o campo sem competir com o que a pessoa digitou dentro. */
.formulario__campo label {
    font-size: var(--text-xs);
    font-weight: var(--weight-semibold);
    line-height: 1.3;
}

.formulario__opcional { font-weight: var(--weight-normal); color: var(--color-text-muted); }

/* Seleção por EXCLUSÃO, não por lista de tipos.
   -------------------------------------------------------------------------
   A lista de tipos já falhou quatro vezes neste projeto (§40): password,
   search e number entraram no HTML e ninguém lembrou do CSS — o navegador
   desenhava o campo cru e nada acusava.

   Invertendo, o padrão passa a ser "todo campo é estilizado", e só o que está
   explicitamente de fora fica sem. Tipo novo nasce certo; o erro, se houver,
   é um checkbox estilizado como caixa de texto — visível na hora.

   ⚠️ A cadeia vai dentro de `:where()` porque `:not()` SOMA especificidade:
   seis atributos levariam esta regra a (0,7,1), e aí toda regra de estado
   escrita depois — `:disabled`, `.tem-erro` — perderia dela em silêncio e o
   campo continuaria com a aparência normal. `:where()` vale zero, então a
   regra fica em (0,1,1) e os estados vencem naturalmente. */
.formulario input:where(:not([type="checkbox"]):not([type="radio"]):not([type="hidden"]):not([type="submit"]):not([type="button"]):not([type="file"])),
.formulario select,
.formulario textarea {
    width: 100%;
    /* Compacto como a referência (§88): ela mede 39px de altura, e aqui
       são 40. O respiro vertical foi cortado, NUNCA a fonte.

       ⚠️ A referência chega aos 39px baixando o texto para 14px, e paga
       por isso no Safari do iPhone: abaixo de 16px ele dá zoom ao focar
       o campo e a página inteira sai do lugar (§41). O mesmo tamanho de
       caixa se consegue com menos padding, e aí o zoom não acontece.

       Os 44px da §29 voltam inteiros sob `pointer: coarse`, logo abaixo:
       a regra não caiu, ficou condicionada ao dedo. */
    min-height: 40px;
    padding: var(--space-2) var(--space-3);
    font: inherit;

    /* ⚠️ Sem esta linha o campo mede 44px e não 40, e a causa é sutil:
       `font: inherit` traz o TAMANHO mas o campo continua herdando a
       entrelinha do corpo (1.6), pensada para parágrafo. Com 16px de
       texto isso são 26px de linha, e o `min-height` deixa de mandar.
       Medido antes: 40px declarado, 44px na tela. */
    line-height: 1.35;
    /* 16px no celular: abaixo disso o Safari dá zoom ao focar o campo, e a
       página inteira sai do lugar. */
    font-size: max(1rem, var(--text-base));
    color: var(--color-text);
    background: var(--color-bg);
    border: 1px solid var(--color-border-strong);
    border-radius: var(--radius);
    transition: border-color var(--transicao), box-shadow var(--transicao);
}

.formulario textarea { min-height: 8rem; resize: vertical; }

/* Onde o ponteiro é o DEDO, os 44px da §29 valem inteiros. Mesma saída da
   §56: não se escolhe entre a medida de toque e a densidade de tela — se
   pergunta ao dispositivo. */
@media (pointer: coarse) {
    .formulario input:where(:not([type="checkbox"]):not([type="radio"]):not([type="hidden"]):not([type="submit"]):not([type="button"]):not([type="file"])),
    .formulario select,
    .formulario textarea {
        min-height: var(--tap-target);
        height: var(--tap-target);
    }
}

/* ---- A linha da inscrição (§88) ----------------------------------------
   Tipo · documento com o botão de consulta · CNAE, nesta ordem e nesta linha.

   ⚠️ O CNAE fica ao LADO do "Buscar na Receita" a pedido do cliente, e o
   arranjo tem lógica própria: os três campos falam da mesma coisa — que
   inscrição é, qual é, e o que a consulta trouxe de volta. Espalhados pela
   grade, o CNAE aparecia quatro campos abaixo do botão que o preenche, e
   quem clicava não via o resultado sem rolar.

   Mobile-first (§29): empilhado na base, em linha a partir de 40rem. */
.linha-inscricao {
    display: grid;
    grid-template-columns: 1fr;
    gap: 0 var(--space-4);
}

/* sm — 640px */
@media (min-width: 40rem) {
    .linha-inscricao { grid-template-columns: 6.5rem minmax(0, 1fr) 9rem; }
}

/* ---- Campo com um botão colado (§88) -----------------------------------
   Hoje é o "Buscar na Receita"; o padrão vale para todo campo que possa
   ser preenchido por consulta.

   ⚠️ O botão nasce com `hidden` no HTML e é o script que o revela. Sem
   isso, quem está sem JavaScript veria um botão morto — e a §29 trata
   botão que não faz nada como defeito, não como recado. Por isso o
   `[hidden]` precisa continuar valendo: `display: flex` numa classe VENCE
   o atributo, que é regra de baixa especificidade do navegador (§56). */
.campo-com-acao {
    display: flex;
    gap: var(--space-2);
    align-items: flex-start;
}

.campo-com-acao > input { flex: 1 1 auto; min-width: 0; }

.campo-com-acao .botao {
    flex: none;
    white-space: nowrap;

    /* ⚠️ `min-height` sozinho NÃO resolve: o botão do site tem 12px de
       respiro vertical e entrelinha de parágrafo (medido: 51,6px), e
       min-height não encolhe nada. Ao lado de um campo de 40px isso
       aparece como desalinhamento de 12px.

       Ele precisa das MESMAS três medidas do campo — altura, respiro e
       entrelinha — porque o que se quer é que os dois sejam a mesma
       caixa, e não que um deles tenha um piso. */
    /* ⚠️ `min-height` E `height`. O `.botao` do site declara
       `min-height: var(--tap-target)` (44px), e min-height GANHA de
       height — declarar só a altura deixava o botão em 44 ao lado de um
       campo de 40, medido. Os 44px voltam logo abaixo, sob `coarse`. */
    min-height: 40px;
    height: 40px;
    padding: 0 var(--space-4);
    line-height: 1.35;
}

.campo-com-acao .botao[hidden] { display: none; }

/* ⚠️ Este bloco tem de vir DEPOIS da regra base, e não junto do outro
   `pointer: coarse` lá em cima. Os dois seletores valem (0,2,0), e nesse
   empate ganha quem vem por último no arquivo — declarado antes, o botão
   ficava em 40px ao lado de um campo de 44 no celular. Medido.

   É a mesma armadilha das §§83 e 87, pela terceira vez: regra que depende de
   ordem quebra na primeira reorganização do arquivo. */
@media (pointer: coarse) {
    .campo-com-acao .botao {
        min-height: var(--tap-target);
        height: var(--tap-target);
    }
}

/* Em tela estreita o botão desce para a própria linha.
   -------------------------------------------------------------------------
   Medido a 375px: lado a lado, o campo do CNPJ sobrava 100px e mostrava
   "00.000.000/0" — a pessoa digita 18 caracteres numa janela que cabe onze,
   e o começo do que ela escreveu some para a esquerda. Um botão de conforto
   não pode estreitar o campo que ele existe para ajudar a preencher. */
@media (max-width: 30rem) {
    .campo-com-acao { flex-wrap: wrap; }
    .campo-com-acao > input { flex: 1 1 100%; }
    .campo-com-acao .botao { width: 100%; }
}

/* ---- Campo que não se edita --------------------------------------------
   Quinta ocorrência da mesma classe de erro da §40: o estado existe no HTML
   e não existia no CSS. O campo desabilitado saía IDÊNTICO ao editável
   (medido: mesmo fundo, mesma borda, mesma cor de texto) — só o cursor
   mudava, o que ninguém percebe antes de tentar digitar.

   O contraste do texto continua alto de propósito: o campo é para LER, e
   `--color-text-muted` sobre `--color-surface-strong` mediria menos que o
   mínimo. Quem sinaliza é o fundo, não o apagamento do texto. */
.formulario input:disabled,
.formulario select:disabled,
.formulario textarea:disabled,
.formulario input[readonly],
.formulario textarea[readonly] {
    color: var(--color-text);
    background: var(--color-surface-strong);
    border-color: var(--color-border);
    cursor: not-allowed;
}

/* ---- Campo em foco -----------------------------------------------------
   Só o anel, a pedido do cliente (§90). A borda azul intensa somada ao anel
   azul fazia o campo saltar duas vezes — é a mesma correção que a §82 já
   tinha feito no painel, e que faltava aqui.

   ⚠️ A cor da borda NÃO é declarada de propósito. Assim o campo recusado
   continua vermelho enquanto está em foco, sem precisar de uma regra que
   desfaça esta — e é justamente quando a cor mais importa. */
.formulario input:focus-visible,
.formulario select:focus-visible,
.formulario textarea:focus-visible {
    /* ⚠️ A "borda azul" que sobrava NÃO vinha daqui — vinha do
       `:focus-visible { outline: 2px solid var(--color-accent) }` global, lá
       no topo do arquivo. Ele é o indicador de foco de TUDO: link, botão,
       caixa de seleção. Some com ele em geral e quem navega por teclado fica
       sem saber onde está (§16).

       Então ele sai só no campo de formulário, e **só porque existe outro no
       lugar**: o anel. `outline: none` sem substituto é a falha de
       acessibilidade mais comum que existe.

       ⚠️ Por isso o anel subiu de 18% para 65%. Como agora é o ÚNICO
       indicador, ele precisa passar no mínimo de 3:1 que a WCAG 2.2 pede para
       elemento de interface (1.4.11) — a 18% ele media 1,98:1, ou seja, era
       enfeite em cima de um contorno de verdade. Medido a 65%: 3,24:1. */
    outline: none;
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-accent) 65%, transparent);
}

/* ---- Campo recusado ----------------------------------------------------
   A cor NUNCA é o único sinal (§16, WCAG): junto dela vai a mensagem escrita
   embaixo do campo e o aria-invalid, que o leitor de tela anuncia. */

.formulario .tem-erro,
.formulario [aria-invalid="true"] {
    border-color: var(--color-danger);
    background: color-mix(in srgb, var(--color-danger) 4%, var(--color-bg));
}

.formulario .tem-erro:focus-visible,
.formulario [aria-invalid="true"]:focus-visible {
    border-color: var(--color-danger);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-danger) 18%, transparent);
}

.formulario__erro {
    display: flex;
    align-items: flex-start;
    gap: var(--space-2);
    margin: 0;
    font-size: var(--text-sm);
    font-weight: var(--weight-medium);
    color: var(--color-danger);
}

.formulario__erro[hidden] { display: none; }

.formulario__erro::before {
    content: "!";
    display: grid;
    place-items: center;
    flex: none;
    width: 1.05rem;
    height: 1.05rem;
    margin-top: 0.1rem;
    font-size: 0.7rem;
    font-weight: var(--weight-bold);
    color: var(--color-text-inverse);
    background: var(--color-danger);
    border-radius: var(--radius-full);
}

.formulario__dica {
    margin: 0;
    font-size: var(--text-xs);
    color: var(--color-text-muted);
}

.formulario__dica[hidden] { display: none; }

/* O retorno da consulta fala por aqui. Vermelho quando não deu certo —
   e nunca só a cor: o texto diz o que fazer ("Preencha à mão"), que é o
   que a §16 exige e o que serve a quem não distingue as duas. */
.formulario__dica--erro { color: var(--color-danger); font-weight: var(--weight-medium); }

/* Honeypot: escondido de gente, visível para robô que lê o HTML (§7.1).
   Nunca type="hidden" — robô ignora campo hidden. */
.formulario__isca {
    position: absolute;
    left: -9999px;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

.formulario__campo--consentimento {
    margin-top: var(--space-2);
    padding: var(--space-4);
    background: var(--color-surface);
    border-radius: var(--radius);
}

.formulario__consentimento {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: var(--space-3);
    align-items: start;
    font-size: var(--text-sm);
    font-weight: var(--weight-normal);
    cursor: pointer;
}

/* Checkbox NUNCA pré-marcado (§7.1). */
.formulario__consentimento input[type="checkbox"] {
    width: 1.15rem;
    height: 1.15rem;
    margin-top: 0.22rem;
    accent-color: var(--color-primary);
}

.formulario__acoes {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
    margin-top: var(--space-6);
    padding-top: var(--space-5);
    border-top: 1px solid var(--color-border);
}

.formulario__acoes .formulario__enviar { align-self: stretch; }

.formulario__nota,
.formulario__aviso {
    margin: 0;
    font-size: var(--text-sm);
    color: var(--color-text-muted);
}

.formulario__aviso {
    padding: var(--space-4) var(--space-5);
    background: var(--color-surface);
    border-left: 3px solid var(--color-warning);
    border-radius: var(--radius-sm);
    max-width: none;
}

/* sm — 640px */
@media (min-width: 40rem) {
    .formulario--cartao { padding: var(--space-8); }

    .formulario__acoes {
        flex-direction: row;
        align-items: center;
        gap: var(--space-6);
    }

    .formulario__acoes .formulario__enviar { align-self: auto; flex: none; }
}

/* ==========================================================================
   Rodapé
   ========================================================================== */

.rodape {
    padding-block: var(--space-10);
    color: var(--color-text-on-dark-muted);
    background: var(--color-dark);
    /* Traço no topo. Sem ele, qualquer bloco escuro imediatamente
       acima se funde com o rodapé e os dois viram uma faixa só — foi o que
       fez o rodapé "parecer enorme". Na home a chamada final subiu para
       antes do FAQ; nas demais páginas ela continua sendo o último bloco, e
       é esta linha que a separa. */
    border-top: 2px solid var(--color-accent);
}

.rodape__grade {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--space-8);
    margin-bottom: var(--space-8);
}

.rodape__marca {
    font-size: var(--text-lg);
    font-weight: var(--weight-bold);
    color: var(--color-text-inverse);
}

.rodape__sobre {
    max-width: 34ch;
    font-size: var(--text-sm);
    line-height: var(--leading-normal);
}

.rodape h4 {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    margin-bottom: var(--space-3);
    font-size: var(--text-xs);
    font-weight: var(--weight-semibold);
    letter-spacing: var(--tracking-wide);
    text-transform: uppercase;
    color: var(--color-accent-light);
}

.rodape ul { margin: 0; padding: 0; list-style: none; }

.rodape p { color: var(--color-text-on-dark-muted); }

.rodape li a {
    display: inline-flex;
    align-items: center;
    /* 44px é o alvo de toque mínimo da §29, item 1. Medido antes: 32px. */
    min-height: var(--tap-target);
    font-size: var(--text-sm);
    color: var(--color-text-on-dark-muted);
    text-decoration: none;
}

.rodape li a:hover { color: var(--color-text-inverse); text-decoration: underline; }

/* ---- Contato ---------------------------------------------------------- */

.rodape__contato li {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    min-height: var(--tap-target);
    font-size: var(--text-sm);
}

.rodape__contato .icon {
    flex: none;
    color: var(--color-accent-light);
}

/* ---- Varas atendidas ---------------------------------------------------
   Também é sinal local: a lista conversa com o areaServed do JSON-LD e com
   as cidades declaradas no Google Business Profile (§3). */

.rodape__varas {
    padding-block: var(--space-8);
    border-top: 1px solid color-mix(in srgb, var(--color-text-inverse) 15%, transparent);
}

.varas + .varas { margin-top: var(--space-6); }

.varas__lista {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    font-size: var(--text-sm);
}

.varas__lista li {
    padding: var(--space-1) var(--space-3);
    color: var(--color-text-on-dark-muted);
    border: 1px solid color-mix(in srgb, var(--color-text-inverse) 18%, transparent);
    border-radius: var(--radius-full);
}

/* ---- Traço final: institucional à esquerda, legal à direita ------------ */

.rodape__base {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
    padding-top: var(--space-6);
    border-top: 1px solid color-mix(in srgb, var(--color-text-inverse) 15%, transparent);
    font-size: var(--text-sm);
}

.rodape__dpo {
    margin: 0;
    max-width: none;
}

.rodape__sep {
    margin-inline: var(--space-2);
    opacity: 0.5;
}

.rodape__legal {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-5);
    margin: 0;
}

.rodape__legal a {
    display: inline-flex;
    align-items: center;
    min-height: var(--tap-target);
    color: var(--color-text-on-dark-muted);
    text-decoration: none;
}

.rodape__legal a:hover { color: var(--color-text-inverse); text-decoration: underline; }

/* sm — 640px */
@media (min-width: 40rem) {
    .rodape__grade { grid-template-columns: 1.4fr 1.2fr 1fr; }
}

/* md — 768px */
@media (min-width: 48rem) {
    .rodape__base {
        flex-direction: row;
        align-items: center;
        justify-content: space-between;
    }

    .rodape__legal { justify-content: flex-end; }
}

/* ==========================================================================
   Área logada — telas isoladas (login, aceite, contexto)

   Sem menu de propósito: o padrão de menu é da §29, item 2, e ainda não foi
   definido. Estas telas não dependem dele.

   Os temas da §15 são exclusivos da área logada e entram depois, apoiados
   nestes mesmos tokens via [data-theme].
   ========================================================================== */

.acesso {
    min-height: 100dvh;
    background:
        radial-gradient(ellipse 90% 60% at 50% -10%, color-mix(in srgb, var(--color-accent) 8%, transparent), transparent),
        var(--color-surface);
}

.acesso__area {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 100dvh;
    padding: var(--space-6) var(--space-5);
}

.acesso__cartao {
    width: 100%;
    max-width: 30rem;
    padding: var(--space-8);
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow);
}

.acesso__marca {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    margin-bottom: var(--space-8);
    font-size: var(--text-lg);
    font-weight: var(--weight-bold);
    letter-spacing: var(--tracking-tight);
    color: var(--color-primary);
    text-decoration: none;
}

.acesso__marca .icon { color: var(--color-accent); }

.acesso__titulo { font-size: var(--text-2xl); margin-bottom: var(--space-2); }

.acesso__apoio {
    margin-bottom: var(--space-6);
    color: var(--color-text-muted);
    font-size: var(--text-sm);
}

.acesso .formulario { max-width: none; margin-top: 0; }

.acesso .formulario__enviar { width: 100%; margin-top: var(--space-2); }

.acesso__secundario { margin-top: var(--space-6); text-align: center; }

/* ---- Rótulo com atalho à direita ("Esqueci minha senha") ---------------
   O link fica na linha do rótulo, não solto abaixo do botão: é onde a
   pessoa olha quando a senha não vem à cabeça. */

.formulario__rotulo-linha {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--space-3);
}

.formulario__ajuda {
    font-size: var(--text-sm);
    color: var(--color-text-muted);
    text-decoration: none;
}

.formulario__ajuda:hover {
    color: var(--color-accent-text);
    text-decoration: underline;
}

/* ---- Pé do cartão de login -------------------------------------------- */

.acesso__rodape {
    margin-top: var(--space-8);
    padding-top: var(--space-5);
    border-top: 1px solid var(--color-border);
}

.acesso__nota {
    margin: 0 0 var(--space-3);
    font-size: var(--text-xs);
    line-height: var(--leading-snug);
    color: var(--color-text-muted);
}

.acesso__legal {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-4);
    margin: 0;
    font-size: var(--text-xs);
}

.acesso__legal a {
    color: var(--color-text-muted);
    text-decoration: none;
}

.acesso__legal a:hover { color: var(--color-accent-text); text-decoration: underline; }

.acesso__link {
    font: inherit;
    font-size: var(--text-sm);
    color: var(--color-text-muted);
    background: none;
    border: 0;
    cursor: pointer;
    text-decoration: underline;
    text-underline-offset: 0.2em;
}

.acesso__link:hover { color: var(--color-accent-text); }

/* Telas de aceite precisam de mais largura que o login. */
.acesso__cartao:has(.documento) { max-width: 44rem; }

/* ---- Alertas ---------------------------------------------------------- */

.alerta {
    padding: var(--space-3) var(--space-4);
    margin-bottom: var(--space-6);
    font-size: var(--text-sm);
    border-radius: var(--radius);
}

.alerta--erro {
    color: var(--color-danger);
    background: color-mix(in srgb, var(--color-danger) 8%, transparent);
    border: 1px solid color-mix(in srgb, var(--color-danger) 28%, transparent);
}

/* ---- Documento legal --------------------------------------------------- */

.documento { margin-bottom: var(--space-6); }

.documento__titulo {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: var(--space-3);
    font-size: var(--text-lg);
    margin-bottom: var(--space-3);
}

.documento__versao {
    font-size: var(--text-xs);
    font-weight: var(--weight-medium);
    letter-spacing: var(--tracking-wide);
    text-transform: uppercase;
    color: var(--color-text-muted);
}

.documento__texto {
    max-height: 16rem;
    padding: var(--space-4) var(--space-5);
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    font-size: var(--text-sm);
}

.documento__texto p { max-width: none; }
.documento__texto p:last-child { margin-bottom: 0; }

.scroll-y { overflow-y: auto; -webkit-overflow-scrolling: touch; }

/* ---- Lista de dados ---------------------------------------------------- */

.dados {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: var(--space-2) var(--space-6);
    margin: 0 0 var(--space-8);
    padding: var(--space-5);
    background: var(--color-surface);
    border-radius: var(--radius);
    font-size: var(--text-sm);
}

.dados dt { font-weight: var(--weight-semibold); color: var(--color-text-muted); }
.dados dd { margin: 0; }

.alerta--ok {
    color: var(--color-success);
    background: color-mix(in srgb, var(--color-success) 8%, transparent);
    border: 1px solid color-mix(in srgb, var(--color-success) 28%, transparent);
}

.alerta__lista { margin: 0; padding-left: var(--space-4); }

.formulario__dica {
    margin: 0;
    font-size: var(--text-xs);
    color: var(--color-text-muted);
    max-width: none;
}

/* ---- Sessões ativas (conflito de sessão única, §21) -------------------- */

.sessoes { margin: 0 0 var(--space-6); padding: 0; list-style: none; }

.sessao {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: var(--space-3);
    align-items: start;
    padding: var(--space-4);
    margin-bottom: var(--space-3);
    background: var(--color-surface);
    border-radius: var(--radius);
}

.sessao .icon { color: var(--color-accent); margin-top: 0.15rem; }
.sessao p { margin: 0; max-width: none; }
.sessao__quando { font-size: var(--text-sm); font-weight: var(--weight-medium); }
.sessao__origem { font-size: var(--text-xs); color: var(--color-text-muted); }

/* ---- Segundo fator ----------------------------------------------------- */

.chave {
    padding: var(--space-4) var(--space-5);
    margin-bottom: var(--space-6);
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    text-align: center;
}

.chave__rotulo {
    margin: 0 0 var(--space-2);
    font-size: var(--text-xs);
    letter-spacing: var(--tracking-wide);
    text-transform: uppercase;
    color: var(--color-text-muted);
    max-width: none;
}

.chave__valor {
    margin: 0;
    font-family: var(--font-mono, ui-monospace, monospace);
    font-size: var(--text-lg);
    font-weight: var(--weight-semibold);
    letter-spacing: 0.12em;
    word-break: break-all;
    max-width: none;
}

.codigos {
    padding: var(--space-5);
    margin-bottom: var(--space-6);
    background: color-mix(in srgb, var(--color-warning) 7%, transparent);
    border: 1px solid color-mix(in srgb, var(--color-warning) 30%, transparent);
    border-radius: var(--radius);
}

.codigos__aviso {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: var(--space-3);
    align-items: start;
    margin: 0 0 var(--space-4);
    font-size: var(--text-sm);
    max-width: none;
}

.codigos__aviso .icon { color: var(--color-warning); margin-top: 0.1rem; }

.codigos__lista {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-2);
    margin: 0;
    padding: 0;
    list-style: none;
    font-family: var(--font-mono, ui-monospace, monospace);
    font-size: var(--text-sm);
    letter-spacing: 0.05em;
}

/* ---- Contador de sessão (§21, item 1) ---------------------------------- */

.sessao-contador-linha {
    margin-bottom: var(--space-6);
    font-size: var(--text-sm);
    color: var(--color-text-muted);
    max-width: none;
}

.sessao-contador {
    font-variant-numeric: tabular-nums;
    color: var(--color-text);
}

.sessao-contador--aviso { color: var(--color-warning); }
.sessao-contador--fim { color: var(--color-danger); }

.sessao--atual { background: color-mix(in srgb, var(--color-accent) 8%, transparent); }
.sessao--atual .icon { color: var(--color-accent); }
.sessao--vazia .icon { color: var(--color-success); }

/* ---- Protocolo da solicitação ------------------------------------------ */

.protocolo {
    display: inline-block;
    margin: var(--space-6) 0;
    padding: var(--space-4) var(--space-8);
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
}

.protocolo__rotulo {
    margin: 0 0 var(--space-1);
    font-size: var(--text-xs);
    font-weight: var(--weight-semibold);
    letter-spacing: var(--tracking-wide);
    text-transform: uppercase;
    color: var(--color-text-muted);
    max-width: none;
}

.protocolo__valor {
    margin: 0;
    font-family: var(--font-mono);
    font-size: var(--text-2xl);
    font-weight: var(--weight-bold);
    letter-spacing: 0.06em;
    color: var(--color-accent-text);
    max-width: none;
}

.alerta--aviso {
    color: var(--color-warning);
    background: color-mix(in srgb, var(--color-warning) 8%, transparent);
    border: 1px solid color-mix(in srgb, var(--color-warning) 30%, transparent);
}

/* Botão travado enquanto envia (§29, item 5). */
.formulario__enviar[disabled] {
    opacity: 0.65;
    cursor: progress;
}

/* ==========================================================================
   Paleta do PAINEL — claro e escuro (CLAUDE.md, §§15 e 56)

   O painel tem paleta PRÓPRIA, diferente do site público. Não é inconsistência:
   são dois produtos com públicos e objetivos distintos. O site vende (vinho e
   dourado, identidade da marca, §40); o painel é ferramenta de trabalho, usada
   horas seguidas, e segue a referência de ERP que o cliente escolheu.

   Como funciona: os MESMOS nomes de token são redefinidos em `body.app`. Todo
   componente do painel continua escrevendo `var(--color-bg)` sem saber de tema
   nenhum — trocar a paleta é trocar este bloco, e nada mais (§6).

   Três estados, nesta ordem, e a ordem importa:
     1. `.app`                        → claro, o padrão;
     2. `prefers-color-scheme: dark`  → segue o sistema, quando não há escolha;
     3. `[data-tema]`                 → a escolha explícita da pessoa vence as duas.

   ⚠️ Contraste medido sobre o fundo em que a cor de fato aparece. Ao trocar
   qualquer cor, MEDIR DE NOVO (§27, item 8).
   ========================================================================== */

body.app {
    /* ⚠️ A paleta CLARA não é repetida aqui: ela vem do `:root` e é a mesma do
       site (§57). Repetir os valores criaria dois lugares para manter em dia,
       e dois lugares divergem (§6). O que este bloco define é só o que é
       exclusivo do painel: as medidas da navegação e as cores do trilho. */

    /* ---- Trilho de seções ------------------------------------------------
       O azul-escuro do trilho é o MESMO nos dois temas. É o que dá âncora
       visual: a coluna da esquerda não pisca ao trocar de tema. */
    --color-trilho-texto: #c3d0e8;         /* 11.20:1 sobre o azul-escuro */
    --color-trilho-texto-ativo: #a1b9ed;   /*  9.85:1 sobre o ativo       */
    --color-trilho-ativo: #000c29;

    /* ---- Medidas da navegação (§56) --------------------------------------
       Vieram da referência: trilho 56, painel 240, item 40 de altura com
       ícone de 16. O que estava aqui antes era maior — 64/208/44 com ícone
       de 20 — e é o que o cliente apontou como "grande demais". */
    --nav-trilho: 56px;
    --nav-trilho-aberto: 232px;
    --nav-painel: 240px;
    --nav-item: 40px;
    --nav-icone: 14px;
    --nav-trilho-icone: 18px;

    /* Submenu recolhido: só os ícones, como o trilho. Volta ao passar o
       mouse. */
    --nav-painel-recolhido: 48px;

    color-scheme: light;
}


/* 2. Sem escolha explícita, segue o sistema. */
@media (prefers-color-scheme: dark) {
    body.app:not([data-tema="claro"]) {
        --color-bg: #242424;
        --color-surface: #202020;
        --color-surface-strong: #2e2e2e;
        --color-border: #383838;
        --color-border-strong: #454545;

        --color-text: #fafafa;           /* 14.54:1 sobre o cartão */
        --color-text-muted: #a1a1a1;     /*  6.01:1 sobre o cartão */

        /* ⚠️ Dois papéis para o azul, pelo mesmo motivo do dourado na §40:
           #0a4ee4 é fundo de botão (branco sobre ele: 6.51:1) e reprovaria
           como TEXTO sobre o escuro. Como texto entra o claro. */
        --color-primary: #0a4ee4;
        --color-primary-hover: #2d68f0;
        /* ⚠️ `accent` e `accent-text` são DIFERENTES no escuro. O primeiro é
           tinta de borda e de fundo; o segundo é traço e texto, e por isso
           precisa de folga: #6791ea mede 5.44:1 sobre o cartão, e qualquer
           fundo levemente claro atrás dele (um selo, por exemplo) derrubava
           para 4.4. #8fadf0 mede 6.96:1 e aguenta. */
        --color-accent: #6791ea;
        --color-accent-text: #8fadf0;
        --color-accent-hover: #b3c8f5;

        /* As semânticas do claro reprovam no escuro: o vermelho #a32020 mede
           2.16:1 sobre #202020. Cada uma tem par próprio. */
        --color-success: #4ade80;        /* 9.35:1 */
        --color-success-vivo: #4ade80;   /* no escuro o próprio verde já é vivo */
        --color-warning: #fbbf24;        /* 9.72:1 */
        --color-danger: #f87171;         /* 5.82:1 */

        color-scheme: dark;
    }
}

/* 3. A escolha da pessoa vence — nos DOIS sentidos. Sem este bloco, quem
      escolhe "escuro" num sistema operacional claro não recebe nada. */
body.app[data-tema="escuro"] {
    --color-bg: #242424;
    --color-surface: #202020;
    --color-surface-strong: #2e2e2e;
    --color-border: #383838;
    --color-border-strong: #454545;

    --color-text: #fafafa;
    --color-text-muted: #a1a1a1;

    --color-primary: #0a4ee4;
    --color-primary-hover: #2d68f0;
    --color-accent: #6791ea;
    --color-accent-text: #8fadf0;
    --color-accent-hover: #b3c8f5;

    --color-success: #4ade80;
    --color-success-vivo: #4ade80;
    --color-warning: #fbbf24;
    --color-danger: #f87171;

    color-scheme: dark;
}

/* ==========================================================================
   Casca da área logada (CLAUDE.md, §38)

   Altura fixa: NADA rola, exceto a tabela.

   100dvh e não 100vh: no celular a barra do navegador aparece e some, e
   100vh não acompanha — o rodapé, que é a faixa mais importante, ficaria
   escondido atrás dela.
   ========================================================================== */

.app { margin: 0; background: var(--color-surface); }

.app__gatilho { position: absolute; opacity: 0; pointer-events: none; }

/* O trilho é ABSOLUTO e a casca reserva o lugar dele com padding.

   Assim, quando ele expande no hover, cresce por cima do conteúdo em vez de
   empurrar a página inteira — tabela reposicionando a cada passada de mouse
   é pior que menu nenhum. */
.app__casca {
    position: relative;
    display: flex;
    height: 100dvh;
    padding-left: var(--nav-trilho);
    overflow: hidden;
}

/* ---- Botão secundário no painel ----------------------------------------

   ⚠️ A regra geral pinta o texto do botão secundário com `--color-primary`.
   No site isso é o vinho, que mede 15:1 sobre branco. No painel `--color-primary`
   é o AZUL DE FUNDO de botão, e como texto sobre o escuro ele mede **2.38:1**
   — medido no navegador, reprovado.

   É o mesmo par de papéis da §40: existe a cor que serve de fundo e a cor que
   serve de texto, e elas não são a mesma. `--color-accent-text` é, por
   definição, a que serve de texto no tema em vigor. */

body.app .botao--secundario,
body.app .botao--secundario:hover,
body.app .mais-acoes > summary { color: var(--color-accent-text); }

/* ---- Botão do painel é COMPACTO (§79) -----------------------------------

   O botão padrão do site tem 44px de altura, 16px de texto e respiro largo —
   medida de landing page, onde ele é o destino da página. Repetido dentro de
   uma ferramenta de trabalho, onde há vários por tela, ele domina tudo: o
   cliente comparou com a referência e disse que estavam "enormes".

   A §57 já tinha encolhido os botões da migalha por esta razão; isto estende a
   mesma decisão para o conteúdo, que é onde eles mais aparecem.

   ⚠️ Isto tensiona a §29, que exige 44px em alvo clicável — e a saída é a
   mesma da §56: **perguntar ao dispositivo**. Sob `pointer: coarse`, onde o
   ponteiro é o dedo, os 44px voltam inteiros. */
body.app .botao,
body.app .formulario__enviar {
    min-height: 32px;
    padding: var(--space-2) var(--space-4);
    font-size: var(--text-sm);
}

/* O deslocamento no hover é enfeite de landing page. Numa tela com seis botões
   lado a lado ele faz a faixa tremer a cada passada de mouse. */
body.app .botao:hover,
body.app .formulario__enviar:hover:not([disabled]) { transform: none; }

@media (pointer: coarse) {
    body.app .botao,
    body.app .formulario__enviar {
        min-height: var(--tap-target);
        padding: var(--space-3) var(--space-5);
    }
}

/* ---- Trilho de seções ---------------------------------------------------

   56px de ícones, que **expandem para 232px ao passar o mouse**, mostrando o
   nome de cada seção (§57).

   Fora do fluxo, sempre: a casca reserva o lugar com `padding-left`. É o que
   permite crescer sem empurrar nada — o conteúdo fica onde estava, e o menu
   passa por cima.

   Regra de fechamento, pedida pelo cliente: abre ao entrar NO TRILHO, e só
   fecha quando o mouse sai **do trilho e do submenu**. Ir do trilho para o
   submenu não pode fechar nada, senão o caminho até o item é uma corrida.

   Isso o CSS sozinho não expressa (não há como dizer "continue aberto"), e
   por isso há duas camadas: `:hover` puro, que funciona sem JavaScript e
   fecha ao sair do trilho; e a classe `nav-aberta`, que o script mantém
   enquanto o mouse estiver em qualquer um dos dois. Sem script, o menu
   continua abrindo — só é menos tolerante. */

.trilho {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    z-index: 25;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: var(--space-1);
    width: var(--nav-trilho);
    padding: var(--space-2) var(--space-2);
    background: var(--color-dark);
    overflow: hidden;
    transition: width var(--transicao);
}

@media (min-width: 48rem) {
    .trilho:hover,
    .app__casca.nav-aberta .trilho { width: var(--nav-trilho-aberto); }

    /* O submenu anda junto: sem isso o trilho expandido cobriria justamente
       o painel que o cliente precisa alcançar sem o menu fechar. */
    .trilho:hover ~ .submenu,
    .app__casca.nav-aberta .submenu {
        transform: translateX(calc(var(--nav-trilho-aberto) - var(--nav-trilho)));
        opacity: 1;
        pointer-events: auto;
    }
}

.trilho__marca {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    height: 40px;
    padding-inline: 10px;
    margin-bottom: var(--space-3);
    color: var(--color-accent-light);
    font-weight: var(--weight-semibold);
    text-decoration: none;
    white-space: nowrap;
}

.trilho__item {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    height: var(--nav-item);
    padding-inline: 10px;
    width: 100%;
    color: var(--color-trilho-texto);
    background: none;
    border: 0;
    border-radius: var(--radius);
    font: inherit;
    font-size: var(--text-sm);
    text-align: left;
    text-decoration: none;
    white-space: nowrap;
    cursor: pointer;
    transition: background var(--transicao), color var(--transicao);
}

.trilho__item .icon,
.trilho__marca .icon { flex: none; }

.trilho__item:hover {
    color: var(--color-text-inverse);
    background: color-mix(in srgb, var(--color-text-inverse) 10%, transparent);
}

.trilho__item--ativo {
    color: var(--color-trilho-texto-ativo);
    background: var(--color-trilho-ativo);
}

/* Seção sendo FOLHEADA na gaveta do celular (§86) — não é a seção da
   página aberta, e por isso tem marca própria e mais discreta. Usar a
   mesma de `--ativo` faria a tela dizer que a pessoa está num lugar em
   que ela não está. */
.trilho__item--folheando {
    background: color-mix(in srgb, var(--color-text-inverse) 18%, transparent);
}

/* ⚠️ `display` numa classe VENCE o atributo `hidden`, que é regra de baixa
   especificidade da folha do navegador (§56). Sem esta linha, o painel
   escondido nasceria visível e os itens das oito seções apareceriam
   empilhados. */
.submenu__painel[hidden] { display: none; }

/* O rótulo existe SEMPRE no HTML, escondido só do olho quando o trilho está
   recolhido. `display: none` o tiraria também do leitor de tela, e aí cada
   ícone viraria um botão sem nome (§16). */
.trilho__rotulo {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

.trilho:hover .trilho__rotulo,
.app__casca.nav-aberta .trilho__rotulo {
    position: static;
    width: auto;
    height: auto;
    overflow: visible;
    clip-path: none;
}

/* Grupo ancorado embaixo: conta, contador de sessão, tema e sair.
   Antes moravam na faixa da migalha, que agora pertence às ações da página. */
.trilho__pe {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: var(--space-1);
    margin-top: auto;
}

.trilho__pe form { display: contents; }

/* O contador precisa caber em 40px quando recolhido: só o número. */
/* ---- Sino de notificações ------------------------------------------------

   O badge é `position: absolute` sobre o ícone, e o item precisa ser o
   contexto de posicionamento — senão ele se ancora na janela e vai parar no
   canto da tela. */
.trilho__sino { position: relative; }

.trilho__badge {
    position: absolute;
    top: 4px;
    left: 22px;
    min-width: 16px;
    height: 16px;
    padding-inline: 4px;
    display: grid;
    place-items: center;
    background: var(--color-danger);
    color: var(--color-text-inverse);
    border-radius: 999px;
    font-size: 10px;
    font-weight: var(--weight-semibold);
    line-height: 1;
    /* O número já vai por extenso no rótulo do item, que é o que o leitor de
       tela anuncia. O badge é `aria-hidden`, então aqui é só desenho (§16). */
}

/* ---- Pé do submenu: relógio e contrair ---------------------------------- */

.submenu__relogio {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-2) var(--space-3);
    border-radius: var(--radius);
    color: var(--color-text-muted);
    font-size: var(--text-xs);
    font-variant-numeric: tabular-nums;
    text-decoration: none;
    transition: background var(--transicao), color var(--transicao);
}

.submenu__relogio:hover { background: var(--color-surface); color: var(--color-text); }

.submenu__relogio .icon { flex: none; }

.submenu__relogio-rotulo { color: var(--color-text-muted); }

/* Últimos dez minutos. Vermelho, e nunca só vermelho: o título do link diz o
   mesmo por extenso, e o número continua correndo (§16). */
.submenu__relogio.sessao-contador--aviso,
.submenu__relogio.sessao-contador--aviso .submenu__relogio-rotulo,
.submenu__relogio.sessao-contador--fim,
.submenu__relogio.sessao-contador--fim .submenu__relogio-rotulo {
    color: var(--color-danger);
    font-weight: var(--weight-medium);
}

.submenu__contrair {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-2) var(--space-3);
    border-radius: var(--radius);
    font-size: var(--text-xs);
    color: var(--color-text-muted);
    cursor: pointer;
    transition: background var(--transicao), color var(--transicao);
}

.submenu__contrair:hover { background: var(--color-surface); color: var(--color-text); }

.submenu__contrair .icon { flex: none; }

/* ---- Painel do submenu --------------------------------------------------

   Dois estados, como na referência:

   • FIXO      — ocupa lugar próprio, o conteúdo começa depois dele;
   • RECOLHIDO — some da largura e **volta ao passar o mouse**, flutuando
                 por cima do conteúdo, sem empurrar nada.

   O que decide é um checkbox, então funciona sem JavaScript; o script só
   guarda a preferência no navegador. Sem ele, o menu nasce fixo a cada
   carregamento — que é o lado seguro para errar. */

.submenu {
    display: flex;
    flex-direction: column;
    width: var(--nav-painel);
    flex: none;
    padding: var(--space-3) var(--space-2);
    background: var(--color-bg);
    border-right: 1px solid var(--color-border);
    overflow-y: auto;
    transition: width var(--transicao), transform var(--transicao);
}

.submenu__titulo {
    margin: 0 0 var(--space-2);
    padding-inline: var(--space-3);
    font-size: var(--text-xs);
    font-weight: var(--weight-semibold);
    letter-spacing: var(--tracking-wide);
    text-transform: uppercase;
    color: var(--color-text-muted);
    max-width: none;
}

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

/* Ícone + rótulo. O ícone não é enfeite: é o que liga o item do painel ao
   ícone da seção no trilho, que é tudo o que sobra quando o menu recolhe. */
.submenu__item {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    min-height: var(--nav-item);
    padding: var(--space-2) var(--space-3);
    border-radius: var(--radius);
    font-size: var(--text-sm);
    line-height: 1.25;
    color: var(--color-text-muted);
    text-decoration: none;
    transition: background var(--transicao), color var(--transicao);
}

.submenu__item .icon { flex: none; width: var(--nav-icone); height: var(--nav-icone); }

.submenu__item:hover { background: var(--color-surface); color: var(--color-text); }

.submenu__item--ativo {
    font-weight: var(--weight-medium);
    color: var(--color-accent-text);
    background: color-mix(in srgb, var(--color-accent) 10%, transparent);
}

.submenu__rodape { margin-top: auto; padding-top: var(--space-3); }

/* Fixar o menu mora na BARRA do menu, junto das demais ações da pessoa.
   Estava no pé do submenu, que é justamente o painel que ele controla — e que
   some quando o menu recolhe. O controle de um painel não pode viver dentro
   dele. */
.trilho__fixar { display: contents; }

/* ---- Menu recolhido: volta ao passar o mouse ---------------------------- */

@media (min-width: 48rem) {
    /* Recolhido, o submenu vira uma barra de ÍCONES — não some.

       Antes ele deslizava para fora por inteiro, e quem recolhia o menu
       perdia toda a pista de onde estava: sobrava o trilho, que mostra a
       seção, mas nada do item aberto dentro dela. Com os ícones à vista, a
       pessoa continua vendo o mapa e reconhece o item pelo mesmo ícone que
       ele tem aberto (§56).

       Sai do fluxo e a casca reserva o lugar com `padding-left`: assim
       expandir no hover NÃO empurra a tabela, pelo mesmo motivo que o trilho
       é absoluto (§57). */
    .app__fixar:not(:checked) ~ .app__casca {
        padding-left: calc(var(--nav-trilho) + var(--nav-painel-recolhido));
    }

    .app__fixar:not(:checked) ~ .app__casca .submenu {
        position: absolute;
        top: 0;
        bottom: 0;
        left: var(--nav-trilho);
        z-index: 15;
        width: var(--nav-painel-recolhido);
        padding-inline: var(--space-1);
    }

    /* Passar o mouse no TRILHO também abre: quem recolheu o menu vai
       procurar por ali, que é a coluna mais larga que sobrou. */
    .app__fixar:not(:checked) ~ .app__casca .trilho:hover ~ .submenu,
    .app__fixar:not(:checked) ~ .app__casca .submenu:hover,
    .app__fixar:not(:checked) ~ .app__casca .submenu:focus-within {
        width: var(--nav-painel);
        padding-inline: var(--space-2);
        box-shadow: var(--shadow-lg);
    }

    /* Recolhido, o item vira um quadrado com o ícone centrado. */
    .app__fixar:not(:checked) ~ .app__casca .submenu__item {
        justify-content: center;
        padding-inline: 0;
    }

    .app__fixar:not(:checked) ~ .app__casca .submenu:hover .submenu__item,
    .app__fixar:not(:checked) ~ .app__casca .submenu:focus-within .submenu__item,
    .app__fixar:not(:checked) ~ .app__casca .trilho:hover ~ .submenu .submenu__item {
        justify-content: flex-start;
        padding-inline: var(--space-3);
    }

    /* O rótulo continua NO HTML, escondido só do olho — `display: none` o
       tiraria do leitor de tela e cada ícone viraria um link sem nome (§16).
       Mesma técnica do `.trilho__rotulo`. */
    .app__fixar:not(:checked) ~ .app__casca .submenu__item span,
    .app__fixar:not(:checked) ~ .app__casca .submenu__titulo,
    .app__fixar:not(:checked) ~ .app__casca .submenu__rodape {
        position: absolute;
        width: 1px;
        height: 1px;
        overflow: hidden;
        clip-path: inset(50%);
        white-space: nowrap;
    }

    .app__fixar:not(:checked) ~ .app__casca .submenu:hover .submenu__item span,
    .app__fixar:not(:checked) ~ .app__casca .submenu:hover .submenu__titulo,
    .app__fixar:not(:checked) ~ .app__casca .submenu:hover .submenu__rodape,
    .app__fixar:not(:checked) ~ .app__casca .submenu:focus-within .submenu__item span,
    .app__fixar:not(:checked) ~ .app__casca .submenu:focus-within .submenu__titulo,
    .app__fixar:not(:checked) ~ .app__casca .submenu:focus-within .submenu__rodape,
    .app__fixar:not(:checked) ~ .app__casca .trilho:hover ~ .submenu .submenu__item span,
    .app__fixar:not(:checked) ~ .app__casca .trilho:hover ~ .submenu .submenu__titulo,
    .app__fixar:not(:checked) ~ .app__casca .trilho:hover ~ .submenu .submenu__rodape {
        position: static;
        width: auto;
        height: auto;
        overflow: visible;
        clip-path: none;
    }
}

.contexto {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: var(--space-2);
    align-items: start;
    margin: 0;
    padding: var(--space-2) var(--space-3);
    background: var(--color-surface);
    border-radius: var(--radius);
    font-size: var(--text-xs);
    max-width: none;
}

.contexto .icon { color: var(--color-accent); margin-top: 0.1rem; }
.contexto__rotulo { display: block; color: var(--color-text-muted); }
.contexto__valor { display: block; font-weight: var(--weight-semibold); }

/* ---- Área principal ----------------------------------------------------- */

/* A ÁREA ROLA INTEIRA (§57).

   Até a §56 a casca era de altura fixa e só a tabela rolava — era a leitura
   que fizemos da referência da Trabt. A do Olist faz o contrário: a página
   rola por completo, migalha e título inclusive, e é essa que o cliente
   escolheu.

   O que continua fixo é o menu, que é navegação, e o rodapé de ações, que
   fica grudado embaixo por `position: sticky` — ele precisa estar à mão
   enquanto se rola a lista, senão selecionar 30 linhas obriga a voltar ao
   topo para agir. */
.area {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-width: 0;
    overflow-y: auto;
    background: var(--color-surface);
}

/* Faixa da migalha: caminho à esquerda, AÇÕES DA PÁGINA à direita (§56).

   O que estava aqui — contador de sessão, renovar e sair — mudou para o pé do
   trilho. São ações da CONTA, e ficavam ocupando o lugar mais nobre da tela em
   toda página, empurrando a migalha para a segunda linha. */
.area__topo {
    display: flex;
    align-items: center;
    flex-wrap: nowrap;
    gap: var(--space-3);
    flex: none;
    min-height: 52px;
    padding: var(--space-2) var(--space-5);
    background: var(--color-bg);
    border-bottom: 1px solid var(--color-border);
}

.hamburguer { display: none; place-items: center; cursor: pointer; color: var(--color-text); }

/* ⚠️ A migalha QUEBRAVA em duas e três linhas em tela estreita, e cada linha
   empurrava o H1 para fora da primeira tela. Agora ela é uma linha só: rola
   dentro de si mesma se não couber, e nunca cresce em altura. */
.trilha {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    min-width: 0;
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
    white-space: nowrap;
    font-size: var(--text-sm);
    color: var(--color-text-muted);
}

.trilha::-webkit-scrollbar { display: none; }
.trilha a { color: var(--color-text-muted); text-decoration: none; }
.trilha a:hover { color: var(--color-accent-text); }
.trilha__atual { color: var(--color-text); font-weight: var(--weight-medium); }

/* Em tela estreita sobra só o **Dashboard** (§87).

   Decisão do cliente, e ela paga uma conta: a faixa passa a ter espaço
   para o botão principal e o "Mais ações" com os rótulos por extenso.
   Era isso que faltava — a §56 mediu 442px pedidos numa tela de 375
   justamente porque o caminho inteiro estava ali.

   O passo atual não se perde: ele é o H1 da página, logo abaixo. */
@media (max-width: 47.99rem) {
    .trilha > *:not(:first-child) { display: none; }
}

/* Ação principal + mais ações, sempre no mesmo lugar em todo módulo. */
.area__topo-acoes {
    display: flex;
    align-items: center;
    flex-wrap: nowrap;
    gap: var(--space-2);
    margin-left: auto;
    flex: none;
}

/* As ações da migalha são COMPACTAS.

   O botão padrão do site tem 44px de altura e 16px de texto — medida de
   landing page, onde ele é o destino. Na barra de um sistema, repetida em
   toda tela, isso é grande demais (foi o que o cliente apontou), e a
   referência confirma: 32px de altura, texto de 14 e forma de pílula.

   Sob `@media (pointer: coarse)` os 44px voltam, pela mesma razão da §56:
   quem toca com o dedo precisa do alvo maior. */
/* ⚠️ O prefixo `body.app` NÃO é enfeite, e a falta dele produziu um defeito
   que o cliente viu: o botão principal saía com 40,4px e o "Mais ações" com
   32,4px, lado a lado.

   A causa é especificidade, e é sutil: `body.app .botao` vale (0,2,1) — o
   ELEMENTO `body` conta —, enquanto `.area__topo-acoes .botao` vale (0,2,0)
   e perdia, mesmo declarada depois. Já `.area__topo-acoes .mais-acoes >
   summary` vale (0,2,1) por causa do elemento `summary`, empatava, e vencia
   por vir depois. Dois seletores irmãos, dois resultados.

   Com o prefixo, os dois passam a (0,3,1) e (0,3,2): ganham da regra geral e
   compartilham UMA declaração. A §80 já tinha dito por que isto importa —
   duas regras declarando medidas iguais é acordo que se desfaz na primeira
   mudança. Aqui ele nem chegou a valer. */
body.app .area__topo-acoes .botao,
body.app .area__topo-acoes .mais-acoes > summary {
    min-height: 32px;
    padding: var(--space-1) var(--space-4);
    font-size: var(--text-sm);
    font-weight: var(--weight-medium);
    border-radius: var(--radius-full);
}

.area__topo-acoes .botao:hover,
.area__topo-acoes .mais-acoes > summary:hover { transform: none; }

@media (pointer: coarse) {
    .area__topo-acoes .botao,
    .area__topo-acoes .mais-acoes > summary { min-height: var(--tap-target); }
}

/* ⚠️ **A regra de "só ícone" em tela estreita SAIU** (§87), e tinha de
   sair por dois motivos que se somam:

   1. os botões da faixa não têm mais ícone (§83) — esconder o texto
      deixaria dois botões VAZIOS na tela;
   2. a migalha do celular passou a mostrar só o Dashboard, então o
      espaço que faltava existe. A medição da §56 (442px pedidos em
      375) era com o caminho inteiro na faixa.

   O texto abaixo descreve a regra ANTIGA e fica como registro do que
   ela resolvia — se a migalha voltar a crescer, o problema volta.

   O rótulo não era apagado, era escondido do olho e mantido para o leitor de
   tela — `display: none` deixaria os dois botões sem nome nenhum, e um
   botão sem nome é inútil para quem navega por voz (§16). */
/* O que sobra da regra antiga: só o respiro menor, que continua servindo
   numa faixa estreita. Esconder o rótulo é que não se faz mais. */
@media (max-width: 47.99rem) {
    .area__topo-acoes .botao,
    .area__topo-acoes .mais-acoes > summary { padding-inline: var(--space-3); }
}

/* ---- Menu de "mais ações" -----------------------------------------------

   <details>/<summary> nativo: abre sem JavaScript e o conteúdo já está no
   HTML. Mesmo motivo do FAQ do site público (§40). */
.mais-acoes { position: relative; }

.mais-acoes > summary {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    list-style: none;
    cursor: pointer;
}

.mais-acoes > summary::-webkit-details-marker { display: none; }

.mais-acoes__lista {
    position: absolute;
    top: calc(100% + var(--space-2));
    right: 0;
    z-index: 25;
    min-width: 13rem;
    padding: var(--space-1);
    margin: 0;
    list-style: none;
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-lg);
}

.mais-acoes__lista a,
.mais-acoes__lista button {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    width: 100%;
    padding: var(--space-2) var(--space-3);
    font: inherit;
    font-size: var(--text-sm);
    text-align: left;
    color: var(--color-text);
    background: none;
    border: 0;
    border-radius: var(--radius-sm);
    text-decoration: none;
    cursor: pointer;
}

.mais-acoes__lista a:hover,
.mais-acoes__lista button:hover { background: var(--color-surface); }
.mais-acoes__lista .icon { flex: none; color: var(--color-text-muted); }

.area__cabecalho {

    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--space-4);
    flex: none;
    padding: var(--space-5) var(--space-5) var(--space-3);
}

.area__titulo { font-size: var(--text-2xl); margin: 0 0 var(--space-2); }

.resumo {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-4);
    margin: 0;
    font-size: var(--text-sm);
    color: var(--color-text-muted);
    max-width: none;
}

.resumo__alerta { display: inline-flex; align-items: center; gap: var(--space-1); color: var(--color-danger); }

.area__acoes { display: flex; gap: var(--space-2); }

/* ---- Filtros ------------------------------------------------------------ */

.filtros {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    flex: none;
    padding: 0 var(--space-5) var(--space-4);
}

/* Pílula, como os menus ao lado: a faixa toda com a mesma forma (§63). */
.filtros__busca {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    flex: 1 1 18rem;
    padding-inline: var(--space-4);
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-full);
}

.filtros__busca:focus-within { border-color: var(--color-accent); }

.filtros__busca .icon { color: var(--color-text-muted); }

.filtros__busca input {
    flex: 1;
    min-height: var(--nav-item);
    font-size: var(--text-sm);
    border: 0;
    background: none;
    font: inherit;
    color: var(--color-text);
    outline: none;
}

/* Sobrou para eventual <select> em filtro de outro módulo; os de
   solicitações viraram menu (§63). */
.filtros select {
    min-height: var(--nav-item);
    padding-inline: var(--space-3);
    font: inherit;
    font-size: var(--text-sm);
    color: var(--color-text);
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-full);
}


/* ---- Tabela: quem rola é ela -------------------------------------------- */

/* Um formulário que ENVOLVE a tabela e o rodapé precisa se comportar como a
   própria área: esticar e distribuir. Sem isto ele encolhe até o tamanho do
   conteúdo, e o rodapé fixo sobe para debaixo da tabela em vez de ficar no pé
   da tela (§56). */
.area__fluxo {
    display: flex;
    flex-direction: column;
    flex: 1;
}

.tabela-caixa {
    margin-inline: var(--space-5);
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
}

/* ⚠️ Dentro da área de CONTEÚDO o recuo já foi dado (§94).

   O `margin-inline` acima existe para a listagem, onde a tabela é filha
   direta do formulário e precisa do próprio recuo. No detalhe ela mora
   dentro de `.area__conteudo`, que já tem `padding-inline` — e os dois se
   somavam: a tabela ficava 20px mais estreita de cada lado que os cartões
   logo acima dela, e o desalinhamento aparecia porque estão empilhados.

   Zerar aqui, e não tirar de lá, porque quem sabe o recuo é o contêiner. */
.area__conteudo > .tabela-caixa { margin-inline: 0; }

/* ⚠️ `overflow: hidden` aqui existia para a tabela não vazar o canto
   arredondado do cartão — e recortava o menu (…) da linha, que é justamente
   o que precisa escapar da caixa. No desktop ele sai; o canto do cabeçalho
   volta a ser arredondado por conta própria. */
@media (max-width: 47.99rem) {
    .tabela-caixa { overflow: hidden; }
}

.tabela thead th:first-child { border-top-left-radius: var(--radius-lg); }
.tabela thead th:last-child { border-top-right-radius: var(--radius-lg); }

/* Rola na vertical e, no celular, também na horizontal (§38). */
/* A rolagem lateral vale só onde ela é necessária: em tela estreita.

   No desktop a caixa fica com `overflow: visible` de propósito — `overflow-x:
   auto` recorta TAMBÉM na vertical, e recortaria o menu de ações da linha
   justo nas últimas linhas da tabela. */
.tabela-rolagem { -webkit-overflow-scrolling: touch; }

@media (max-width: 47.99rem) {
    .tabela-rolagem { overflow-x: auto; }
}

.tabela { width: 100%; border-collapse: collapse; font-size: var(--text-sm); }

.tabela thead th {
    position: sticky;
    top: 0;
    z-index: 1;
    padding: var(--space-3) var(--space-4);
    text-align: left;
    white-space: nowrap;
    font-size: var(--text-xs);
    font-weight: var(--weight-semibold);

    /* ⚠️ SEM caixa alta (§94). Ela era o que fazia o cabeçalho pesar mais
       que o conteúdo — palavra em maiúsculas se lê letra a letra, e numa
       tabela o que precisa ser lido de relance é a LINHA, não o rótulo da
       coluna. O `letter-spacing` saiu junto: ele existia só para a caixa
       alta não ficar apertada.

       Vale para TODAS as tabelas, e não só a do histórico: duas convenções
       de cabeçalho no mesmo painel seria o retalho que a regra de ouro nº 6
       proíbe. _(se era só o histórico, é uma linha para separar)_ */
    color: var(--color-text-muted);

    /* ⚠️ Branco como o resto da tabela (§92), e opaco de propósito: o
       cabeçalho é `sticky`, então ele passa POR CIMA das linhas ao rolar.
       Com fundo transparente as linhas apareceriam através dele.

       O que separa cabeçalho de corpo passa a ser só a linha de baixo —
       era a faixa cinza somada a ela, e duas marcas para a mesma divisão
       é uma a mais. */
    background: var(--color-bg);
    border-bottom: 1px solid var(--color-border);
}

.tabela thead a { color: inherit; text-decoration: none; }
.tabela thead a:hover { color: var(--color-accent-text); }

.tabela tbody td {
    padding: var(--space-3) var(--space-4);
    border-bottom: 1px solid var(--color-border);
    vertical-align: middle;
}

/* O cartão da tabela tem o mesmo fundo do resto; o hover só o escurece um
   pouco. Mistura com a cor do TEXTO, e não uma cor fixa: assim funciona nos
   dois temas sem segunda regra. */
/* Cinza muito claro (§92). A mistura é com a cor do TEXTO, e não uma cor
   fixa: assim escurece no tema claro, clareia no escuro, e uma regra serve
   para os dois (§63).

   ⚠️ 3% e não mais: o hover é rastro para o olho seguir a linha, não
   informação. Uma faixa que se lê como "esta linha é diferente" competiria
   com a etiqueta de fase e com o realce de atrasada, que informam de
   verdade. */
.tabela tbody tr:hover { background: color-mix(in srgb, var(--color-text) 3%, transparent); }

.tabela__linha--atrasada { background: color-mix(in srgb, var(--color-danger) 4%, transparent); }

.tabela__selecao, .tabela__acoes { width: 1%; white-space: nowrap; }
.tabela__mono { font-family: var(--font-mono); font-size: var(--text-xs); }
.tabela__secundario { display: block; font-size: var(--text-xs); color: var(--color-text-muted); }

.tabela__vazio { padding: var(--space-16) var(--space-4); text-align: center; color: var(--color-text-muted); }
.tabela__vazio .icon { opacity: 0.4; }
.tabela__vazio p { margin: var(--space-3) auto 0; max-width: none; }

.acao-linha {
    display: inline-grid;
    place-items: center;
    width: 34px;
    height: 34px;
    color: var(--color-text-muted);
    border-radius: var(--radius-sm);
    cursor: pointer;
    transition: background var(--transicao), color var(--transicao);
}

.acao-linha:hover {
    color: var(--color-accent-text);
    background: color-mix(in srgb, var(--color-accent) 10%, transparent);
}

.etiqueta-status {
    display: inline-block;
    padding: 0.1rem var(--space-2);
    font-size: var(--text-xs);
    font-weight: var(--weight-semibold);
    border-radius: var(--radius-full);
    background: var(--color-surface-strong);
    color: var(--color-text-muted);
}

/* ⚠️ Fundo NEUTRO e opaco; a cor fica só no texto.

   Duas medições levaram até aqui. Com fundo translúcido, o selo herdava o que
   estivesse atrás e caía para 4.42:1 sobre linha atrasada. Tingindo o fundo
   com a PRÓPRIA cor do texto ficou pior — 4.09:1 — porque aproximar fundo e
   texto do mesmo tom é exatamente o que derruba contraste.

   Neutro resolve os dois: o selo vale o mesmo em qualquer linha, e a cor do
   texto é a única variável. Medido nos dois temas. */
/* ⚠️ As classes saem do VALOR do enum (`etiqueta-status--{{ $status->value }}`).
   Quando as fases mudaram (§73), estas regras ficaram apontando para valores
   que não existem mais — e o selo sairia sem cor nenhuma, sem nada acusar.

   É a sexta ocorrência da mesma família (§§40, 44, 55, 63): a classe existe de
   um lado e não do outro. Renomear valor de enum obriga a vir aqui. */

/* Fases das solicitações (§§73 e 74) */
.etiqueta-status--solicitado {
    background: var(--color-surface-strong);
    color: var(--color-accent-text);
}

.etiqueta-status--analise,
.etiqueta-status--reanalise {
    background: var(--color-surface-strong);
    color: var(--color-warning);
}

.etiqueta-status--finalizado {
    background: var(--color-surface-strong);
    color: var(--color-success);
}

.etiqueta-status--spam {
    background: var(--color-surface-strong);
    color: var(--color-text-muted);
}

/* Situações dos pedidos de titular (`PrivacyRequestStatus`) — outro enum,
   outros valores.

   ⚠️ Este bloco estava ERRADO, e a §73 é a origem: ao trocar as fases das
   solicitações, ela moveu para cá as classes antigas — `new`, `answered`,
   `closed` — supondo que fossem deste enum. Não eram. Os valores daqui são
   `received`, `in_review`, `fulfilled` e `refused`, e três deles nunca
   tiveram regra: saíam no cinza neutro da base, todos iguais, e a lista de
   pedidos não distinguia "Recebido" de "Atendido" nem de "Recusado".

   Os dois lados da mesma falha na mesma rodada: três classes MORTAS apontando
   para valores que sumiram, e três valores VIVOS sem classe. Nada acusa
   nenhum dos dois — por isso agora há teste cruzando enum e folha. */
.etiqueta-status--received {
    background: var(--color-surface-strong);
    color: var(--color-accent-text);
}

.etiqueta-status--in_review {
    background: var(--color-surface-strong);
    color: var(--color-warning);
}

.etiqueta-status--fulfilled {
    background: var(--color-surface-strong);
    color: var(--color-success);
}

.etiqueta-status--refused {
    background: var(--color-surface-strong);
    color: var(--color-danger);
}

/* Selos escritos à MÃO, que não saem de enum nenhum.

   ⚠️ Existem por causa de um erro meu: a §98 apagou `--new` e `--answered`
   lendo-as como resto do enum antigo das solicitações. Onze telas as usavam
   como etiqueta genérica — "Ativa", "Publicada", "Rascunho", "Prestador do
   site" —, e o selo continuou aparecendo, no cinza neutro da base. Não sumiu:
   ficou SEM DISTINÇÃO, que numa listagem de páginas é pior, porque "Publicada"
   e "Rascunho" passaram a se ler iguais.

   O nome agora é pelo SIGNIFICADO, e não pelo valor de um enum. É isso que
   impede a próxima troca de fase de alcançar estas telas outra vez. */
.etiqueta-status--ativo {
    background: var(--color-surface-strong);
    color: var(--color-success);
}

.etiqueta-status--pendente {
    background: var(--color-surface-strong);
    color: var(--color-warning);
}

.etiqueta-status--atraso {
    background: var(--color-surface-strong);
    color: var(--color-danger);
}


/* Os botões de ação em massa (§83), no lugar da lista + "Aplicar".

   ⚠️ Esta regra faltava, e a varredura a apanhou antes de subir — pela
   NONA vez nesta família (§§40, 44, 55, 63, 72, 82). Diferente das últimas,
   esta não era nome morto: sem ela os botões saem colados, sem espaçamento
   e sem quebrar de linha quando não cabem. */
/* ⚠️ Pílula e 32px, como o "Mais ações" da faixa da migalha (§92).

   Eles nasciam com o `.botao` do painel — 32px de altura, mas raio de
   campo (10px) — e com a classe `tap`, que impõe 44px de altura mínima e
   GANHA de qualquer altura declarada. Lado a lado com o "Mais ações" do
   topo, a mesma barra de ações aparecia em dois tamanhos.

   Os 44px do dedo voltam sob `pointer: coarse`, logo abaixo — a §29 não
   caiu, ficou condicionada ao dispositivo, como nas §§56, 79 e 89. */
body.app .rodape-selecao__acoes .botao {
    min-height: 32px;
    height: 32px;
    padding-inline: var(--space-4);
    border-radius: var(--radius-full);
}

@media (pointer: coarse) {
    body.app .rodape-selecao__acoes .botao {
        min-height: var(--tap-target);
        height: var(--tap-target);
    }
}

.rodape-selecao__acoes {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
}

/* Botão que não serve à seleção some do olho E do envio (§83). `hidden`
   sozinho perde para qualquer classe que declare `display` (§56). */
.rodape-selecao__acoes .botao[hidden] { display: none; }

.paginacao { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-1); }

.paginacao__contagem { font-size: var(--text-xs); color: var(--color-text-muted); margin-right: var(--space-3); }

.paginacao__item {
    display: inline-grid;
    place-items: center;
    min-width: var(--tap-target);
    min-height: 36px;
    padding-inline: var(--space-2);
    font-size: var(--text-sm);
    color: var(--color-text);
    text-decoration: none;
    border-radius: var(--radius-sm);
}

.paginacao__item:hover { background: var(--color-surface); color: var(--color-accent-text); }

/* Fundo `--color-primary`, não `--color-accent`: o accent do tema escuro é o
   azul CLARO, e branco sobre ele mede 2.85:1. O primary é o mesmo azul nos
   dois temas, e branco sobre ele mede 6.51:1. */
.paginacao__item--atual {
    background: var(--color-primary);
    color: #ffffff;
    font-weight: var(--weight-semibold);
}

.paginacao__item--inerte { color: var(--color-text-muted); opacity: 0.5; }

.app__sombra { display: none; }

/* ==========================================================================
   Celular: a navegação vira gaveta (§38)

   Feita com checkbox e label, sem JavaScript: se o script não carregar, o
   menu continua abrindo. O único JS da área logada é o contador de sessão,
   que é enfeite.
   ========================================================================== */

@media (max-width: 47.99rem) {
    .trilho, .submenu {
        position: fixed;
        top: 0;
        bottom: 0;
        z-index: 40;
        transform: translateX(-100%);
        transition: transform var(--transicao);
    }

    .trilho { left: 0; }
    .submenu { left: var(--nav-trilho); box-shadow: var(--shadow-lg); }

    .app__gatilho:checked ~ .app__casca .trilho,
    .app__gatilho:checked ~ .app__casca .submenu { transform: translateX(0); }

    .app__gatilho:checked ~ .app__casca .app__sombra {
        display: block;
        position: fixed;
        inset: 0;
        z-index: 30;
        background: rgb(0 22 71 / 0.5);
    }

    /* ⚠️ **A casca reserva o lugar do trilho com `padding-left` (§57), e no
       celular o trilho é GAVETA — está fora do fluxo.** Sem zerar isto,
       sobravam 60px vazios na lateral esquerda de toda tela: medido em
       375px, o cabeçalho e o rodapé começavam em x=60 e tinham 315px de
       largura numa tela de 375. */
    .app__casca { padding-left: 0; }

    /* O hambúrguer do topo da migalha SAI: quem abre o menu no celular é o
       botão do cabeçalho próprio (§83). Dois botões de menu na mesma tela é
       um a mais do que existe de menu. */
    .hamburguer { display: none; }

    .area__cabecalho, .filtros, .area__rodape { padding-inline: var(--space-4); }
    .tabela-caixa { margin-inline: var(--space-4); }

    /* ⚠️ A busca ocupava a linha inteira (`flex-basis: 100%`), e o botão
       "Filtros" caía para a linha de baixo — medido: faixa de 114px, duas
       linhas, quando o pedido era UMA (§87). Agora ela cede o espaço do
       botão e os dois dividem a mesma linha.

       `min-width: 0` junto: sem ele o `<input>` não encolhe abaixo do
       tamanho do próprio placeholder e empurra o botão para fora (§40). */
    .filtros__busca { flex: 1 1 auto; min-width: 0; }
}

/* ==========================================================================
   Celular — o desenho da tela estreita (§83)

   Regra que o cliente deu, e que governa tudo abaixo:

   > "tudo é fixo na horizontal; a única coisa que corre na horizontal são
   >  tabelas. Na vertical somente o menu é fixo, o resto corre com a tela —
   >  paginação e mais ações sempre fixos no rodapé."
   ========================================================================== */

/* O cabeçalho de celular não existe no desktop, e o de desktop não existe no
   celular. Um só serviria mal aos dois: no desktop não há gaveta para abrir, e
   no celular não cabe migalha com ações do lado. */
.topo-celular { display: none; }

/* sm — até 767px */
@media (max-width: 47.99rem) {

    /* ---- O cabeçalho ----------------------------------------------------

       ⚠️ É o ÚNICO bloco fixo na vertical junto do menu, e a razão é
       funcional: ele carrega o botão que abre a gaveta. Botão de menu que rola
       para fora da tela deixa a navegação inalcançável — e no celular a gaveta
       é a única navegação que existe. */
    .topo-celular {
        position: sticky;
        top: 0;
        z-index: 20;
        display: flex;
        align-items: center;
        gap: var(--space-3);
        flex: none;
        min-height: 52px;
        padding-inline: var(--space-4);
        background: var(--color-bg);
        border-bottom: 1px solid var(--color-border);
    }

    .topo-celular__menu {
        display: grid;
        place-items: center;
        color: var(--color-text);
        cursor: pointer;
        margin-left: calc(var(--space-2) * -1);
    }

    .topo-celular__marca {
        font-weight: var(--weight-semibold);
        color: var(--color-text);
        text-decoration: none;
    }

    /* À direita: conta, notificações e sessão. É o pé do trilho, que no
       celular fica DENTRO da gaveta fechada — e com ele o relógio de sessão,
       que precisa estar à vista (§21). */
    .topo-celular__acoes {
        display: flex;
        align-items: center;
        gap: var(--space-1);
        margin-left: auto;
    }

    .topo-celular__acao {
        position: relative;
        display: inline-flex;
        align-items: center;
        gap: var(--space-1);
        justify-content: center;
        min-width: var(--tap-target);
        min-height: var(--tap-target);
        color: var(--color-text-muted);
        text-decoration: none;
    }

    .topo-celular__acao:hover { color: var(--color-accent-text); }

    .topo-celular__tempo { font-size: var(--text-xs); }

    /* ---- A gaveta preenche a TELA INTEIRA -------------------------------

       Pedido do cliente. As duas camadas continuam existindo — é isso que
       mantém o caminho de volta para outra seção sem fechar a gaveta —, mas no
       celular elas dividem a largura da tela, não a do desktop.

       ⚠️ **O trilho de 56px NÃO serve aqui, e o defeito era grave:** o rótulo
       de cada seção é escondido por `clip-path` e só reaparece com
       `.trilho:hover` ou com a classe `nav-aberta`, que o script põe no
       `mouseenter`. Nenhum dos dois vale no toque — então a gaveta abria
       mostrando **ícones sem nome nenhum**.

       E o `mouseenter` sintético do toque piorava: tocar no trilho acrescentava
       `nav-aberta`, o rótulo aparecia, e ele era cortado pelo
       `overflow: hidden` de um trilho de 56px. Ou seja, o menu tinha dois
       estados errados, não um.

       No celular o trilho nasce LARGO e os rótulos ficam sempre visíveis. Não
       há hover num dedo; esconder nome para revelar depois é um gesto que só
       existe com mouse. */
    body.app { --nav-trilho-celular: 9.5rem; }

    .trilho, .submenu { top: 0; bottom: 0; }

    .trilho {
        width: var(--nav-trilho-celular);
        /* Oito seções mais o pé da conta passam da altura numa tela pequena
           deitada. Sem isto o que não coubesse ficaria inalcançável. */
        overflow-y: auto;
    }

    /* Sempre à vista: no toque não existe o gesto que os revelaria. */
    .trilho__rotulo {
        position: static;
        width: auto;
        height: auto;
        overflow: hidden;
        clip-path: none;
        text-overflow: ellipsis;
    }

    .submenu {
        left: var(--nav-trilho-celular);
        right: 0;
        width: auto;
        box-shadow: none;

        /* ⚠️ `translateX(-100%)` NÃO basta aqui, e o defeito foi medido: com
           `left: 56px`, mover o painel pela própria largura o deixa parando
           justamente na borda do trilho — sobravam **56px do submenu visíveis**
           sobre o conteúdo, cobrindo o botão de menu do cabeçalho.

           Antes de a gaveta ocupar a tela inteira isso não aparecia: com
           largura fixa, a própria largura era a distância até sair. Ao trocar
           para `right: 0`, as duas deixaram de ser a mesma coisa. */
        transform: translateX(calc(-100% - var(--nav-trilho-celular)));
    }

    /* ⚠️ As ações VOLTARAM para a faixa da migalha (§87), onde já estavam
       no desktop. A §83 as tinha descido para uma barra fixa no rodapé
       porque a faixa não comportava caminho + ações; com a migalha
       reduzida ao Dashboard, comporta — e ter o mesmo controle no mesmo
       lugar nos dois tamanhos vale mais que a barra separada. */

    /* O conteúdo termina acima do rodapé fixo, senão a última linha nasce
       escondida atrás dele.

       ⚠️ No `.area__fluxo` o respiro vai no CONTEÚDO, não no formulário
       inteiro: o rodapé é filho dele, e um `padding-bottom` ali empurraria
       o próprio rodapé para fora da tela. */
    .area__conteudo { padding-bottom: var(--rodape-linha); }
    .area__fluxo .tabela-caixa { margin-bottom: var(--rodape-linha); }

    /* ---- Nada corre na horizontal, exceto a tabela ---------------------- */
    .area { overflow-x: hidden; }

    /* ---- Uma linha de filtro: busca + "Filtros" (§87) --------------------

       Cinco menus lado a lado quebravam em três linhas a 375px, e cada linha
       empurrava a tabela para baixo. No celular eles entram numa folha só. */
    .filtros__demais {
        position: fixed;
        left: 0;
        right: 0;
        bottom: 0;
        z-index: 45;
        display: none;
        flex-direction: column;
        gap: var(--space-2);
        max-height: 50dvh;
        overflow-y: auto;
        padding: var(--space-4);
        background: var(--color-bg);
        border-top: 1px solid var(--color-border);
        border-radius: var(--radius-lg) var(--radius-lg) 0 0;
        box-shadow: 0 -12px 32px rgb(0 22 71 / 0.18);
    }

    /* ⚠️ O irmão `~` exige que o checkbox venha ANTES na mesma faixa — é por
       isso que ele mora logo depois da busca no HTML, e não junto do painel. */
    .filtros__gatilho:checked ~ .filtros__demais { display: flex; }

    /* Aberto, o resto da tela escurece por conta do próprio painel: sem uma
       sombra clicável, tocar fora não fecha. O `<label>` gêmeo cobre a tela. */
    .filtros__gatilho:checked ~ .filtros__botao::after {
        content: "";
        position: fixed;
        inset: 0;
        z-index: 44;
        background: rgb(0 22 71 / 0.4);
    }

    /* Os menus de dentro ocupam a largura toda da folha. */
    .filtros__demais .filtro-menu,
    .filtros__demais .filtro-menu > summary { width: 100%; }

    /* ---- Todo painel de menu vira FOLHA no celular (§87) -----------------

       Pedido do cliente: ao escolher um filtro, as opções sobem preenchendo a
       largura inteira e metade da altura, com rolagem se passar disso.

       ⚠️ `50dvh` e não `50vh`: no celular a barra do navegador aparece e some,
       e `vh` não acompanha — a folha ficaria com metade de uma altura que a
       tela não tem naquele instante (§38).

       ⚠️ E `body.app` no seletor pelo mesmo motivo da §84: as regras base
       destes painéis moram DEPOIS deste bloco no arquivo, empatam em
       (0,1,0) e venciam por ordem. Medido: o painel do filtro saía com
       256px de largura, solto no meio da tela, em vez de folha. Regra que
       depende de ficar embaixo quebra na primeira reorganização. */
    /* ⚠️ UM rolador, não dois. A lista de opções tem teto próprio no
       desktop, e dentro da folha isso a fazia parar antes: medido, a folha
       ficava com 327px numa tela de 812 — bem abaixo da metade que o
       cliente pediu — e a rolagem acontecia na lista de dentro. Rolador
       aninhado também é ruim de usar no dedo: o gesto para na borda do
       interno e a pessoa não sabe qual dos dois está movendo. */
    body.app .filtro-menu__opcoes,
    body.app .campo-lista__opcoes { max-height: none; }

    body.app .filtro-menu__painel,
    body.app .mais-acoes__lista {
        position: fixed;
        top: auto;
        left: 0;
        right: 0;
        bottom: 0;
        width: auto;
        min-width: 0;
        max-height: 50dvh;
        overflow-y: auto;
        z-index: 46;
        border-radius: var(--radius-lg) var(--radius-lg) 0 0;
        box-shadow: 0 -12px 32px rgb(0 22 71 / 0.18);
    }

    /* ---- Campo de lista abre de BAIXO PARA CIMA -------------------------

       Pedido do cliente, e é o padrão que o celular já ensina: a lista sobe do
       pé da tela. O motivo prático é o teclado — a §29 exige que o componente
       funcione com o teclado virtual aberto, e um painel ancorado no campo
       ficaria embaixo dele, fora da metade visível. */
    .campo-lista__painel {
        position: fixed;
        top: auto;
        left: 0;
        right: 0;
        bottom: 0;
        width: auto;
        z-index: 30;
        border-radius: var(--radius-lg) var(--radius-lg) 0 0;
        box-shadow: 0 -12px 32px rgb(0 22 71 / 0.18);
    }

    body.app .campo-lista__painel { z-index: 46; max-height: 50dvh; overflow-y: auto; }
}

/* ---- Conteúdo que não é tabela -----------------------------------------
   A §38 diz "nada rola exceto a tabela". Numa tela de conteúdo, quem faz o
   papel da tabela é este contêiner: a casca (menu e topo) continua fixa, e
   só ele rola.
   ------------------------------------------------------------------------ */

.area__conteudo {
    padding: 0 var(--space-5) var(--space-8);
}

/* ⚠️ Filho de flex column ENCOLHE por padrão (`flex-shrink: 1`). Sem esta
   linha, o conteúdo se espreme para caber na altura da área e é recortado —
   a área nunca chega a ter o que rolar. Foi o que aconteceu na primeira
   tentativa: `overflow-y: auto` no lugar certo, e nada rolando. */
.area > *,
.area__fluxo > * { flex-shrink: 0; }

/* Leitura confortável em telas de conta e configuração. */
.area__conteudo--estreito > * { max-width: 46rem; }

.area__conteudo .acesso__titulo { font-size: var(--text-xl); margin-top: var(--space-2); }

/* Dentro da casca os cartões respiram menos que na página pública. */
.area__conteudo .cartoes { margin-top: var(--space-2); }

@media (max-width: 47.99rem) {
    .area__conteudo { padding-inline: var(--space-4); }
}

/* Contador de sessão no cabeçalho (§21, item 1). */
.sessao-aviso {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    font-size: var(--text-sm);
    color: var(--color-text-muted);
}

.sessao-aviso .icon { color: var(--color-text-muted); }

/* Em tela estreita some o texto e fica o relógio, que o ícone explica. */
@media (max-width: 47.99rem) {
    .sessao-aviso__texto { display: none; }
}

/* ==========================================================================
   Tela "ver" de um registro (CLAUDE.md, §§8 e 38)
   --------------------------------------------------------------------------
   Duas colunas: o que precisa de leitura corrida à esquerda (mensagem, notas,
   histórico) e os dados de referência à direita. Padrão replicado nos
   próximos módulos — a §29 diz que só a FORMA se copia, nunca a lógica.
   ========================================================================== */

.detalhe {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--space-5);
    align-items: start;
    padding-bottom: var(--space-6);
}

.detalhe__principal,
.detalhe__lado {
    display: grid;
    gap: var(--space-5);
    align-content: start;
}

.cartao-sistema {
    padding: var(--space-5);
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
}

.cartao-sistema h2 {
    margin-bottom: var(--space-4);
    font-size: var(--text-sm);
    font-weight: var(--weight-semibold);
    letter-spacing: var(--tracking-wide);
    text-transform: uppercase;
    color: var(--color-text-muted);
}

.cartao-sistema .dados { margin: 0; padding: 0; background: none; }

.cartao-sistema--perigo { border-color: color-mix(in srgb, var(--color-danger) 30%, var(--color-border)); }
.cartao-sistema--perigo p { font-size: var(--text-sm); margin-bottom: var(--space-4); }

/* O texto do titular é o miolo da tela: largura de leitura e quebra de linha
   preservada, porque ele foi escrito em textarea. */
.detalhe__mensagem {
    max-width: var(--measure);
    margin: 0;
    white-space: pre-line;
}

.detalhe__vazio {
    margin: 0;
    font-size: var(--text-sm);
    color: var(--color-text-muted);
}

/* ---- Notas de atendimento --------------------------------------------- */

.cartao-sistema .formulario { max-width: none; margin: 0 0 var(--space-5); }
.cartao-sistema .formulario__campo { margin-bottom: var(--space-3); }

.nota {
    padding-top: var(--space-4);
    border-top: 1px solid var(--color-border);
}

.nota__topo {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--space-2);
    margin-bottom: var(--space-2);
    font-size: var(--text-sm);
}

.nota__topo time { color: var(--color-text-muted); }

.nota p { margin: 0; font-size: var(--text-sm); white-space: pre-line; }

/* ---- Histórico do audit trail ------------------------------------------
   Guarda referências, nunca valores (§13): quem, quando, qual ação e quais
   campos mudaram. */

.historico {
    display: grid;
    gap: var(--space-2);
    margin: 0;
    padding: 0;
    list-style: none;
    font-size: var(--text-sm);
}

.historico li {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: var(--space-2) var(--space-3);
    padding-bottom: var(--space-2);
    border-bottom: 1px solid var(--color-border);
}

.historico li:last-child { border-bottom: 0; padding-bottom: 0; }

.historico__quando {
    flex: none;
    font-variant-numeric: tabular-nums;
    color: var(--color-text-muted);
}

.historico__acao { font-weight: var(--weight-semibold); }
.historico__quem { color: var(--color-text-muted); }

.historico__campos {
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    color: var(--color-text-muted);
}

/* ---- Grade de dados: rótulo em cima, valor embaixo (§79) ----------------

   Substitui o `<dl class="dados">` em duas colunas. O cliente comparou com a
   referência: "tem muitos blocos e informação". A grade resolve os dois — três
   por linha ocupam a largura que sobrava, e o rótulo pequeno acima do valor
   deixa claro o que é etiqueta e o que é dado, sem precisar de outra caixa.

   `minmax(0, 1fr)` e não `1fr`: a §40 registra que `1fr` é `minmax(auto, 1fr)`,
   e um valor longo — um e-mail — empurraria a faixa deixando as colunas
   desiguais. */
.dados-grade {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-3) var(--space-6);
    margin-bottom: var(--space-5);
}

@media (min-width: 40rem) {
    .dados-grade { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (min-width: 64rem) {
    .dados-grade { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

.dados-grade__rotulo {
    display: block;
    font-size: var(--text-xs);
    color: var(--color-text-muted);
    margin-bottom: 2px;
}

/* `min-width: 0` no filho da grade: sem isso, um e-mail longo não quebra e
   estoura a coluna — é o mesmo mecanismo do `minmax(0, 1fr)`, um nível abaixo. */
.dados-grade > div { min-width: 0; }

.dados-grade__valor {
    display: block;
    color: var(--color-text);
    overflow-wrap: anywhere;
}

/* O texto que a pessoa escreveu: `pre-line` preserva as quebras dela. */
.dados-grade__texto {
    margin: 0 0 var(--space-5);
    max-width: 80ch;
    white-space: pre-line;
}

/* A faixa de ações de fase: botões lado a lado, quebrando quando não couberem.
   Não é cartão — mais uma caixa aqui seria o que o cliente apontou. */
.acoes-fase {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
}

.acoes-fase form { margin: 0; }

/* ---- Histórico como tabela (§§77 e 78) ----------------------------------

   ⚠️ A primeira versão (§77) tinha etiqueta colorida com ícone na coluna Tipo.
   O cliente comparou com a referência e apontou: ficou SUJO. Uma etiqueta em
   toda linha de toda coluna vira ruído — a coluna já diz que aquilo é o tipo,
   e o texto simples basta.

   Cor aqui fica só onde ela informa algo que o texto não dá de graça: a fase,
   onde o par "de → para" precisa ser lido de relance. */

/* As duas ações do topo, lado a lado. `minmax(0, 1fr)` e não `1fr`: a §40
   registra que `1fr` é `minmax(auto, 1fr)`, e um rótulo longo empurraria a
   faixa deixando as duas caixas de larguras diferentes. */
.historico-acoes {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-4);
    margin-bottom: var(--space-4);
}

@media (min-width: 60rem) {
    .historico-acoes { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* Título de cartão pequeno: estes dois não competem com o H1 da página. */
/* O rótulo miúdo ao lado do título — "só a equipe vê". Peso e cor menores
   para não competir com o título que ele qualifica. */
.cartao-sistema__nota {
    margin-left: var(--space-2);
    font-size: var(--text-xs);
    font-weight: var(--weight-normal);
    color: var(--color-text-muted);
}

/* ---- Título de bloco com FAIXA DE FUNDO (§81) ---------------------------

   Pedido do cliente. Ele resolve um problema real que a §79 tinha deixado meio
   aberto: com um cartão só por aba, o que separa um grupo do outro era um
   título solto, e título solto no meio de uma lista de campos não lê como
   divisor — lê como mais uma linha.

   A faixa vai de ponta a ponta do cartão, por margem negativa: o divisor que
   para antes da borda parece defeito de alinhamento, não intenção. */
.cartao-sistema__titulo {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: var(--space-2);
    margin: var(--space-5) calc(var(--space-5) * -1) var(--space-4);
    padding: var(--space-2) var(--space-5);
    font-size: var(--text-sm);
    font-weight: var(--weight-semibold);
    color: var(--color-text);
    background: var(--color-surface-strong);
    border-block: 1px solid var(--color-border);
}

/* O primeiro título encosta no topo do cartão. Sem isto sobra uma faixa de
   respiro acima dele, e a caixa parece torta. O raio acompanha o do cartão,
   senão o canto quadrado da faixa aparece por cima do canto arredondado. */
.cartao-sistema > .cartao-sistema__titulo:first-child,
.cartao-sistema > .formulario > .cartao-sistema__titulo:first-child {
    margin-top: calc(var(--space-5) * -1);
    border-top: 0;
    border-radius: var(--radius) var(--radius) 0 0;
}

/* ---- Largura do campo na grade de três colunas (§81) --------------------

   ⚠️ Por CLASSE, nunca por `style="grid-column: span 2"`: a CSP
   (`style-src 'self'`) bloqueia estilo inline, e ela falha CALADA — o campo
   simplesmente não ocupa a largura pedida e só o console acusa (§40). */
.dados-grade__campo { min-width: 0; }

/* Em duas colunas não há meio-termo: quem pede mais de uma ocupa a linha. */
@media (min-width: 40rem) {
    .dados-grade__campo--2,
    .dados-grade__campo--3 { grid-column: 1 / -1; }
}

@media (min-width: 64rem) {
    .dados-grade__campo--2 { grid-column: span 2; }
    .dados-grade__campo--3 { grid-column: 1 / -1; }
}

/* ---- Campo de lista com busca (§§19 e 82) -------------------------------

   Acima de 30 opções o `<select>` sai de cena. A forma é a do filtro (§63),
   arredondada, e pelo mesmo motivo daquela seção: a lista que o `<select>`
   abre é desenhada pelo SISTEMA OPERACIONAL — quadrada, com borda própria,
   sem nada a ver com o painel. Aqui a lista é nossa, e por isso combina. */
.campo-lista { position: relative; }

.campo-lista > summary {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-2);
    min-height: 32px;
    padding: var(--space-2) var(--space-3);
    font-size: var(--text-sm);
    color: var(--color-text);
    background: var(--color-bg);
    border: 1px solid var(--color-border-strong);
    /* ⚠️ O raio é o do CAMPO (10px), não a pílula do filtro. Os dois são
       `<details>`, mas ocupam papéis diferentes: o filtro fica numa faixa
       de botões e a pílula o separa do conteúdo; este fica numa LINHA DE
       CAMPOS, e ali a pílula lê como coisa de outra natureza no meio de
       retângulos. O que se espelha no filtro é o PAINEL que abre — a lista
       desenhada por nós, arredondada, em vez da caixa quadrada que o
       sistema operacional desenha para o `<select>` (§63). */
    border-radius: var(--radius);
    list-style: none;
    cursor: pointer;
}

/* ---- Campo de arquivo ---------------------------------------------------
   Medidas lidas da referência que o cliente mandou (§96): caixa de 38px com
   raio de 8, e dentro dela um botão sólido de 36px colado na borda — sem
   folga em cima, embaixo nem à esquerda.

   ⚠️ A altura NÃO é declarada. Quem a produz é o respiro do botão: 14px de
   texto + 8px em cima e embaixo = 36, mais a borda = 38. É como a referência
   faz, e é melhor que fixar um número — se a fonte do sistema mudar, a caixa
   acompanha em vez de cortar o botão.

   ⚠️ `overflow: hidden` porque o botão é retangular e a caixa não: sem ele o
   canto quadrado do botão vaza para fora do raio. */
.formulario input[type="file"] {
    display: block;
    width: 100%;
    padding: 0;
    font: inherit;
    font-size: var(--text-sm);
    color: var(--color-text-muted);
    background: transparent;
    border: 1px solid var(--color-border-strong);
    border-radius: 8px;
    overflow: hidden;
    cursor: pointer;
}

.formulario input[type="file"]:hover { border-color: var(--color-accent); }

.formulario input[type="file"]:focus-visible {
    outline: none;
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-accent) 65%, transparent);
}

.formulario input[type="file"].tem-erro { border-color: var(--color-danger); }

/* ⚠️ `::file-selector-button` e `::-webkit-file-upload-button` em regras
   SEPARADAS. Seletor desconhecido invalida a regra INTEIRA — medido: ela some
   do CSSOM, sem nada no console —, então os dois na mesma lista fariam o campo
   voltar ao cinza do sistema num navegador que só conheça um deles (§§40, 60). */
.formulario input[type="file"]::file-selector-button {
    margin-right: var(--space-3);
    padding: var(--space-2) var(--space-4);
    font: inherit;
    font-size: var(--text-sm);

    /* ⚠️ A entrelinha PRECISA ser declarada. `font: inherit` traz o tamanho, mas
       o botão continua herdando a entrelinha do corpo (1.6, medida de
       parágrafo): 14 × 1.6 = 22,4, e o botão ia a 38,4 dentro de uma caixa de
       40,4 — a mesma armadilha da §88. Com 20px de linha, 8+20+8 = 36, e a
       caixa fecha em 38, que é o número da referência. */
    line-height: 1.4286;

    font-weight: var(--weight-medium);
    color: var(--color-text-inverse);
    background: var(--color-primary);
    border: 0;
    border-radius: 0;
    cursor: pointer;
    transition: background var(--transicao);
}

.formulario input[type="file"]:hover::file-selector-button {
    background: var(--color-primary-hover);
}

/* Regra separada de propósito — ver a nota acima. */
.formulario input[type="file"]::-webkit-file-upload-button {
    margin-right: var(--space-3);
    padding: var(--space-2) var(--space-4);
    font: inherit;
    font-size: var(--text-sm);

    /* ⚠️ A entrelinha PRECISA ser declarada. `font: inherit` traz o tamanho, mas
       o botão continua herdando a entrelinha do corpo (1.6, medida de
       parágrafo): 14 × 1.6 = 22,4, e o botão ia a 38,4 dentro de uma caixa de
       40,4 — a mesma armadilha da §88. Com 20px de linha, 8+20+8 = 36, e a
       caixa fecha em 38, que é o número da referência. */
    line-height: 1.4286;

    font-weight: var(--weight-medium);
    color: var(--color-text-inverse);
    background: var(--color-primary);
    border: 0;
    border-radius: 0;
    cursor: pointer;
    transition: background var(--transicao);
}

.formulario input[type="file"]:hover::-webkit-file-upload-button {
    background: var(--color-primary-hover);
}

/* No dedo, os 44px da §29 vêm pelo RESPIRO do botão, não por altura na caixa:
   altura na caixa deixaria o botão de 36 flutuando dentro dela. */
@media (pointer: coarse) {
    .formulario input[type="file"]::file-selector-button { padding-block: 12px; }
    .formulario input[type="file"]::-webkit-file-upload-button { padding-block: 12px; }
}
.campo-lista > summary::-webkit-details-marker { display: none; }
.campo-lista > summary .icon { flex: none; color: var(--color-text-muted); }
.campo-lista[open] > summary { border-color: var(--color-accent); }

/* Campo recusado: a cor NUNCA é o único sinal (§16) — junto vão a mensagem
   embaixo e o `aria-invalid`. */
.campo-lista.tem-erro > summary { border-color: var(--color-danger); }

.campo-lista__painel {
    position: absolute;
    top: calc(100% + var(--space-1));
    left: 0;
    z-index: 20;
    width: 100%;
    min-width: 15rem;
    padding: var(--space-2);
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-lg);
}

/* A busca é o PRIMEIRO item do painel, como a §19 pede. */
.campo-lista__busca { margin-bottom: var(--space-2); }

/* Teto de altura: 645 municípios não cabem na tela, e uma lista que passa
   da dobra esconde o próprio campo de busca ao rolar. */
.campo-lista__opcoes {
    max-height: 15rem;
    overflow-y: auto;
    margin: 0;
    padding: 0;
    list-style: none;
}

.campo-lista__opcoes label {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-2) var(--space-3);
    font-size: var(--text-sm);
    border-radius: var(--radius-sm);
    cursor: pointer;
}

.campo-lista__opcoes label:hover { background: var(--color-surface); }

/* O rádio continua no HTML — é ele que faz o campo funcionar sem
   JavaScript (§29) —, e some do olho porque a linha inteira já é o alvo.
   `opacity` e não `display: none`: escondido de verdade, ele sairia da
   ordem de foco e o campo ficaria inalcançável pelo teclado (§16). */
.campo-lista__opcoes input[type="radio"] { accent-color: var(--color-primary); }

.campo-lista__opcoes label:has(input:checked) {
    color: var(--color-accent-text);
    background: color-mix(in srgb, var(--color-accent) 8%, var(--color-bg));
}

.campo-lista__nota { color: var(--color-text-muted); font-style: normal; }

.campo-lista__vazio {
    margin: 0;
    padding: var(--space-3);
    font-size: var(--text-sm);
    color: var(--color-text-muted);
}

/* ---- Botões sempre à DIREITA (§81) -------------------------------------- */
.acoes-formulario {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: var(--space-2);
    margin-top: var(--space-4);
}

/* O formulário que ENVOLVE os cartões da aba não é um formulário de página:
   ele não tem largura de leitura nem recuo próprio, porque quem dá os dois é
   o cartão que ele contém. */
body.app .area__conteudo > .formulario {
    max-width: none;
    margin: 0;
}

/* ---- Campo do painel é MINIMALISTA, como o botão (§81) ------------------

   Mesma razão da §79 para o botão: 44px de altura e 16px de texto é medida de
   landing page, onde o campo é o destino. Numa tela de trabalho com quinze
   campos, ela transforma um cadastro em rolagem.

   ⚠️ Isto NÃO mexe em `border-color` nem em `background`, e a omissão é
   deliberada. O seletor aqui vale (0,2,2), acima das regras de estado
   `.formulario .tem-erro` (0,2,0) e `.formulario input:disabled` (0,2,1) — se
   declarasse cor de borda, o campo RECUSADO deixaria de ficar vermelho e o
   desabilitado voltaria a parecer editável. É exatamente a armadilha que a §55
   registrou, vista do outro lado.

   ⚠️ E o alvo de toque volta inteiro sob `pointer: coarse` (§§29 e 56), junto
   com os 16px que impedem o Safari de dar zoom ao focar o campo. */
body.app .formulario input:where(:not([type="checkbox"]):not([type="radio"]):not([type="hidden"]):not([type="submit"]):not([type="button"]):not([type="file"])),
body.app .formulario select,
body.app .formulario textarea {
    min-height: 32px;
    padding: var(--space-2) var(--space-3);
    font-size: var(--text-sm);
}

body.app .formulario textarea { min-height: 5rem; }

/* ---- Foco: só o anel, sem trocar a cor da borda (§82) -------------------

   Pedido do cliente. No painel, a borda azul intensa somada ao anel azul
   fazia o campo focado saltar duas vezes; o anel sozinho já diz onde está o
   cursor, e continua cumprindo o "foco visível" do WCAG (§16).

   ⚠️ `:where(:not(.tem-erro))` e não `:not(.tem-erro)`: `:not()` SOMA
   especificidade (§55), e sem o `:where` esta regra passaria a ganhar da
   regra do campo recusado — focar um campo com erro apagaria o vermelho,
   que é justamente quando a cor mais importa. */
body.app .formulario input:where(:not(.tem-erro)):focus-visible,
body.app .formulario select:where(:not(.tem-erro)):focus-visible,
body.app .formulario textarea:where(:not(.tem-erro)):focus-visible {
    border-color: var(--color-border-strong);
}

@media (pointer: coarse) {
    body.app .formulario input:where(:not([type="checkbox"]):not([type="radio"]):not([type="hidden"]):not([type="submit"]):not([type="button"]):not([type="file"])),
    body.app .formulario select,
    body.app .formulario textarea {
        min-height: var(--tap-target);
        padding: var(--space-3);
        font-size: max(1rem, var(--text-base));
    }
}

.historico__tipo {
    color: var(--color-text-muted);
    white-space: nowrap;
}

/* `pre-line` porque a descrição de uma NOTA é o texto que a pessoa digitou, e
   as quebras dela são parte do que foi dito. */
.historico__descricao {
    white-space: pre-line;
    min-width: 22ch;
}

.historico__seta {
    color: var(--color-text-muted);
    padding-inline: 2px;
}

/* A coluna de data não quebra, e a de descrição fica com o resto. */
.tabela--historico td:first-child { white-space: nowrap; }

/* A descrição do E-MAIL traz o destinatário e o conteúdo remontado (§81),
   e o conteúdo tem quebras de linha próprias — `pre-line` já está em
   `.historico__descricao`. O teto de altura existe para um e-mail longo não
   empurrar as demais linhas para fora da tela. */
.historico__descricao {
    max-height: 12rem;
    overflow-y: auto;
}

/* A seta do "Voltar" aponta para o outro lado. */
.icone--voltar { transform: rotate(180deg); }

/* lg — 1024px */
@media (min-width: 64rem) {
    .detalhe { grid-template-columns: minmax(0, 1fr) minmax(0, 22rem); }
}

/* Alvo de toque de 44px (§29) nos links que são AÇÃO, não texto corrido:
   e-mail, WhatsApp e telefone na coluna de dados, e o "renovar" da sessão.
   Medido antes: 19px e 22px. */
.dados dd a,
.sessao-aviso .acesso__link,
.trilha a,
.trilho__marca {
    display: inline-flex;
    align-items: center;
    min-height: var(--tap-target);
}

/* ==========================================================================
   Configurações → Módulos (§§8 e 39)
   --------------------------------------------------------------------------
   A tela se monta a partir de config/modulos.php; o CSS descreve só a forma
   do cartão, que qualquer módulo novo herda sem uma linha a mais.
   ========================================================================== */

.modulo + .modulo { margin-top: var(--space-5); }

.modulo__topo {
    display: flex;
    align-items: flex-start;
    gap: var(--space-4);
    margin-bottom: var(--space-5);
    padding-bottom: var(--space-4);
    border-bottom: 1px solid var(--color-border);
}

.modulo__icone {
    display: grid;
    place-items: center;
    flex: none;
    width: 40px;
    height: 40px;
    color: var(--color-primary);
    background: color-mix(in srgb, var(--color-primary) 8%, transparent);
    border-radius: var(--radius);
}

/* Sobrescreve o h2 genérico do cartão: aqui ele é título de verdade, não
   rótulo de seção em caixa alta. */
.modulo__topo h2 {
    margin: 0 0 var(--space-1);
    font-size: var(--text-lg);
    font-weight: var(--weight-bold);
    letter-spacing: normal;
    text-transform: none;
    color: var(--color-text);
}

.modulo__descricao {
    margin: 0;
    font-size: var(--text-sm);
    color: var(--color-text-muted);
}

.modulo .formulario { max-width: none; margin: 0; }

/* Checkbox ocupa a linha inteira: rótulo de opção ao lado de um campo de
   número deixa os dois desalinhados na vertical. */
@media (min-width: 40rem) {
    .formulario__campo--largo { grid-column: 1 / -1; }
}

/* ==========================================================================
   Grupos de permissão (§15)
   ========================================================================== */

.permissoes + .permissoes {
    margin-top: var(--space-5);
    padding-top: var(--space-5);
    border-top: 1px solid var(--color-border);
}

.permissoes__titulo {
    margin-bottom: var(--space-3);
    font-size: var(--text-xs);
    font-weight: var(--weight-semibold);
    letter-spacing: var(--tracking-wide);
    text-transform: uppercase;
    color: var(--color-text-muted);
}

/* Cada permissão é uma linha clicável inteira, não só a caixinha: alvo de
   18px é o oposto do que a §29 pede. */
.permissao,
.permissoes__lista li {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    gap: var(--space-3);
    align-items: start;
    min-height: var(--tap-target);
    padding: var(--space-2);
    border-radius: var(--radius-sm);
    font-size: var(--text-sm);
}

.permissao { cursor: pointer; }
.permissao:hover { background: var(--color-surface); }

.permissao input[type="checkbox"],
.permissao input[type="radio"] {
    width: 1.15rem;
    height: 1.15rem;
    margin-top: 0.3rem;
    accent-color: var(--color-primary);
}

/* Visibilidade do contexto (§§107 e 108): cada eixo é um `formulario__grupo`
   com a legenda sublinhada; a lista de opções fica recuada sob o rádio
   "Só estes". */
.visibilidade__lista { padding-left: var(--space-6); }

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

.permissoes__lista .icon { color: var(--color-success); margin-top: 0.2rem; }

.permissao__ajuda {
    display: block;
    margin-top: var(--space-1);
    font-size: var(--text-xs);
    line-height: var(--leading-snug);
    color: var(--color-text-muted);
}

/* ---- Seletor de contexto no rodapé do submenu (§18) -------------------- */

.contexto-troca {
    display: grid;
    gap: var(--space-2);
}

.contexto-troca select {
    width: 100%;
    min-height: var(--tap-target);
    padding: var(--space-2);
    font: inherit;
    font-size: var(--text-sm);
    color: var(--color-text);
    background: var(--color-bg);
    border: 1px solid var(--color-border-strong);
    border-radius: var(--radius-sm);
}

/* ---- Contexto, na tela de editar usuário (§18) -------------------------- */

.vinculo {
    max-width: none;
    margin: 0;
    padding-top: var(--space-4);
    border-top: 1px solid var(--color-border);
}

.vinculo:first-of-type { padding-top: 0; border-top: 0; }

.vinculo__titulo {
    margin: 0 0 var(--space-3);
    font-weight: var(--weight-semibold);
}

/* Ações lado a lado dentro de uma nota (reenviar / revogar). */
.nota__acoes {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-3);
    margin-top: var(--space-3);
}

/* ==========================================================================
   Manutenção (§17)
   ========================================================================== */

.checagens {
    display: grid;
    gap: var(--space-1);
    margin: 0;
    padding: 0;
    list-style: none;
}

.checagem {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    gap: var(--space-3);
    align-items: start;
    padding: var(--space-3);
    font-size: var(--text-sm);
    border-radius: var(--radius-sm);
}

/* A marca é ícone + cor + texto para leitor de tela: cor sozinha nunca é o
   único sinal (§16, WCAG). */
.checagem__marca {
    display: grid;
    place-items: center;
    width: 1.6rem;
    height: 1.6rem;
    border-radius: var(--radius-full);
}

.checagem--ok .checagem__marca { color: var(--color-success); background: color-mix(in srgb, var(--color-success) 12%, transparent); }
.checagem--aviso .checagem__marca { color: var(--color-warning); background: color-mix(in srgb, var(--color-warning) 14%, transparent); }
.checagem--falha .checagem__marca { color: var(--color-danger); background: color-mix(in srgb, var(--color-danger) 12%, transparent); }

.checagem--falha { background: color-mix(in srgb, var(--color-danger) 5%, transparent); }
.checagem--aviso { background: color-mix(in srgb, var(--color-warning) 6%, transparent); }

.checagem__detalhe {
    display: block;
    margin-top: var(--space-1);
    color: var(--color-text-muted);
    /* Mensagem de erro de banco pode ser uma linha só, muito longa. */
    overflow-wrap: anywhere;
}

/* O que fazer: é o que separa diagnóstico de alarme. */
.checagem__saida {
    display: block;
    margin-top: var(--space-2);
    padding-left: var(--space-3);
    border-left: 2px solid var(--color-border-strong);
    font-size: var(--text-xs);
    line-height: var(--leading-snug);
    color: var(--color-text-muted);
}

.comando + .comando {
    margin-top: var(--space-4);
    padding-top: var(--space-4);
    border-top: 1px solid var(--color-border);
}

.comando__ajuda {
    margin: 0 0 var(--space-3);
    font-size: var(--text-xs);
    line-height: var(--leading-snug);
    color: var(--color-text-muted);
}

.cartao-sistema code {
    padding: 0.1em 0.35em;
    font-family: var(--font-mono);
    font-size: 0.9em;
    background: var(--color-surface-strong);
    border-radius: var(--radius-sm);
}

/* ==========================================================================
   Editor de páginas e blocos (§5)
   ========================================================================== */

.bloco {
    padding: var(--space-4);
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
}

.bloco + .bloco { margin-top: var(--space-3); }

.bloco__topo {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--space-3);
}

.bloco__acoes {
    display: flex;
    align-items: center;
    gap: var(--space-1);
}

/* Botão dentro de formulário de uma ação só: sem borda nem fundo próprios,
   para a linha de ações ler como uma coisa só. */
.bloco__acoes button {
    font: inherit;
    background: none;
    border: 0;
    cursor: pointer;
}

.bloco__acoes button[disabled] { opacity: 0.3; cursor: default; }

.bloco__resumo {
    margin: var(--space-3) 0 0;
    font-size: var(--text-sm);
    color: var(--color-text-muted);
}

.bloco-novo {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-3);
    align-items: center;
    max-width: none;
    margin: var(--space-5) 0 0;
    padding-top: var(--space-5);
    border-top: 1px solid var(--color-border);
}

.bloco-novo select { flex: 1 1 12rem; }

/* Grupo repetível: cada item é uma caixa, para não virar uma parede de
   campos sem começo nem fim. */
.item-repetido {
    padding: var(--space-4);
    background: var(--color-surface);
    border-radius: var(--radius);
}

.item-repetido + .item-repetido { margin-top: var(--space-3); }

.item-repetido .formulario__campo:last-child { margin-bottom: 0; }

/* As setas de reordenar reaproveitam o ícone de flecha. */
.icone--cima { transform: rotate(-90deg); }
.icone--baixo { transform: rotate(90deg); }

/* Dados de apoio da chave do segundo fator: conta, emissor e tipo. Sem eles,
   quem digita à mão precisa adivinhar o que preencher em cada campo do app. */
.chave__ajuda {
    margin: var(--space-3) 0 0;
    font-size: var(--text-xs);
    line-height: var(--leading-snug);
    color: var(--color-text-muted);
}

/* ==========================================================================
   Rodapé fixo, alvo de toque e mensagens em modal (CLAUDE.md, §56)
   ========================================================================== */

/* ---- Rodapé: ações em massa em cima, paginação embaixo -------------------

   Empilhadas, não lado a lado. A ação em massa aparece e some conforme a
   seleção; se dividisse a linha com a paginação, a paginação pularia de
   lugar a cada caixa marcada.

   As duas faixas são independentes: cada uma existe só quando tem o que
   mostrar, e o rodapé inteiro some quando nenhuma tem. */

/* A borda mora em cada FAIXA, não no rodapé. Assim, quando a seleção está
   vazia e não há mais de uma página, o rodapé não deixa uma linha solta no
   pé da tela — ele simplesmente não tem altura. */
.area__rodape {
    position: sticky;
    bottom: 0;
    z-index: 5;
    display: flex;
    flex-direction: column;
    flex: none;
    margin-top: auto;
    background: var(--color-bg);
}

/* ⚠️ `display: flex` numa classe VENCE o atributo `hidden`, que é só uma
   regra de baixa especificidade da folha do navegador. Sem esta linha, a
   barra de ações em massa nasce visível e nunca some — é a mesma família de
   falha silenciosa das §§40, 44 e 55. */
.rodape-selecao[hidden] { display: none; }

.rodape-selecao {
    border-top: 1px solid var(--color-border);
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-2) var(--space-5);
    font-size: var(--text-sm);
    background: color-mix(in srgb, var(--color-accent) 8%, var(--color-bg));
}

.rodape-paginacao {
    border-top: 1px solid var(--color-border);
    display: flex;
    align-items: center;
    justify-content: flex-end;
    padding: var(--space-2) var(--space-5);
}

/* ---- Alvo de toque (§29) ------------------------------------------------

   A §29 exige 44px em elemento clicável. As medidas da referência são
   menores — 40px de item de menu — e num ERP usado com mouse o dia inteiro
   isso é acerto, não descuido: 44px em toda linha de menu empurra metade
   dos itens para fora da tela.

   A saída não é escolher um dos dois: é perguntar ao dispositivo. Onde o
   ponteiro é grosso (dedo), 44px volta a valer. */

@media (pointer: coarse) {
    body.app {
        --nav-item: var(--tap-target);
        --nav-trilho: 60px;
    }

    /* ⚠️ A ALTURA vale em todo dispositivo de toque; a LARGURA, não.

       Esta regra nasceu para o trilho RECOLHIDO — uma coluna de ícones de
       56px, onde 44x44 é o alvo do dedo. No celular a gaveta aberta usa o
       mesmo trilho com 152px e rótulo ao lado do ícone, e `width: 44px`
       prendia cada item nesse tamanho: medido, o rótulo "Solicitações"
       saía com **24px** e o menu abria com os nomes cortados.

       Por isso a largura fica sob `min-width: 48rem` — onde o trilho é de
       fato a barra de ícones. Abaixo disso ele estica, que é o que
       `align-items: stretch` já queria fazer. */
    .trilho__item,
    .trilho__marca { height: var(--tap-target); }

    .paginacao__item { min-height: var(--tap-target); }
}

@media (pointer: coarse) and (min-width: 48rem) {
    .trilho__item,
    .trilho__marca { width: var(--tap-target); }
}

/* ---- Mensagem em modal --------------------------------------------------

   Toda mensagem de resultado — salvou, falhou, recusou — abre como modal.
   Antes era uma faixa no alto da página, e a faixa tem dois defeitos: em
   tela cheia de conteúdo ela passa despercebida, e ela EMPURRA o conteúdo
   para baixo, então a página dá um solavanco a cada retorno.

   Sem JavaScript continua funcionando: `<dialog open>` é renderizado no
   fluxo, então a mensagem aparece do mesmo jeito, só que sem escurecer o
   fundo. Nunca fica invisível. */

.aviso {
    max-width: 30rem;
    padding: 0;
    color: var(--color-text);
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
}

.aviso::backdrop { background: rgb(0 0 0 / 0.45); }

.aviso__corpo {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    gap: var(--space-3);
    padding: var(--space-5);
}

.aviso__icone {
    display: grid;
    place-items: center;
    width: 2.25rem;
    height: 2.25rem;
    border-radius: var(--radius-full);
}

.aviso--ok .aviso__icone {
    color: var(--color-success);
    background: color-mix(in srgb, var(--color-success) 14%, transparent);
}

.aviso--erro .aviso__icone {
    color: var(--color-danger);
    background: color-mix(in srgb, var(--color-danger) 12%, transparent);
}

.aviso__titulo {
    margin: 0 0 var(--space-1);
    font-size: var(--text-base);
    font-weight: var(--weight-semibold);
}

.aviso__texto { margin: 0; font-size: var(--text-sm); max-width: none; }

.aviso__lista {
    margin: var(--space-2) 0 0;
    padding-left: var(--space-4);
    font-size: var(--text-sm);
}

.aviso__pe {
    display: flex;
    justify-content: flex-end;
    padding: 0 var(--space-5) var(--space-5);
}

/* Sem JavaScript o modal fica no fluxo, e aí o botão "Entendi" não teria o
   que fechar — o `form method="dialog"` só funciona dentro de um dialog
   aberto por script. Escondê-lo evita botão que não faz nada. */
.aviso:not([open]) { display: none; }
.aviso[open]:not(.aviso--modal) .aviso__pe { display: none; }

.aviso--modal { margin: auto; }

/* ---- Escolha de tema (Minha conta → Meus dados, §56) --------------------- */

.tema-escolha {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    min-width: 0;
    padding: 0;
    margin: 0;
    border: 0;
}

.tema-escolha__item {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-2) var(--space-3);
    font-size: var(--text-sm);
    border: 1px solid var(--color-border-strong);
    border-radius: var(--radius);
    cursor: pointer;
}

.tema-escolha__item:has(:checked) {
    color: var(--color-accent-text);
    border-color: var(--color-accent);
    background: color-mix(in srgb, var(--color-accent) 10%, transparent);
}

.tema-escolha__item input { flex: none; }

/* ---- Menu de ações da linha (§57) ---------------------------------------

   Substitui a coluna de ícones no fim da linha. Fica depois do checkbox, em
   toda tabela, e por isso a coluna tem largura de conteúdo. */

.tabela__menu { width: 1%; white-space: nowrap; padding-inline: 0; }

.acoes-linha { position: relative; }

.acoes-linha > summary { list-style: none; }
.acoes-linha > summary::-webkit-details-marker { display: none; }
.acoes-linha[open] > summary { color: var(--color-accent-text); background: var(--color-surface); }

.acoes-linha__lista {
    position: absolute;
    top: calc(100% + var(--space-1));
    left: 0;
    z-index: 20;
    min-width: 12rem;
    margin: 0;
    padding: var(--space-1);
    list-style: none;
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-lg);
}

.acoes-linha__lista a,
.acoes-linha__lista button {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    width: 100%;
    min-height: var(--nav-item);
    padding: var(--space-2) var(--space-3);
    font: inherit;
    font-size: var(--text-sm);
    text-align: left;
    color: var(--color-text);
    background: none;
    border: 0;
    border-radius: var(--radius-sm);
    text-decoration: none;
    cursor: pointer;
    white-space: nowrap;
}

.acoes-linha__lista a:hover,
.acoes-linha__lista button:hover { background: var(--color-surface); }
/* O menu (…) é TEXTO, sem ícone (§58): ele lista TODAS as ações do item, e
   uma lista de dez ícones diferentes vira caça-palavras. Ícone é atalho, e
   atalho mora na coluna Ações. */
.acoes-linha__lista .icon { display: none; }

/* ⚠️ `overflow-x: auto` também recorta na VERTICAL — é assim que a
   propriedade funciona. No desktop a tabela não precisa rolar de lado, então
   o recorte sai e o menu pode escapar da caixa. */
@media (max-width: 47.99rem) {
    /* Em tela estreita o recorte volta, junto com a rolagem lateral. Aí o
       menu abre DENTRO da linha em vez de flutuar: melhor empurrar a tabela
       para baixo do que abrir um menu que fica pela metade. */
    .acoes-linha__lista {
        position: static;
        min-width: 0;
        box-shadow: none;
    }
}

/* ---- Abas das telas de ver e editar (§58) --------------------------------

   Linha de guias sob o cabeçalho da página. Rolam de lado em tela estreita
   em vez de quebrar em duas linhas — quebra empurra o conteúdo para fora da
   primeira tela, que é o mesmo problema que a migalha tinha (§56). */

.abas {
    display: flex;
    gap: var(--space-1);
    flex: none;
    padding: 0 var(--space-5);
    margin-bottom: var(--space-4);
    overflow-x: auto;
    scrollbar-width: none;
    white-space: nowrap;
    border-bottom: 1px solid var(--color-border);
}

.abas::-webkit-scrollbar { display: none; }

.abas__item {
    display: inline-flex;
    align-items: center;
    min-height: var(--nav-item);
    padding: var(--space-2) var(--space-4);
    font-size: var(--text-sm);
    font-weight: var(--weight-medium);
    color: var(--color-text-muted);
    text-decoration: none;
    border-bottom: 2px solid transparent;
    /* -1px para o traço da aba cobrir a borda da própria faixa, senão fica
       uma linha dupla embaixo da aba ativa. */
    margin-bottom: -1px;
}

.abas__item:hover { color: var(--color-text); }

.abas__item--atual {
    color: var(--color-accent-text);
    border-bottom-color: var(--color-primary);
}

@media (pointer: coarse) {
    .abas__item { min-height: var(--tap-target); }
}

@media (max-width: 47.99rem) {
    .abas { padding-inline: var(--space-4); }
}

/* Aba sem coluna de apoio (histórico): o conteúdo ocupa a largura toda. */
.detalhe--unico { grid-template-columns: minmax(0, 1fr); }

/* ==========================================================================
   Início — painel de pendências, módulos e atividade (§58)
   ========================================================================== */

.inicio-secao { margin-bottom: var(--space-8); }

.inicio-secao__titulo {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    margin: 0 0 var(--space-3);
    font-size: var(--text-sm);
    font-weight: var(--weight-semibold);
    letter-spacing: var(--tracking-wide);
    text-transform: uppercase;
    color: var(--color-text-muted);
}

.inicio-secao__titulo .icon { color: var(--color-text-muted); }

/* ---- Pendências ---------------------------------------------------------

   Uma linha por coisa que espera alguém. A cor da borda diz a urgência, e o
   texto diz de novo — cor nunca é o único sinal (§16). */

.pendencia {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-3) var(--space-4);
    margin-bottom: var(--space-2);
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    border-left: 3px solid var(--color-border-strong);
    border-radius: var(--radius);
}

.pendencia--urgente { border-left-color: var(--color-danger); }
.pendencia--atencao { border-left-color: var(--color-warning); }
.pendencia--aviso { border-left-color: var(--color-primary); }

.pendencia__icone { display: grid; place-items: center; flex: none; }
.pendencia--urgente .pendencia__icone { color: var(--color-danger); }
.pendencia--atencao .pendencia__icone { color: var(--color-warning); }
.pendencia--aviso .pendencia__icone { color: var(--color-accent-text); }

.pendencia__texto { display: grid; gap: 2px; flex: 1; min-width: 0; }
.pendencia__texto strong { font-size: var(--text-sm); }
.pendencia__texto span { font-size: var(--text-xs); color: var(--color-text-muted); }

.pendencia .botao {
    flex: none;
    min-height: 32px;
    padding: var(--space-1) var(--space-4);
    font-size: var(--text-sm);
    font-weight: var(--weight-medium);
    border-radius: var(--radius-full);
}

.pendencia .botao:hover { transform: none; }

.pendencia__nenhuma {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    margin: 0;
    padding: var(--space-4);
    max-width: none;
    font-size: var(--text-sm);
    color: var(--color-text-muted);
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
}

.pendencia__nenhuma .icon { color: var(--color-success); flex: none; }

/* ---- Cartões dos módulos ------------------------------------------------ */

.modulos {
    display: grid;
    /* minmax(0, 1fr) e não 1fr: rótulo longo não pode empurrar a coluna e
       deixar os cartões de larguras diferentes (§40). */
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 15rem), 1fr));
    gap: var(--space-4);
    margin: 0;
    padding: 0;
    list-style: none;
}

.modulo {
    display: flex;
    flex-direction: column;
    padding: var(--space-4);
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
}

.modulo__topo { display: flex; align-items: center; gap: var(--space-2); }
.modulo__topo h3 { margin: 0; font-size: var(--text-sm); }

.modulo__icone {
    display: grid;
    place-items: center;
    width: 28px;
    height: 28px;
    flex: none;
    color: var(--color-accent-text);
    background: color-mix(in srgb, var(--color-accent) 10%, transparent);
    border-radius: var(--radius-sm);
}

.modulo__valor {
    display: flex;
    align-items: baseline;
    gap: var(--space-2);
    margin: var(--space-3) 0;
    max-width: none;
}

.modulo__valor strong { font-size: var(--text-3xl); line-height: 1; }
.modulo__valor span { font-size: var(--text-xs); color: var(--color-text-muted); }

.modulo__linhas { margin: 0 0 var(--space-3); display: grid; gap: 2px; }

.modulo__linhas > div {
    display: flex;
    justify-content: space-between;
    gap: var(--space-2);
    font-size: var(--text-xs);
}

.modulo__linhas dt { color: var(--color-text-muted); }
.modulo__linhas dd { margin: 0; font-weight: var(--weight-semibold); }

.modulo__linha--alerta dt,
.modulo__linha--alerta dd { color: var(--color-danger); }

.modulo__link {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    margin-top: auto;
    font-size: var(--text-sm);
    font-weight: var(--weight-medium);
    color: var(--color-accent-text);
    text-decoration: none;
}

/* ---- Atividade ---------------------------------------------------------- */

.atividade {
    margin: 0;
    padding: 0;
    list-style: none;
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    overflow: hidden;
}

.atividade li {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: var(--space-2) var(--space-3);
    padding: var(--space-2) var(--space-4);
    font-size: var(--text-sm);
}

.atividade li + li { border-top: 1px solid var(--color-border); }

.atividade__quando {
    flex: none;
    font-size: var(--text-xs);
    font-variant-numeric: tabular-nums;
    color: var(--color-text-muted);
}

.atividade__acao { font-weight: var(--weight-medium); }
.atividade__alvo { font-size: var(--text-xs); color: var(--color-text-muted); }
.atividade__quem { margin-left: auto; font-size: var(--text-xs); color: var(--color-text-muted); }

/* ---- Menu de período na faixa de filtros (§62) ---------------------------

   Um controle só: o botão mostra o recorte em vigor e abre um painel com os
   atalhos, as duas datas e o botão de aplicar. */

.filtro-menu { position: relative; }

.filtro-menu > summary {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    min-height: var(--nav-item);
    padding: var(--space-2) var(--space-4);
    font-size: var(--text-sm);
    color: var(--color-text);
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-full);
    list-style: none;
    cursor: pointer;
    white-space: nowrap;
}

.filtro-menu > summary:hover { border-color: var(--color-border-strong); }

.filtro-menu > summary::-webkit-details-marker { display: none; }
.filtro-menu > summary .icon { flex: none; color: var(--color-text-muted); }
.filtro-menu[open] > summary { border-color: var(--color-accent); }

/* Recorte ativo: o botão fica marcado, senão a lista aparece filtrada sem
   nada na tela dizendo por quê. */
.filtro-menu--ativo > summary {
    color: var(--color-accent-text);
    border-color: var(--color-accent);
    background: color-mix(in srgb, var(--color-accent) 8%, var(--color-bg));
}

.filtro-menu--ativo > summary .icon { color: var(--color-accent-text); }

.filtro-menu__painel {
    position: absolute;
    top: calc(100% + var(--space-1));
    left: 0;
    z-index: 20;
    width: max-content;
    min-width: 16rem;
    padding: var(--space-3);
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-lg);
}

.filtro-menu__titulo {
    margin: 0 0 var(--space-2);
    font-size: var(--text-xs);
    font-weight: var(--weight-semibold);
    letter-spacing: var(--tracking-wide);
    text-transform: uppercase;
    color: var(--color-text-muted);
    max-width: none;
}

.filtro-menu__atalhos {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-1);
    margin: 0 0 var(--space-4);
    padding: 0;
    list-style: none;
}

.filtro-menu__atalhos a {
    display: block;
    padding: var(--space-2) var(--space-3);
    font-size: var(--text-sm);
    color: var(--color-text);
    text-decoration: none;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    white-space: nowrap;
}

.filtro-menu__atalhos a:hover {
    color: var(--color-accent-text);
    border-color: var(--color-accent);
    background: color-mix(in srgb, var(--color-accent) 8%, transparent);
}

.filtro-menu__datas {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    margin-bottom: var(--space-4);
}

.filtro-menu__datas input[type="date"] {
    flex: 1;
    min-width: 8.5rem;
    min-height: var(--nav-item);
    padding: var(--space-2) var(--space-3);
    font: inherit;
    font-size: var(--text-sm);
    color: var(--color-text);
    background: var(--color-bg);
    border: 1px solid var(--color-border-strong);
    border-radius: var(--radius-sm);
}

.filtros__rotulo {
    flex: none;
    font-size: var(--text-xs);
    color: var(--color-text-muted);
}

.filtro-menu__acoes {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: var(--space-3);
}

.filtro-menu__acoes .botao {
    min-height: 32px;
    padding: var(--space-1) var(--space-4);
    font-size: var(--text-sm);
    font-weight: var(--weight-medium);
    border-radius: var(--radius-full);
}

.filtro-menu__acoes .botao:hover { transform: none; }

.filtro-menu__limpar {
    margin-right: auto;
    font-size: var(--text-sm);
    color: var(--color-text-muted);
}

@media (pointer: coarse) {
    .filtro-menu > summary { min-height: var(--tap-target); }
    .filtro-menu__acoes .botao { min-height: var(--tap-target); }
}

@media (max-width: 47.99rem) {
    /* Em tela estreita o painel se ancora à direita para não sair pela borda. */
    .filtro-menu__painel { left: auto; right: 0; }
    .filtro-menu__datas { flex-wrap: wrap; }
}

/* ---- Lista de opções dentro do menu de filtro (§63) ---------------------- */

.filtro-menu__opcoes {
    display: grid;
    gap: 2px;
    margin: 0;
    padding: 0;
    list-style: none;
    min-width: 12rem;
}

.filtro-menu__opcoes a {
    display: block;
    padding: var(--space-2) var(--space-3);
    font-size: var(--text-sm);
    color: var(--color-text);
    text-decoration: none;
    border-radius: var(--radius-sm);
    white-space: nowrap;
}

.filtro-menu__opcoes a:hover { background: var(--color-surface); }

/* A opção em vigor fica marcada: sem isso, abrir o menu não diz o que está
   aplicado — e o botão fechado mostra só o rótulo. */
.filtro-menu__opcoes a.esta-ativa {
    font-weight: var(--weight-medium);
    color: var(--color-accent-text);
    background: color-mix(in srgb, var(--color-accent) 10%, transparent);
}

/* Uma lista longa (analistas) rola dentro do painel em vez de esticar a tela. */
.filtro-menu__opcoes { max-height: 17rem; overflow-y: auto; }

/* ---- Cores dos atalhos da coluna Ações (§63) -----------------------------

   ⚠️ O de arquivar é um <button>, e botão traz borda e fundo do navegador —
   era o "quadrado" em volta dele. `.acao-linha` não zerava isso porque os
   outros dois são <a>, que não têm o problema. Mesma família de falha
   silenciosa das §§40, 44 e 55: o seletor existia, o estado não.

   A cor é atalho de leitura, nunca o único sinal (§16): cada ícone continua
   com `title` e `aria-label` dizendo o que faz. */

.acao-linha {
    background: none;
    border: 0;
    font: inherit;
}

.acao-linha--ver:hover {
    color: var(--color-accent-text);
    background: color-mix(in srgb, var(--color-accent) 12%, transparent);
}

.acao-linha--editar { color: var(--color-success-vivo); }

.acao-linha--editar:hover {
    color: var(--color-success);
    background: color-mix(in srgb, var(--color-success) 12%, transparent);
}

.acao-linha--arquivar { color: var(--color-danger); }

/* Os verbos do fluxo (§§73 e 75). A cor agrupa por NATUREZA da ação, não uma
   por verbo: sete cores diferentes numa linha viram caça-palavras, e a §63 já
   registrou que cor é atalho de leitura — nunca o único sinal, e cada ícone
   continua com `title` e `aria-label`.

   avança  → verde   (abrir, finalizar)
   volta   → âmbar   (reanálise, retornar)
   descarta→ vermelho (spam, arquivar) */
.acao-linha--abrir,
.acao-linha--finalizar { color: var(--color-success); }

.acao-linha--abrir:hover,
.acao-linha--finalizar:hover {
    color: var(--color-success);
    background: color-mix(in srgb, var(--color-success) 12%, transparent);
}

.acao-linha--reanalise,
.acao-linha--retornar { color: var(--color-warning); }

.acao-linha--reanalise:hover,
.acao-linha--retornar:hover {
    color: var(--color-warning);
    background: color-mix(in srgb, var(--color-warning) 12%, transparent);
}

.acao-linha--spam { color: var(--color-danger); }

.acao-linha--spam:hover {
    color: var(--color-danger);
    background: color-mix(in srgb, var(--color-danger) 12%, transparent);
}

/* Ação que a fase não permite: aparece no menu, apagada e sem ser clicável.
   Sumir ensinaria menos — quem vê a opção bloqueada aprende que ela existe e
   que não cabe agora (§73). */
.acoes-linha__bloqueada {
    display: block;
    padding: var(--space-2) var(--space-3);
    color: var(--color-text-muted);
    opacity: 0.55;
    cursor: not-allowed;
}

.acao-linha--arquivar:hover {
    color: var(--color-danger);
    background: color-mix(in srgb, var(--color-danger) 12%, transparent);
}

/* ⚠️ `--color-accent-text`, e NÃO `--color-primary`: o primary é o azul de
   FUNDO de botão, e como traço sobre o tema escuro ele mede 2.8:1 — medido,
   reprovado no mínimo de 3:1 para elemento de interface. É o mesmo par de
   papéis do dourado na §40 e do azul na §56.

   Os três tokens já são conferidos por tema, então nenhum deles é misturado
   com o texto: misturar mudaria o valor medido e exigiria medir de novo. */
.acao-linha--ver { color: var(--color-accent-text); }

/* ---- O agrupamento de filtros só existe no celular (§87) -----------------

   ⚠️ `display: contents` é o que permite UM HTML servir os dois tamanhos: o
   invólucro some do layout e os filtros voltam a ser filhos diretos da faixa,
   exatamente como eram antes de existir agrupamento.

   Duplicar a lista de filtros — uma para desktop, outra para celular — seria
   dois lugares para a mesma verdade, e o que ficasse para trás seria o do
   celular, que é o que menos se olha ao desenvolver (regra de ouro nº 6). */
.filtros__gatilho { position: absolute; opacity: 0; pointer-events: none; }

/* ⚠️ A base descreve o CELULAR e o desktop é que esconde — mobile-first,
   como a §29 manda. Escrito ao contrário (`display: none` na base, e a
   media query do celular reabrindo), as duas regras empatam em (0,1,0) e
   vence a que vier depois no arquivo: o botão sumia no celular, que é o
   único lugar onde ele serve. É a mesma armadilha de ordem das §§82 e 84. */
.filtros__botao {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    min-height: var(--nav-item);
    padding: var(--space-2) var(--space-4);
    font-size: var(--text-sm);
    color: var(--color-text);
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-full);
    cursor: pointer;
}

.filtros__botao .icon { color: var(--color-text-muted); }

/* Recorte em vigor: o botão fica marcado, senão a lista aparece filtrada sem
   nada na tela dizendo por quê (§62). */
.filtros__botao--ativo {
    color: var(--color-accent-text);
    border-color: var(--color-accent);
    background: color-mix(in srgb, var(--color-accent) 8%, var(--color-bg));
}

.filtros__botao--ativo .icon { color: var(--color-accent-text); }

/* md — 768px: o invólucro desaparece e a faixa volta a ser o que era. */
@media (min-width: 48rem) {
    .filtros__botao { display: none; }
    .filtros__demais { display: contents; }
}
/* ---- E-mail na linha: estado por cor, e o badge de envios (§104) --------

   O ícone de e-mail SEMPRE aparece na coluna Ações, e a cor diz o estado:
   cinza quando a situação do registro não recebe aquele e-mail, vermelho
   quando ainda não foi enviado nesta situação, verde quando já foi. Cor
   nunca é o único sinal (§16): o `title` e o `aria-label` dizem o mesmo.

   Os três tokens (`text-muted`, `danger`, `success`) já passam no mínimo
   de 3:1 para elemento de interface nos dois temas (§§27 e 63). */

.acao-linha--email { position: relative; }

.acao-linha--email-bloqueado {
    color: var(--color-text-muted);
    opacity: 0.55;
    cursor: not-allowed;
}

.acao-linha--email-pendente { color: var(--color-danger); }

.acao-linha--email-pendente:hover {
    color: var(--color-danger);
    background: color-mix(in srgb, var(--color-danger) 12%, transparent);
}

.acao-linha--email-enviado { color: var(--color-success-vivo); }

.acao-linha--email-enviado:hover {
    color: var(--color-success);
    background: color-mix(in srgb, var(--color-success) 12%, transparent);
}

/* O badge conta quantos e-mails já saíram. Fica no canto do ícone, sobre a
   cor do estado — e é texto, então o número é lido, não só visto. */
.acao-linha__badge {
    position: absolute;
    top: -0.2rem;
    right: -0.2rem;
    min-width: 1.05rem;
    height: 1.05rem;
    padding: 0 0.25rem;
    font-size: 0.65rem;
    font-weight: 600;
    line-height: 1.05rem;
    text-align: center;
    /* A cor é a do ÍCONE (§106): o badge herda o `color` do link — cinza,
       vermelho ou verde — e desenha contorno e dígito com ela sobre o fundo
       da página. Uma regra serve aos três estados; cor de fundo sólida
       exigiria um texto claro que reprovaria sobre o verde vivo. */
    color: inherit;
    background: var(--color-bg);
    border: 1.5px solid currentColor;
    border-radius: var(--radius-full);
}

/* Blocos de permissão por MENU e SUBMENU (§106): o menu tem faixa de fundo,
   como o título de bloco (§81); o submenu é o título miúdo de sempre. */
.permissoes-menu + .permissoes-menu { margin-top: var(--space-5); }

.permissoes-menu__titulo {
    margin: 0 0 var(--space-3);
    padding: var(--space-2) var(--space-4);
    font-size: var(--text-sm);
    font-weight: var(--weight-semibold);
    color: var(--color-text);
    background: var(--color-surface-strong);
    border-radius: var(--radius);
}

.permissoes-menu .permissoes + .permissoes {
    margin-top: var(--space-4);
    padding-top: 0;
    border-top: 0;
}

/* ---- O compositor de e-mail (§104) --------------------------------------

   Campos à esquerda, prévia à direita — pedido do cliente. Não é o layout de
   duas colunas que a §101 eliminou: ali as colunas dividiam UM assunto; aqui
   são dois — o que se escreve e o que a pessoa vai receber. Mobile-first
   (§29): empilha, e vira duas colunas a partir de 64rem. */

.compositor {
    display: grid;
    gap: var(--space-5);
}

@media (min-width: 64rem) {
    .compositor { grid-template-columns: minmax(0, 6fr) minmax(0, 4fr); }
}

.compositor__previa { min-width: 0; }

/* Para e Responder para lado a lado; o resto, um abaixo do outro (§105). */
.compositor__linha {
    display: grid;
    gap: var(--space-3);
}

@media (min-width: 40rem) {
    .compositor__linha { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.previa-email {
    padding: var(--space-4);
    color: var(--color-text);
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
}

.previa-email__linha {
    margin: 0 0 var(--space-2);
    font-size: 0.875rem;
    overflow-wrap: anywhere;
}

.previa-email__linha span {
    display: inline-block;
    min-width: 4.5rem;
    color: var(--color-text-muted);
}

.previa-email__corpo {
    padding-top: var(--space-3);
    border-top: 1px solid var(--color-border);
    overflow-wrap: anywhere;
}

.previa-email__corpo p { margin: 0 0 var(--space-3); }

/* O modal remoto: a tela do compositor aberta sobre a listagem (§104). O
   conteúdo vem do próprio HTML da página do compositor, buscado pelo script
   — sem script o link navega até ela, e nada se perde (§29). */
.modal-remoto {
    width: min(64rem, calc(100vw - 2rem));
    max-height: calc(100dvh - 2rem);
    padding: 0;
    color: var(--color-text);
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
    overflow: auto;
}

.modal-remoto::backdrop { background: rgb(0 0 0 / 0.45); }

.modal-remoto > .cartao-sistema { border: 0; box-shadow: none; }
