/*
 * Complemento ao tema django-unfold — o tema em si (cores, sidebar, cards,
 * modo claro/escuro) já vem todo configurado em UNFOLD (config/settings/
 * base.py). Este arquivo só cobre o que o Unfold não tem pronto: os
 * botões coloridos de ação por linha (visualizar/editar/excluir), no
 * padrão do GestãoClick — ver core/admin.py (AcoesLinhaAdminMixin) e
 * templates/unfold/helpers/actions_row.html.
 */

/*
 * Menu lateral cinza + fundo do site num cinza bem claro (pedido do
 * cliente) — hoje os dois usam a mesma cor do Unfold (`bg-base-50`,
 * praticamente branco), por isso pareciam tudo branco, sem distinção
 * entre o menu e o conteúdo. Cor direto aqui (não via UNFOLD["COLORS"]
 * ["base"], settings.py) de propósito: a paleta "base" também define
 * cor de texto/borda em boa parte do admin (ver unfold/settings.py,
 * mapa "font" deriva de base-500/600/900) — mudar a paleta inteira
 * arriscava desbotar texto/bordas em telas que nem foram conferidas
 * agora. `!important` porque o CSS do Unfold (unfold/css/styles.css)
 * carrega DEPOIS deste arquivo (ver unfold/layouts/skeleton.html) — sem
 * isso, a classe `bg-base-50` do próprio Unfold ganharia por último.
 */
body.bg-base-50 {
    background-color: #f9fafb !important;
}

.tasso-sidebar-fundo {
    background-color: #f3f4f6 !important;
}

/*
 * Logomarca de fundo — marca d'água bem discreta (pedido antigo do
 * cliente, perdido quando o tema mudou pro django-unfold). Primeira
 * versão ficava no canto do CONTEÚDO (`body::before`) e sumia atrás de
 * cards mais altos em produção — trocado pro espaço vazio do MENU
 * LATERAL (abaixo dos itens de navegação, acima do rodapé de usuário),
 * que não varia com o tanto de conteúdo da página. `#nav-sidebar` já é
 * `position: fixed` (ver templates/admin/nav_sidebar.html), então já
 * serve de referência pro `::after` sem precisar de mais nada.
 * `tasso-icone.png` é só o símbolo (recortado de tasso-logo.png, sem a
 * palavra "TASSO" nem o subtítulo) — cabe melhor num espaço estreito.
 * `pointer-events: none` não atrapalha clique nos itens do menu.
 */
#nav-sidebar::after {
    content: "";
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    width: 150px;
    height: 127px;
    background-image: url("../img/tasso-icone.381d669ae2ae.png");
    background-repeat: no-repeat;
    background-position: center;
    background-size: contain;
    opacity: 0.12;
    pointer-events: none;
}

.botao-acao {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border-radius: 6px;
    color: #fff !important;
    text-decoration: none !important;
    transition: filter 0.1s ease-in-out;
}

.botao-acao:hover {
    filter: brightness(0.9);
}

.botao-acao .material-symbols-outlined {
    font-size: 18px;
}

.botao-visualizar {
    background-color: #2563eb;
}

.botao-editar {
    background-color: #f59e0b;
}

.botao-excluir {
    background-color: #dc2626;
}

.botao-imprimir {
    background-color: #64748b;
}

/* Baixar PDF fica ao lado de Imprimir e faz a mesma folha — por isso a cor é
 * parente do cinza dele, e não uma sexta cor no meio da fileira. Escuro o
 * bastante para não parecer o mesmo botão duas vezes; o ícone
 * (picture_as_pdf) é quem diz qual é qual. Vermelho, que seria a convenção de
 * PDF, está ocupado por Excluir na mesma barra — e vizinho de uma ação sem
 * volta não é lugar de experimentar semelhança de cor. */
.botao-baixar-pdf {
    background-color: #334155;
}

/* Verde: é o único botão da linha que CONFIRMA alguma coisa — as contas
 * entram na lista pendentes e saem pagas, e o verde é a leitura imediata
 * disso. Fica na primeira posição da linha, o mais longe possível do
 * vermelho de excluir: as duas ações são vizinhas na mesma barra e uma
 * delas não tem volta. */
.botao-quitar {
    background-color: #16a34a;
}

.botao-alterar-situacao {
    background-color: #7c3aed;
}

.botao-email {
    background-color: #16a34a;
}

.botao-whatsapp {
    background-color: #25d366; /* verde oficial do WhatsApp */
}

/*
 * Fundo escurecido atrás do menu lateral no celular (fecha o menu ao
 * tocar fora dele — ver templates/admin/nav_sidebar.html). Cor direto em
 * CSS porque `bg-black/50` do Tailwind não está no build já compilado do
 * Unfold (static/unfold/css/styles.css é gerado uma vez, na release do
 * pacote, só com as classes que os templates DELE usam).
 */
.tasso-backdrop {
    background-color: rgba(0, 0, 0, 0.5);
}

/*
 * Cards do dashboard (A receber/pagar hoje, Recebimentos/Pagamentos do
 * mês) — card branco com listra colorida no topo e número colorido, no
 * estilo do outro painel do cliente (Só Reparo) que ele apontou como
 * referência de "limpo, fácil de ver". As variáveis --color-base-* e
 * --color-font-* usadas abaixo são geradas pelo próprio Unfold (inline,
 * por request, a partir de UNFOLD["COLORS"] em settings) — ao contrário
 * de classe Tailwind solta, essas sempre existem.
 */
.tasso-kpi-card {
    display: flex;
    flex-direction: column;
    min-width: 0;
    overflow: hidden;
    background-color: #fff;
    border: 1px solid var(--color-base-200);
    border-top: 4px solid transparent;
    border-radius: var(--border-radius, 0.5rem);
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04), 0 1px 6px rgba(0, 0, 0, 0.04);
    padding: 1.5rem;
    text-decoration: none !important;
}

/* Divisória horizontal entre "Recebimentos do mês" e "Pagamentos do mês",
   dentro do mesmo card — deliberadamente empilhado (não lado a lado): o
   card ocupa só 1/3 da tela, então 2 colunas ali dentro ficariam
   espremidas demais pra ler "Realizado: R$ 8.015,00" sem quebrar feio. */
.tasso-kpi-divisor-horizontal {
    margin-top: 1rem;
    padding-top: 1rem;
    border-top: 1px solid var(--color-base-200);
}

html.dark .tasso-kpi-divisor-horizontal {
    border-top-color: var(--color-base-800);
}

html.dark .tasso-kpi-card {
    background-color: var(--color-base-900);
    border-color: var(--color-base-800);
}

.tasso-kpi-verde {
    border-top-color: #16a34a;
}

.tasso-kpi-vermelho {
    border-top-color: #dc2626;
}

.tasso-kpi-azul {
    border-top-color: #2563eb;
}

.tasso-kpi-label {
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--color-font-subtle-light);
}

html.dark .tasso-kpi-label {
    color: var(--color-font-subtle-dark);
}

.tasso-kpi-valor {
    font-size: 1.875rem;
    font-weight: 600;
    margin: 0.5rem 0;
    color: var(--color-font-important-light);
}

html.dark .tasso-kpi-valor {
    color: var(--color-font-important-dark);
}

.tasso-kpi-valor-verde {
    color: #16a34a;
}

.tasso-kpi-valor-vermelho {
    color: #dc2626;
}

.tasso-kpi-rodape {
    display: flex;
    align-items: center;
    gap: 0.25rem;
    margin-top: auto;
    padding-top: 0.75rem;
    border-top: 1px solid var(--color-base-200);
    font-size: 0.875rem;
    color: var(--color-font-default-light);
}

html.dark .tasso-kpi-rodape {
    border-top-color: var(--color-base-800);
    color: var(--color-font-default-dark);
}

.tasso-kpi-card:hover .tasso-kpi-rodape {
    color: var(--color-primary-600);
}

.tasso-secao-titulo {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-bottom: 0.75rem;
    font-size: 0.75rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--color-font-subtle-light);
}

html.dark .tasso-secao-titulo {
    color: var(--color-font-subtle-dark);
}

.tasso-secao-titulo .material-symbols-outlined {
    font-size: 16px;
}

/*
 * Botão de abrir/fechar o menu no cabeçalho — só aparece abaixo do
 * breakpoint xl (celular/tablet), onde o menu lateral é um overlay em vez
 * de fixo ao lado do conteúdo. No desktop o botão equivalente é o
 * `.tasso-toggle-menu-sidebar` abaixo, ancorado no próprio menu. O ícone
 * puro do Unfold é pequeno (18px) e sem nenhum indício visual de que é
 * clicável (sem fundo, sem borda). Ver templates/unfold/helpers/
 * welcomemsg.html.
 */
.tasso-toggle-menu {
    justify-content: center;
    flex-shrink: 0;
    width: 32px;
    height: 32px;
    border-radius: var(--border-radius, 0.5rem);
    color: var(--color-font-default-light);
    transition: background-color 0.1s ease-in-out;
}

html.dark .tasso-toggle-menu {
    color: var(--color-font-default-dark);
}

.tasso-toggle-menu:hover {
    background-color: var(--color-base-100);
}

html.dark .tasso-toggle-menu:hover {
    background-color: var(--color-base-800);
}

.tasso-toggle-menu .material-symbols-outlined {
    font-size: 20px;
}

/*
 * Botão de recolher/expandir o menu lateral no desktop — ancorado no
 * canto superior direito do próprio menu (não no cabeçalho, longe dele).
 * `position: fixed` porque fica fora do <div> que o menu recolhido
 * esconde (ver templates/admin/nav_sidebar.html) — só assim ele continua
 * visível com o menu recolhido, que é o objetivo (é o único jeito de
 * reabrir). O deslocamento à esquerda muda conforme o menu está aberto
 * (perto da borda direita dos 288px do menu) ou recolhido (perto da
 * borda esquerda da tela, onde o menu ficava).
 *
 * display/breakpoint escritos aqui em vez de classes Tailwind (`hidden!
 * xl:flex!`) de propósito: o styles.css do Unfold é um bundle Tailwind
 * pré-compilado e podado (só inclui classe já usada nos templates do
 * próprio pacote) — "xl:flex!" nunca existiu nesse build (só "xl:block!"),
 * então a classe Tailwind não fazia nada e o botão ficava sempre
 * invisível. 1280px repete o breakpoint "xl" do próprio Unfold.
 */
.tasso-toggle-menu-sidebar {
    display: none;
    position: fixed;
    top: 16px;
    left: 244px;
    z-index: 70;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border-radius: var(--border-radius, 0.5rem);
    color: var(--color-font-default-light);
    font-size: 20px;
    cursor: pointer;
    transition: left 0.2s ease-in-out, background-color 0.1s ease-in-out;
}

@media (min-width: 1280px) {
    .tasso-toggle-menu-sidebar {
        display: flex;
    }
}

html.dark .tasso-toggle-menu-sidebar {
    color: var(--color-font-default-dark);
}

.tasso-toggle-menu-sidebar:hover {
    background-color: var(--color-base-100);
}

html.dark .tasso-toggle-menu-sidebar:hover {
    background-color: var(--color-base-800);
}

.tasso-toggle-menu-sidebar--recolhido {
    left: 12px;
}

/*
 * Botão "Buscar CNPJ" no cadastro de Cliente — injetado via JS (não dá pra
 * usar {% component %} porque o botão não existe no template, só depois
 * que static/js/tasso-busca-cnpj.js roda). Ver cadastros/admin.py.
 */
.tasso-botao-buscar-cnpj {
    display: inline-flex;
    align-items: center;
    margin-top: 0.5rem;
    padding: 0.375rem 0.75rem;
    border: 1px solid var(--color-primary-600);
    border-radius: var(--border-radius, 0.5rem);
    background-color: transparent;
    color: var(--color-primary-600);
    font-size: 0.8125rem;
    font-weight: 600;
    cursor: pointer;
    transition: background-color 0.1s ease-in-out;
}

.tasso-botao-buscar-cnpj:hover {
    background-color: var(--color-primary-50);
}

.tasso-botao-buscar-cnpj:disabled {
    opacity: 0.6;
    cursor: default;
}

.tasso-status-buscar-cnpj {
    display: inline-block;
    margin-top: 0.5rem;
    margin-left: 0.75rem;
    font-size: 0.8125rem;
}

/*
 * Status da busca automática de CEP (sem botão — ver
 * static/js/tasso-busca-cep.js) nas linhas do formset de Endereço.
 */
.tasso-status-buscar-cep {
    display: block;
    margin-top: 0.25rem;
    font-size: 0.8125rem;
}

/*
 * Páginas de relatório (relatorios/templates/admin/relatorios/*.html) — são
 * views com HTML escrito à mão, não um ModelAdmin/changelist do Unfold, então
 * não herdam nenhum estilo dele automaticamente. Este bloco reaproveita a
 * mesma linguagem visual (cores, cantos, espaçamento) escrita em CSS puro.
 */
.tasso-relatorio-filtros {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 1rem 1.25rem;
    margin-bottom: 1.5rem;
    padding: 1.25rem;
    background-color: #fff;
    border: 1px solid var(--color-base-200);
    border-radius: var(--border-radius, 0.5rem);
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04), 0 1px 6px rgba(0, 0, 0, 0.04);
}

.tasso-relatorio-campo {
    display: flex;
    flex-direction: column;
    gap: 0.375rem;
    font-size: 0.8125rem;
    font-weight: 600;
    color: var(--color-font-subtle-light);
}

.tasso-relatorio-acoes {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin-left: auto;
}

.tasso-input,
.tasso-select {
    min-height: 38px;
    padding: 0.5rem 0.75rem;
    border: 1px solid var(--color-base-200);
    border-radius: var(--border-radius, 0.5rem);
    background-color: #fff;
    color: var(--color-font-default-light);
    font-size: 0.875rem;
    font-weight: 400;
}

.tasso-input:focus,
.tasso-select:focus {
    outline: 2px solid var(--color-primary-600);
    outline-offset: -2px;
}

