html, body {
    font-family: 'Inter', 'Segoe UI', Helvetica, Arial, sans-serif;
    margin: 0;
}

h1:focus {
    outline: none;
}

/* Barra superior clara (2026-10-12): filete no lugar da sombra. Sobre branco a sombra do Elevation vira um borrão
   cinza; uma linha de 1px separa a barra do conteúdo sem sujar a transição. */
.barra-topo.mud-appbar {
    border-bottom: 1px solid #E2E8EE;
}

/* O logo na barra, sem chip atrás (2026-10-12): o PNG é vermelho sobre transparente, e numa barra branca ele se
   sustenta sozinho — o chip escuro existia só para salvá-lo da barra vermelha. */
.logo-link {
    display: flex;
    align-items: center;
    padding: 4px 8px;
    border-radius: 8px;
    text-decoration: none;
}

    .logo-link:hover {
        background-color: rgba(27, 75, 102, 0.06);
    }

/* 34px de altura; a largura acompanha a proporção do PNG recortado (780x162 — o logo_header.png original tem ~57% de
   transparência vertical, por isso usamos a versão _trim). */
.logo-header {
    height: 34px;
    width: auto;
    display: block;
}

.material-symbols-rounded {
    font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24;
}

#blazor-error-ui {
    color-scheme: light only;
    background: lightyellow;
    bottom: 0;
    box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
    box-sizing: border-box;
    display: none;
    left: 0;
    padding: 0.6rem 1.25rem 0.7rem 1.25rem;
    position: fixed;
    width: 100%;
    z-index: 1000;
}

    #blazor-error-ui .dismiss {
        cursor: pointer;
        position: absolute;
        right: 0.75rem;
        top: 0.5rem;
    }

.blazor-error-boundary {
    background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
    padding: 1rem 1rem 1rem 3.7rem;
    color: white;
}

    .blazor-error-boundary::after {
        content: "Ocorreu um erro."
    }

.loading-progress {
    position: relative;
    display: block;
    width: 8rem;
    height: 8rem;
    margin: 20vh auto 1rem auto;
}

    .loading-progress circle {
        fill: none;
        stroke: #e0e0e0;
        stroke-width: 0.6rem;
        transform-origin: 50% 50%;
        transform: rotate(-90deg);
    }

        .loading-progress circle:last-child {
            stroke: #1B4B66;
            stroke-dasharray: calc(3.141 * var(--blazor-load-percentage, 0%) * 0.8), 500%;
            transition: stroke-dasharray 0.05s ease-in-out;
        }

.loading-progress-text {
    position: absolute;
    text-align: center;
    font-weight: bold;
    inset: calc(20vh + 3.25rem) 0 auto 0.2rem;
}

    .loading-progress-text:after {
        content: var(--blazor-load-percentage-text, "Carregando");
    }

/* Browsers de cadastro: linha selecionada em cinza claro (regra do projeto — ver CONTEXT.md §8).
   Aplicada via RowClassFunc="@((x, _) => x == _selecionado ? "linha-selecionada" : "")" na MudTable.
   Sobrepõe o destaque padrão do MudBlazor (mud-selected-item, tom da cor primária) e o hover. */
.mud-table-root .mud-table-row.linha-selecionada > td,
.mud-table-root .mud-table-row.linha-selecionada:hover > td {
    background-color: #e6e6e6 !important;
}

/* Célula que abre o registro em um clique (2026-10-16): número do chamado, hostname do dispositivo. É um <span> e não um
   MudLink de propósito — em componente, @onclick:stopPropagation colide com o @onclick e o Razor recusa; no elemento, não.
   Sem href também não há navegação falsa quando o clique só abre uma dialog. */
.link-tabela {
    cursor: pointer;
    color: var(--mud-palette-primary);
    text-decoration: none;
}

.link-tabela:hover {
    text-decoration: underline;
}

/* Tabelas dentro de dialogs: área rolável com cabeçalho fixo. Uso: MudSimpleTable FixedHeader="true" Class="tabela-rolavel"
   e, opcionalmente, Style="--altura-tabela:50vh". O max-height precisa ficar no .mud-table-container (é ele quem rola);
   no elemento raiz o MudBlazor só propaga "max-height:100%", que não limita nada (seletor com 3 classes pra vencer o do MudBlazor). */