.tasso-botao-primario,
.tasso-botao-secundario {
    display: inline-flex;
    align-items: center;
    height: 38px;
    padding: 0 1rem;
    border-radius: var(--border-radius, 0.5rem);
    font-size: 0.8125rem;
    font-weight: 600;
    cursor: pointer;
    text-decoration: none !important;
}

.tasso-botao-primario {
    border: none;
    background-color: var(--color-primary-600);
    color: #fff !important;
}

.tasso-botao-primario:hover {
    background-color: var(--color-primary-700);
}

.tasso-botao-secundario {
    border: 1px solid var(--color-base-200);
    background-color: #fff;
    color: var(--color-font-default-light) !important;
}

.tasso-botao-secundario:hover {
    background-color: var(--color-base-50);
}

.tasso-relatorio-widgets {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    margin-bottom: 1.5rem;
}

/* Extrato: os widgets vêm em grupos rotulados (A receber / A pagar / Saldo),
   porque ali as duas naturezas convivem na mesma tela e um número solto não
   diz de qual lado é. */
.tasso-relatorio-widgets-grupo .tasso-relatorio-widgets {
    margin-bottom: 1rem;
}

.tasso-relatorio-widgets-titulo {
    margin: 0 0 0.375rem;
    font-size: 0.75rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--color-font-subtle-light);
}

.tasso-relatorio-paginacao {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    margin-bottom: 1.5rem;
}

.tasso-relatorio-paginacao-atual {
    font-size: 0.8125rem;
    color: var(--color-font-subtle-light);
}

.tasso-stat-mini {
    min-width: 9rem;
    padding: 0.75rem 1rem;
    background-color: #fff;
    border: 1px solid var(--color-base-200);
    border-radius: var(--border-radius, 0.5rem);
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04), 0 1px 6px rgba(0, 0, 0, 0.04);
}

.tasso-stat-mini-label {
    font-size: 0.6875rem;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--color-font-subtle-light);
}

.tasso-stat-mini-valor {
    margin-top: 0.25rem;
    font-size: 1.125rem;
    font-weight: 600;
    color: var(--color-font-important-light);
}

.tasso-relatorio-tabela {
    overflow-x: auto;
    margin-bottom: 0.75rem;
    background-color: #fff;
    border: 1px solid var(--color-base-200);
    border-radius: var(--border-radius, 0.5rem);
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04), 0 1px 6px rgba(0, 0, 0, 0.04);
}

.tasso-relatorio-tabela table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.875rem;
}

.tasso-relatorio-tabela th {
    padding: 0.75rem 1.25rem;
    border-bottom: 1px solid var(--color-base-200);
    color: var(--color-font-subtle-light);
    font-size: 0.6875rem;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-align: left;
    text-transform: uppercase;
    white-space: nowrap;
}

.tasso-relatorio-tabela td {
    padding: 0.75rem 1.25rem;
    border-bottom: 1px solid var(--color-base-200);
    color: var(--color-font-default-light);
}

.tasso-relatorio-tabela tbody tr:last-child td {
    border-bottom: none;
}

.tasso-relatorio-tabela tbody tr:hover {
    background-color: var(--color-base-50);
}

.tasso-relatorio-tabela a {
    color: var(--color-primary-600);
    text-decoration: none;
}

.tasso-relatorio-tabela a:hover {
    text-decoration: underline;
}

.tasso-relatorio-contagem {
    font-size: 0.8125rem;
    color: var(--color-font-subtle-light);
}

/*
 * Miniatura de anexo de imagem (coluna "Prévia" do inline de Anexos — ver
 * core.admin.AnexoInline) e o overlay de tela cheia que abre ao clicar
 * nela (static/js/tasso-anexo-lightbox.js).
 */
.tasso-anexo-miniatura-link {
    display: inline-block;
}

.tasso-anexo-miniatura {
    display: block;
    width: 56px;
    height: 56px;
    object-fit: cover;
    border-radius: var(--border-radius, 0.5rem);
    border: 1px solid var(--color-base-200);
    cursor: zoom-in;
}

html.dark .tasso-anexo-miniatura {
    border-color: var(--color-base-700);
}

.tasso-lightbox-overlay {
    position: fixed;
    inset: 0;
    z-index: 200;
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: rgba(0, 0, 0, 0.85);
    cursor: zoom-out;
}

.tasso-lightbox-imagem {
    max-width: 90vw;
    max-height: 90vh;
    border-radius: var(--border-radius, 0.5rem);
    cursor: default;
}

.tasso-lightbox-fechar {
    position: fixed;
    top: 16px;
    right: 16px;
    z-index: 201;
    width: 40px;
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 9999px;
    border: none;
    background-color: rgba(255, 255, 255, 0.15);
    color: #fff;
    font-size: 24px;
    line-height: 1;
    cursor: pointer;
}

.tasso-lightbox-fechar:hover {
    background-color: rgba(255, 255, 255, 0.3);
}

#tasso-voltar-ao-topo {
    position: fixed;
    right: 20px;
    /* 90px, não 20px: Unfold tem uma barra fixa própria no rodapé (ações em
       lote na lista, Salvar/Cancelar no formulário) — sem esse respiro o
       botão fica atrás dela (mesmo com z-index maior, a barra abre um
       stacking context próprio) e o clique não chega a acontecer. */
    bottom: 90px;
    width: 44px;
    height: 44px;
    border-radius: 9999px;
    border: none;
    background-color: #e51b20;
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
    opacity: 0;
    pointer-events: none;
    transform: translateY(10px);
    transition: opacity 0.2s ease, transform 0.2s ease;
    z-index: 50;
}

#tasso-voltar-ao-topo.tasso-visivel {
    opacity: 1;
    pointer-events: auto;
    transform: translateY(0);
}

#tasso-voltar-ao-topo:hover {
    filter: brightness(0.9);
}

/* ==========================================================================
   Dashboard — visual "Soft 3D" (tela enviada pelo cliente, jul/2026)
   ==========================================================================

   Neumorfismo: as superfícies não têm borda nem sombra projetada; o relevo vem
   de DUAS sombras opostas — uma escura embaixo/direita e uma branca em cima/à
   esquerda — sobre um fundo do mesmo tom. Isso só funciona se o fundo da
   página for exatamente a cor base; por isso `--tasso-soft-bg` é aplicada ao
   container do dashboard, e não herdada.

   O risco conhecido desse estilo é CONTRASTE: relevo feito de cinza sobre
   cinza tende a apagar texto e borda. Aqui o texto fica em #1b1c1d (quase
   preto) sobre #f5f3f4, e o que o relevo transmite é agrupamento — nunca
   informação sozinha. Nenhum dado depende de enxergar a sombra.

   Fontes: Sora nos títulos e JetBrains Mono nos rótulos técnicos, servidas
   localmente (static/fonts/). São fontes variáveis — um arquivo cobre toda a
   faixa de peso, o que é por que `font-weight` traz um intervalo. */

@font-face {
    font-family: "Sora";
    src: url("../fonts/Sora-Variable.fc575ebf6f7c.woff2") format("woff2");
    font-weight: 400 800;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: "JetBrains Mono";
    src: url("../fonts/JetBrainsMono-Variable.075ec35bc15b.woff2") format("woff2");
    font-weight: 400 700;
    font-style: normal;
    font-display: swap;
}

/* Os tokens do relevo nascem no :root, não só dentro de .tasso-dash.
 *
 * Eles viveram presos ao escopo do dashboard desde que o visual "Soft 3D"
 * chegou — e funcionava, porque só o dashboard usava .tasso-soft. Quando a
 * tela de Relatórios virou cards, os cartões saíram INVISÍVEIS: `.tasso-soft`
 * pedia `var(--tasso-soft-bg)`, a variável não existia fora do dashboard, e o
 * fundo e as sombras simplesmente não eram pintados. Sem erro no console, sem
 * nada quebrado — só cartões transparentes.
 *
 * `.tasso-dash` mantém as mesmas declarações logo abaixo: nada muda no
 * dashboard, e o relevo passa a estar disponível em qualquer tela. */
:root {
    --tasso-soft-bg: #f5f3f4;
    --tasso-soft-escuro: #d1d9e6;
    --tasso-soft-claro: #ffffff;
    --tasso-tinta: #1b1c1d;
    --tasso-tinta-2: #5f6368;
    --tasso-vermelho: #9c1917;
}

.tasso-dash {
    --tasso-soft-bg: #f5f3f4;
    --tasso-soft-escuro: #d1d9e6;
    --tasso-soft-claro: #ffffff;
    --tasso-tinta: #1b1c1d;
    --tasso-tinta-2: #5f6368;
    --tasso-vermelho: #9c1917;
    --tasso-vermelho-vivo: #e21d20;
    --tasso-azul: #0b60a4;

    background: var(--tasso-soft-bg);
    margin: -1rem -1rem 0;
    padding: 1.75rem 1.5rem 2.5rem;
    min-height: 100%;
}

.tasso-dash-titulo {
    font-family: "Sora", system-ui, sans-serif;
    font-size: 1.9rem;
    font-weight: 700;
    letter-spacing: -0.02em;
    color: var(--tasso-vermelho);
    line-height: 1.15;
}

.tasso-dash-data {
    font-size: 0.9rem;
    color: var(--tasso-tinta-2);
    margin-top: 0.15rem;
}

/* A frase que troca a cada visita (core/frases.py).
 *
 * Discreta de propósito: ela acompanha a saudação, não compete com ela. Se
 * ficasse do tamanho da data e na mesma cor, viraria uma segunda linha de
 * informação — e não é informação, é recado. A barra à esquerda separa sem
 * precisar de caixa, que quebraria o respiro do topo do painel. */
.tasso-dash-frase {
    margin-top: 0.6rem;
    padding-left: 0.7rem;
    border-left: 3px solid var(--tasso-vermelho);
    font-size: 0.92rem;
    font-style: italic;
    color: var(--tasso-tinta-2);
    max-width: 46rem;
    line-height: 1.45;
}
html.dark .tasso-dash-frase { color: #a8adb4; }

/* Relevo padrão. O raio grande é o que o estilo pede — e é também a razão de
   ele não seguir o `Sharp (0)` descrito no DESIGN.md; ver docs/ARQUITETURA.md. */
.tasso-soft {
    background: var(--tasso-soft-bg);
    border-radius: 1.75rem;
    box-shadow: 9px 9px 18px var(--tasso-soft-escuro),
                -9px -9px 18px var(--tasso-soft-claro);
}

.tasso-soft-fundo {
    background: var(--tasso-soft-bg);
    border-radius: 1.25rem;
    box-shadow: inset 5px 5px 10px var(--tasso-soft-escuro),
                inset -5px -5px 10px var(--tasso-soft-claro);
}

a.tasso-soft { display: block; text-decoration: none; color: inherit; transition: box-shadow .18s ease, transform .18s ease; }
a.tasso-soft:hover { transform: translateY(-2px); box-shadow: 12px 12px 22px var(--tasso-soft-escuro), -12px -12px 22px var(--tasso-soft-claro); }
a.tasso-soft:active { transform: translateY(0); box-shadow: inset 5px 5px 10px var(--tasso-soft-escuro), inset -5px -5px 10px var(--tasso-soft-claro); }
a.tasso-soft:focus-visible { outline: 3px solid var(--tasso-vermelho-vivo); outline-offset: 3px; }

/* Cartão de alerta: o único bloco de cor cheia da tela. Ele é o destaque
   porque carrega a informação que exige ação hoje. */
.tasso-soft-alerta {
    background: linear-gradient(145deg, #a71b19, #8c1715);
    color: #fff;
    border-radius: 1.75rem;
    box-shadow: 9px 9px 18px var(--tasso-soft-escuro),
                -9px -9px 18px var(--tasso-soft-claro);
    text-decoration: none;
    display: block;
    transition: transform .18s ease;
}
.tasso-soft-alerta:hover { transform: translateY(-2px); color: #fff; }
.tasso-soft-alerta:focus-visible { outline: 3px solid var(--tasso-tinta); outline-offset: 3px; }

.tasso-rotulo-tec {
    font-family: "JetBrains Mono", ui-monospace, monospace;
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--tasso-tinta-2);
}
.tasso-soft-alerta .tasso-rotulo-tec { color: rgba(255, 255, 255, .92); }

.tasso-num {
    font-family: "Sora", system-ui, sans-serif;
    font-weight: 700;
    letter-spacing: -0.03em;
    font-variant-numeric: tabular-nums;
    color: var(--tasso-tinta);
    line-height: 1.05;
}
.tasso-num-g { font-size: 2rem; }
.tasso-num-m { font-size: 1.6rem; }
.tasso-soft-alerta .tasso-num { color: #fff; }

/* Círculo do ícone: relevo afundado, mesma linguagem do resto. */
.tasso-icone-soft {
    width: 3.1rem; height: 3.1rem; border-radius: 999px;
    display: flex; align-items: center; justify-content: center; flex-shrink: 0;
    background: var(--tasso-soft-bg);
    box-shadow: inset 4px 4px 8px var(--tasso-soft-escuro),
                inset -4px -4px 8px var(--tasso-soft-claro);
}
.tasso-soft-alerta .tasso-icone-soft {
    background: rgba(255, 255, 255, .14);
    box-shadow: none;
    width: 2.4rem; height: 2.4rem;
    color: #fff;
}

.tasso-botao-soft {
    display: inline-flex; align-items: center; justify-content: center; gap: .4rem;
    background: #fff; color: var(--tasso-vermelho);
    font-family: "JetBrains Mono", ui-monospace, monospace;
    font-size: .75rem; font-weight: 600; letter-spacing: .08em; text-transform: uppercase;
    padding: .8rem 1.6rem; border-radius: 999px; text-decoration: none;
    transition: transform .15s ease;
}
.tasso-botao-soft:hover { transform: scale(1.03); color: var(--tasso-vermelho); }

.tasso-link-tec {
    display: inline-flex; align-items: center; gap: .3rem;
    font-family: "JetBrains Mono", ui-monospace, monospace;
    font-size: .7rem; font-weight: 600; letter-spacing: .08em; text-transform: uppercase;
    color: var(--tasso-vermelho); text-decoration: none;
}

/* Gráfico + resumo do mês na mesma linha. O gráfico é `min-width: 0` porque
   item de flex não encolhe abaixo do conteúdo por padrão — sem isso o canvas
   empurraria o resumo pra fora do card em telas estreitas. */
.tasso-dash-fluxo { display: flex; align-items: stretch; gap: 1.5rem; }
.tasso-dash-grafico { height: 17rem; position: relative; flex: 1 1 auto; min-width: 0; }

.tasso-dash-resumo {
    flex: 0 0 12.5rem; display: flex; flex-direction: column; justify-content: center;
    gap: .1rem; padding-left: 1.5rem; border-left: 1px solid rgba(0, 0, 0, .07);
}
.tasso-dash-resumo-mes { margin-bottom: .6rem; }
.tasso-dash-resumo-item {
    display: flex; flex-direction: column; gap: .1rem;
    padding: .5rem 0; text-decoration: none; border-radius: .5rem;
}
a.tasso-dash-resumo-item:hover .tasso-dash-resumo-valor { text-decoration: underline; }
a.tasso-dash-resumo-item:focus-visible { outline: 2px solid var(--tasso-vermelho); outline-offset: 3px; }
.tasso-dash-resumo-rotulo {
    font-size: .68rem; text-transform: uppercase; letter-spacing: .06em;
    font-weight: 700; color: var(--tasso-tinta-2);
}
.tasso-dash-resumo-valor {
    font-size: 1.05rem; font-weight: 700; color: var(--tasso-tinta);
    font-variant-numeric: tabular-nums;
}
/* O resultado é a leitura final, então ganha separador e corpo maior. */
.tasso-dash-resumo-final { border-top: 1px solid rgba(0, 0, 0, .07); margin-top: .5rem; padding-top: .8rem; }
.tasso-dash-resumo-final .tasso-dash-resumo-valor { font-size: 1.25rem; }
.tasso-dash-resumo-valor.tasso-negativo { color: #9c1917; }
.tasso-dash-resumo-nota { font-size: .7rem; color: var(--tasso-tinta-2); margin-top: .45rem; }

/* Abaixo de 1100px o resumo vai pra baixo do gráfico em vez de espremer os
   dois: com 12,5rem fixos, o canvas ficaria estreito demais pra 6 meses. */
@media (max-width: 1100px) {
    .tasso-dash-fluxo { flex-direction: column; }
    .tasso-dash-resumo {
        flex: 1 1 auto; padding-left: 0; border-left: 0;
        border-top: 1px solid rgba(0, 0, 0, .07); padding-top: 1rem;
    }
}

html.dark .tasso-dash-resumo,
html.dark .tasso-dash-resumo-final { border-color: rgba(255, 255, 255, .1); }
html.dark .tasso-dash-resumo-valor.tasso-negativo { color: #ff8a85; }
.tasso-dash-rosca { width: 11rem; height: 11rem; position: relative; margin: 0 auto; }
.tasso-dash-rosca-num {
    position: absolute; inset: 0; display: flex; flex-direction: column;
    align-items: center; justify-content: center; text-align: center;
}

/* O tema do admin é fixado em claro (UNFOLD["THEME"]), mas o toggle continua
   existindo no cabeçalho. Sem estas regras, quem clicasse nele veria texto
   quase preto sobre relevo claro — ilegível. O relevo escuro usa as mesmas
   duas sombras, com os tons invertidos. */
html.dark {
    --tasso-soft-bg: #24262a;
    --tasso-soft-escuro: #1a1c1f;
    --tasso-soft-claro: #2e3136;
    --tasso-tinta: #f0f1f2;
    --tasso-tinta-2: #a8adb4;
    --tasso-vermelho: #ff8a85;
}

html.dark .tasso-dash {
    --tasso-soft-bg: #24262a;
    --tasso-soft-escuro: #1a1c1f;
    --tasso-soft-claro: #2e3136;
    --tasso-tinta: #f0f1f2;
    --tasso-tinta-2: #a8adb4;
}
html.dark .tasso-dash-titulo { color: #ff8a85; }
html.dark .tasso-botao-soft { background: #f0f1f2; }
html.dark .tasso-link-tec { color: #ff8a85; }

@media (max-width: 640px) {
    .tasso-dash { margin: -0.5rem -0.5rem 0; padding: 1.25rem 1rem 2rem; border-radius: 0; }
    .tasso-dash-titulo { font-size: 1.5rem; }
    .tasso-num-g { font-size: 1.65rem; }
}

@media (prefers-reduced-motion: reduce) {
    a.tasso-soft, .tasso-soft-alerta, .tasso-botao-soft { transition: none; }
}

/* ==========================================================================
   Menu lateral "Soft 3D" (templates/unfold/helpers/navigation.html)
   ==========================================================================

   Dois cards em relevo sobre o fundo: a logo em cima, o menu embaixo. Mesma
   linguagem do dashboard — o relevo vem de duas sombras opostas, não de borda.

   O que NÃO mudou: a permissão. Cada item continua passando pelo
   `has_permission` do Unfold; este arquivo só troca a aparência. */

.tasso-nav {
    --tasso-soft-bg: #f5f3f4;
    --tasso-soft-escuro: #d1d9e6;
    --tasso-soft-claro: #ffffff;
    --tasso-tinta: #1b1c1d;
    --tasso-tinta-2: #5f6368;
    --tasso-vermelho: #9c1917;

    background: var(--tasso-soft-bg);
    display: flex;
    flex-direction: column;
    gap: 1.25rem;
    height: 100vh;
    padding: 1.25rem 1rem;
    overflow: hidden;
}

.tasso-nav-logo {
    background: var(--tasso-soft-bg);
    border-radius: 1.75rem;
    box-shadow: 9px 9px 18px var(--tasso-soft-escuro), -9px -9px 18px var(--tasso-soft-claro);
    padding: 1.5rem 1.25rem;
    flex-shrink: 0;
    display: flex;
    justify-content: center;
}
.tasso-nav-logo img { max-width: 11rem; width: 100%; height: auto; display: block; }

.tasso-nav-corpo {
    background: var(--tasso-soft-bg);
    border-radius: 1.75rem;
    box-shadow: 9px 9px 18px var(--tasso-soft-escuro), -9px -9px 18px var(--tasso-soft-claro);
    padding: 1.1rem .85rem;
    display: flex;
    flex-direction: column;
    gap: .75rem;
    flex: 1;
    min-height: 0;
}

/* h-0 + flex-1 é o que permite a lista rolar sem empurrar o rodapé pra fora. */
.tasso-nav-lista { flex: 1; min-height: 0; overflow-y: auto; display: flex; flex-direction: column; gap: .15rem; }

.tasso-nav-item {
    display: flex; align-items: center; gap: .85rem; width: 100%;
    padding: .7rem .9rem; border-radius: 1rem;
    color: var(--tasso-tinta-2); text-decoration: none;
    font-size: .9rem; font-weight: 500; text-align: left;
    background: none; border: 0; cursor: pointer;
    transition: color .15s ease;
}
.tasso-nav-item .material-symbols-outlined { font-size: 1.35rem; flex-shrink: 0; }
.tasso-nav-texto { flex: 1; min-width: 0; }
.tasso-nav-item:hover { color: var(--tasso-tinta); }
.tasso-nav-item:focus-visible { outline: 2px solid var(--tasso-vermelho); outline-offset: 2px; }

/* Item ativo: relevo AFUNDADO, como na tela. */
.tasso-nav-item--ativo {
    color: var(--tasso-vermelho);
    font-weight: 600;
    box-shadow: inset 4px 4px 8px var(--tasso-soft-escuro), inset -4px -4px 8px var(--tasso-soft-claro);
}

.tasso-nav-seta { margin-left: auto; font-size: 1.1rem !important; transition: transform .18s ease; }
.tasso-nav-seta--aberta { transform: rotate(180deg); }

.tasso-nav-sub { display: flex; flex-direction: column; gap: .1rem; padding: .15rem 0 .35rem 2.9rem; }
.tasso-nav-subitem {
    padding: .4rem .6rem; border-radius: .7rem; font-size: .82rem;
    color: var(--tasso-tinta-2); text-decoration: none;
}
.tasso-nav-subitem:hover { color: var(--tasso-tinta); }
.tasso-nav-subitem--ativo { color: var(--tasso-vermelho); font-weight: 600; }
.tasso-nav-subitem:focus-visible { outline: 2px solid var(--tasso-vermelho); outline-offset: 2px; }

.tasso-nav-rodape { flex-shrink: 0; border-top: 1px solid rgba(0,0,0,.07); padding-top: .9rem; display: flex; flex-direction: column; gap: .75rem; }

.tasso-nav-cta {
    display: flex; align-items: center; justify-content: center; gap: .5rem;
    background: linear-gradient(145deg, #a71b19, #8c1715); color: #fff;
    padding: .8rem 1rem; border-radius: 999px; text-decoration: none;
    font-family: "JetBrains Mono", ui-monospace, monospace;
    font-size: .75rem; font-weight: 600; letter-spacing: .06em; text-transform: uppercase;
    box-shadow: 5px 5px 10px var(--tasso-soft-escuro), -5px -5px 10px var(--tasso-soft-claro);
    transition: transform .15s ease;
}
.tasso-nav-cta:hover { transform: translateY(-1px); color: #fff; }
.tasso-nav-cta:focus-visible { outline: 2px solid var(--tasso-tinta); outline-offset: 2px; }

.tasso-nav-perfil { display: flex; align-items: center; gap: .7rem; text-decoration: none; padding: .3rem .2rem; border-radius: 1rem; }
.tasso-nav-perfil:focus-visible { outline: 2px solid var(--tasso-vermelho); outline-offset: 2px; }
.tasso-nav-perfil-foto {
    width: 2.4rem; height: 2.4rem; border-radius: 999px; flex-shrink: 0;
    display: flex; align-items: center; justify-content: center; overflow: hidden;
    background: var(--tasso-soft-bg); color: var(--tasso-vermelho);
    box-shadow: inset 3px 3px 6px var(--tasso-soft-escuro), inset -3px -3px 6px var(--tasso-soft-claro);
}
/* `contain`, não `cover` — o "fora do eixo" que o cliente viu.
 *
 * `cover` preenche o círculo e corta o que sobra, que é o certo pra retrato
 * (rosto no meio, sobra nas bordas). Só que o que se sobe aqui, na prática, é
 * a LOGOMARCA da empresa: 1995x1349, proporção 1,48. Num quadrado, `cover`
 * escala pela altura e corta as laterais — sobrava a fatia do meio, com o
 * texto decepado nos dois lados e o ícone fora de centro. Parecia desalinhado
 * porque estava mesmo: era um recorte, não a imagem.
 *
 * `contain` cabe a imagem inteira, e o padding tira ela de encostar na borda
 * do círculo. Retrato passa a ter tarja em cima e embaixo em vez de recorte —
 * troca justa: em 2,4rem, decapitar é pior que sobrar margem. */
.tasso-nav-perfil-foto img { width: 100%; height: 100%; object-fit: contain; padding: .18rem; }
.tasso-nav-perfil-txt { min-width: 0; line-height: 1.25; }
.tasso-nav-perfil-txt b {
    display: block; font-size: .78rem; font-weight: 700; color: var(--tasso-tinta);
    text-transform: uppercase; letter-spacing: .02em;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.tasso-nav-perfil-txt span { display: block; font-size: .7rem; color: var(--tasso-tinta-2); }

/* "Início" do cabeçalho: link de volta pra tela inicial.
 * Ícone + palavra, porque ícone sozinho não se anuncia como botão — foi
 * exatamente a queixa ("o botão de início tem que ser clicável"). */
.tasso-link-inicio {
    display: inline-flex; align-items: center; gap: .35rem; flex-shrink: 0;
    color: #1b1c1d; text-decoration: none; font-weight: 600; font-size: .85rem;
    padding: .25rem .5rem; border-radius: .5rem; transition: background .15s ease;
}
.tasso-link-inicio:hover { background: rgba(0, 0, 0, .05); color: #9c1917; }
.tasso-link-inicio:focus-visible { outline: 2px solid #9c1917; outline-offset: 2px; }
.tasso-link-inicio .material-symbols-outlined { font-size: 19px; }
html.dark .tasso-link-inicio { color: #f0f1f2; }
html.dark .tasso-link-inicio:hover { background: rgba(255, 255, 255, .08); color: #ff8a85; }

/* Botão de adicionar com rótulo, no lugar do "+" mudo.
 *
 * Continua redondo e só com o ícone no celular: lá o texto competiria com o
 * título da página pela mesma faixa. Da largura `sm` pra cima ele cresce numa
 * pílula e diz o que faz. */
.tasso-botao-novo {
    display: inline-flex; align-items: center; gap: .4rem;
    height: 38px; padding: 0; width: 38px; justify-content: center;
    border-radius: 999px; background: var(--tasso-vermelho, #9c1917); color: #fff;
    font-size: .82rem; font-weight: 600; text-decoration: none;
    transition: background .15s ease;
}
.tasso-botao-novo:hover { background: #7d1412; color: #fff; }
.tasso-botao-novo:focus-visible { outline: 2px solid #1b1c1d; outline-offset: 2px; }
.tasso-botao-novo .material-symbols-outlined { font-size: 20px; }
.tasso-botao-novo-texto { display: none; }

@media (min-width: 640px) {
    .tasso-botao-novo { width: auto; padding: 0 1rem 0 .8rem; }
    .tasso-botao-novo-texto { display: inline; white-space: nowrap; }
}

/* Prévia da foto no formulário de funcionário e de condomínio.
 *
 * `cover` aqui, ao contrário do avatar do menu lateral: a imagem já sai
 * quadrada de core/imagens.py (ImageOps.fit), então não há o que recortar
 * errado — e no formulário quem manda é ver a foto grande o bastante pra
 * conferir se é a certa. */
.tasso-foto-previa {
    width: 7rem; height: 7rem; object-fit: cover;
    border-radius: .75rem; border: 1px solid rgba(0, 0, 0, .1);
    background: #fff; display: block;
}
html.dark .tasso-foto-previa { border-color: rgba(255, 255, 255, .12); background: #24262a; }

/* Inline de Serviço da OS: cabeçalho de coluna fora.
 *
 * O inline ficou com uma coluna só, e o título do grupo (<h2>) já diz
 * "Serviço" — o <th> repetiria a palavra. O rótulo em branco vem do
 * OrdemServicoItemForm, mas sobra o asterisco de campo obrigatório, e um
 * asterisco vermelho sozinho num cabeçalho vazio é pior que o cabeçalho.
 *
 * UMA CLASSE, E NÃO O ID DO INLINE
 *
 * A primeira versão era `#itens-group thead`, e derrubou o cabeçalho de OUTRA
 * tela: o id do inline sai do `related_name` da chave estrangeira, e
 * `OrdemServicoItem` e `ContratoServicoItem` se chamam os dois `itens`. Os
 * Itens de serviço do contrato — que têm quatro colunas e precisam do
 * cabeçalho — ficaram com quatro campos sem nome nenhum em cima. Relatado
 * assim: *"no contratos, nos itens de serviço, tem campo sem dados"*.
 *
 * A classe é declarada no inline que quer o efeito (ordens_servico/admin.py),
 * então nenhuma outra tela pode ser atingida por coincidência de nome.
 *
 * Nada se perde aqui: o Unfold já nasce com `hidden lg:table-header-group`
 * nesse <thead>, ou seja, no celular ele nunca apareceu; quem nomeia a seção
 * é o <h2>. */
.tasso-inline-sem-cabecalho thead { display: none; }

/* O container do Unfold traz borda e fundo próprios que brigam com o relevo. */
#nav-sidebar, #nav-sidebar > div { border: 0 !important; background: #f5f3f4 !important; }

html.dark .tasso-nav {
    --tasso-soft-bg: #24262a;
    --tasso-soft-escuro: #1a1c1f;
    --tasso-soft-claro: #2e3136;
    --tasso-tinta: #f0f1f2;
    --tasso-tinta-2: #a8adb4;
    --tasso-vermelho: #ff8a85;
}
html.dark #nav-sidebar, html.dark #nav-sidebar > div { background: #24262a !important; }

@media (prefers-reduced-motion: reduce) {
    .tasso-nav-seta, .tasso-nav-cta, .tasso-nav-item { transition: none; }
}

/* A marca d'água do menu foi desligada quando a logomarca passou a ficar no
   topo da barra (layout "Soft 3D"): a mesma marca duas vezes na mesma coluna
   vira ruído, e ela vazava por cima dos cards de relevo. O bloco original
   continua acima, caso o layout antigo volte. */
#nav-sidebar::after { content: none !important; }

/* ==========================================================================
   Fundo bege único em todo o admin
   ==========================================================================

   O Unfold pinta `#main` de branco e o menu ficava bege, então o conteúdo
   aparecia como uma ilha clara com faixas brancas em volta (o `#content` é um
   `container` centralizado, o que deixa sobra nas laterais). Aqui o tom do
   menu passa a valer pra página inteira.

   Vale para TODAS as telas, não só o dashboard: listagem, formulário e
   relatório usam os mesmos containers. Os cards brancos do Unfold continuam
   brancos e agora têm sobre o que se destacar — antes eram branco sobre
   branco. */

body,
#page,
#main,
#content,
.tasso-dash {
    background-color: #f5f3f4 !important;
}

/* O cabeçalho fixo é parte da mesma superfície; com fundo próprio ele criava
   uma faixa de tom diferente no topo ao rolar a página. */
#main > header,
#main > header > div {
    background-color: #f5f3f4 !important;
}

/* Sem a margem negativa que existia pra "furar" o padding do container: com o
   fundo já correto por baixo, ela só deslocava o conteúdo. */
.tasso-dash {
    margin: 0;
    padding: 1.75rem 0 2.5rem;
}

html.dark body,
html.dark #page,
html.dark #main,
html.dark #content,
html.dark .tasso-dash,
html.dark #main > header,
html.dark #main > header > div {
    background-color: #24262a !important;
}

@media (max-width: 640px) {
    .tasso-dash { padding: 1.25rem 0 2rem; }
}

/* Cartões e células da listagem de Clientes (tela enviada, jul/2026). */

.tasso-kpis-lista {
    display: grid; grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
    gap: 1rem; margin-bottom: 1.25rem;
}
.tasso-kpi-lista {
    background: #f5f3f4; border-radius: 1.5rem; padding: 1.25rem 1.4rem;
    box-shadow: 8px 8px 16px #d1d9e6, -8px -8px 16px #ffffff;
    display: flex; flex-direction: column; gap: .9rem;
}
.tasso-kpi-lista-cab { display: flex; align-items: center; justify-content: space-between; gap: 1rem; }
.tasso-kpi-lista-nota {
    display: block; margin-top: .35rem; font-family: inherit;
    font-size: .78rem; font-weight: 400; letter-spacing: 0; color: #5f6368;
}

/* Nome em duas linhas: fantasia em cima, razão social embaixo. */
.tasso-cel-nome { display: block; font-weight: 600; }
.tasso-cel-sub { display: block; font-size: .78rem; color: #6b7280; margin-top: .1rem; }

.tasso-badge {
    display: inline-block; padding: .2rem .7rem; border-radius: 999px;
    font-family: "JetBrains Mono", ui-monospace, monospace;
    font-size: .68rem; font-weight: 600; letter-spacing: .06em; text-transform: uppercase;
    white-space: nowrap;
}
.tasso-badge--ativo    { background: #dcfce7; color: #146c37; }
.tasso-badge--atencao  { background: #fef3c7; color: #92610a; }
.tasso-badge--neutro   { background: #e8e9ea; color: #4b5157; }
.tasso-badge--rascunho { background: #dbeafe; color: #1e4b8f; }

html.dark .tasso-kpi-lista { background: #24262a; box-shadow: 8px 8px 16px #1a1c1f, -8px -8px 16px #2e3136; }
html.dark .tasso-kpi-lista-nota, html.dark .tasso-cel-sub { color: #a8adb4; }
html.dark .tasso-badge--ativo   { background: #14361f; color: #6ee7a0; }
html.dark .tasso-badge--atencao { background: #3a2c0a; color: #fcd34d; }
html.dark .tasso-badge--neutro  { background: #2c2f33; color: #b6bcc3; }
html.dark .tasso-badge--rascunho { background: #16294a; color: #93b8f0; }

/* Variantes das células de listagem (core/listagem.py). */

.tasso-cel-nome--normal { font-weight: 500; }
.tasso-cel-sub--destaque {
    color: #9c1917; font-weight: 600; text-transform: uppercase;
    font-size: .68rem; letter-spacing: .06em;
}
.tasso-cel-lista { display: block; font-size: .82rem; color: #4b5157; line-height: 1.45; }
.tasso-cel-mais {
    display: block; margin-top: .15rem; font-size: .72rem; font-weight: 600; color: #9c1917;
}
.tasso-cel-vazio { color: #9aa0a6; font-style: italic; }

/* Estado que exige ação: mesmo peso visual do alerta do dashboard. */
.tasso-badge--critico { background: #fde2e1; color: #9c1917; }

html.dark .tasso-cel-sub--destaque, html.dark .tasso-cel-mais { color: #ff8a85; }
html.dark .tasso-cel-lista { color: #b6bcc3; }
html.dark .tasso-cel-vazio { color: #7f8f86; }
html.dark .tasso-badge--critico { background: #3a1614; color: #ff8a85; }

/* ---------- Filtros recolhidos (templates/admin/filter.html) ---------- */

.tasso-filtro { border-bottom: 1px solid #e4e4e7; padding-bottom: .5rem; }
.tasso-filtro:last-of-type { border-bottom: 0; }

.tasso-filtro-titulo {
    display: flex; align-items: center; justify-content: space-between; gap: .5rem;
    cursor: pointer; list-style: none; padding: .45rem 0;
    font-weight: 600; font-size: .82rem; color: #1b1c1d;
}
/* O triângulo padrão do <summary> some nos dois motores; a seta é a nossa. */
.tasso-filtro-titulo::-webkit-details-marker { display: none; }
.tasso-filtro-titulo::marker { content: ""; }
.tasso-filtro-titulo:hover { color: #9c1917; }

/* O valor ativo escrito no título do filtro recolhido. É o que permite manter
 * tudo fechado sem esconder o que está filtrando: ocupa uma linha em vez das
 * dez que a lista aberta ocupava. Fica em bloco próprio (não inline no meio da
 * frase) pra não empurrar a seta pra fora quando o valor é longo. */
.tasso-filtro-valor {
    display: block; margin-top: .15rem;
    font-weight: 600; font-size: .72rem; color: #9c1917;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
html.dark .tasso-filtro-valor { color: #ff8a85; }
.tasso-filtro-titulo:focus-visible { outline: 2px solid #9c1917; outline-offset: 2px; border-radius: .3rem; }

.tasso-filtro-seta { font-size: 1.1rem !important; color: #6b7280; transition: transform .18s ease; }
.tasso-filtro[open] .tasso-filtro-seta { transform: rotate(180deg); }
.tasso-filtro-corpo { padding-top: .35rem; }

html.dark .tasso-filtro { border-color: #2f3237; }
html.dark .tasso-filtro-titulo { color: #f0f1f2; }
html.dark .tasso-filtro-titulo:hover { color: #ff8a85; }
html.dark .tasso-filtro-seta { color: #a8adb4; }

@media (prefers-reduced-motion: reduce) { .tasso-filtro-seta { transition: none; } }

/* ---------- Formulário: uma superfície só ---------- */
/*
 * Pedido do cliente: "eu não quero esse quadrado branco, quero tudo da mesma
 * cor". O Unfold desenha cada fieldset e cada inline como um cartão branco
 * sobre o fundo — com o fundo agora bege, cada bloco virava um retângulo
 * claro recortado. Os campos continuam brancos de propósito: é o que
 * distingue "onde eu escrevo" de "o que é só rótulo".
 */
/* O `:not(button)` precisa estar nos DOIS seletores.
 *
 * Ele foi acrescentado ao segundo e esquecido no primeiro, e o "Aplicar
 * filtros" pagou: o botão do Unfold nasce com `border-base-200 bg-primary-600
 * text-white`, casava com o primeiro seletor pela classe da BORDA, recebia
 * fundo #f5f3f4 e ficava com texto branco sobre quase-branco. Some da tela sem
 * sumir do HTML — o pior tipo de invisível, porque nada quebra e o botão
 * continua clicável para quem souber onde ele está.
 *
 * A regra existe para achatar os cartões do formulário, e botão não é cartão. */
#content .border-base-200:not(input):not(select):not(textarea):not(button),
#content [class*="bg-white"]:not(input):not(select):not(textarea):not(button) {
    background-color: #f5f3f4 !important;
}
#content input:not([type="checkbox"]):not([type="radio"]),
#content select,
#content textarea {
    background-color: #ffffff !important;
}
html.dark #content .border-base-200:not(input):not(select):not(textarea):not(button),
html.dark #content [class*="bg-white"]:not(input):not(select):not(textarea):not(button) {
    background-color: #24262a !important;
}
html.dark #content input:not([type="checkbox"]):not([type="radio"]),
html.dark #content select,
html.dark #content textarea {
    background-color: #1b1d20 !important;
}

/* Valores quitados do Fluxo de caixa: clicáveis, levam pra lista do mês.
 * Sublinhado pontilhado em vez de cor sozinha — num relatório cheio de
 * números, cor diferente se lê como "outro tipo de valor", não como link. */
.tasso-fluxo-link {
    color: inherit; text-decoration: underline;
    text-decoration-style: dotted; text-underline-offset: 3px;
}
.tasso-fluxo-link:hover { color: #9c1917; text-decoration-style: solid; }
.tasso-fluxo-link:focus-visible { outline: 2px solid #9c1917; outline-offset: 2px; }
html.dark .tasso-fluxo-link:hover { color: #ff8a85; }

/* Card de relatório — um cartão por relatório, no relevo do painel.
 * O alvo de toque passa a ser o cartão inteiro em vez de uma linha de texto,
 * que é o que muda no celular. */
 /* Seletor com as DUAS classes de propósito: existe um `a.tasso-soft
  * { display: block }` neste mesmo arquivo, e (0,1,1) ganha de (0,1,0).
  * Com `.tasso-soft.tasso-card-relatorio` a conta fica (0,2,0) e a ordem
  * das regras deixa de importar. Sem isso o cartão saía empilhado — ícone
  * numa linha, texto embaixo — e parecia erro de layout. */
.tasso-soft.tasso-card-relatorio {
    display: flex; align-items: center; gap: .85rem;
    padding: 1rem 1.1rem; text-decoration: none; min-width: 0;
    transition: transform .12s ease, box-shadow .12s ease;
}
.tasso-card-relatorio:hover { transform: translateY(-1px); }
.tasso-card-relatorio:focus-visible { outline: 2px solid var(--tasso-vermelho, #9c1917); outline-offset: 3px; }
.tasso-card-relatorio-icone {
    display: flex; align-items: center; justify-content: center; flex-shrink: 0;
    width: 2.5rem; height: 2.5rem; border-radius: .75rem;
    background: var(--tasso-soft-bg, #f5f3f4); color: var(--tasso-vermelho, #9c1917);
    box-shadow: inset 2px 2px 5px var(--tasso-soft-escuro, #e0dedf),
                inset -2px -2px 5px var(--tasso-soft-claro, #ffffff);
}
.tasso-card-relatorio-icone .material-symbols-outlined { font-size: 20px; }
.tasso-card-relatorio-texto {
    flex: 1 1 auto; min-width: 0; font-size: .9rem; font-weight: 600;
    color: var(--tasso-tinta, #1b1c1d); line-height: 1.3;
}
.tasso-card-relatorio-seta { flex-shrink: 0; color: var(--tasso-tinta-2, #6b7076); font-size: 20px; }
.tasso-card-relatorio:hover .tasso-card-relatorio-seta { color: var(--tasso-vermelho, #9c1917); }

@media (prefers-reduced-motion: reduce) {
    .tasso-card-relatorio { transition: none; }
    .tasso-card-relatorio:hover { transform: none; }
}

/* Avatar na célula de nome das listagens (condomínio e funcionário).
 * Sem foto entra um círculo com as iniciais em vez de um ícone genérico
 * repetido: o placeholder continua diferenciando uma linha da outra, que é a
 * função da coluna. */
.tasso-cel-com-foto { display: flex; align-items: center; gap: .7rem; min-width: 0; }
.tasso-cel-foto {
    width: 2.25rem; height: 2.25rem; border-radius: 999px; flex-shrink: 0;
    object-fit: contain; padding: .1rem; background: #fff;
    border: 1px solid rgba(0, 0, 0, .08);
}
.tasso-cel-foto--vazia {
    display: flex; align-items: center; justify-content: center;
    background: var(--tasso-soft-bg, #f5f3f4); color: var(--tasso-vermelho, #9c1917);
    font-size: .72rem; font-weight: 700; letter-spacing: .02em; padding: 0;
}
html.dark .tasso-cel-foto { background: #24262a; border-color: rgba(255, 255, 255, .12); }

/* Campo de foto: área de arrastar + o input de sempre.
 * A área é um <label> apontando pro input, então clicar nela abre o seletor de
 * arquivo sem uma linha de JS — o arrastar é que precisa de script. */
.tasso-foto-campo { display: flex; flex-direction: column; gap: .6rem; }
.tasso-foto-soltar {
    display: flex; align-items: center; gap: .85rem; cursor: pointer;
    padding: 1rem 1.1rem; border-radius: .9rem;
    border: 2px dashed rgba(0, 0, 0, .16); background: rgba(0, 0, 0, .015);
    transition: border-color .15s ease, background .15s ease;
}
.tasso-foto-soltar:hover { border-color: var(--tasso-vermelho, #9c1917); background: rgba(156, 25, 23, .04); }
.tasso-foto-soltar.arrastando {
    border-color: var(--tasso-vermelho, #9c1917); border-style: solid;
    background: rgba(156, 25, 23, .08);
}
.tasso-foto-soltar-icone { font-size: 30px; color: var(--tasso-vermelho, #9c1917); flex-shrink: 0; }
.tasso-foto-soltar-texto { display: flex; flex-direction: column; gap: .1rem; line-height: 1.35; min-width: 0; }
.tasso-foto-soltar-texto strong { font-size: .88rem; color: var(--tasso-tinta, #1b1c1d); }
.tasso-foto-soltar-texto span { font-size: .78rem; color: var(--tasso-tinta-2, #5f6368); }
.tasso-foto-previa-local {
    width: 3.5rem; height: 3.5rem; object-fit: cover; border-radius: .6rem;
    margin-left: auto; flex-shrink: 0; border: 1px solid rgba(0, 0, 0, .1);
}
.tasso-foto-atual-nome { font-size: .78rem; color: var(--tasso-tinta-2, #5f6368); }
.tasso-foto-limpar { display: inline-flex; align-items: center; gap: .3rem; margin-left: .6rem; }

html.dark .tasso-foto-soltar { border-color: rgba(255, 255, 255, .18); background: rgba(255, 255, 255, .03); }

/* O input de arquivo some da tela sem sair do documento: a área de soltar é um
 * <label for>, então o clique continua abrindo o seletor sem JS, o Tab continua
 * alcançando o campo e o leitor de tela continua anunciando. `display: none`
 * tiraria as três coisas. */
.tasso-foto-input {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0;
}
.tasso-foto-input:focus-visible + .tasso-foto-soltar,
.tasso-foto-soltar:has(+ .tasso-foto-input:focus-visible) {
    outline: 2px solid var(--tasso-vermelho, #9c1917); outline-offset: 3px;
}

/* Área de arrastar anexos, acima da tabela do inline.
 * Mesma linguagem visual do campo de foto — é a mesma ação, e o cliente pediu
 * justamente "igual o método da foto de perfil". A diferença é que aqui não há
 * <label for>: não existe um input único para apontar, porque cada arquivo
 * solto vira uma LINHA nova. Por isso ela não é clicável: quem quer escolher
 * pelo seletor usa o botão "Adicionar" logo abaixo, que já faz isso. */
.tasso-anexos-soltar {
    display: flex; align-items: center; gap: .85rem; flex-wrap: wrap;
    margin: 0 0 .9rem; padding: .9rem 1.1rem; border-radius: .9rem;
    border: 2px dashed rgba(0, 0, 0, .16); background: rgba(0, 0, 0, .015);
    transition: border-color .15s ease, background .15s ease;
}
.tasso-anexos-soltar.arrastando {
    border-color: var(--tasso-vermelho, #9c1917); border-style: solid;
    background: rgba(156, 25, 23, .08);
}
.tasso-anexos-soltar-icone { font-size: 28px; color: var(--tasso-vermelho, #9c1917); flex-shrink: 0; }
.tasso-anexos-soltar-texto { display: flex; flex-direction: column; gap: .1rem; line-height: 1.35; min-width: 0; }
.tasso-anexos-soltar-texto strong { font-size: .88rem; color: var(--tasso-tinta, #1b1c1d); }
.tasso-anexos-soltar-texto span { font-size: .78rem; color: var(--tasso-tinta-2, #5f6368); }
/* Recado de arquivo recusado: largura inteira para não espremer o texto ao lado
 * do ícone, e some sozinho quando a próxima soltada dá certo. */
.tasso-anexos-recado {
    flex-basis: 100%; margin: .2rem 0 0; padding-left: 1.1rem;
    font-size: .78rem; color: var(--tasso-vermelho, #9c1917);
}
html.dark .tasso-anexos-soltar { border-color: rgba(255, 255, 255, .18); background: rgba(255, 255, 255, .03); }
html.dark .tasso-anexos-soltar-texto strong { color: #e8eaed; }

/* ==========================================================================
   Cards de número e tabelas de resumo (Financeiro)
   ==========================================================================

   Mesma linguagem dos cards de relatório — relevo `.tasso-soft`, sem borda —,
   só que o conteúdo é um valor e não um destino. Quando o card é clicável ele
   é um <a>, e aí `a.tasso-soft` já dá o hover/foco; quando é só leitura é uma
   <div>, e nada muda visualmente de propósito: o que muda é o cursor.

   `.tasso-soft.tasso-card-numero` (dois seletores) pelo mesmo motivo do card
   de relatório: `a.tasso-soft { display:block }` tem especificidade (0,1,1) e
   venceria um `.tasso-card-numero` sozinho (0,1,0) — o flex-column não pegaria
   e o rótulo, o valor e a nota sairiam empilhados sem espaçamento nenhum. */
.tasso-soft.tasso-card-numero {
    display: flex; flex-direction: column; gap: .3rem;
    padding: 1.1rem 1.25rem; text-decoration: none; min-width: 0;
}
.tasso-card-numero-rotulo {
    font-size: .75rem; font-weight: 600; letter-spacing: .04em;
    text-transform: uppercase; color: var(--tasso-tinta-2, #6b7076);
}
.tasso-card-numero-valor {
    font-size: 1.45rem; font-weight: 700; line-height: 1.15;
    color: var(--tasso-tinta, #1b1c1d);
}
.tasso-card-numero-valor.tasso-negativo { color: #9c1917; }
.tasso-card-numero-nota { font-size: .75rem; color: var(--tasso-tinta-2, #6b7076); }
html.dark .tasso-card-numero-valor.tasso-negativo { color: #ff8a85; }

/* A tabela do resumo dentro do relevo: sem bordas externas (o relevo já é a
   moldura), só a linha divisória entre registros. */
.tasso-resumo-tabela { padding: 1.1rem 1.25rem; }
.tasso-resumo-tabela table { width: 100%; font-size: .85rem; border-collapse: collapse; }
.tasso-resumo-tabela th {
    text-align: left; font-weight: 600; font-size: .72rem; letter-spacing: .04em;
    text-transform: uppercase; color: var(--tasso-tinta-2, #6b7076);
    padding: 0 .5rem .55rem; white-space: nowrap;
}
.tasso-resumo-tabela td {
    padding: .55rem .5rem; color: var(--tasso-tinta, #1b1c1d);
    border-top: 1px solid rgba(0, 0, 0, .07);
}
.tasso-resumo-tabela .tasso-col-num { text-align: right; white-space: nowrap; }
.tasso-resumo-rodape { margin-top: .9rem; font-size: .8rem; }
.tasso-resumo-rodape a { color: var(--tasso-vermelho, #9c1917); font-weight: 600; }
.tasso-resumo-rodape a:hover { text-decoration: underline; }
html.dark .tasso-resumo-tabela td { border-color: rgba(255, 255, 255, .1); }

/* Aviso da ponte com o Painel Predial: bloco de texto no relevo do painel, em
   vez do estilo de mensagem do admin — a tela inteira é de cards, e uma faixa
   amarela do Django no meio destoaria. */
.tasso-aviso-ponte { padding: 1.25rem 1.4rem; font-size: .88rem; line-height: 1.5; }
.tasso-aviso-ponte p + p { margin-top: .6rem; }
.tasso-aviso-ponte code {
    background: rgba(0, 0, 0, .06); border-radius: .3rem;
    padding: .1rem .35rem; font-size: .85em;
}
html.dark .tasso-aviso-ponte code { background: rgba(255, 255, 255, .1); }

/* Grade dos cards — CSS puro, e não as classes responsivas do Tailwind.
 *
 * Motivo concreto: o Tailwind do Unfold vem COMPILADO no pacote, e as variantes
 * `sm:grid-cols-*` simplesmente não existem no arquivo (só `xl:` em diante).
 * A tela de Relatórios usava `sm:grid-cols-2 xl:grid-cols-3` e, entre 640px e
 * 1280px, caía em UMA coluna — cada card esticado na largura inteira. Não
 * quebrava nada, então passou despercebido.
 *
 * `auto-fit` + `minmax` resolve sem depender de recompilar nada e sem escolher
 * pontos de quebra: a grade acomoda quantos cards couberem com a largura mínima.
 */
.tasso-grade-cards {
    display: grid; gap: 1rem;
    grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
}
.tasso-grade-numeros {
    display: grid; gap: 1rem;
    grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
}
/* Duas colunas de tabela lado a lado quando cabe; empilhadas quando não. */
.tasso-grade-colunas {
    display: grid; gap: 1.5rem;
    grid-template-columns: repeat(auto-fit, minmax(26rem, 1fr));
}

/* Relatório de contas e acessos. As duas listas longas (condomínios e módulos)
 * ficam em corpo menor e cinza: a informação que se procura na tabela é o
 * PAPEL e o alerta; as listas são consulta, não varredura. */
.tasso-contas-email { font-size: .78rem; color: var(--tasso-tinta-2, #6b7076); }
.tasso-contas-lista { font-size: .78rem; line-height: 1.5; color: var(--tasso-tinta-2, #6b7076); }
.tasso-contas-nota { font-size: .75rem; color: var(--tasso-tinta-2, #6b7076); }
.tasso-resumo-tabela td { vertical-align: top; }

/* Assistente de novo condomínio (cadastros/assistente.py). Tela própria, fora
 * do changeform do admin — então nada aqui herda estilo do Unfold, igual às
 * telas de relatório. A largura é limitada de propósito: um passo de 4 campos
 * esticado em 1600px lê pior do que a ficha inteira. */
.tasso-assistente { max-width: 46rem; }

.tasso-assistente-trilha {
    display: flex; flex-wrap: wrap; gap: .4rem 1.4rem;
    margin: 0 0 1.25rem; padding: 0; list-style: none;
}
.tasso-assistente-passo {
    display: flex; align-items: center; gap: .5rem;
    font-size: .8rem; font-weight: 600; color: var(--tasso-tinta-2, #6b7076);
}
.tasso-assistente-bolha {
    display: inline-flex; align-items: center; justify-content: center;
    width: 1.6rem; height: 1.6rem; border-radius: 999px;
    border: 1px solid var(--color-base-200); background: #fff;
    font-size: .78rem; line-height: 1;
}
.tasso-assistente-bolha .material-symbols-outlined { font-size: 1rem; }
.tasso-assistente-passo--atual { color: var(--tasso-vermelho, #9c1917); }
.tasso-assistente-passo--atual .tasso-assistente-bolha {
    border-color: var(--color-primary-600); background: var(--color-primary-600); color: #fff;
}
.tasso-assistente-passo--feito .tasso-assistente-bolha {
    border-color: var(--color-primary-600); color: var(--color-primary-600);
}

.tasso-assistente-cartao { padding: 1.5rem; }
.tasso-assistente-titulo { margin: 0; font-size: 1rem; font-weight: 600; }
.tasso-assistente-ajuda {
    margin: .4rem 0 0; font-size: .85rem; line-height: 1.5;
    color: var(--tasso-tinta-2, #6b7076);
}
.tasso-assistente-nota {
    margin: 1.25rem 0 0; font-size: .82rem; line-height: 1.5;
    color: var(--tasso-tinta-2, #6b7076);
}

/* `auto-fill`, e não `auto-fit`: com um campo só (o passo 4 tem exatamente um),
 * o `auto-fit` recolhe as colunas vazias e estica aquele campo pela largura
 * inteira do cartão — um <select> de 700px para escolher entre três opções. O
 * `auto-fill` mantém as colunas, e o campo fica do tamanho dos outros. */
.tasso-assistente-campos {
    display: grid; gap: 1rem; margin-top: 1.25rem;
    grid-template-columns: repeat(auto-fill, minmax(13rem, 1fr));
}
.tasso-assistente-campo { display: flex; flex-direction: column; gap: .35rem; min-width: 0; }
.tasso-assistente-campo label { font-size: .8125rem; font-weight: 600; }
.tasso-assistente-campo .tasso-input,
.tasso-assistente-campo .tasso-select { width: 100%; }
/* O botão "Buscar CNPJ" é criado pelo JS (static/js/tasso-busca-cnpj.js) logo
 * depois do campo, ou seja, dentro desta coluna flex — que estica os filhos por
 * padrão. Sem o `flex-start` ele saía com a largura inteira da coluna, do
 * tamanho do próprio campo de CNPJ. */
.tasso-assistente-campo .tasso-botao-buscar-cnpj { align-self: flex-start; }
.tasso-assistente-dica, .tasso-assistente-erro { font-size: .78rem; line-height: 1.4; }
.tasso-assistente-dica { color: var(--tasso-tinta-2, #6b7076); }
.tasso-assistente-erro { color: #dc2626; font-weight: 600; }

/* Lista de funcionários (passo 3) e qualquer outro campo que precise da linha
 * inteira: a grade acima é de campos curtos, e uma lista de 20 nomes espremida
 * em 13rem vira coluna de rolagem. */
.tasso-assistente-campo:has(.tasso-assistente-marcar) { grid-column: 1 / -1; }
/* O CheckboxSelectMultiple do Django repete a classe do widget no container E
 * em cada <input>; `div.` desempata, senão as regras de caixa cairiam também
 * sobre as caixinhas. Onze funcionários numa coluna só viram uma lista de
 * rolagem — em colunas cabem numa olhada. */
div.tasso-assistente-marcar {
    display: grid; gap: .1rem .75rem;
    grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
}
div.tasso-assistente-marcar > div { min-width: 0; }
div.tasso-assistente-marcar label {
    display: flex; align-items: center; gap: .45rem;
    font-size: .85rem; font-weight: 400; padding: .18rem 0;
}
div.tasso-assistente-marcar input { margin: 0; flex: none; }

.tasso-assistente-acoes {
    display: flex; flex-wrap: wrap; align-items: center; gap: .75rem;
    margin-top: 1.5rem; padding-top: 1.25rem;
    border-top: 1px solid var(--color-base-200);
}
.tasso-assistente-acoes-fim { display: flex; gap: .75rem; margin-left: auto; }
.tasso-assistente-cancelar { color: var(--tasso-tinta-2, #6b7076) !important; }

html.dark .tasso-assistente-bolha { background: transparent; border-color: rgba(255, 255, 255, .18); }
html.dark .tasso-assistente-acoes { border-color: rgba(255, 255, 255, .12); }

/* Modelo de análise — largura das colunas do checklist.
 *
 * A coluna "Ordem" guarda um número de um ou dois dígitos e vinha com o mesmo
 * peso da coluna do documento, que é onde mora o texto longo. O resultado era
 * um campo de 400px para digitar "3" e "Termo de responsabilidade de
 * solicitação de análise de reforma" cortado no meio.
 *
 * Escopado pela classe que o Django põe no <body> (model-modeloanalise) porque
 * `field-ordem` é um nome genérico: outro inline com um campo chamado `ordem`
 * herdaria esta largura sem ninguém pedir. Em telas estreitas o Unfold troca a
 * <td> de `table-cell` para `flex`, e aí a largura é ignorada — que é o
 * comportamento certo, cada campo em uma linha. */
body.model-modeloanalise td.field-ordem,
body.model-modeloanalise th.field-ordem { width: 7rem; }
body.model-modeloanalise td.field-situacao_inicial,
body.model-modeloanalise th.field-situacao_inicial { width: 15rem; }
body.model-modeloanalise td.field-ordem input,
body.model-modeloanalise td.field-nome input { width: 100%; }

/* Pílulas de escolha do checklist da obra — entrega e parecer.
 *
 * São RadioSelect, e o padrão do Django empilha uma opção por linha: seis
 * linhas por documento, vinte documentos, e a tabela vira uma coluna de
 * rolagem. Aqui elas ficam lado a lado e viram botões — o pedido foi "um botão
 * para eu escolher".
 *
 * Botão, e não caixa de marcar, também por um motivo que não é estética: a
 * caixa tem dois estados e três significados — desmarcada é "não entregou" ou
 * "ainda não conferi"? "Não entregue" é um fato que a análise AFIRMA, e um fato
 * afirmado não pode depender de uma caixa que ficou em branco.
 *
 * O <input> continua no DOM (só escondido do olho, não do leitor de tela nem do
 * teclado): `display:none` tiraria o campo da navegação por Tab e do foco. */
.tasso-pilulas { display: flex; flex-wrap: wrap; gap: .3rem; margin: 0; padding: 0; }
.tasso-pilulas > div { margin: 0; }
.tasso-pilulas input[type="radio"] {
    position: absolute; opacity: 0; width: 1px; height: 1px; margin: 0;
}
.tasso-pilulas label {
    display: inline-flex; align-items: center; cursor: pointer;
    padding: .22rem .6rem; border-radius: 999px;
    border: 1px solid var(--color-base-200);
    font-size: .75rem; font-weight: 600; line-height: 1.2; white-space: nowrap;
    color: var(--tasso-tinta-2, #6b7076); background: #fff;
}
.tasso-pilulas label:hover { border-color: var(--color-base-300); }
.tasso-pilulas label:focus-within { outline: 2px solid var(--color-primary-600); outline-offset: 1px; }

/* Escolhido — com `:has()`, e não com o irmão `input:checked + label`.
 *
 * O RadioSelect do Django põe o <input> DENTRO do <label> (`wrap_label`), então
 * eles nunca são irmãos e o seletor de irmão adjacente não casa nunca. A
 * primeira versão disto estava assim e falhava em silêncio: as pílulas
 * apareciam, clicavam, gravavam — e não mudavam de cor. Só apareceu ao olhar a
 * captura de tela.
 *
 * Os seletores por `value` amarram a COR ao significado, não à posição na
 * lista: acrescentar uma opção no meio não repinta as outras. */
.tasso-pilulas label:has(input:checked) { border-color: currentColor; }
.tasso-pilulas label:has(input[value="APROVADO"]:checked),
.tasso-pilulas label:has(input[value="ENTREGUE"]:checked) {
    color: #14622e; background: #e8f5ec;
}
.tasso-pilulas label:has(input[value="NEGADO"]:checked),
.tasso-pilulas label:has(input[value="NAO_ENTREGUE"]:checked) {
    color: #9c1917; background: #fdeaea;
}
.tasso-pilulas label:has(input[value="NAO_SE_APLICA"]:checked) {
    color: #4b5563; background: #e9ebee;
}
.tasso-pilulas label:has(input[value=""]:checked) {
    color: var(--tasso-tinta, #1b1c1d); background: var(--color-base-100, #eceef1);
}

html.dark .tasso-pilulas label {
    background: transparent; border-color: rgba(255, 255, 255, .18);
}
html.dark .tasso-pilulas label:has(input[value="APROVADO"]:checked),
html.dark .tasso-pilulas label:has(input[value="ENTREGUE"]:checked) {
    color: #6ee7a0; background: rgba(20, 98, 46, .25);
}
html.dark .tasso-pilulas label:has(input[value="NEGADO"]:checked),
html.dark .tasso-pilulas label:has(input[value="NAO_ENTREGUE"]:checked) {
    color: #fca5a5; background: rgba(156, 25, 23, .25);
}
html.dark .tasso-pilulas label:has(input[value="NAO_SE_APLICA"]:checked) {
    color: #d1d5db; background: rgba(255, 255, 255, .14);
}
html.dark .tasso-pilulas label:has(input[value=""]:checked) {
    color: #f0f1f2; background: rgba(255, 255, 255, .12);
}

/* Larguras do checklist da obra — mesma razão do checklist do modelo: sem isto
 * as quatro colunas dividem o espaço em partes iguais e o nome do documento,
 * que é a única coluna com texto longo, fica cortado. */
body.model-obra td.field-entrega,
body.model-obra th.field-entrega { width: 13rem; }
/* São quatro pílulas ("Não avaliado", "Aprovado", "Negado", "Não se aplica") e
 * elas precisam caber numa linha: quebradas em duas, a de baixo parece
 * pertencer à linha seguinte da tabela. */
body.model-obra td.field-parecer,
body.model-obra th.field-parecer { width: 24rem; }
body.model-obra td.field-observacao,
body.model-obra th.field-observacao { width: 16rem; }
body.model-obra td.field-observacao input { width: 100%; }
/* Na tela de CRIAR o nome vem de um widget próprio (texto + campo escondido) em
 * vez de um <input readonly>: numa linha só o texto cortava no meio — "Termo de
 * responsabilidade de solicitação de análise de r". Como span, quebra. */
body.model-obra .tasso-doc-nome { display: block; line-height: 1.35; }

/* Perfil + sair, no pé do menu.
 *
 * O botão de sair não existia em lugar nenhum do painel: quem quisesse trocar
 * de conta tinha que digitar /admin/logout/ na barra de endereço. Fica ao lado
 * do perfil porque é ali que se procura — é o bloco que responde "quem sou eu
 * aqui dentro", e sair é a outra metade dessa pergunta.
 *
 * `min-width: 0` no link do perfil: sem isso o nome longo empurra o botão para
 * fora do menu em vez de ser cortado por `text-overflow`. */
.tasso-nav-conta { display: flex; align-items: center; gap: .4rem; }
.tasso-nav-conta .tasso-nav-perfil { flex: 1; min-width: 0; }

/* Linha própria, abaixo do perfil, e não um ícone espremido ao lado dele: na
 * primeira versão o botão comia a largura do nome e "MAICON TASSO" virava
 * "MAICON TAS…". O nome é a informação que responde "estou logado como quem?",
 * e cortá-la para caber um botão troca uma resposta por um enfeite. */
.tasso-nav-sair-form { margin: 0; }
.tasso-nav-sair {
    display: flex; align-items: center; gap: .6rem; width: 100%;
    padding: .5rem .6rem; border-radius: .8rem;
    background: none; border: 1px solid transparent; cursor: pointer;
    color: var(--tasso-tinta-2); font-size: .82rem; font-weight: 600;
    font-family: inherit; text-align: left;
    transition: color .15s ease, background .15s ease;
}
.tasso-nav-sair .material-symbols-outlined { font-size: 1.2rem; flex-shrink: 0; }
.tasso-nav-sair:hover { color: var(--tasso-vermelho, #9c1917); background: rgba(0, 0, 0, .05); }
.tasso-nav-sair:focus-visible { outline: 2px solid var(--tasso-vermelho, #9c1917); outline-offset: 2px; }
html.dark .tasso-nav-sair:hover { color: #ff8a85; background: rgba(255, 255, 255, .08); }

/* ---------- Painel de obras (obras/templates/admin/obras/painel.html) ------

O quadro "tipo tabela periódica": uma célula por unidade, agrupada por torre,
pintada pelo que exige ação. As três cores são as que o cliente pediu, no
formato dos cartões da referência que ele enviou — fundo cheio, texto branco,
canto arredondado — "porém pequeno".

Fundo cheio e não pastel: a grade é para ser lida de relance, de longe, e um
tom claro com texto escuro exige focar em cada célula para distinguir amarelo
de verde. */

/* -- topo: escolher o condomínio ------------------------------------------ */

/* O seletor é o primeiro passo do fluxo ("em cima eu seleciono qual o
   condomínio"), então ele é grande e sozinho na faixa — e não mais um campo
   dentro de um bloco de filtros como nos relatórios. */
.tasso-painel-topo {
    display: flex; align-items: center; gap: .8rem; flex-wrap: wrap;
    margin-bottom: 1.5rem;
}
.tasso-painel-topo label {
    font-size: .78rem; font-weight: 600; letter-spacing: .04em;
    text-transform: uppercase; color: var(--tasso-tinta-2, #6b7076);
}
.tasso-painel-select { min-width: 20rem; font-size: .95rem; padding: .6rem .8rem; }
.tasso-painel-topo .tasso-botao-secundario { margin-left: auto; }

/* Trocar o condomínio já recarrega (onchange no <select>), então o botão só
   serve a quem está sem JS ou navegando por teclado. Fica acessível e fora do
   caminho: some visualmente, continua no DOM e volta ao receber foco. */
.tasso-painel-so-sem-js {
    position: absolute; width: 1px; height: 1px; overflow: hidden;
    clip: rect(0 0 0 0); white-space: nowrap;
}
.tasso-painel-so-sem-js:focus {
    position: static; width: auto; height: auto; overflow: visible; clip: auto;
}

/* -- números do topo ------------------------------------------------------ */

.tasso-painel-numeros {
    display: grid; gap: .8rem; margin-bottom: 1.2rem;
    grid-template-columns: repeat(auto-fill, minmax(10rem, 1fr));
}
.tasso-painel-numero {
    display: flex; align-items: center; justify-content: space-between; gap: .6rem;
    padding: .7rem 1rem; border-radius: .9rem;
    background: var(--tasso-superficie, #f2f3f5);
}
.tasso-painel-numero-rotulo {
    font-size: .72rem; font-weight: 600; letter-spacing: .04em; text-transform: uppercase;
}
.tasso-painel-numero-valor { font-size: 1.5rem; font-weight: 700; line-height: 1; }

/* -- legenda -------------------------------------------------------------- */

/* A legenda fica SEMPRE visível, e não num "?" que se abre: a cor só é mais
   rápida que a palavra depois que a pessoa aprendeu o código, e ela aprende
   lendo isto sem procurar. */
.tasso-painel-legenda {
    display: flex; flex-wrap: wrap; gap: .4rem 1.4rem; margin-bottom: 2rem;
    font-size: .8rem; color: var(--tasso-tinta-2, #6b7076);
}
.tasso-painel-legenda-item { display: flex; align-items: center; gap: .45rem; }
.tasso-painel-legenda-item strong { color: var(--tasso-tinta, #1b1c1d); }
.tasso-painel-amostra {
    width: .9rem; height: .9rem; border-radius: .25rem; flex: none;
}

/* -- o quadro ------------------------------------------------------------- */

.tasso-painel-condominio { margin-bottom: 2.5rem; }
.tasso-painel-contagem {
    margin-left: auto; font-size: .78rem; font-weight: 500;
    color: var(--tasso-tinta-2, #6b7076); text-transform: none; letter-spacing: 0;
}

/* As torres de um condomínio fluem lado a lado. Uma por linha desperdiçava a
   tela inteira onde a torre tem uma unidade só — no Campos do Coxipó, dois
   cartões ocupavam duas faixas cheias e empurravam o condomínio seguinte para
   fora da vista. `align-items: flex-start` para que uma torre alta não estique
   as vizinhas. */
.tasso-painel-torres {
    display: flex; flex-wrap: wrap; gap: .2rem 2rem; align-items: flex-start;
}
.tasso-painel-torre { margin: .9rem 0 1.3rem; }
.tasso-painel-torre-nome {
    font-size: .74rem; font-weight: 700; letter-spacing: .07em; text-transform: uppercase;
    color: var(--tasso-tinta-2, #6b7076); margin-bottom: .45rem;
}

/* `auto-fill` e não `auto-fit`: com poucas unidades numa torre, `auto-fit`
   recolhe as colunas vazias e ESTICA as células que sobraram — uma torre com
   dois apartamentos viraria dois retângulos gigantes, e o quadro perde a
   comparação visual entre torres. */
.tasso-painel-grade {
    display: grid; gap: .45rem;
    grid-template-columns: repeat(auto-fill, minmax(4.4rem, 1fr));
}

/* Dentro do container que flui, a grade deixa de ser `grid` e vira `flex`.
   `auto-fill` precisa de uma largura de container para calcular quantas
   colunas cabem, e um item de flex tem a largura do próprio conteúdo — a
   conta fica circular e o grid resolve para UMA coluna, empilhando os cartões
   em fila indiana. Foi o que aconteceu na primeira tentativa. Com flex, a
   torre ocupa a largura dos cartões que tem e as vizinhas se acomodam ao
   lado. */
.tasso-painel-torres .tasso-painel-grade {
    display: flex; flex-wrap: wrap; gap: .45rem;
}
.tasso-painel-torres .tasso-painel-cel { width: 4.4rem; }
/* Torre grande volta a usar a largura toda: com dez ou mais unidades, espremer
   a grade ao lado de outra torre faz a leitura em linha se perder. */
.tasso-painel-torres .tasso-painel-torre--larga { flex: 1 1 100%; }

.tasso-painel-cel {
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    min-height: 3.9rem; padding: .35rem .3rem; border-radius: .6rem;
    text-decoration: none; text-align: center; line-height: 1.1;
    box-shadow: 0 1px 2px rgba(0, 0, 0, .12);
    transition: transform .12s ease, box-shadow .12s ease;
}
.tasso-painel-cel:hover {
    transform: translateY(-2px); box-shadow: 0 4px 10px rgba(0, 0, 0, .18); color: #fff;
}
.tasso-painel-cel:focus-visible { outline: 2px solid var(--tasso-tinta, #1b1c1d); outline-offset: 2px; }
.tasso-painel-cel-unidade { font-size: .95rem; font-weight: 700; }
/* A nota vive baixa de propósito: ela é o detalhe ("3 doc"), não o dado que se
   procura na grade, que é o número da unidade. */
.tasso-painel-cel-nota { font-size: .62rem; opacity: .9; margin-top: .1rem; }

.tasso-painel-vazio { padding: 2rem 1.5rem; text-align: center; }
.tasso-painel-vazio p { margin: 0; }
.tasso-painel-vazio-nota {
    margin-top: .6rem !important; font-size: .82rem;
    color: var(--tasso-tinta-2, #6b7076);
}

/* As três cores vêm DEPOIS de tudo que declara fundo neste bloco, e não antes:
   `.tasso-painel-numero` também define `background`, e com a mesma
   especificidade (0,1,0) vence quem vem por último. Declaradas em cima, os
   cartões coloridos saíam com fundo claro e texto branco — ilegíveis, e só na
   captura de tela dava para ver. */
.tasso-cor--verde    { background: linear-gradient(135deg, #2fbf85, #23a06d); }
.tasso-cor--amarelo  { background: linear-gradient(135deg, #f7b955, #eda033); }
.tasso-cor--vermelho { background: linear-gradient(135deg, #f4645f, #de3b3b); }
.tasso-cor--verde, .tasso-cor--amarelo, .tasso-cor--vermelho { color: #fff; }

html.dark .tasso-painel-numero { background: #24262a; }
html.dark .tasso-painel-topo label,
html.dark .tasso-painel-legenda,
html.dark .tasso-painel-torre-nome,
html.dark .tasso-painel-contagem,
html.dark .tasso-painel-vazio-nota { color: #a8adb4; }
html.dark .tasso-painel-legenda-item strong { color: #e8e9ea; }

/* ---------- Resumo da unidade (obras/.../_resumo_obra.html) ----------------

Aberto ao clicar numa célula do painel: "um resumo do tipo do documento de
impressão e com um botão para editar". O visual segue a folha impressa — faixas
de seção, lista de documentos, observações — sem virar uma cópia dela: aqui é
tela, então cabe o botão de ação, que no papel não faria sentido. */

.tasso-resumo-overlay {
    position: fixed; inset: 0; z-index: 100;
    background: rgba(20, 22, 25, .55);
    display: flex; align-items: flex-start; justify-content: center;
    padding: 3rem 1rem; overflow-y: auto;
}
.tasso-resumo-janela {
    position: relative; width: 100%; max-width: 46rem;
    background: #fff; border-radius: 1rem; padding: 2rem 2.2rem;
    box-shadow: 0 18px 50px rgba(0, 0, 0, .3);
}
.tasso-resumo-fechar {
    position: absolute; top: .7rem; right: .9rem;
    background: none; border: none; cursor: pointer;
    font-size: 1.6rem; line-height: 1; color: var(--tasso-tinta-2, #6b7076);
}
.tasso-resumo-fechar:hover { color: var(--tasso-vermelho, #9c1917); }

.tasso-resumo-voltar { margin-bottom: 1.2rem; font-size: .85rem; }

/* O bloco do resumo em si, usado igual na janela e na página inteira. */
.tasso-resumo-topo {
    display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem;
    border-bottom: 2px solid var(--tasso-tinta, #1b1c1d); padding-bottom: .8rem;
    margin-bottom: 1.2rem;
}
.tasso-resumo-condominio {
    font-size: .78rem; font-weight: 600; letter-spacing: .05em; text-transform: uppercase;
    color: var(--tasso-tinta-2, #6b7076);
}
.tasso-resumo-unidade { font-size: 1.5rem; font-weight: 700; line-height: 1.2; }

.tasso-resumo-grade {
    display: grid; gap: .8rem 1.5rem; margin-bottom: 1.5rem;
    grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr));
}
.tasso-resumo-rotulo {
    display: block; font-size: .68rem; font-weight: 600; letter-spacing: .07em;
    text-transform: uppercase; color: var(--tasso-tinta-2, #6b7076);
}
.tasso-resumo-valor { display: block; font-size: .95rem; font-weight: 600; }

/* Faixa escura, igual à do documento impresso: é o que faz o resumo ser
   reconhecido como "a mesma folha" por quem já usa o PDF todo dia. */
.tasso-resumo-secao-titulo {
    background: #2b2b2b; color: #fff; padding: .4rem .8rem; border-radius: .35rem;
    font-size: .78rem; font-weight: 700; letter-spacing: .03em;
    margin: 1.4rem 0 .8rem;
}

.tasso-resumo-docs { list-style: none; margin: 0; padding: 0; font-size: .88rem; }
.tasso-resumo-docs li {
    padding: .45rem 0; border-bottom: 1px solid rgba(0, 0, 0, .07);
}
.tasso-resumo-docs li:last-child { border-bottom: none; }
.tasso-resumo-doc-nome { display: block; }
.tasso-resumo-doc-sit {
    display: block; font-size: .78rem; font-weight: 600;
    color: var(--tasso-tinta-2, #6b7076);
}
.tasso-resumo-doc-obs {
    display: block; font-size: .78rem; font-style: italic;
    color: var(--tasso-tinta-2, #6b7076); margin-top: .15rem;
}

.tasso-resumo-observacoes { font-size: .9rem; line-height: 1.55; white-space: pre-line; }
.tasso-resumo-vazio { color: var(--tasso-tinta-2, #6b7076); font-style: italic; }

.tasso-resumo-assinatura {
    margin-top: 1.5rem; padding-top: .5rem; text-align: center;
    border-top: 1px solid rgba(0, 0, 0, .12); font-size: .82rem;
    color: var(--tasso-tinta-2, #6b7076);
}

.tasso-resumo-acoes {
    display: flex; flex-wrap: wrap; gap: .7rem;
    margin-top: 1.8rem; padding-top: 1.2rem;
    border-top: 1px solid rgba(0, 0, 0, .1);
}

html.dark .tasso-resumo-janela { background: #24262a; }
html.dark .tasso-resumo-condominio,
html.dark .tasso-resumo-doc-sit,
html.dark .tasso-resumo-doc-obs,
html.dark .tasso-resumo-vazio,
html.dark .tasso-resumo-assinatura,
html.dark .tasso-resumo-rotulo { color: #a8adb4; }
html.dark .tasso-resumo-topo { border-bottom-color: #e8e9ea; }
html.dark .tasso-resumo-docs li { border-bottom-color: rgba(255, 255, 255, .1); }

/* As cores da análise no resumo da unidade — mesmos tons da folha impressa
   (obras/templates/admin/obras/imprimir_analise.html), para o resumo na tela e
   o PDF na mão da pessoa dizerem a mesma coisa com a mesma cor.

   Pedido do cliente: "ajuste para que as letras dos documentos exigidos sigam
   as cores da análise, verde, vermelho". Antes tudo saía em cinza, e a linha
   "Entregue · Negado" tinha o mesmo peso visual de "Entregue · Aprovado". */
.tasso-sit { font-weight: 700; }
.tasso-sit--ENTREGUE,
.tasso-sit--APROVADO      { color: #14622e; }
.tasso-sit--NAO_ENTREGUE,
.tasso-sit--NEGADO        { color: #9c1917; }
.tasso-sit--PENDENTE      { color: #8a5a00; }
.tasso-sit--DISPENSADO,
.tasso-sit--NAO_SE_APLICA { color: #666; }

html.dark .tasso-sit--ENTREGUE,
html.dark .tasso-sit--APROVADO      { color: #6ee7a0; }
html.dark .tasso-sit--NAO_ENTREGUE,
html.dark .tasso-sit--NEGADO        { color: #ff8a85; }
html.dark .tasso-sit--PENDENTE      { color: #fcd34d; }
html.dark .tasso-sit--DISPENSADO,
html.dark .tasso-sit--NAO_SE_APLICA { color: #a8adb4; }

/* ---------- Olho de "mostrar senha" (static/js/tasso-ver-senha.js) --------- */

.tasso-campo-senha { position: relative; display: block; }
/* `padding-right` no input para o texto da senha não passar por baixo do
   botão — sem isso uma senha longa fica escondida atrás do próprio olho. */
.tasso-campo-senha input { padding-right: 2.6rem !important; width: 100%; }
.tasso-olho {
    position: absolute; top: 50%; right: .5rem; transform: translateY(-50%);
    display: flex; align-items: center; justify-content: center;
    width: 1.9rem; height: 1.9rem; padding: 0;
    background: none; border: none; cursor: pointer;
    color: var(--tasso-tinta-2, #6b7076); border-radius: .4rem;
}
.tasso-olho:hover { color: var(--tasso-vermelho, #9c1917); background: rgba(0, 0, 0, .05); }
.tasso-olho:focus-visible { outline: 2px solid var(--tasso-vermelho, #9c1917); outline-offset: 1px; }
.tasso-olho .material-symbols-outlined { font-size: 1.25rem; }
html.dark .tasso-olho { color: #a8adb4; }
html.dark .tasso-olho:hover { color: #ff8a85; background: rgba(255, 255, 255, .08); }

/* ---------- Fechamento mensal (relatorios/.../fechamento.html) -------------

A tela que substitui a planilha de 20 abas do fechamento. O visual segue o
resto dos relatórios — filtros no topo, cartões de número, tabela — e acrescenta
duas coisas que só existem aqui: o quadro contratado × realizado e a marcação
do que é extra. */

/* O aviso de serviço sem tipo é ÂMBAR e não vermelho de propósito: o relatório
   continua correto, só está incompleto. Vermelho aqui treinaria a pessoa a
   ignorar vermelho. */
.tasso-aviso-fechamento {
    padding: .9rem 1.1rem; margin-bottom: 1.2rem; border-radius: .8rem;
    border-left: 4px solid #eda033; font-size: .88rem;
}
.tasso-aviso-nota {
    display: block; margin-top: .3rem; font-size: .82rem;
    color: var(--tasso-tinta-2, #6b7076);
}

.tasso-fech-condominio { margin-bottom: 2.6rem; }

/* O conteúdo do contrato desligado (ver tasso-contrato-recolhido.js).
   `!important` porque o Unfold define `display: flex` nas linhas do formulário
   com especificidade maior — sem isto o bloco continua inteiro na tela, que
   foi o defeito relatado. */
.tasso-recolhido { display: none !important; }

.tasso-fech-sem-plano {
    margin: 0 0 .8rem; padding: .6rem .9rem; border-radius: .6rem;
    border-left: 4px solid #eda033; background: var(--tasso-superficie, #f2f3f5);
    font-size: .84rem;
}

/* O escopo do contrato, quando o condomínio tem mais de um. Etiqueta e não
   texto corrido: ela precisa ser lida junto com o nome do prédio, no mesmo
   golpe de vista, porque é a única coisa que diferencia dois blocos seguidos
   com o mesmo título. */
.tasso-fech-escopo {
    margin-left: .5rem; padding: .12rem .5rem; border-radius: 1rem;
    background: var(--tasso-superficie, #f2f3f5);
    border: 1px solid var(--tasso-borda, #d8dade);
    font-size: .74rem; font-weight: 600; letter-spacing: .02em;
    text-transform: none; vertical-align: middle;
}

.tasso-fech-responsavel {
    margin: -.4rem 0 .8rem; font-size: .82rem;
    color: var(--tasso-texto-suave, #6b7280);
}

.tasso-fech-aviso {
    margin: 0 0 .8rem; padding: .6rem .9rem; border-radius: .6rem;
    border-left: 4px solid #6b8fd8; background: var(--tasso-superficie, #f2f3f5);
    font-size: .84rem;
}

/* O quadro não ocupa a largura toda: quatro colunas esticadas em tela larga
   viram quatro palavras perdidas no branco, e o olho perde a comparação entre
   contratado e realizado, que é a única coisa que este quadro serve para ver. */
.tasso-fech-quadro { max-width: 46rem; margin-bottom: 1rem; }

.tasso-fech-periodo {
    font-size: .76rem; font-weight: 400; color: var(--tasso-tinta-2, #6b7076);
}
.tasso-fech-excedente { color: #c0392b; }
.tasso-fech-incluso { color: #157347; font-size: .84rem; }

.tasso-fech-total {
    margin-top: .6rem; padding: .7rem 1rem; border-radius: .8rem;
    background: var(--tasso-superficie, #f2f3f5);
    text-align: right; font-size: .95rem;
}
.tasso-fech-total strong { font-size: 1.1rem; }

/* Rodapé de soma dentro da tabela de ordens. A tabela não tinha nenhum, e por
   isso o único total à vista era o do fecho — que inclui os avulsos e não
   fecha com estas linhas. Ver o comentário no template. */
.tasso-relatorio-tabela tr.tasso-fech-soma td {
    background: var(--tasso-superficie, #f2f3f5);
    font-weight: 600;
    border-bottom: none;
}
.tasso-relatorio-tabela tr.tasso-fech-soma:hover td {
    background: var(--tasso-superficie, #f2f3f5);
}

html.dark .tasso-fech-sem-plano,
html.dark .tasso-relatorio-tabela tr.tasso-fech-soma td,
html.dark .tasso-relatorio-tabela tr.tasso-fech-soma:hover td,
html.dark .tasso-fech-total { background: #24262a; }
html.dark .tasso-fech-periodo,
html.dark .tasso-aviso-nota { color: #a8adb4; }
html.dark .tasso-fech-excedente { color: #ff8a85; }
html.dark .tasso-fech-incluso { color: #6ee7a0; }

/* Os cartões do fechamento carregam DINHEIRO, e o formato do painel de obras
   (rótulo e valor lado a lado) partia "R$ 6.300,00" no meio — "R$" numa linha,
   o valor noutra. Empilhado, com coluna mais larga e sem quebra, cabe. */
.tasso-fech-numeros { grid-template-columns: repeat(auto-fill, minmax(12.5rem, 1fr)); }
.tasso-fech-numeros .tasso-painel-numero {
    flex-direction: column; align-items: flex-start; justify-content: center; gap: .25rem;
}
.tasso-fech-numeros .tasso-painel-numero-valor {
    font-size: 1.3rem; white-space: nowrap;
}

/* O número da O.S. no fechamento leva à própria ordem: quem confere quer abrir
   e ver o que foi feito, e copiar o número para a busca era o caminho que
   existia antes disso. */
.tasso-fech-link { color: inherit; text-decoration: underline; text-underline-offset: 2px; }
.tasso-fech-link:hover { color: var(--tasso-vermelho, #9c1917); }
html.dark .tasso-fech-link:hover { color: #ff8a85; }

/* Franquia marcada como "não previsto no contrato": o campo fica inativo e o
   rótulo esmaece junto — campo cinza com rótulo normal parece defeito de
   carregamento, não escolha de quem preencheu. */
.tasso-franquia-desligada { opacity: .55; }
.tasso-franquia-desligada input[disabled] { cursor: not-allowed; }

/* -- cartões do painel viram filtro --------------------------------------- */

/* "eu quero clicar e você já me entregar essas análises": cada cartão recorta
   a grade pela sua cor. Eles são <a>, e não <button> num formulário, porque o
   estado do recorte precisa caber na URL — é assim que se compartilha "as
   reprovadas do Cesari" com alguém. */
.tasso-painel-numero--link {
    text-decoration: none; color: inherit;
    transition: transform .12s ease, box-shadow .12s ease;
}
.tasso-painel-numero--link:hover {
    transform: translateY(-2px); box-shadow: 0 4px 10px rgba(0, 0, 0, .16);
}
.tasso-painel-numero--link:focus-visible {
    outline: 2px solid var(--tasso-tinta, #1b1c1d); outline-offset: 2px;
}
/* O cartão ativo ganha um anel, e não uma cor nova: trocar a cor dele
   quebraria justamente o código de cores que a tela inteira ensina. */
.tasso-painel-numero--ativo {
    box-shadow: 0 0 0 3px var(--tasso-tinta, #1b1c1d);
}
html.dark .tasso-painel-numero--ativo { box-shadow: 0 0 0 3px #e8e9ea; }

.tasso-painel-recorte {
    margin: -.6rem 0 1.2rem; font-size: .85rem;
    color: var(--tasso-tinta-2, #6b7076);
}
.tasso-painel-recorte a { margin-left: .4rem; }
html.dark .tasso-painel-recorte { color: #a8adb4; }

/* A torre dentro do card: "é fundamental para identificar rapidamente de qual
   unidade é o card". Menor que o número da unidade de propósito — a unidade
   continua sendo o dado que se procura; a torre é o que desambigua o 101 da
   torre A do 101 da torre B. */
.tasso-painel-cel-torre {
    font-size: .58rem; line-height: 1.1; opacity: .9;
    text-transform: uppercase; letter-spacing: .04em;
    max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* Subseção dentro do bloco de um condomínio (os serviços avulsos, sob as OS):
   menor que o nome do condomínio para não competir com ele. */
.tasso-fech-subsecao { font-size: .85rem; margin-top: 1.2rem; }

/* ==========================================================================
   TELA DE ENTRADA (/admin/login/)
   ==========================================================================

   O cliente desenhou esta tela junto com a home (mock `1b`, 02/08). O que ela
   precisava resolver: a marca não aparecia, e os alvos de toque eram pequenos
   demais para quem entra no painel em pé, na portaria de um prédio.

   Não há reescrita do template do Unfold aqui — ele continua montando o
   formulário, com os campos, os erros e o CSRF que o Django espera. O que este
   bloco faz é vestir o que já existe. Motivo: o Unfold está pinado em 0.91.0
   porque uma versão nova já derrubou o admin em produção, e quanto menos
   template do pacote este projeto substituir, menor a chance de repetir aquilo.

   Tudo abaixo é escopado em `body.login` — a classe que o próprio layout
   `unauthenticated.html` põe no body. Sem esse escopo, o botão vermelho de
   54px vazaria para as telas internas do painel. */

body.login .tasso-login-marca {
    background: linear-gradient(135deg, #1b1c1d 0%, #24262a 100%);
    padding: 2.4rem 2rem 2rem;
    margin-bottom: 2rem;
    display: flex; flex-direction: column; align-items: center; gap: .9rem;
    position: relative; overflow: hidden;
    border-radius: .25rem;
}

/* A logo é colorida sobre branco; aqui o fundo é grafite. `brightness(0)
   invert(1)` a deixa toda branca sem precisar de um segundo arquivo para
   manter em dia — o manual da marca prevê a versão em branco sobre escuro. */
body.login .tasso-login-logo {
    position: relative; width: 168px; max-width: 70%; height: auto; display: block;
    filter: brightness(0) invert(1);
}

body.login .tasso-login-sub {
    position: relative;
    font-size: .72rem; letter-spacing: .2em; text-transform: uppercase;
    color: #a8adb4; text-align: center;
}

/* O mesmo mosaico de triângulos da página pública, aqui em SVG pelo mesmo
   motivo: a arte do manual tem 13 MB e esta tela abre no celular, em campo. */
body.login .tasso-login-marca::before {
    content: ""; position: absolute; inset: 0; pointer-events: none;
    background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120' viewBox='0 0 120 120'%3E%3Cg fill='%23e51b20' fill-opacity='0.16'%3E%3Cpath d='M0 0h60L0 60z'/%3E%3Cpath d='M120 120H60l60-60z'/%3E%3C/g%3E%3Cg fill='%23ffffff' fill-opacity='0.05'%3E%3Cpath d='M120 0v60L60 0z'/%3E%3Cpath d='M0 120v-60l60 60z'/%3E%3C/g%3E%3C/svg%3E");
    background-size: 120px 120px;
    -webkit-mask-image: linear-gradient(to bottom left, #000 0%, transparent 60%);
            mask-image: linear-gradient(to bottom left, #000 0%, transparent 60%);
}

body.login .tasso-login-titulo {
    font-family: "Sora", system-ui, sans-serif;
    font-size: 1.6rem; font-weight: 700; line-height: 1.15;
    color: #1b1c1d; margin-bottom: .35rem;
}
html.dark body.login .tasso-login-titulo { color: #f2f3f4; }

body.login .tasso-login-apoio {
    font-size: .92rem; color: #6b7076; margin-bottom: 1.4rem;
}
html.dark body.login .tasso-login-apoio { color: #a8adb4; }

/* ALVO DE TOQUE
   52px no campo e 54px no botão, do mock. O mínimo recomendado é 44px, e o
   padrão do Unfold fica abaixo disso — o que só incomoda de verdade em pé, na
   portaria, que é justamente onde esta tela é usada. */
body.login input[type="text"],
body.login input[type="email"],
body.login input[type="password"] {
    min-height: 52px; font-size: 1rem;
}

body.login .submit-row,
body.login button[type="submit"] {
    min-height: 54px; font-size: 1rem; font-weight: 700;
}

/* O aviso do rodapé, com a barra da marca à esquerda: explica o acesso negado
   antes de a pessoa levar um, que é quando ela ainda vai ler. */
body.login .tasso-login-aviso {
    border: 1px solid #e6e7e8; border-left: 3px solid #e51b20;
    background: #fbfbfc; padding: .9rem 1.1rem;
    font-size: .85rem; line-height: 1.6; color: #444545;
    margin-top: 2rem;
}
html.dark body.login .tasso-login-aviso {
    background: #24262a; border-color: #353739; border-left-color: #e51b20; color: #a8adb4;
}

/* ==========================================================================
   PAINEL DO COLABORADOR (templates/admin/_cartoes_do_colaborador.html)
   ==========================================================================

   A tela inicial de quem não é da Administração era a saudação e mais nada.
   Estes cartões usam o MESMO vocabulário visual do resto do dashboard —
   `.tasso-soft`, `.tasso-num`, `.tasso-rotulo-tec`, `.tasso-badge` — porque a
   tela é uma só: um segundo sistema de cartão na mesma página faria o painel
   parecer dois painéis colados. O que segue é o mínimo que faltava. */

/* O cartão de boa notícia ("Preenchimento — em dia") não abre nada: ele existe
   para dizer que não há o que abrir. Continua sendo <a> para o laço do template
   ser um só, e sem `href` já não é foco de teclado — o relevo de clique precisa
   sair junto, senão o cartão promete um clique que não acontece. */
a.tasso-soft:not([href]) { cursor: default; }
a.tasso-soft:not([href]):hover {
    transform: none;
    box-shadow: 9px 9px 18px var(--tasso-soft-escuro),
                -9px -9px 18px var(--tasso-soft-claro);
}

/* Duas cores, e as mesmas do resto do painel: o vermelho da marca para o que
   cobra ação, o azul das séries de "recebido" para o que está resolvido. Cor
   nunca é a única pista — o rótulo e o ícone dizem o mesmo. */
.tasso-icone-soft--alerta { color: #9c1917; }
.tasso-icone-soft--ok { color: #0b60a4; }
html.dark .tasso-icone-soft--alerta { color: #ff8a85; }

/* -- franquia do mês, prédio a prédio ------------------------------------- */

/* Lista e não grade de cartões: são poucas linhas, cada uma com nome longo de
   condomínio e um par de números curto. Em cartões, o nome quebraria em três
   linhas e o número — que é o que se procura — ficaria disperso pela tela. */
.tasso-franquia { list-style: none; margin: 0; padding: 0; }
.tasso-franquia-item {
    display: flex; align-items: center; justify-content: space-between;
    gap: .8rem; padding: .55rem 0;
    color: inherit; text-decoration: none;
    border-bottom: 1px solid rgba(0, 0, 0, .07);
}
.tasso-franquia li:last-child .tasso-franquia-item { border-bottom: 0; }
.tasso-franquia-item:hover .tasso-franquia-nome { text-decoration: underline; }
.tasso-franquia-item:focus-visible {
    outline: 2px solid var(--tasso-vermelho, #9c1917); outline-offset: 2px;
}
/* `overflow-wrap` e não `nowrap`: nome de condomínio é comprido ("CONDOMINIO
   RESIDENCIAL CHAPADA DAS ANDORINHAS — Obra da portaria") e no celular ele
   precisa quebrar em vez de empurrar o par de números para fora da tela. */
.tasso-franquia-nome { font-size: .9rem; min-width: 0; overflow-wrap: anywhere; }
.tasso-franquia-item .tasso-badge { flex: none; }
.tasso-franquia-nota {
    margin-top: .7rem; font-size: .75rem; line-height: 1.5;
    color: var(--tasso-tinta-2, #6b7076);
}
html.dark .tasso-franquia-item { border-bottom-color: rgba(255, 255, 255, .1); }
html.dark .tasso-franquia-nota { color: #a8adb4; }