.mud-simple-table.tabela-rolavel .mud-table-container,
.mud-table.tabela-rolavel .mud-table-container {
    max-height: var(--altura-tabela, 45vh);
    overflow: auto;
}

/* Campo de texto que a pessoa pode esticar com o mouse. Uso: MudTextField Lines="N" Class="texto-ajustavel".
   O seletor pega o <textarea> DESCENDENTE (e o próprio, se a classe for pro InputClass): quem tem alça é ele, não o
   container, e não dá pra depender do nome que o MudBlazor dá às classes internas.
   O !important existe só pra vencer o `resize:none` de .mud-input-root-multiline — e vai SÓ no resize.
   Nada de `height` aqui: arrastar a alça faz o navegador escrever `style="height:…"` inline no elemento, e qualquer
   regra !important de altura sobrepõe o inline — a alça aparece, o arrasto "funciona" e a altura não muda na tela.
   Foi exatamente esse o defeito. O MudBlazor já deixa o multiline com height:auto, então basta não atrapalhar. */
.texto-ajustavel textarea,
textarea.texto-ajustavel {
    resize: vertical !important;
    overflow: auto;
}

/* Sino do header: item ainda não lido com fundo levemente destacado. */
.notificacao-nao-lida { background-color: rgba(27, 75, 102, 0.06); }

/* Helpdesk: interações — nota interna (âmbar), resposta da Perceptiva (azul claro), do solicitante (neutra). */
.hlp-interna { background-color: #fff8e1 !important; border-color: #ffca28 !important; }
.hlp-atendente { background-color: #eef5f9 !important; }
.hlp-solicitante { background-color: #ffffff !important; }

/* Dashboard do helpdesk: bolinha com a cor do status/prioridade nas listas de contagem */
.hlp-dot { display:inline-block; width:10px; height:10px; border-radius:50%; margin-right:8px; vertical-align:middle; }

/* WhatsApp: lista à esquerda + chat à direita; em tela estreita empilha. */
.wapp-layout { display:flex; gap:12px; height:calc(100vh - 170px); min-height:420px; }
.wapp-lista { width:360px; min-width:280px; display:flex; flex-direction:column; overflow:hidden; }
.wapp-lista > .pa-2, .wapp-lista > .mud-divider { flex:0 0 auto; }
.wapp-lista-itens { flex:1 1 auto; overflow-y:auto; }
.wapp-item { display:flex; gap:10px; padding:10px 12px; cursor:pointer; border-bottom:1px solid rgba(0,0,0,.06); }
.wapp-item:hover { background:rgba(0,0,0,.03); }
.wapp-item-ativo { background:#e8f5e9 !important; }
.wapp-item-corpo { flex:1; min-width:0; }
.wapp-item-linha1, .wapp-item-linha2 { display:flex; justify-content:space-between; align-items:center; gap:6px; }
.wapp-item-linha3 { display:flex; align-items:center; gap:8px; margin-top:2px; }
.wapp-item-nome { font-weight:600; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.wapp-item-hora, .wapp-item-meta { font-size:.75rem; color:var(--mud-palette-text-secondary); white-space:nowrap; }
.wapp-item-resumo { font-size:.85rem; color:var(--mud-palette-text-secondary); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.wapp-badge { height:20px; min-width:20px; }
.wapp-chat { flex:1; min-width:0; display:flex; flex-direction:column; overflow:hidden; }
.wapp-chat-cabecalho { display:flex; gap:12px; align-items:center; padding:10px 12px; border-bottom:1px solid rgba(0,0,0,.08); }
.wapp-vazio { flex:1; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:8px; }
.wapp-mensagens { flex:1; overflow-y:auto; padding:12px; background:#efe7dd; display:flex; flex-direction:column; gap:6px; }
.wapp-balao { max-width:72%; padding:6px 10px; border-radius:8px; box-shadow:0 1px 1px rgba(0,0,0,.1); font-size:.9rem; }
.wapp-entrada { align-self:flex-start; background:#fff; }
.wapp-saida { align-self:flex-end; background:#dcf8c6; }
.wapp-autor { font-size:.72rem; font-weight:600; color:#075e54; }
.wapp-texto { white-space:pre-wrap; word-break:break-word; }
.wapp-rodape { display:flex; justify-content:flex-end; align-items:center; gap:4px; margin-top:2px; }
.wapp-hora { font-size:.68rem; color:rgba(0,0,0,.45); }
.wapp-erro { font-size:.72rem; color:#c62828; }
/* Tag especial expandida na matriz de permissões (2026-10-10): recuo e fundo discreto para a linha ficar claramente
   SUBORDINADA ao programa acima dela, e não parecer outro programa da lista. */
.perfil-perm-especial > td { background:var(--mud-palette-background-gray); padding-left:8px; }
/* Logo do cliente na barra superior (2026-10-09). A imagem guardada tem até 160 px de altura; aqui ela entra na barra,
   que tem 64. `object-fit: contain` preserva a proporção de logos largos (a maioria) sem esticar nada. */
.logo-cliente-barra { max-height:36px; max-width:180px; object-fit:contain; margin-right:12px; display:block; }
/* Falha de envio (2026-10-09): tem que saltar da conversa — é a mensagem que o cliente NÃO recebeu, e o atendente
   costuma descobrir isso tarde demais. Faixa dentro do balão, não uma linha fina embaixo dele. */
.wapp-falhou { display:flex; align-items:flex-start; gap:6px; margin-top:6px; padding:6px 8px; border-radius:6px;
               background:rgba(198,40,40,.12); border-left:3px solid #c62828; color:#c62828; font-size:.78rem; line-height:1.3; }
.wapp-sistema { align-self:center; background:#fff3cd; color:#5d4a00; font-size:.75rem; padding:3px 10px; border-radius:10px; display:flex; gap:8px; align-items:center; text-align:center; }
.wapp-img { max-width:280px; max-height:280px; border-radius:6px; display:block; margin-bottom:4px; }
.wapp-midia-off { font-size:.8rem; color:rgba(0,0,0,.5); }
/* Áudio no balão (2026-11-05): player próprio — botão, a palavra "Áudio" e o baixar. O nativo encolhia junto com o
   balão e, sem duração declarada no arquivo, virava um traço com um menu de três pontos. */
.wapp-audio { display:flex; align-items:center; gap:4px; margin-bottom:4px; }
.wapp-audio-rotulo { font-size:.82rem; color:rgba(0,0,0,.72); margin-right:4px; }
.wapp-audio-fonte { display:none; }
/* Imagem do balão: a miniatura abre em tamanho real. */
.wapp-img-abre { cursor:zoom-in; }
/* Visualizador: tamanho real, com teto só para não estourar a janela. */
.wapp-dlg-midia { max-width:100%; max-height:78vh; display:block; margin:0 auto; }
video.wapp-dlg-midia { background:#000; }
/* Envio de mídia (2026-11-05): anexo pendente e zona de soltar ficam ACIMA do campo, nunca sobre ele. */
.wapp-anexo { display:flex; align-items:center; gap:10px; padding:8px; margin:8px 8px 0; border:1px solid rgba(0,0,0,.12); border-radius:8px; background:rgba(0,0,0,.03); }
.wapp-anexo-previa { max-width:120px; max-height:80px; border-radius:6px; display:block; }
.wapp-anexo-audio { height:36px; max-width:240px; }
.wapp-anexo-info { flex:1 1 auto; min-width:0; }
.wapp-soltar { margin:8px 8px 0; }
.wapp-gravando { display:flex; align-items:center; gap:6px; font-variant-numeric:tabular-nums; font-size:.85rem; color:#c62828; }
.wapp-ponto { width:9px; height:9px; border-radius:50%; background:#c62828; animation:wapp-pulsa 1s infinite; }
@keyframes wapp-pulsa { 0%,100% { opacity:1 } 50% { opacity:.25 } }
.wapp-composer { display:flex; gap:8px; align-items:flex-end; padding:8px; border-top:1px solid rgba(0,0,0,.08); }
.wapp-previa { background:#efe7dd; }
@media (max-width: 900px) {
    .wapp-layout { flex-direction:column; height:auto; }
    .wapp-lista { width:auto; max-height:40vh; }
    .wapp-chat { min-height:60vh; }
}

/* Agenda por técnico: grade semanal do dialog (horas × dias) e agenda geral (técnicos × dias). */
.agd-grade { overflow:auto; max-height:52vh; }
.agd-grade table { border-collapse:collapse; width:100%; font-size:.8rem; }
.agd-grade th { position:sticky; top:0; background:#fff; padding:4px 6px; font-weight:600; text-align:center; border-bottom:1px solid rgba(0,0,0,.12); z-index:1; }
.agd-grade tbody th { position:static; text-align:right; white-space:nowrap; color:var(--mud-palette-text-secondary); }
.agd-grade td { border:1px solid rgba(0,0,0,.08); height:30px; min-width:70px; text-align:center; user-select:none; }
.agd-livre { background:#f1f8e9; cursor:pointer; }
.agd-livre:hover { background:#c5e1a5; }
.agd-sel { background:#2e7d32; color:#fff; font-weight:700; cursor:pointer; }
.agd-ocupado { background:#e0e0e0; color:#616161; font-size:.7rem; }
.agd-mesmo { background:#bbdefb; color:#0d47a1; font-size:.7rem; }
.agd-passado { background:#fafafa; color:#bdbdbd; }
.agd-fora { background:#fafafa; }
.agd-hoje { color:var(--mud-palette-primary) !important; }
.agd-fechado { color:#bdbdbd !important; }
.agd-geral { overflow:auto; }
.agd-geral table { border-collapse:collapse; width:100%; table-layout:fixed; }
.agd-geral th { padding:6px; border-bottom:1px solid rgba(0,0,0,.12); background:#fff; text-align:left; font-size:.85rem; }
.agd-geral thead th { text-align:center; }
.agd-geral td { border:1px solid rgba(0,0,0,.08); vertical-align:top; padding:3px; min-height:60px; }
.agd-item { border-left:4px solid #9e9e9e; background:#f5f5f5; border-radius:4px; padding:3px 6px; margin-bottom:3px; cursor:pointer; font-size:.75rem; line-height:1.25; }
.agd-item:hover { background:#e8f5e9; }
.agd-item-hora { font-weight:600; display:block; }
.agd-item-num { color:var(--mud-palette-primary); }
.agd-item-tit { display:block; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; color:var(--mud-palette-text-secondary); }

/* Dialog do dispositivo (Dispositivos › cliente): altura fixa em qualquer aba — sem "flutuar" conforme a aba selecionada.
   O MudDialog já é flex column; o conteúdo ocupa o que sobra do título/ações e rola por dentro. */
.mud-dialog.dialogo-dispositivo { height: 90vh; max-height: 90vh; }
.mud-dialog.dialogo-dispositivo .mud-dialog-content { flex: 1 1 auto; overflow-y: auto; }

/* Gestão de usuários M365 (2026-09-15): a dialog de usuário usa abas só quando a aba M365 existe; sem ela, o cabeçalho das abas some. */
.abas-ocultas .mud-tabs-toolbar { display: none; }

/* Dialog do cliente (2026-09-16): com abas de resumo, altura fixa como a do dispositivo — o conteúdo rola por dentro. */
.mud-dialog.dialogo-cliente { height: 90vh; max-height: 90vh; }
.mud-dialog.dialogo-cliente .mud-dialog-content { flex: 1 1 auto; overflow-y: auto; }

/* Tela de login (2026-09-24): imagem de fundo cobrindo a viewport, com um véu escuro por cima.
   O véu não é enfeite — a arte é escura e bem carregada (cadeados, circuitos), e sem ele o padrão compete
   com o formulário. Com ele, o cartão branco fica sendo o único ponto claro da tela.
   `fixed` evita que o fundo role junto quando o teclado do celular encolhe a viewport. */
.login-fundo {
    min-height: 100vh;
    /* A opacidade do véu é o único botão de volume da arte: quanto maior, mais a imagem recua e vira textura.
       .78 deixa reconhecer o escudo e os circuitos sem que eles disputem atenção com o formulário. */
    background-image: linear-gradient(rgba(10, 14, 24, .78), rgba(10, 14, 24, .78)), url('../img/login_fundo.jpg');
    background-size: cover;
    background-position: center;
    background-attachment: fixed;
    background-repeat: no-repeat;
}

/* Fundo sólido claro seria um retângulo branco no meio da arte; um leve desfoque do que está atrás
   costura o cartão à imagem sem custar legibilidade (o conteúdo continua sobre branco quase opaco). */
.login-fundo .mud-paper {
    background-color: rgba(255, 255, 255, .96);
    backdrop-filter: blur(6px);
}

/* Cabeçalho das telas de cadastro grudado no topo (2026-09-25, opção A).
   Em lista longa — Dispositivos de um cliente é o caso que motivou — o título, os botões e a pesquisa subiam junto
   com o conteúdo e a pessoa ficava sem ação à mão. Aqui a rolagem continua sendo a da página; o que muda é que o
   cabeçalho para logo abaixo da barra do aplicativo em vez de sair da tela.

   `--mud-appbar-height` é do próprio MudBlazor (a barra já é `position:fixed`), então não há número mágico: se a
   altura da barra mudar, isto acompanha. O fundo é obrigatório — sem ele o conteúdo passaria por baixo e ficaria
   legível através do cabeçalho. O `z-index` fica abaixo do da barra (1100) e acima do conteúdo. */
.toolbar-fixa {
    position: sticky;
    top: var(--mud-appbar-height);
    z-index: 3;
    background: var(--mud-palette-background);
    padding-top: 8px;
}

/* Barra fixa DENTRO de abas (2026-10-14). Uso: Class="abas-com-toolbar-fixa" no MudTabs cuja aba contém a barra.
   O MudBlazor põe `overflow:hidden` em .mud-tabs-rounded (é o que arredonda o conteúdo), e elemento sticky gruda no
   ancestral que corta ou rola — como esse container tem a altura do conteúdo inteiro, a barra nunca chegava a grudar e
   sumia ao rolar a lista. Nas telas sem aba (dispositivos, clientes) isso nunca apareceu porque não há esse container.
   Devolver `overflow:visible` custa o arredondamento do canto do conteúdo, que ninguém vê numa tabela de largura cheia. */
.abas-com-toolbar-fixa.mud-tabs-rounded {
    overflow: visible;
}

/* Falha ao abrir uma janela (LimiteDeErro ParaDialog): a mensagem ocupa o lugar da dialog que não abriu,
   por cima do overlay — não pode ficar empurrando o conteúdo da página lá no topo do App.razor. */
.limite-erro-dialog {
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    z-index: 1501;
}

/* Conteúdo das páginas (2026-09-27): margem estreita e fixa, em vez do container centralizado do MudBlazor.
   O padrão (MaxWidth.Large) reserva ~24px de padding E limita a 1280px centralizado — num monitor de 1920 sobravam
   320px vazios de cada lado enquanto as tabelas largas rolavam na horizontal. O !important é necessário porque o
   .mud-container traz o padding por media query, com especificidade maior que uma classe solta. */
.mud-container.conteudo {
    padding-left: 20px !important;
    padding-right: 20px !important;
}

/* Cabeçalho que ordena (2026-10-06): o clique é no span inteiro, e o texto não pode ser selecionado sem querer no duplo clique. */
.coluna-ordenavel { cursor: pointer; user-select: none; display: inline-flex; align-items: center; white-space: nowrap; }
.coluna-ordenavel:hover .coluna-ordenavel-seta { opacity: 1 !important; }

/* Criar em destaque (2026-10-13): vermelho #BA3435 da marca, o mesmo que a barra do topo usava antes de clarear.
   Não é Color.Error de propósito — Error é a cor de perigo (excluir, falha), e criar chamado não é perigo. */
.mud-button-root.btn-novo-destaque {
    background-color: #BA3435;
    color: #FFFFFF;
}

.mud-button-root.btn-novo-destaque:hover {
    background-color: #9E2C2D;
}
/* Quadro de projetos (2026-10-16): o cartão arrasta, então o cursor diz isso, e o toque não pode "selecionar" o
   cartão enquanto o dedo segura — no celular isso virava uma seleção de texto azul em cima do arraste. */
.prj-cartao { cursor: grab; user-select: none; -webkit-user-select: none; }
.prj-cartao:active { cursor: grabbing; }

/* O buraco que acompanha o dedo: o cartão original fica fantasma no lugar de onde saiu. */
.prj-cartao-fantasma { opacity: .35; }

/* A coluna precisa de altura mesmo vazia, senão não há onde soltar o primeiro cartão de uma coluna sem nada. */
.prj-cartoes { min-height: 48px; }

/* Corpo rolável da coluna (10/11/2026). Só os cartões moram aqui: "Criar atividade" e "ver todas" saíram para o
   .prj-coluna-rodape, fora da rolagem, porque como último filho DAQUI eles desciam junto com os cartões e sumiam da
   tela a partir do sexto.

   A altura era 58vh — fração fixa, que em monitor grande deixava a coluna curta à toa e em janela baixa fazia a
   coluna passar do fim da tela (aí o rodapé cairia fora, justamente o que se quer evitar). Agora o teto é a altura
   que a tela TEM, descontando o que fica acima e abaixo da coluna: barra do topo (64) + respiro do container (16) +
   cabeçalho do projeto (50) + abas (60) + filtros (52) + cabeçalho da coluna (60) + rodapé (47) + rodapé da página e
   a barra de rolagem horizontal (36). Se esse enfeite mudar, muda --prj-coluna-desconto e mais nada.

   O desconto NÃO inclui o aviso do cronômetro, que só aparece quando há hora correndo: nesse caso a coluna fica uns
   64px mais alta que a tela e a página rola um pouco. Era isso ou encurtar a coluna de todo mundo por causa de um
   aviso que quase nunca está lá.

   dvh depois de vh de propósito: onde o navegador entende dvh ele vence, e é o que conta no celular, onde a barra do
   navegador aparece e some. O piso garante coluna para uns dois cartões em janela muito baixa. */
.prj-coluna-corpo {
    --prj-coluna-desconto: 385px;
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 8px;
    overflow-y: auto;
    max-height: calc(100vh - var(--prj-coluna-desconto));
    max-height: calc(100dvh - var(--prj-coluna-desconto));
    min-height: 200px;
}

/* Rodapé fixo da coluna: um botão por linha, alinhados à esquerda como estavam quando moravam no meio dos cartões. */
.prj-coluna-rodape {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 4px;
    padding: 6px 8px 8px;
}

/* Gantt do projeto (2026-10-16, §25 fase 8). Somente leitura: barras posicionadas em cima de uma faixa de dias, sem
   biblioteca. A largura de tudo sai de --prj-gantt-px (pixels por dia) e --prj-gantt-dias (tamanho da faixa), que a
   tela define conforme a escala escolhida. */
.prj-gantt { display: flex; border: 1px solid var(--mud-palette-lines-default); border-radius: 4px; overflow: hidden; }

/* A coluna de nomes nao rola com o grafico: sem ela, rolar para ver dezembro faria perder de vista de quem e a barra. */
.prj-gantt-nomes {
    flex: 0 0 240px;
    border-right: 1px solid var(--mud-palette-lines-default);
    background: var(--mud-palette-surface);
}

.prj-gantt-faixa { flex: 1 1 auto; overflow-x: auto; }
.prj-gantt-trilho { position: relative; width: calc(var(--prj-gantt-dias) * var(--prj-gantt-px)); min-width: 100%; }

.prj-gantt-cabeca { height: 34px; border-bottom: 1px solid var(--mud-palette-lines-default); }
.prj-gantt-regua { position: relative; }

.prj-gantt-mes, .prj-gantt-semana {
    position: absolute;
    top: 0;
    font-size: .72rem;
    white-space: nowrap;
    padding-left: 3px;
    border-left: 1px solid var(--mud-palette-lines-default);
    height: 34px;
    line-height: 16px;
    color: var(--mud-palette-text-secondary);
}

.prj-gantt-mes { font-weight: 600; color: var(--mud-palette-text-primary); }
.prj-gantt-semana { top: 17px; border-left-style: dotted; }

/* Linha do grupo (a coluna do quadro) e da atividade tem a MESMA altura nos dois lados: e o que mantem nome e barra
   alinhados sem grid compartilhado. */
.prj-gantt-grupo {
    height: 28px;
    line-height: 28px;
    padding: 0 8px;
    font-size: .78rem;
    font-weight: 600;
    background: var(--mud-palette-background-grey);
    border-bottom: 1px solid var(--mud-palette-lines-default);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.prj-gantt-nome, .prj-gantt-linha {
    height: 30px;
    line-height: 30px;
    border-bottom: 1px solid var(--mud-palette-lines-default);
}

.prj-gantt-nome {
    padding: 0 8px;
    font-size: .8rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.prj-gantt-linha { position: relative; }

.prj-gantt-barra {
    position: absolute;
    top: 5px;
    height: 20px;
    border-radius: 3px;
    cursor: pointer;
    opacity: .85;
    display: flex;
    align-items: center;
    overflow: hidden;
}

.prj-gantt-barra:hover { opacity: 1; }

/* Atrasada ganha contorno, e nao outra cor: a cor da barra e a da coluna, que e a informacao principal. */
.prj-gantt-barra-atrasada { outline: 2px solid var(--mud-palette-error); outline-offset: -2px; }

.prj-gantt-rotulo {
    font-size: .72rem;
    color: #fff;
    padding: 0 6px;
    white-space: nowrap;
    text-shadow: 0 0 2px rgba(0, 0, 0, .45);
}

/* O marco de hoje atravessa o grafico inteiro, por cima das barras. */
.prj-gantt-hoje {
    position: absolute;
    top: 0;
    bottom: 0;
    width: 0;
    border-left: 2px solid var(--mud-palette-error);
    z-index: 2;
    pointer-events: none;
}

/* Paleta curta da cor da coluna (2026-10-17). O seletor de cor do componente abre um grid que transborda a dialog e
   cobre os campos de baixo; aqui sao doze amostras que cabem em duas linhas. Quem precisa de outra cor digita o
   hexadecimal no campo ao lado. */
.prj-cores { display: flex; flex-wrap: wrap; gap: 6px; max-width: 320px; }

.prj-cor {
    width: 28px;
    height: 28px;
    border-radius: 4px;
    border: 1px solid var(--mud-palette-lines-default);
    cursor: pointer;
    padding: 0;
}

.prj-cor:hover { transform: scale(1.08); }

/* A escolhida ganha um anel, e nao so borda: sobre cor escura a borda sozinha nao se ve. */
.prj-cor-ativa { outline: 2px solid var(--mud-palette-primary); outline-offset: 2px; }


/* ── Quadros do diagrama de rede (09/11/2026) ──
   Alças de redimensionar e o retângulo-fantasma de quem está desenhando. O Cytoscape não tem nada disso nativo, e as
   extensões que têm pedem jQuery e Konva — aqui são divs por cima do canvas dele.
   A camada NÃO recebe clique (as alças recebem), senão ela engoliria o arrasto dos nós. */
.dgr-camada { position: absolute; inset: 0; pointer-events: none; z-index: 3; }
.dgr-alca {
    position: absolute; width: 12px; height: 12px; margin: -6px 0 0 -6px; box-sizing: border-box;
    background: #fff; border: 2px solid #0d47a1; border-radius: 2px; pointer-events: auto;
}
.dgr-alca-no, .dgr-alca-se { cursor: nwse-resize; }
.dgr-alca-ne, .dgr-alca-so { cursor: nesw-resize; }

/* Enquanto o modo de desenhar está ligado, esta tela fica por cima de tudo: é ela que separa "desenhar um quadro" de
   "deslocar o diagrama", que no Cytoscape são o mesmo arrasto no fundo. */
.dgr-tela { position: absolute; inset: 0; z-index: 4; cursor: crosshair; background: rgba(13, 71, 161, .04); }
.dgr-previa { position: absolute; border: 2px dashed #0d47a1; background: rgba(13, 71, 161, .08); pointer-events: none; }

/* Zoom por área (09/11/2026): o mesmo gesto do quadro, com outra cor. A distinção é necessária, não enfeite — os dois
   modos são idênticos na mão e só diferem no que acontece ao soltar o mouse. Verde-azulado porque não é cor de estado
   de equipamento: azul é o quadro e a seleção, e verde, laranja, vermelho e roxo são situações no diagrama. */
.dgr-tela-zoom { background: rgba(0, 105, 92, .04); }
.dgr-previa-zoom { border-color: #00695c; background: rgba(0, 105, 92, .10); }
