/* ============================================================
   SELETA — folha de estilo base (identidade Dext)
   Paleta: neutros (cinza/branco/preto) + vermelho só em detalhes.
   ============================================================ */

/* ---- Fontes ---- */
@font-face { font-family:'Satoshi'; src:url('/assets/fonts/Satoshi-Regular.woff2') format('woff2'); font-weight:400; font-display:swap; }
@font-face { font-family:'Satoshi'; src:url('/assets/fonts/Satoshi-Medium.woff2') format('woff2'); font-weight:500; font-display:swap; }
@font-face { font-family:'Satoshi'; src:url('/assets/fonts/Satoshi-Bold.woff2') format('woff2'); font-weight:700; font-display:swap; }
@font-face { font-family:'Satoshi'; src:url('/assets/fonts/Satoshi-Black.woff2') format('woff2'); font-weight:900; font-display:swap; }
@font-face { font-family:'Montserrat'; src:url('/assets/fonts/Montserrat-Variable.ttf') format('truetype'); font-weight:100 900; font-display:swap; }

/* ---- Tokens ---- */
:root{
  --preto:#111111;
  --branco:#ffffff;
  --cinza:#dddddd;
  --cinza-fundo:#f4f4f5;
  --cinza-medio:#8a8a8a;
  --cinza-borda:#e6e6e8;
  --vermelho:#e81840;
  --vermelho-hover:#cf1338;

  /* ⭐ ALTURA DE UM RÓTULO DE CAMPO (ele, 11/08/2026: *"página tá desalinhada
     com relação aos campos"*). Quem divide a linha com um campo rotulado — um
     botão, um interruptor — tem de assentar na CAIXA e não no rótulo, e para
     isso desce exactamente a altura de um.
     ⚠️ Isto era um `margin-top:26px` chutado à mão em cada sítio, e chutado
     diferente em cada um: bastava mexer no `.campo label` para tudo sair do
     lugar sem ninguém perceber porquê. O valor deriva do próprio rótulo:
     a caixa da letra (13px × 1,5 de entrelinha = 19,5px, arredondado a 20 pelo
     browser) mais os 7px de margem. Medido no ecrã, não estimado. */
  --altura-rotulo: calc(20px + 7px);

  /* SINAL DO DINHEIRO — verde entrou, vermelho saiu.
     Estas quatro NÃO entram na customização por empresa (ver layout.php, onde
     --vermelho passa a ser a cor da marca). O motivo é simples: numa empresa de
     marca verde, o prejuízo apareceria verde. Sinal é leitura, não identidade. */
  --verde:#1c7a44;
  --verde-fundo:#e9f7ef;
  --vermelho-sinal:#cf1338;
  --vermelho-sinal-fundo:#fdecef;
  /* ⚠️ O ÂMBAR é sinal como os outros dois, e faltava-lhe nome (28/08/2026).
     Estava escrito à mão em DOIS sítios — `.selo-alerta` e `.st-pendente` —
     com o mesmo par de hexadecimais copiado. Dois pares iguais escritos à mão
     é um par que um dia deixa de ser igual, e ninguém dá por isso: é a mesma
     doença que a auditoria de 26/08 apanhou no `.alg-selo`. */
  --ambar:#b26a00;
  --ambar-fundo:#fff3e0;

  /* Tema customizável (sobrescrito no layout conforme as 3 cores da empresa) */
  --fundo:#f4f4f5;
  --menu:#111111;
  --destaque:#e81840;
  --menu-fg:#ffffff;
  --texto:#111111;
  --menu-fg-suave:#dddddd;
  --menu-borda:rgba(255,255,255,.1);
  --menu-hover:rgba(255,255,255,.08);

  --fonte-titulo:'Satoshi', system-ui, -apple-system, sans-serif;
  --fonte-texto:'Montserrat', system-ui, -apple-system, sans-serif;

  /* ⭐⭐ A ESCALA DOS CANTOS (18/08/2026). O símbolo da marca é definido pelo
     quanto arredonda: é ele que manda aqui. Havia **23 valores diferentes** de
     `border-radius` no ficheiro, doze deles escritos à mão (2,3,4,5,6,7,8,9,10,
     12,13,14) — e `10px` aparecia 8 vezes quando `--raio-sm` já ERA 10px.
     ⚠️ Três degraus chegam, e cada um tem um trabalho:
       `--raio-xs`  miudezas: código, teclas, amostras de cor, anel de foco
       `--raio-sm`  o que se clica: botões, campos, itens de lista
       `--raio`     o que contém: cartões, painéis, diálogos
     Fora da escala ficam só a cápsula (999px) e o círculo (50%). */
  --raio:14px;
  --raio-sm:10px;
  --raio-xs:6px;
  --sombra:0 12px 40px rgba(17,17,17,.10);
}

*{ box-sizing:border-box; margin:0; padding:0; }
[hidden]{ display:none !important; }
html,body{ height:100%; }
body{
  font-family:var(--fonte-texto);
  color:var(--preto);
  background:var(--cinza-fundo);
  -webkit-font-smoothing:antialiased;
  line-height:1.5;
  /* sticky footer: a página ocupa ao menos a altura toda e o rodapé "Powered by
     Dext" fica sempre colado no fundo, mesmo em telas com pouco conteúdo. */
  display:flex;
  flex-direction:column;
  min-height:100vh;
}

/* ============================================================
   LOGIN — painel escuro (marca) + formulário claro
   ============================================================ */
.login{ display:flex; min-height:100vh; position:relative; z-index:1; } /* acima da marca d'água de fundo */

/* Painel da marca (escuro) */
.login__marca{
  flex:1 1 46%;
  background:var(--preto);
  color:var(--branco);
  display:flex; flex-direction:column; justify-content:center; align-items:center;
  padding:48px; text-align:center;
}
.login__marca .simbolo{ width:88px; height:88px; margin-bottom:22px; }
.login__marca .wordmark{ width:158px; height:auto; display:block; }
.login__marca .descritor{ color:var(--cinza); font-size:13px; font-weight:600; letter-spacing:3px; text-transform:uppercase; margin-top:16px; opacity:.85; }
.login__marca .nome{
  font-family:var(--fonte-texto); font-weight:600;
  font-size:54px; letter-spacing:-1px; line-height:1;
}
.login__marca .assinatura{
  color:var(--cinza-medio); font-weight:500; font-size:15px;
  letter-spacing:1px; margin-top:8px;
}
.login__marca .tagline{
  color:var(--cinza); font-size:14px; margin-top:16px; max-width:280px;
  opacity:.6;
}

/* Lado do formulário (claro) */
.login__form{
  flex:1 1 54%;
  background:var(--branco);
  display:flex; align-items:center; justify-content:center; padding:40px;
  position:relative; overflow:hidden;
}
.form-card{ width:100%; max-width:380px; position:relative; z-index:1; }

/* Marca d'água do "D" no login.
   Desktop (preto à esquerda): fica SOBRE o painel preto, atrás do logo — como na foto.
   Mobile (preto no topo): passa a ficar só na área branca, atrás do login, sem invadir o preto.
   Cada painel tem overflow:hidden, então a marca d'água nunca escapa da sua área. */
.login__marca{ position:relative; overflow:hidden; }
.login__marca > *{ position:relative; z-index:1; } /* logo/descritor acima da marca d'água */
.login__marca::before{
  content:''; position:absolute; z-index:0; pointer-events:none;
  left:50%; top:50%; transform:translate(-50%,-50%);
  width:min(150%, 560px); height:min(150%, 560px);
  background:url('/assets/img/dext-icon.svg') no-repeat center center; background-size:contain;
  filter:brightness(0) invert(1); opacity:.06; /* "D" branco sutil sobre o preto */
}
.form-card h1{
  font-family:var(--fonte-titulo); font-weight:700; font-size:28px;
  letter-spacing:-.5px; margin-bottom:6px;
}
.form-card .sub{ color:var(--cinza-medio); font-size:15px; margin-bottom:30px; }

.campo{ margin-bottom:18px; }
.campo label{
  display:block; font-size:13px; font-weight:600; color:var(--texto);
  margin-bottom:7px;
}
.login__form .campo label{ color:var(--preto); } /* login é sempre painel claro */
.campo input:not([type=checkbox]):not([type=radio]), .campo textarea{
  width:100%; padding:13px 15px; font-family:var(--fonte-texto); font-size:15px;
  border:1.5px solid var(--cinza-borda); border-radius:var(--raio-sm);
  background:var(--branco); color:var(--preto); transition:border-color .15s;
}
.campo textarea{ resize:vertical; min-height:84px; line-height:1.45; }
.campo input:focus, .campo textarea:focus{ outline:none; border-color:var(--preto); }
/* ⚠️ E os controlos de DATA e HORA precisam dos dois: poder encolher, e escrever
   o valor à esquerda como qualquer outro campo. O Safari centra-o por omissão
   (`::-webkit-date-and-time-value`), e uma data centrada ao lado de um nome
   alinhado à esquerda lê-se como um campo de outra família. */
.campo input[type=date], .campo input[type=time]{ min-width:0; }
.campo input[type=date]::-webkit-date-and-time-value,
.campo input[type=time]::-webkit-date-and-time-value{ text-align:left; }
.campo-check input[type=checkbox]{ width:17px; height:17px; flex:none; }

/* ============================================================
   CAMPO — o aspeto base de QUALQUER campo do sistema
   ============================================================
   Antes, o aspeto bonito só existia dentro de `.campo`. Telas que põem o
   <input> solto — as Configurações do Financeiro, por exemplo — caíam no
   estilo do navegador: cantos rectos e borda fina, ao lado de um campo de
   dinheiro redondo. O mesmo ecrã tinha dois desenhos de campo.
   Agora o aspeto está no ELEMENTO, dentro do conteúdo da app. `.campo` volta a
   ser só arrumação, e uma tela nova nasce certa sem ninguém se lembrar disso.
   Fora: checkbox/radio (têm desenho próprio), hidden, color e range.

   ⚠️ TUDO VAI DENTRO DE `:where()`, e isso não é estilo — é o que faz a regra
   funcionar. Uma base tem de perder de TODA a gente; se ganhar de alguém, esse
   alguém quebra. Duas armadilhas, apanhadas as duas a olhar para o ecrã:
     · `:not([type=x]):not([type=y])…` SOMA a especificidade de cada argumento.
       Com cinco, isto valia 0,6,1 e esmagava `.turno-linha input[type=time]`
       (0,2,1): as horas do turno ficavam com 13px de padding e cortadas.
     · Mesmo em 0,1,1 ainda ganhava de `.inp-sal` (0,1,0) e de qualquer outra
       regra de uma classe só — e há várias.
   Com `:where(.conteudo)` a base cai para 0,0,1: fica debaixo de tudo, que é o
   lugar dela. Quem quiser um campo diferente escreve uma classe e ganha.

   ⚠️ E OS DIÁLOGOS, que ficavam de fora (03/08/2026, apanhado por ele no
   divisor da retirada: "os campos devem estar padronizados, gosto mais desse
   redondinho"). Um `<dialog>` vive FORA do `.conteudo` — é filho do body — por
   isso os campos lá dentro caíam no desenho do navegador, cantos rectos ao lado
   do campo de dinheiro redondo, no mesmo ecrã. É exactamente o defeito que a
   v0.31.1 tinha resolvido para as telas, e que os diálogos nunca chegaram a
   apanhar. `dialog` entra na MESMA lista `:where()`, portanto a base continua a
   valer 0,0,1 e a perder de toda a gente. */
:where(.conteudo, dialog) input:where(:not([type=checkbox],[type=radio],[type=hidden],[type=color],[type=range])),
:where(.conteudo, dialog) select,
:where(.conteudo, dialog) textarea{
  font-family:var(--fonte-texto); font-size:15px;
  padding:13px 15px;
  border:1.5px solid var(--cinza-borda); border-radius:var(--raio-sm);
  background:var(--branco); color:var(--preto);
  transition:border-color .15s;
}
:where(.conteudo, dialog) input:where(:not([type=checkbox],[type=radio],[type=hidden])):focus,
:where(.conteudo, dialog) select:focus, :where(.conteudo, dialog) textarea:focus{
  outline:none; border-color:var(--preto);
}

.btn{
  width:100%; padding:14px; font-family:var(--fonte-texto); font-weight:600;
  font-size:15px; border:none; border-radius:var(--raio-sm); cursor:pointer;
  background:var(--botao); color:var(--botao-fg); transition:background .15s;
}
.btn:hover{ background:var(--botao-hover); }
/* 🐞🐞 `btn-ghost` ERA UMA CLASSE QUE NÃO EXISTIA (auditoria de 25/08/2026).
   Achada na prova de tela dos pedidos a 375px — a prova que estava em dívida
   desde ontem. A tela escrevia `class="btn btn-inline btn-ghost"` nos botões
   por fornecedor, a classe não tinha regra nenhuma no CSS, e por isso os SETE
   saíam pintados como o botão principal: um bloco inteiro de cor forte, e sem
   se distinguir *"Pedido completo"* — a folha da casa — das folhas que se
   mandam a cada fornecedor.
   ⭐ Duas regras da casa de uma vez: **cor forte só em selo pequeno** (superfície
   grande leva cor em traço), e **uma ação principal por bloco**.
   ⚠️ A forma é a do `.btn-mini-ghost`, que já existia e funcionava — o fantasma
   do botão pequeno. Isto é o mesmo, no tamanho do `.btn`. */
.btn-ghost{ background:transparent; color:var(--cinza-medio);
  border:1px solid var(--cinza-borda); }
.btn-ghost:hover{ background:transparent; color:var(--preto); border-color:var(--cinza-medio); }
.btn-ghost .ajuda{ color:inherit; opacity:.65; }

/* Busca global: campo na sidebar + página de resultados */
.sb-busca{ display:flex; align-items:center; gap:8px; margin-top:12px; padding:8px 12px;
  background:var(--menu-hover, rgba(255,255,255,.07)); border-radius:var(--raio-sm); }
.sb-busca svg{ width:15px; height:15px; flex:none; color:var(--menu-fg-suave, #9a9a9a); }
.sb-busca input{ flex:1; min-width:0; background:transparent; border:none; outline:none;
  font:inherit; font-size:13.5px; color:var(--menu-fg, #fff); }
.sb-busca input::placeholder{ color:var(--menu-fg-suave, #9a9a9a); }
.busca-form{ display:flex; gap:10px; margin-bottom:24px; }
.busca-form input{ flex:1; padding:12px 15px; font:inherit; font-size:15px;
  border:1.5px solid var(--cinza-borda); border-radius:var(--raio-sm); background:var(--branco); color:var(--preto); }
.busca-form input:focus{ outline:none; border-color:var(--preto); }
.busca-form .btn{ width:auto; }
.busca-lista{ display:flex; flex-direction:column; gap:8px; margin-bottom:22px; }
.busca-item{ display:flex; align-items:baseline; justify-content:space-between; gap:14px;
  background:var(--branco); border:1px solid var(--cinza-borda); border-radius:var(--raio-sm);
  padding:12px 16px; text-decoration:none; color:inherit; transition:border-color .15s; }
.busca-item:hover{ border-color:var(--cinza-medio); }
.busca-nome{ font-weight:600; }
.busca-detalhe{ font-size:13px; color:var(--cinza-medio); text-align:right; }
@media (max-width:600px){ .busca-item{ flex-direction:column; gap:2px; } .busca-detalhe{ text-align:left; } }

/* Minha escala (funcionário): os próprios turnos, dia a dia */
.mesc-lista{ display:flex; flex-direction:column; gap:10px; }
.mesc-dia{ background:var(--branco); border:1px solid var(--cinza-borda); border-radius:var(--raio-sm);
  padding:14px 16px; display:flex; align-items:center; justify-content:space-between; gap:14px; flex-wrap:wrap; }
.mesc-hoje{ border-color:color-mix(in srgb, var(--vermelho) 45%, transparent); }
.mesc-data{ font-weight:700; font-size:14.5px; display:flex; align-items:center; gap:8px; }
/* ⚠️ `.tag-hoje` MORREU a 28/08/2026 — era o `.selo-marca` com outro nome.
   Desenhava a mesma cápsula, na mesma cor da marca, com 12% em vez de 10% de
   mistura e 11px/700 em vez de 11,5px/700. Ninguém escolheu essa diferença:
   ela nasceu de se escrever a peça outra vez em vez de a usar.
   ⭐ E o tom certo é mesmo `marca`, que pede *"um por tela"*: numa lista de
   dias há exatamente um «Hoje». Ver `app/Views/minha-escala.php`. */
.mesc-turnos{ display:flex; gap:8px; flex-wrap:wrap; }

/* Mapa do salão: estado de cada mesa num horário */
.mapa-filtros{ display:flex; align-items:flex-end; gap:16px; flex-wrap:wrap; margin-bottom:14px; }
.mapa-filtros .campo{ margin-bottom:0; }
.mapa-resumo{ margin-left:auto; font-size:14px; color:var(--cinza-medio); }
.mapa-resumo strong{ font-size:20px; color:var(--preto); }
.mapa-legenda{ display:flex; gap:14px; margin-bottom:18px; font-size:12.5px; color:var(--cinza-medio); }
.leg::before{ content:''; display:inline-block; width:10px; height:10px; border-radius:var(--raio-xs); margin-right:6px; }
.leg-livre::before{ background:#16a34a; }
.leg-reservada::before{ background:#f59e0b; }
.leg-ocupada::before{ background:var(--vermelho); }
.leg-junta::before{ background:#6d28d9; }
.mapa-grade{ display:grid; grid-template-columns:repeat(auto-fill,minmax(150px,1fr)); gap:12px; margin-bottom:22px; }
.mesa-tile{ background:var(--branco); border:1.5px solid var(--cinza-borda); border-radius:var(--raio-sm);
  padding:12px 14px; display:flex; flex-direction:column; gap:8px; min-height:86px; }
.mesa-livre{ border-color:color-mix(in srgb, #16a34a 45%, transparent); }
.mesa-reservada{ border-color:#f59e0b; background:color-mix(in srgb, #f59e0b 5%, var(--branco)); }
.mesa-ocupada{ border-color:var(--vermelho); background:color-mix(in srgb, var(--vermelho) 5%, var(--branco)); }
.mesa-topo{ display:flex; align-items:center; justify-content:space-between; }
.mesa-nome{ font-size:14.5px; }
.mesa-cap{ font-size:12.5px; color:var(--cinza-medio); display:flex; align-items:center; gap:4px; }
.mesa-res{ display:flex; flex-direction:column; gap:2px; }
.mesa-cliente{ font-size:13px; font-weight:600; }
.mesa-info{ font-size:12px; color:var(--cinza-medio); }
.mesa-res-livre{ font-size:12.5px; color:#15803d; font-weight:600; }

/* Mesas juntas no mapa: um grupo tem de se ler como UM. O traço grosso à
   esquerda amarra as mesas do grupo; a acompanhante leva-o tracejado, porque
   ela não se reserva sozinha (ver Mesas::juntar).
   ⚠️ Cor PRÓPRIA, e não a --destaque da marca: verde/âmbar/vermelho já são os
   ESTADOS da mesa (livre/reservada/ocupada) e nesta marca a --destaque é o
   próprio vermelho — o traço da junção lia-se como "ocupada". Junção não é
   estado, é relação, e por isso tem uma cor que não disputa com as outras. */
.mesa-junta{ --junta:#6d28d9; border-left:4px solid var(--junta); padding-left:11px; }
.mesa-junta-secundaria{ border-left-style:dashed; }
.mesa-juncao{ display:flex; align-items:center; gap:6px; flex-wrap:wrap; }
.mesa-juncao-rot{ font-size:12px; color:var(--cinza-medio); font-weight:600; }
.pill-junta{ background:color-mix(in srgb, #6d28d9 13%, transparent);
  color:#5b21b6; font-size:11px; padding:2px 8px; }

/* Lista de espera: estados da fila */
.st-esp-aguardando{ background:color-mix(in srgb, #f59e0b 16%, transparent); color:#b45309; }
.st-esp-chamado{ background:color-mix(in srgb, #2563eb 14%, transparent); color:#1d4ed8; }
.st-esp-sentado{ background:color-mix(in srgb, #16a34a 14%, transparent); color:#15803d; }
.st-esp-desistiu{ background:var(--cinza-claro, #f0f0f2); color:var(--cinza-medio); }
.campo-curto{ max-width:110px; }

/* Avisos (notificações da pessoa) + selo de não lidos na sidebar */
.sb-badge{ margin-left:auto; background:var(--vermelho); color:#fff; font-size:11px; font-weight:700;
  border-radius:999px; padding:1px 7px; line-height:1.5; }
.avisos-lista{ display:flex; flex-direction:column; gap:10px; }
.aviso-item{ display:flex; flex-direction:column; gap:3px; text-decoration:none; color:inherit;
  background:var(--branco); border:1px solid var(--cinza-borda); border-radius:var(--raio-sm); padding:14px 16px;
  transition:border-color .15s; }
.aviso-item:hover{ border-color:var(--cinza-medio); }
.aviso-novo{ border-left:3px solid var(--vermelho); }
.aviso-titulo{ font-weight:700; font-size:14.5px; }
.aviso-corpo{ font-size:13.5px; color:var(--cinza-medio); line-height:1.5; }
.aviso-quando{ font-size:12px; color:var(--cinza-medio); margin-top:2px; }

/* Painel de indicadores ("pulso" do dia): cartões grandes, didáticos e clicáveis */
.dash-strip{ display:flex; flex-wrap:wrap; gap:14px; margin-bottom:26px; }
.dash-tile{
  flex:1 1 158px; min-width:152px; max-width:240px;
  background:var(--branco); border:1px solid var(--cinza-borda); border-radius:var(--raio-sm);
  padding:16px 18px; text-decoration:none; color:inherit; display:flex; flex-direction:column; gap:2px;
  transition:border-color .15s, box-shadow .15s;
}
.dash-tile:hover{ border-color:var(--cinza-medio); box-shadow:0 4px 14px rgba(0,0,0,.06); }
.dash-num{ font-family:var(--fonte-titulo); font-weight:700; font-size:34px; line-height:1.1; letter-spacing:-1px; }
.dash-rot{ font-size:13.5px; font-weight:700; color:var(--preto); }
.dash-ctx{ font-size:12.5px; color:var(--cinza-medio); }
/* O que pede ação salta aos olhos */
.dash-alerta{ border-color:color-mix(in srgb, var(--vermelho) 45%, transparent);
  background:color-mix(in srgb, var(--vermelho) 4%, var(--branco)); }
.dash-alerta .dash-num, .dash-alerta .dash-ctx{ color:var(--vermelho); }
.dash-alerta:hover{ border-color:var(--vermelho); }

/* ═══ AS PEÇAS LARGAS DO PAINEL (19/08/2026) ═══
   Um cartão responde "quanto"; a tabela responde "onde" e o gráfico "quando". */
.dash-blocos{ display:grid; grid-template-columns:repeat(auto-fit, minmax(300px, 1fr)); gap:16px; margin-bottom:26px; }
.dash-bloco{
  background:var(--branco); border:1px solid var(--cinza-borda);
  border-radius:var(--raio-sm); padding:16px 18px;
  /* 🚨 A TABELA ROLA DENTRO DO CARTÃO, e não empurra a PÁGINA (20/08/2026).
     Medido: cada uma destas tabelas quer ~660px e a casa dela tem 308px — a
     três cartões, a página do Operacional ficava com 1.567px de largura numa
     janela de 1.280 e rolava de lado. Já rolava antes com dois cartões (1.405);
     o terceiro só tornou o defeito impossível de ignorar.
     ⚠️ `min-width:0` é a metade que falta: numa grelha, uma célula recusa-se a
     encolher abaixo do conteúdo dela, e sem isto o `overflow` não tem por onde
     agir. */
  overflow-x:auto; min-width:0;
}
.dash-bloco-cab{ display:flex; align-items:baseline; justify-content:space-between; gap:12px; }
.dash-bloco-cab .secao-titulo{ margin:0; }
.dash-bloco-cab .nome-link{ font-size:12.5px; white-space:nowrap; }
.dash-tabela{ margin-top:10px; }
/* ⭐ O recado da peça sem dados na janela (23/08/2026). Discreto: é a ausência
   de notícia, não uma notícia. ⚠️ Com altura mínima para a peça vazia não
   encolher ao pé das cheias — uma grelha com uma caixa de 60px ao lado de outra
   de 300px lê-se como defeito. */
.dash-bloco-vazio{ margin:14px 0 0; font-size:13.5px; color:var(--cinza-medio);
  min-height:64px; display:flex; align-items:center; }
.dash-tabela td{ border-top:1px solid var(--linha); padding:8px 0; font-size:13.5px; vertical-align:middle; }
.dash-tabela tbody tr:first-child td{ border-top:none; }
/* ⚠️ O rótulo fica com a SOBRA, e é isso que `auto` quer dizer numa tabela.
   Com `width:99%` ele comia tudo e a coluna da barra ficava a zero — a barra
   existia no HTML e media 0px, que é a maneira mais silenciosa de uma peça
   desaparecer. */
.td-dash-rot{ width:auto; }
/* ⚠️ E `.barra-fundo` nasceu numa linha FLEX (as análises de reservas), com
   `flex:1`. Dentro de um `<td>` isso não vale nada: aqui ela é bloco e leva
   largura mínima própria, senão a tabela volta a espremê-la. */
.td-dash-barra{ width:34%; min-width:80px; padding-left:12px !important; }
.td-dash-barra .barra-fundo{ display:block; width:100%; min-width:70px; }
/* 🚨 E o PREENCHIMENTO também: `.barra-fill` é um `<span>`, e `width` não se
   aplica a caixa em linha. Na origem ele era item de um flex (o pai
   blockificava-o) e ninguém reparou. Fora do flex, o `width:24%` do style era
   ignorado em silêncio e a barra ficava sempre vazia.
   ⭐ É a mesma família do card largo em coluna estreita: peça nascida num
   contexto, reutilizada noutro. Ao reusar um componente, provar no sítio novo. */
.td-dash-barra .barra-fill{ display:block; }
.td-dash-val{ text-align:right; white-space:nowrap; padding-left:12px !important; }
.td-dash-val .lanc-sub{ display:block; }

/* 🚨 O gráfico é SVG feito em PHP, sem biblioteca: o app funciona offline e uma
   biblioteca vinda de um CDN seria a primeira coisa a falhar no telemóvel da
   equipa no meio do turno. `preserveAspectRatio:none` deixa as barras esticarem
   com a caixa — é um gráfico de proporção, não um desenho técnico. */
.dash-graf{ display:block; width:100%; height:120px; margin-top:6px; overflow:visible; }
/* ⚠️ O ENDEREÇO LONGO É UMA PALAVRA SÓ. Sem isto, o endereço do agendador saía
   do cartão e **empurrava a página inteira para fora do ecrã** — visto no
   telemóvel dele a 20/08. `anywhere` porque um token não tem sítio bonito para
   partir: partir feio é melhor do que não caber. */
.link-publico{ overflow-wrap:anywhere; word-break:break-word; min-width:0; }
/* Quando é o próprio `code` que leva a classe, não há nada para alinhar ao lado
   — e `flex` num texto só complica a quebra. */
code.link-publico{ display:block; }

/* ⭐ A JANELA DO PAINEL TROCA SEM RECARREGAR: enquanto o pedaço novo não chega,
   o que está no ecrã recua um pouco. É o sinal de que o toque foi ouvido — e
   sem ele metade da lentidão que se sente é não haver resposta nenhuma. */
.dash-trocando{ opacity:.55; transition:opacity .12s; pointer-events:none; }

/* ⭐⭐ ESCOLHER UMA BARRA E VER O VALOR (ele, 20/08/2026). O alvo é a COLUNA
   inteira — um dia fraco tem 2px de barra, e acertar-lhe com o dedo é sorte. */
.dash-graf .graf-alvo{ fill:transparent; }
.dash-graf .graf-barra{ fill:color-mix(in srgb, var(--destaque) 55%, transparent); transition:fill .12s; }
.dash-graf .graf-col-max .graf-barra{ fill:var(--destaque); }
.dash-graf .graf-col:hover .graf-barra,
.dash-graf .graf-col.graf-sel .graf-barra{ fill:var(--destaque); }
/* O valor só do melhor dia, e do escolhido: escrever os trinta é uma parede.
   🚨 E com AURÉOLA branca à volta das letras (`paint-order`): num mês de 31 dias
   o rótulo "€1.310" é mais largo do que a coluna dele e passa por cima das
   barras vizinhas. Visto na tela a 20/08 — o "€0" de um dia parado saía cortado
   ao meio por uma barra alta ao lado, e sem isto o número mais importante do
   gráfico é o que se lê pior. */
.dash-graf .graf-valor{
  opacity:0; transition:opacity .12s;
  paint-order:stroke fill; stroke:var(--branco); stroke-width:1.1px; stroke-linejoin:round;
}
.dash-graf .graf-col-max .graf-valor,
.dash-graf .graf-col:hover .graf-valor,
.dash-graf .graf-col.graf-sel .graf-valor{ opacity:1; }
/* O dia da barra escolhida aparece mesmo quando não é um dos rótulos fixos —
   é o que responde a "que dia é esta barra?". */
.dash-graf .graf-dia-so-sel{ opacity:0; transition:opacity .12s; }
.dash-graf .graf-col:hover .graf-dia-so-sel,
.dash-graf .graf-col.graf-sel .graf-dia-so-sel{ opacity:1; }
.dash-graf .graf-col.graf-sel .graf-dia{ fill:var(--texto); font-weight:700; }
/* ⚠️ O dedo não tem `:hover`. A classe `.graf-sel` é posta por um toque, e é
   por isso que isto funciona no telemóvel — onde ele olha para o painel. */
.dash-graf .graf-col{ cursor:pointer; }
/* ⚠️ O texto dentro do SVG não escala com o viewBox se levar `font-size` em px:
   estas medidas são unidades do desenho, e é por isso que são tão pequenas. */
.dash-graf .graf-valor{ font-size:3.4px; font-weight:700; fill:var(--texto); }
.dash-graf .graf-dia{ font-size:3px; fill:var(--cinza-medio); }
.dash-graf-total{ margin:0; font-size:15px; }
.dash-graf-total .lanc-sub{ font-weight:400; }
.dash-graf-eixo{ display:flex; justify-content:space-between; font-size:11.5px; color:var(--cinza-medio); margin-top:2px; }
.dash-marca{ color:var(--vermelho); font-weight:700; }

/* ═══ ⭐⭐ A EQUIPA: DUAS PERCENTAGENS LADO A LADO (ele, 19/08/2026) ═══
   *"A informação que mais faz sentido pra mim aí é pontualidade e coerência com
   a escala, em porcentagem."*
   ⚠️ Esta tabela é a ÚNICA do painel com cabeçalho, e de propósito: com duas
   percentagens na mesma linha, "26%" e "51%" sem título são dois números sem
   pergunta. As outras têm uma coluna só e o rótulo do bloco já a nomeia.
   ⚠️ A largura das duas colunas é IGUAL e fixa: se cada uma se ajustasse ao seu
   conteúdo, a barra da esquerda ficava maior do que a da direita e o olho lia
   diferença onde só há tipografia. */
.dash-equipa thead th{ font-size:11px; text-transform:uppercase; letter-spacing:.04em;
  color:var(--cinza-medio); font-weight:700; padding:0 0 6px; border:none; }
.dash-equipa thead th + th{ padding-left:12px; }
.td-dash-pct{ width:20%; min-width:92px; padding-left:12px !important; }
.td-dash-pct .barra-fundo{ display:block; width:100%; margin-top:3px; height:6px; }
.td-dash-pct .barra-fill{ display:block; }
.td-dash-pct .lanc-sub{ display:block; margin-top:3px; }
.dash-pct{ font-size:15px; line-height:1.1; }
/* ⭐ A TAXA DE APROVEITAMENTO é o número que ele lê primeiro: o maior da linha e
   o único com cor própria. Faixas iguais às das parcelas (90/70), para o painel
   não ter duas ideias de "bom".
   🚨 E desde que passou de nota 0–10 para PERCENTAGEM, o tamanho é a única
   coisa que a distingue das parcelas — ela é o TODO, elas são as PARTES. Se
   algum dia encolher para o tamanho delas, a linha passa a ler-se como quatro
   percentagens soltas. Há teste a exigir que seja maior. */
.td-dash-nota{ width:92px; padding-left:12px !important; }
.dash-nota{ font-size:24px; line-height:1; font-family:var(--fonte-titulo); }
.dash-nota.nota-ok{ color:#16a34a; }
.dash-nota.nota-neutro{ color:var(--texto); }
.dash-nota.nota-ruim{ color:var(--vermelho); }
.th-nota{ cursor:help; }
/* ⚠️ Os ajustes são CONTAGEM e não proporção: sem barra, de propósito — uma
   barra pede um todo, e "3 ajustes" não é 3 de coisa nenhuma. */
.td-dash-aj{ width:96px; padding-left:12px !important; }
.td-dash-aj strong{ font-size:15px; }
.dash-aj-tem{ color:var(--vermelho); }
/* ⚠️ `em 5 dia(s)` quebrava em duas linhas numa coluna estreita e empurrava a
   linha inteira para baixo. Medido no navegador. */
.td-dash-aj .lanc-sub{ display:block; margin-top:2px; white-space:nowrap; }
/* ⚠️ A diferença de horas é o número que ele lê primeiro, e continua a ser o
   maior da linha: as percentagens explicam, ela é o resultado. */
.dash-equipa .td-dash-val strong{ font-size:15.5px; }

@media (max-width:820px){
  /* Em cartão, o cabeçalho não tem onde viver: cada célula leva o seu rótulo
     no `data-label`, como no resto da casa. */
  .dash-equipa thead{ display:none; }
}

/* ⭐ A NOTA na lista das tarefas: etiqueta discreta, tom neutro. Não é um aviso
   nem um alerta — é só a espécie da linha, e uma cor forte fá-la-ia competir com
   o que de facto precisa de ação. */
.tar-e-nota{ background:var(--cinza-claro, #f0f0f2); color:var(--cinza-medio); font-weight:700; }

/* ═══ ⭐⭐⭐ O MEU APROVEITAMENTO — a caixa que a equipa vê (19/08/2026) ═══
   ⚠️ O número é grande e sozinho de propósito: é a única coisa que a pessoa tem
   de levar do bloco. A posição e a média ficam ao lado, mais pequenas, porque
   são contexto — e as três parcelas por baixo, porque são a explicação. */
.meu-aprov{ display:flex; align-items:center; gap:18px; flex-wrap:wrap; margin-top:8px; }
.meu-aprov-num{ font-size:44px; }
.meu-aprov-lado{ display:flex; flex-direction:column; gap:2px; }
.meu-aprov-pos{ font-size:15px; font-weight:700; }
/* ⚠️ As parcelas empurram-se para a direita no ecrã largo e passam para baixo no
   telemóvel: `margin-left:auto` com `flex-wrap` faz as duas coisas sozinho. */
.meu-aprov-mods{ display:flex; gap:16px; margin-left:auto; flex-wrap:wrap;
  font-size:12.5px; color:var(--cinza-medio); }
.meu-aprov-mods strong{ display:block; font-size:15px; color:var(--texto); }

/* ═══ AS SECÇÕES (ele, 19/08/2026: *"separar por sessões, mas de forma muito
   sutil, pra não misturar o que é financeiro do que é reservas, pessoas"*).
   ⚠️ Subtil quer dizer: um rótulo pequeno e um fio. Nada de caixas dentro de
   caixas — os cartões já têm moldura, e moldura sobre moldura vira parede. */
.dash-sec{ margin-bottom:8px; }
.dash-sec-cab{ display:flex; align-items:center; gap:12px; margin:26px 0 12px; }
.dash-sec-cab:first-of-type{ margin-top:0; }
.dash-sec-rot{ font-size:11.5px; font-weight:700; letter-spacing:.09em; text-transform:uppercase;
  color:var(--cinza-medio); white-space:nowrap; }
.dash-sec-fio{ flex:1; height:1px; background:var(--linha); }

/* ═══ o seletor de janela (ele, 19/08/2026) ═══
   Três janelas e mais nada. É um LINK, não JavaScript: o painel tem de servir
   com a rede a cair, como o resto da casa. */
.dash-periodo{ display:inline-flex; gap:2px; margin:0 0 14px; padding:3px;
  background:var(--cinza-fundo); border-radius:999px; }
.dash-per{ padding:6px 14px; border-radius:999px; font-size:13px; font-weight:600;
  color:var(--cinza-medio); text-decoration:none; transition:background .15s, color .15s; }
.dash-per:hover{ color:var(--texto); }
.dash-per.ativo{ background:var(--branco); color:var(--texto); box-shadow:0 1px 3px rgba(0,0,0,.08); }

/* ⭐⭐ AS SETAS DA JANELA DO PAINEL (24/08/2026).
   Ele: *"não mostra mais a semana na segunda-feira (…) e quando o dia acabou,
   que é quando eu quero ver o que passou no dia, ele já não aparece nada"*.
   ⚠️ Ficam FORA da pílula das lentes, com fundo próprio: dentro dela, o `‹`
   parecia uma quarta opção a par de Hoje/Semana/Mês. São duas coisas
   diferentes — a régua, e onde se está com ela.
   ⚠️ O rótulo usa `tabular-nums` e uma largura mínima: sem isso, a barra dança
   de largura a cada seta ("7–13 ago" é mais estreito que "24–30 ago"). */
.dash-nav{ display:inline-flex; align-items:center; gap:2px; margin:0 0 14px 8px;
  padding:3px; background:var(--cinza-fundo); border-radius:999px; vertical-align:middle; }
.dash-nav-seta{ display:inline-flex; align-items:center; justify-content:center;
  min-width:30px; height:30px; border-radius:999px; font-size:17px; line-height:1;
  color:var(--cinza-medio); text-decoration:none; transition:background .15s, color .15s; }
.dash-nav-seta:hover{ background:var(--branco); color:var(--texto); }
.dash-nav-rot{ min-width:112px; padding:0 6px; text-align:center; font-size:13px;
  font-weight:600; color:var(--texto); font-variant-numeric:tabular-nums; }
/* ⭐ O RÓTULO É O CALENDÁRIO (25/08/2026). O campo de data está POR CIMA do
   texto, transparente e do tamanho todo: quem carrega onde lê a janela abre o
   calendário do sistema. Um ícone ao lado era mais uma coisa na barra, e a
   barra do telemóvel já estava a rebentar em agosto.
   ⚠️ `opacity:0` e não `display:none`: escondido de verdade, o campo deixava de
   receber o toque — e sem toque não há calendário nenhum. */
.dash-nav-rot{ position:relative; cursor:pointer; }
.dash-nav-rot:hover{ color:var(--vermelho); }
.dash-nav-cal{ position:absolute; inset:0; width:100%; height:100%;
  margin:0; padding:0; border:0; background:none; opacity:0; cursor:pointer;
  /* ⚠️ O iOS aumenta a letra de um campo com menos de 16px e, ao focar, dá zoom
     na página inteira. Invisível ou não, o campo continua a ser um campo. */
  font-size:16px; }
/* ⚠️ O anel do teclado tem de aparecer no que SE VÊ: o campo é transparente, e
   sem isto quem navega por Tab não sabia onde estava. */
.dash-nav-rot:has(.dash-nav-cal:focus-visible){ outline:2px solid var(--vermelho);
  outline-offset:2px; border-radius:999px; }
/* A volta ao presente vive DENTRO da navegação (é tempo, como as setas) e só
   existe quando se saiu do presente — ver a nota na view. */
.dash-nav-agora{ padding:0 12px; height:30px; display:inline-flex; align-items:center;
  border-radius:999px; font-size:12.5px; font-weight:700; color:var(--vermelho);
  text-decoration:none; white-space:nowrap; transition:background .15s; }
.dash-nav-agora:hover{ background:var(--branco); }
/* ⭐ ARRUMAR O PAINEL NÃO É UMA LENTE (25/08/2026). Ao lado de Hoje · Semana ·
   Mês é uma porta para outra tela, e por isso ocupa o que precisa em vez de
   pedir a mesma fatia que as réguas. No largo diz-se por extenso. */
.arrumar-curto{ display:none; }
.dash-arrumar{ flex:0 0 auto; white-space:nowrap; }

/* 🚨 O ALVO DE TOQUE: 30px é o desenho, 44 é o dedo — a régua da auditoria de
   23/08, a mesma dos `‹ ›` do Diário e do `?` das dicas. */
@media (pointer:coarse){
  .dash-nav-seta{ min-width:44px; height:44px; }
  /* ⭐ E as LENTES também (25/08/2026). Até aqui tinham 30px de altura e
     escapavam à régua — só cumpriam por acidente, porque o "Arrumar o painel"
     partido em duas linhas esticava a fila. Arrumado o rótulo, o alvo caía para
     30px: a correção de uma coisa ia estragar a outra, calada. */
  .dash-per{ min-height:44px; display:inline-flex; align-items:center; justify-content:center; }
  /* ⭐ E o "Tirar" de cada aparelho (25/08/2026): mede 31px por omissão, e é um
     botão que APAGA — o pior sítio para um alvo pequeno é ao lado de um nome
     que se parece com o do vizinho.
     ⚠️ 🔍 E fica um facto medido, que NÃO se arruma aqui: o `.btn-mini` da casa
     tem 31px com o dedo em TODAS as telas. Mudá-lo em bloco mexe em dezenas de
     ecrãs de uma vez, e isso quer-se medido e visto, não enfiado ao lado de
     outro trabalho. Está anotado no PENDENCIAS. */
  .push-ap .btn-mini{ min-height:44px; display:inline-flex; align-items:center; }
}

/* ⚠️ O dinheiro é MAIS COMPRIDO do que uma contagem: "€12.480,20" não cabe no
   corpo de 34px que servia para "3". Encolhe-se o número, não o cartão — a
   fila tem de continuar alinhada. */
/* 🚨 `overflow-wrap:anywhere` partia "€-2.525,54" ao meio ("€-2.525,5" / "4"),
   que é a pior coisa que se pode fazer a um número. Dinheiro não se quebra:
   encolhe-se a letra até caber. */
.dash-num{ white-space:nowrap; }
/* 🚨🚨 O NÚMERO CRESCIA COM A JANELA E A CAIXA ENCOLHIA COM A FILA (25/08/2026).
   Ele: *"Arruma o Dashboard, tem valores pra fora."*
   O tamanho vinha de `2vw` — uma percentagem do ECRÃ — e a largura do cartão
   vem da FILA: `flex:1 1 158px` reparte o que sobra entre os cartões que lá
   estão. São duas medidas diferentes, e por isso um painel com sete cartões
   dava letra de 34px dentro de uma caixa de 210px: **€-3.078,30 saía por fora
   sem o ecrã ter mudado de tamanho.** Acrescentar um cartão piorava tudo o que
   já lá estava — que é o pior tipo de acoplamento que uma tela pode ter.
   ⭐ `cqi` é a mesma percentagem, medida no CARTÃO — e `1cqi` é 1% do MIOLO,
   já sem os 36px de respiro. O número volta a ser grande porque o cartão é
   grande, e não porque o monitor é.
   📏 **16% é medido, não escolhido a olho.** É o maior valor que ainda deixa
   caber o pior número plausível — `€-123.480,20`, doze caracteres — no cartão
   mais apertado que a fila produz (8 cartões num ecrã de 1980). A 16,8% cabia
   tudo o que ele tem hoje e rebentava com seis dígitos; a 16% sobram 5px, e um
   cartão cheio fica com 32px em vez dos 34 de antes — dois pixels que ninguém
   vê, em troca de um número que nunca mais sai da caixa.
   ⚠️ `container-type:inline-size` só contém o eixo HORIZONTAL. A altura
   continua a vir do conteúdo, que é o que mantém a fila alinhada. */
.dash-tile{ container-type:inline-size; }
.dash-tile:has(.dash-num) .dash-num{ font-size:clamp(17px, 16cqi, 34px); }
/* ⚠️ E o aperto da letra passa a ser relativo: `-1px` num número de 34px é
   ajuste; no mesmo número a 18px é o que faz os dígitos tocarem-se. */
.dash-num{ letter-spacing:-.03em; }

/* A variação face ao período anterior, discreta ao lado do rótulo. */
.dash-var{ font-size:12.5px; font-weight:700; font-variant-numeric:tabular-nums; }

/* ⚠️ O SEMÁFORO não é a cor do dinheiro: marca a MEDIDA (prime cost acima do
   alvo). Por isso pinta a borda e não o número — o número já tem dono. */
.dash-tom-atencao{ border-color:color-mix(in srgb, #d97706 45%, transparent); }
.dash-tom-perigo{ border-color:color-mix(in srgb, var(--vermelho-sinal) 45%, transparent); }
.dash-tom-ok{ border-color:color-mix(in srgb, var(--verde) 35%, transparent); }

@media (max-width:600px){
  .dash-tile{ max-width:none; flex:1 1 44%; }
  .dash-num{ font-size:28px; }
  /* ⚠️ No telemóvel os cartões são dois por linha e já não têm `max-width`, por
     isso a percentagem do cartão continua a servir — só o teto baixa, que é o
     que impede um número de 34px num ecrã de 375. */
  .dash-tile:has(.dash-num) .dash-num{ font-size:clamp(16px, 16cqi, 28px); }
  /* 🐞 A BARRA TRANSBORDAVA NO TELEMÓVEL (apanhado na prova de tela, 24/08).
     O `.dash-periodo` é uma linha flex SEM quebra, e a navegação nasceu lá
     dentro: a 375px o rótulo saía cortado — "Julho 202" — e a seta `›` e o
     "Agora" ficavam fora do ecrã, sem nada a dizer que existiam.
     ⭐ `flex-wrap` na barra e linha inteira para a navegação: as lentes em cima,
     o tempo em baixo. */
  .dash-periodo{ display:flex; width:100%; flex-wrap:wrap; }
  /* ⚠️ 10px de respiro e não 14: medido a 375px, os quatro pedaços pediam 330
     numa barra de 319 — e o que sobrava dos 11px em falta era a segunda linha
     do "Arrumar o painel", que esticava a fila toda para 51px de altura.
     ⭐ A altura do alvo não vem daqui: vem do `pointer:coarse` mais abaixo. */
  .dash-per{ flex:1; text-align:center; padding:6px 10px; }
  /* 🐞 A CULPADA DAS DUAS LINHAS. Ver a nota na view: aqui troca-se o rótulo
     longo pelo verbo, e a porta deixa de pedir a fatia de uma lente.
     ⚠️ O `flex:0 0 auto` tem de estar AQUI dentro: a regra de cima vive antes
     da média no ficheiro e tem o mesmo peso, portanto o `flex:1` das lentes
     ganhava-lhe por ordem — e os quatro pedaços voltavam a ser iguais, com o
     link a parecer a quarta régua. */
  .dash-arrumar{ flex:0 0 auto; }
  .arrumar-longo{ display:none; }
  .arrumar-curto{ display:inline; }
  /* ⚠️ As setas vão para as PONTAS e o rótulo fica no meio, que é onde o polegar
     alcança as duas sem esticar — e é a mesma forma do `.mes-nav` do Diário no
     telemóvel, que ele já usa todos os dias. */
  .dash-nav{ display:flex; flex:1 0 100%; margin:8px 0 0; justify-content:space-between; }
  .dash-nav-rot{ flex:1; }
  /* ⚠️ A navegação ocupa a linha inteira e por isso EMPURRA quem vem depois
     dela no HTML — o "Arrumar o painel" caía sozinho numa terceira linha. A
     ordem visual arruma isso sem mexer no HTML: lentes e "arrumar" em cima, o
     tempo em baixo. Duas linhas, e não três, antes de o painel começar. */
  .dash-nav{ order:3; }
  .dash-arrumar{ order:2; }
  /* ⚠️ Já está dentro da navegação: aqui só se garante que não encolhe. */
  .dash-nav-agora{ flex:0 0 auto; }
}

/* Relógio de ganhos (funcionário) + tela de Salários */
.relogio{ background:var(--branco); border:1px solid var(--cinza-borda); border-radius:var(--raio);
  padding:20px 22px; margin:0 auto 22px; max-width:420px; text-align:center; }
.relogio-topo{ display:flex; align-items:center; justify-content:center; gap:10px; margin-bottom:6px; }
.relogio-rot{ font-size:13px; font-weight:600; color:var(--cinza-medio); text-transform:uppercase; letter-spacing:1px; }
.relogio-pulso{ font-size:11.5px; font-weight:700; color:var(--vermelho);
  background:color-mix(in srgb, var(--vermelho) 12%, transparent); padding:2px 9px; border-radius:999px; }
.relogio-ativo .relogio-pulso{ animation:pulsa 1.6s ease-in-out infinite; }
@keyframes pulsa{ 0%,100%{ opacity:1 } 50%{ opacity:.45 } }
.relogio-valor{ font-family:var(--fonte-titulo); font-size:40px; font-weight:700; letter-spacing:-1px; line-height:1.1; }
.relogio-tempo{ color:var(--cinza-medio); font-size:14px; margin-top:2px; }
.relogio-mes{ display:flex; align-items:baseline; justify-content:center; gap:8px;
  margin-top:14px; padding-top:12px; border-top:1px solid var(--cinza-borda); font-size:14px; }
.relogio-mes span{ color:var(--cinza-medio); }
.relogio-nota{ margin-top:12px; font-size:11.5px; line-height:1.5; color:var(--cinza-medio); text-align:left; }
.aviso-sensivel{ background:color-mix(in srgb, var(--vermelho) 7%, transparent);
  border:1px solid color-mix(in srgb, var(--vermelho) 25%, transparent);
  color:var(--preto); padding:11px 14px; border-radius:var(--raio-sm); font-size:13.5px; margin-bottom:18px; }
.inp-sal{ width:110px; padding:6px 9px; text-align:right; font:inherit; font-size:14px;
  border:1.5px solid var(--cinza-borda); border-radius:var(--raio-sm); background:var(--branco); color:var(--preto); }
.inp-sal:focus{ outline:none; border-color:var(--preto); }
.sel-sal{ padding:6px 9px; font:inherit; font-size:14px; border:1.5px solid var(--cinza-borda);
  border-radius:var(--raio-sm); background:var(--branco); color:var(--preto); }

/* Análises de reservas: barras em CSS puro (sem biblioteca) */
.cartoes-taxa{ display:flex; flex-wrap:wrap; gap:16px; margin-bottom:26px; }
.cartao-taxa{ flex:1 1 220px; background:var(--branco); border:1px solid var(--cinza-borda);
  border-radius:var(--raio-sm); padding:16px 18px; }
.taxa-topo{ display:flex; align-items:baseline; justify-content:space-between; gap:10px; margin-bottom:10px; }
.taxa-rot{ font-size:13.5px; color:var(--cinza-medio); font-weight:600; }
.taxa-val{ font-family:var(--fonte-titulo); font-size:24px; }
.barra-fundo{ background:var(--cinza-claro, #f0f0f2); border-radius:999px; height:9px; overflow:hidden; flex:1; }
.barra-fill{ height:100%; border-radius:999px; background:var(--vermelho); transition:width .3s; }
.barra-fill.tom-ok{ background:#16a34a; }
.barra-fill.tom-ruim{ background:var(--vermelho); }
.barra-fill.tom-neutro{ background:var(--cinza-medio); }
.grade-analises{ display:flex; flex-wrap:wrap; gap:28px; margin-bottom:8px; }
.bloco-analise{ flex:1 1 320px; min-width:280px; }
.linha-barra{ display:flex; align-items:center; gap:12px; margin-bottom:8px; }
.barra-rot{ width:44px; flex:none; font-size:13px; color:var(--cinza-medio); font-weight:600; }
.barra-rot-larga{ width:110px; }
.barra-num{ width:44px; flex:none; text-align:right; font-size:13.5px; font-weight:700; }
.grade-origem{ max-width:520px; }
@media (max-width:600px){ .barra-rot-larga{ width:80px; } }

/* Trilha de auditoria */
.form-filtros{ display:flex; flex-wrap:wrap; gap:14px; align-items:flex-end; margin-bottom:18px; }
.form-filtros .campo{ margin-bottom:0; display:flex; flex-direction:column; }
.form-filtros .campo > label{ display:block; font-size:13px; font-weight:600; color:var(--cinza-medio); margin-bottom:6px; }
/* o form de filtros não fica dentro de .form, então os campos não herdavam o
   estilo do sistema: select e input[type=date] vinham com a altura padrão do
   navegador (diferentes entre si) e os rótulos desalinhavam. Iguala tudo. */
.form-filtros .campo select,
.form-filtros .campo input{
  height:44px; padding:0 14px; font-family:var(--fonte-texto); font-size:15px;
  border:1.5px solid var(--cinza-borda); border-radius:var(--raio-sm);
  background:var(--branco); color:var(--preto);
}
.form-filtros .campo select:focus,
.form-filtros .campo input:focus{ outline:none; border-color:var(--preto); }
.form-filtros .campo-acao{ display:flex; flex-direction:row; gap:10px; align-items:center; height:44px; }
.form-filtros .campo-acao .btn-inline{ padding:0 20px; height:44px; line-height:42px; }
.selo-aud{ background:var(--cinza-claro, #f0f0f2); color:var(--cinza-medio); }   /* forma: ver .selo */
.selo-aud.aud-excluir{ background:color-mix(in srgb, var(--vermelho) 14%, transparent); color:var(--vermelho); }
.selo-aud.aud-criar{ background:color-mix(in srgb, #16a34a 14%, transparent); color:#15803d; }
.selo-aud.aud-editar, .selo-aud.aud-status{ background:color-mix(in srgb, #2563eb 12%, transparent); color:#1d4ed8; }
.selo-aud.aud-aprovar{ background:color-mix(in srgb, #16a34a 14%, transparent); color:#15803d; }
.selo-aud.aud-recusar{ background:color-mix(in srgb, var(--vermelho) 12%, transparent); color:var(--vermelho); }
.td-quando{ white-space:nowrap; }
.td-detalhe{ color:var(--cinza-medio); font-size:13.5px; }
.paginacao{ display:flex; align-items:center; justify-content:center; gap:14px; margin-top:18px; }

/* Fluxo de atendimento: grade do mês com lançamento dos avulsos */
.tabela-fluxo th{ text-align:center; }
.tabela-fluxo td{ text-align:center; }
.tabela-fluxo .td-nome{ text-align:left; white-space:nowrap; }
.tabela-fluxo .grupo-almoco, .tabela-fluxo .grupo-jantar{
  border-bottom:2px solid color-mix(in srgb, var(--vermelho) 35%, transparent);
}
.tabela-fluxo tfoot th{ background:color-mix(in srgb, var(--vermelho) 7%, transparent); font-weight:700; }
.tabela-fluxo .linha-hoje{ background:color-mix(in srgb, var(--vermelho) 5%, transparent); }
.inp-fluxo{
  width:64px; padding:5px 7px; text-align:center; font:inherit; font-size:13.5px;
  border:1.5px solid var(--cinza-borda); border-radius:var(--raio-sm); background:var(--branco); color:var(--preto);
}
.inp-fluxo:focus{ outline:none; border-color:var(--preto); }
.fluxo-salvar{ position:sticky; bottom:14px; margin-top:16px; z-index:5; }
.fluxo-salvar .btn{ box-shadow:var(--sombra); }

/* dias fechados (exceções) na Disponibilidade */
.fech-form{ display:flex; gap:10px; flex-wrap:wrap; align-items:center; margin:12px 0 16px; }
.fech-form input[type="date"]{ padding:9px 10px; border:1.5px solid var(--cinza-borda); border-radius:var(--raio-sm); font:inherit; background:var(--branco); }
.fech-form input[type="text"]{ flex:1; min-width:200px; padding:9px 12px; border:1.5px solid var(--cinza-borda); border-radius:var(--raio-sm); font:inherit; }
.fech-lista{ display:flex; flex-direction:column; gap:8px; }
.fech-item{ display:flex; align-items:center; gap:14px; background:var(--branco); border:1px solid var(--cinza-borda);
  border-left:3px solid #b3261e; border-radius:var(--raio-sm); padding:10px 14px; }
.fech-item .fech-motivo{ color:var(--cinza-medio); flex:1; }
/* faixa "fechado" na agenda */
.agenda-fechado{ background:#fdecef; border:1px solid #f6c9d3; color:#a3122c; padding:12px 16px;
  border-radius:var(--raio-sm); margin-bottom:18px; font-size:14px; font-weight:600; }

/* ═══ modo operação: a tela do turno ═══
   🐞 08/08/2026 (ele, com o ecrã do portátil à frente): *"as reservas estão
   todas umas embaixo das outras formando uma coluna, quando poderiam estar em
   3 colunas... reorganiza essa regra da página pra sempre aproveitar o espaço"*.

   ⚠️ A CAUSA não era a lista: era a grade. Era `340px 1fr`, com o ponto a
   ocupar a coluna fixa. Só que o bloco do ponto é CONDICIONAL — quem não tem
   registo de colaborador (a administração, por exemplo) não o vê —, e aí as
   reservas caíam na coluna de 340px e o `1fr` ficava vazio o ecrã todo. Um
   layout que só funciona quando um bloco opcional existe não é um layout.

   Agora as colunas nascem do espaço que há (`auto-fill`), e não de um número
   escrito à mão. `dense` é o que fecha os buracos: um bloco largo obriga a
   mudar de linha, e sem ele os blocos pequenos que vêm a seguir não recuavam
   para preencher a linha de cima. */
/* ⚠️ `min(300px, 100%)` e não `300px` seco: num ecrã de 320px o mínimo fixo era
   maior que o espaço disponível e a página passava a rolar de lado. Ver
   [[dext-responsivo]] — nesta casa nada tem licença para alargar a página. */
.op-grade{
  display:grid; grid-template-columns:repeat(auto-fill, minmax(min(300px, 100%), 1fr));
  gap:22px; align-items:start; grid-auto-flow:row dense;
}
/* ⚠️ `1/-1` e não `span 2`: com auto-fill o número de colunas é desconhecido, e
   um `span` maior que a grade cria colunas implícitas — a página passava a
   rolar de lado no telemóvel. `1/-1` significa "todas as que houver", seja uma
   ou cinco. Reservas e mesas são as duas listas que se repartem por dentro:
   dar-lhes a largura toda é o que lhes permite fazer as suas próprias colunas. */
.op-reservas, .op-mesas{ grid-column:1/-1; }
.op-bloco .secao-titulo{ margin-bottom:10px; }
.op-bater{ max-width:none; }
.op-mesas-grade{ display:grid; grid-template-columns:repeat(auto-fill, minmax(120px, 1fr)); gap:10px; }
.op-mesa{ display:flex; flex-direction:column; gap:2px; padding:12px 14px; border-radius:var(--raio-sm);
  border:1px solid var(--cinza-borda); background:var(--branco); font-size:13px; }
.op-mesa span{ color:var(--cinza-medio); font-size:12px; }
.op-mesa-livre{ border-left:3px solid #16a34a; }
.op-mesa-livre .op-mesa-estado{ color:#15803d; font-weight:700; }
.op-mesa-ocupada{ border-left:3px solid #b3261e; background:var(--cinza-fundo); }
.op-mesa-ocupada .op-mesa-estado{ color:#b3261e; font-weight:700; }
@media (max-width:820px){ .tabela-fluxo td, .tabela-fluxo th{ text-align:left; } }

/* Zona de perigo (ações destrutivas, ex.: excluir cliente) — discreta, no rodapé. */
.zona-perigo{ margin-top:34px; padding-top:20px; border-top:1px solid var(--cinza-borda); }
.btn-perigo{
  display:inline-block; text-decoration:none; text-align:center;
  font-family:var(--fonte-texto); font-weight:600; font-size:14px; cursor:pointer;
  padding:10px 18px; border-radius:var(--raio-sm);
  background:transparent; color:var(--vermelho); border:1.5px solid var(--vermelho);
  transition:background .15s, color .15s;
}
.btn-perigo:hover{ background:var(--vermelho); color:#fff; }

.alerta{
  background:#fdecef; border:1px solid #f6c9d3; color:#a3122c;
  padding:11px 14px; border-radius:var(--raio-sm); font-size:14px; margin-bottom:20px;
}
.rodape-form{ margin-top:26px; color:var(--cinza-medio); font-size:13px; }
.rodape-form a{ color:var(--vermelho); text-decoration:none; font-weight:600; }
.rodape-form a:hover{ text-decoration:underline; }
.login-esqueci{ margin-top:16px; font-size:14px; }
.login-esqueci a{ color:var(--vermelho); text-decoration:none; font-weight:600; }
.login-esqueci a:hover{ text-decoration:underline; }

/* Responsivo — empilha no celular */
@media (max-width:820px){
  .login{ flex-direction:column; }
  .login__marca{ flex:none; padding:40px 24px; }
  .login__marca .simbolo{ width:56px; height:56px; margin-bottom:14px; }
  .login__marca .wordmark{ width:118px; }
  .login__marca .tagline{ display:none; }
  .login__form{ flex:none; padding:32px 24px 48px; }

  /* Mobile: tira a marca d'água do painel preto (topo) e leva pra área branca,
     atrás do login, contida (overflow:hidden do .login__form) — não invade o preto. */
  .login__marca::before{ display:none; }
  .login__form::before{
    content:''; position:absolute; z-index:0; pointer-events:none;
    left:50%; top:50%; transform:translate(-50%,-50%);
    width:min(135vw, 480px); height:min(135vw, 480px);
    background:url('/assets/img/dext-icon.svg') no-repeat center center; background-size:contain;
    opacity:.05; /* "D" cinza sutil sobre o branco */
  }
}

/* ============================================================
   PAINEL — barra superior + cartões de módulo
   ============================================================ */
.topo{
  background:var(--preto); color:var(--branco);
  display:flex; align-items:center; justify-content:space-between;
  padding:14px 22px;
}
.topo .marca{ display:flex; align-items:center; gap:12px; text-decoration:none; }
.topo .marca .sim{ width:30px; height:30px; }
.topo .marca .wm{ height:19px; width:auto; display:block; }
.topo-esq{ display:flex; align-items:center; gap:14px; min-width:0; }
.topo-sep{ width:1px; height:24px; background:rgba(255,255,255,.18); flex:none; }
.empresa-marca{ display:inline-flex; align-items:center; gap:8px; min-width:0; background:color-mix(in srgb, var(--vermelho) 8%, transparent); border:1px solid transparent; padding:5px 12px; border-radius:999px; }
.empresa-logo{ height:22px; width:auto; max-width:100px; object-fit:contain; border-radius:var(--raio-xs); background:#fff; padding:2px; }
.empresa-nome{ font-weight:600; font-size:14px; color:var(--vermelho); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; max-width:200px; }
.logo-atual{ margin-bottom:10px; }
.logo-atual img{ max-height:60px; max-width:220px; background:var(--cinza-fundo); border:1px solid var(--cinza-borda); border-radius:var(--raio-sm); padding:6px; }
.endereco-linha{ display:flex; gap:8px; }
.endereco-linha input{ flex:1; }
.btn-buscar{ white-space:nowrap; padding:0 14px; border:1.5px solid var(--cinza-borda); border-radius:var(--raio-sm); background:var(--branco); font-family:var(--fonte-texto); font-weight:600; font-size:13px; cursor:pointer; }
.btn-buscar:hover{ border-color:var(--preto); }
.mapa-config{ height:320px; border-radius:var(--raio-sm); border:1px solid var(--cinza-borda); overflow:hidden; z-index:0; }
.topo .user{ display:flex; align-items:center; gap:14px; font-size:14px; }
.topo .user .nome-user{ font-weight:700; color:var(--branco); }
.topo .user .badge{
  background:rgba(255,255,255,.12); color:var(--cinza);
  padding:4px 10px; border-radius:999px; font-size:12px; font-weight:600;
  text-transform:capitalize;
}
.topo .user .badge-admin{ background:color-mix(in srgb, var(--vermelho) 8%, transparent); color:var(--vermelho); }
.topo a.sair{ color:var(--cinza); text-decoration:none; font-weight:600; font-size:13px;
  background:rgba(255,255,255,.08); border:1px solid rgba(255,255,255,.14);
  padding:6px 14px; border-radius:999px; transition:background .15s, border-color .15s, color .15s; }
.topo a.sair:hover{ color:var(--vermelho); border-color:var(--vermelho); box-shadow:0 4px 14px color-mix(in srgb, var(--vermelho) 14%, transparent); }
@media (max-width:600px){
  .topo{ padding:12px 16px; }
  .topo .user{ gap:8px; }
  .topo a.sair{ padding:6px 11px; }
  .topo .user .nome-user{ display:none; } /* no celular, só badge + sair */
  .topo .marca .wm{ display:none; }       /* no celular, só o símbolo Dext */
  .topo-esq{ gap:10px; }
  .empresa-nome{ max-width:120px; font-size:14px; }
}

.conteudo{ max-width:1000px; margin:0 auto; padding:40px 22px; }

/* ⭐ TELA COM TABELA LARGA USA O ECRÃ QUE EXISTE (pedido dele, 03/08/2026, num
   portátil de 13": "é pra se adaptar a telas menores, mas se tem espaço, quero
   que ela se abra o máximo").
   Os 1000px são uma largura de LEITURA, boa para formulários e texto corrido, e
   má para uma tabela de 8 colunas: sobrava ecrã à direita e o Diário aparecia
   cortado na horizontal. Só que alargar tudo estragava as telas de texto.
   ⚠️ Por isso a regra é condicional, e a condição é a própria tabela: uma tela
   que tenha um `.tabela-wrap` cresce, as outras ficam como estavam. É por isto
   que serve para o sistema inteiro sem se ir a cada tela marcá-la à mão.
   `@supports` porque o `:has()` não existe em navegadores antigos — lá, fica
   nos 1000px de sempre, que é o comportamento de hoje, e nada quebra. */
@supports selector(:has(*)) {
  /* ⭐ F11 (13/08/2026, ele: *"alargar o Resumo como se fez com a tabela de
     Lançamentos; há tabelas com informação a sair fora e outras apertadas"*).
     O Resumo não tem `.tabela-wrap` — são cartões com mini-tabelas — e por isso
     ficava nos 1000px com meio ecrã por usar, com os nomes das categorias a
     partir-se em duas linhas dentro de cartões de 308px.
     ⚠️ A condição continua a ser o CONTEÚDO e não o nome da tela: quem tem
     tabela larga (ou a grade do Resumo) cresce, o resto fica como está. */
  /* ⭐ A ESCALA TAMBÉM CRESCE (19/08/2026). Ele: *"dá pra deixar essa janela da
     escala inteira? Aqui pode aparecer inteira. Tem espaço."*
     ⚠️ A grelha é `width:100%` da coluna e os chips do turno
     (`17:00–23:30 15' ×`) empurram cada dia para ~170px. Com a coluna nos
     1000px, sete dias mais o nome e o total não cabiam e a semana ficava
     cortada ao meio. A condição continua a ser o CONTEÚDO e não o nome da
     tela. */
  /* ⭐⭐ O PAINEL TAMBÉM CRESCE (ele, 23/08/2026, com o print de um portátil de
     13": *"pode deixar o Dashboard mais largo, inclusive daria pra não ter
     algumas janelas precisando de barra de rolagem"*).
     🚨 E as barras de rolagem que ele viu são consequência DISTO, não um defeito
     à parte: o painel é uma grelha de peças de 300px mínimos, e nos 1000px cabem
     três — a *"Aproveitamento geral"* e a *"A equipe no período"* ficavam com
     ~370px cada, e as tabelas de 4 e 5 colunas lá dentro rolavam de lado. Com
     1560px cabem as colunas, e a rolagem some por não ser precisa.
     ⚠️ A condição continua a ser o CONTEÚDO e não o nome da tela: é o `.dash-sec`
     (o painel por secções) e o `.dash-blocos` (o painel de um módulo) que
     mandam. Uma tela que um dia mostre uma peça destas cresce sozinha.
     ⚠️ No telemóvel não muda nada, e não é preciso media query nenhuma: um
     `max-width` de 1560px não alarga uma tela de 375px, e lá a grelha das peças
     já empilha numa coluna sozinha. */
  .conteudo:has(.tabela-wrap),
  .conteudo:has(.escala-wrap),
  .conteudo:has(.dash-sec),
  .conteudo:has(.dash-blocos),
  .conteudo:has(.resumo-grade){ max-width:1560px; }
  /* Numa tela mista (tabela + formulário), o formulário não deve esticar com
     ela: um campo de 1400px de largura não se lê melhor, lê-se pior. */
  .conteudo:has(.tabela-wrap) > .form,
  .conteudo:has(.tabela-wrap) > .pagina-cabecalho + .form{ max-width:720px; }
}
.conteudo .ola{ font-family:var(--fonte-titulo); font-weight:700; font-size:26px; letter-spacing:-.5px; }
.conteudo .ola-sub{ color:var(--cinza-medio); margin:6px 0 32px; }

.grade{ display:grid; grid-template-columns:repeat(auto-fill,minmax(220px,1fr)); gap:16px; }
.modulo{
  background:var(--branco); border:1px solid var(--cinza-borda); border-radius:var(--raio);
  padding:22px; box-shadow:var(--sombra);
}
.modulo .ic{
  width:44px; height:44px; border-radius:var(--raio); background:var(--menu);
  display:flex; align-items:center; justify-content:center; color:var(--destaque-menu); margin-bottom:16px;
}
.modulo .ic svg{ width:23px; height:23px; }
.modulo.em-breve .ic{ color:var(--cinza-medio); background:var(--cinza-fundo); }
.modulo h3{ font-family:var(--fonte-titulo); font-weight:700; font-size:17px; margin-bottom:4px; }
.modulo p{ color:var(--cinza-medio); font-size:13.5px; }
.modulo.em-breve{ opacity:.62; }
/* ⚠️ `.modulo .tag` MORREU a 28/08/2026 — o *"Em breve"* dos módulos por abrir.
   🚨 Levava `background:#fdecef` escrito à mão, que é o `--vermelho-sinal-fundo`
   da paleta letra a letra: a cor do ERRO, num rótulo que não diz erro nenhum.
   ⭐ Passou a `selo-neutro`, e o tom é uma decisão, não uma cópia: *"Em breve"*
   **classifica sem julgar**, que é a definição do neutro. Vermelho ali dizia
   *"algo está mal"* de um módulo que apenas ainda não abriu — e a grelha mostra
   vários ao mesmo tempo, o que é exatamente o *"se tudo é destaque, nada é"*.
   ⚠️ O `margin-top:12px` era posicionamento, não peça: fica, com nome de sítio.
   Ver `app/Views/modulo.php`. */
.modulo .selo{ margin-top:12px; }
a.modulo{ text-decoration:none; color:inherit; display:block; transition:transform .12s, box-shadow .12s; }
a.modulo:hover{ transform:translateY(-2px); box-shadow:0 16px 44px rgba(17,17,17,.13); }

/* ============================================================
   PÁGINAS INTERNAS — cabeçalho, tabela e formulário
   ============================================================ */
.conteudo-estreito{ max-width:640px; }
.voltar{ display:inline-flex; align-items:center; gap:6px; color:var(--preto); text-decoration:none;
  font-size:13px; font-weight:600; margin-bottom:18px; background:var(--branco);
  border:1px solid var(--cinza-borda); padding:7px 14px 7px 11px; border-radius:999px;
  box-shadow:0 2px 8px rgba(17,17,17,.05); transition:border-color .15s, color .15s, box-shadow .15s; }
.voltar:hover{ color:var(--vermelho); border-color:var(--vermelho); box-shadow:0 4px 14px color-mix(in srgb, var(--vermelho) 14%, transparent); }

.pagina-cabecalho{ display:flex; align-items:flex-end; justify-content:space-between; gap:20px; margin-bottom:26px; }
.pagina-titulo{ font-family:var(--fonte-titulo); font-weight:700; font-size:26px; letter-spacing:-.5px; }
.pagina-sub{ color:var(--cinza-medio); font-size:14px; margin-top:4px; }

.btn-inline{ width:auto; display:inline-block; padding:11px 18px; text-decoration:none; text-align:center; white-space:nowrap; }

/* min-width:0 é o que faz o overflow-x funcionar de facto: sem ele a caixa
   herda a largura mínima da tabela e, em vez de rolar por dentro, empurra a
   página inteira para o lado no telemóvel. */
.tabela-wrap{ background:var(--branco); border:1px solid var(--cinza-borda); border-radius:var(--raio); overflow-x:auto; min-width:0; box-shadow:var(--sombra); }
.tabela{ width:100%; border-collapse:collapse; font-size:14px; }
.tabela thead th{
  text-align:left; font-size:12px; font-weight:600; text-transform:uppercase; letter-spacing:.5px;
  color:var(--cinza-medio); padding:13px 18px; border-bottom:1px solid var(--cinza-borda);
}
.tabela tbody td{ padding:14px 18px; border-bottom:1px solid var(--cinza-borda); }
.tabela tbody tr:last-child td{ border-bottom:none; }
.tabela .td-nome{ font-weight:600; }
.tabela .linha-inativa{ opacity:.5; }
/* ⭐ MARCADOR COM DONO: `ajuda-fixa` diz ao recolhedor de dicas
   (`public/assets/js/dica.js`) que este texto NÃO se esconde atrás de um "?" —
   é rótulo, não instrução. Fica com regra própria por duas razões: para o
   marcador ter dono no CSS (a varredura de markup sem estilo cobra isso, e com
   razão) e porque um rótulo de unidade anda AO LADO do número, não numa linha
   só para ele como as ajudas de campo. */
.ajuda-fixa{ display:inline; }

.td-acoes{ text-align:right; white-space:nowrap; }

/* ⭐⭐ AS AÇÕES FICAM PRESAS À DIREITA (26/08/2026). Ele: *"o Desativar tá quase
   pra fora quando abre-se um item e a tela retrai."*
   🚨 Medido antes de mexer, na tela dos Produtos com um item aberto: o
   contentor cai para **606px**, a tabela precisa de **840** e o botão acaba
   **215px para fora** — atrás da barra de rolagem lateral, onde ninguém o
   procura. E o gesto que ele quer fazer é logo o de desativar.
   ⭐ Prender a coluna em vez de esconder colunas: **nenhum dado dele
   desaparece**, o resto da linha desliza por baixo e o botão está sempre lá.
   ⚠️ O fundo é obrigatório: sem ele vê-se o texto da linha a passar por baixo
   dos botões, que é pior do que o problema original.
   ⚠️ E o traço à esquerda é o que diz que aquilo está POUSADO por cima — sem
   ele parece uma coluna normal que por acaso não se mexe. */
.tabela-acoes-fixas th.td-acoes,
.tabela-acoes-fixas td.td-acoes{
  position:sticky; right:0; z-index:2;
  background:var(--branco); box-shadow:-8px 0 8px -8px rgba(0,0,0,.14);
}
.tabela-acoes-fixas thead th.td-acoes{ background:var(--branco); }
/* ⚠️ Uma linha marcada muda de fundo, e a célula presa tem de acompanhar —
   senão fica um retângulo branco a flutuar sobre a linha realçada. */
.tabela-acoes-fixas tbody tr:hover td.td-acoes{ background:var(--cinza-claro, #f0f0f2); }
/* ⭐⭐ A AÇÃO NA LINHA (18/08/2026, segunda passagem do padrão visual).
   🚨 Ela era VERMELHA POR OMISSÃO, e isso é o contrário do que o manual da
   marca manda: o vermelho é acento, nunca o quotidiano. Medido nas views: 14
   ações saíam vermelhas sem ninguém ter pedido (Editar, Acessar, Aprovar,
   "Preencher eu mesmo"), 12 tinham `link-neutro` para as acalmar, e 11 eram
   vermelhas de propósito. A MESMA ideia, três roupas.
   ⚠️ Em `/reservas/clientes` isto são **537 "Editar" a vermelho** num ecrã só.
   ⭐ Passam a existir DOIS estados e não três: **normal** (tinta) e
   **destrutivo** (vermelho). Quem destrói é o único a gritar.
   ⚠️ Não vira botão: a lista de clientes tem 537 linhas, e 537 cápsulas com
   borda seriam uma parede. O molde é o do Financeiro, que já usa micro-link
   escuro na linha e guarda a cápsula escura para a ação principal da tela. */
.link-acao{
  background:none; border:none; padding:0 0 0 14px; cursor:pointer; font-family:var(--fonte-texto);
  font-size:13px; font-weight:600; color:var(--texto); text-decoration:none;
}
.link-acao:hover{ text-decoration:underline; color:var(--destaque); }
/* ⚠️ `link-neutro` era o remendo de quem não queria a ação vermelha. Agora o
   normal já é sereno, portanto ele não tem trabalho: fica como álias enquanto
   as views não o largam, e `test-acao-linha.php` conta-o a descer. */
.link-neutro{ color:var(--texto); }
.link-perigo{ color:#b3261e; font-weight:700; }
.aviso-linha{ display:flex; align-items:stretch; gap:8px; }
.aviso-linha .aviso-item{ flex:1; }
.aviso-excluir{ display:flex; align-items:center; justify-content:center; padding:0 14px; text-decoration:none;
  color:#b3261e; font-size:20px; font-weight:700; line-height:1; border:1px solid var(--cinza-borda); border-radius:var(--raio-sm); }
.aviso-excluir:hover{ background:color-mix(in srgb, #b3261e 8%, transparent); }

/* ⭐⭐ O SELO: A ETIQUETA DE ESTADO DA CASA (18/08/2026).
   Ele: *"metade dela tá num nível, a outra metade em outro."* Ao abrir o CSS,
   a mesma forma estava escrita **cinco vezes**, com medidas diferentes em cada
   uma: `.pill` (12px/600), `.lanc-tag` (11px/700), `.pill-aud` (12px/700),
   `.pill-status` e `.pill-perfil` (11px/700). 76 usos nas views.
   ⭐⭐ **A MIGRAÇÃO ACABOU (26/08/2026).** Ele: *"tem uns módulos que estão ok,
   outros ainda falta. Vai um por um e deixa tudo no mesmo nível."* Os cinco
   nomes velhos saíram das 36 telas que ainda os usavam e desapareceram daqui:
   **há uma forma e um nome só.** O que sobra dos nomes antigos são as regras de
   COR (`.pill-ativo`, `.pill-pedido`, `.pill-motivo-*`…), que não desenham
   forma nenhuma e por isso não confundem ninguém.
   ⚠️ As medidas são escolhidas, não a média: 11,5px e peso 700 porque isto é
   rótulo e não texto, e `inline-flex` com `gap` para caber um ícone sem
   ninguém precisar de reescrever a forma outra vez. */
.selo{
  display:inline-flex; align-items:center; gap:5px;
  font-size:11.5px; font-weight:700; line-height:1.45;
  padding:3px 10px; border-radius:999px; white-space:nowrap;
}

/* ⭐⭐⭐ A PALETA DO SELO — cinco tons, e cada um com um trabalho.
   Ele, 26/08/2026: *"alguns até colorido, pra dar destaque e deixar mais
   bonito."* ⚠️ Cinco, e não um arco-íris: **se tudo é destaque, nada é.** Um
   sexto tom tem de justificar o que os cinco não dizem.

     neutro   classifica sem julgar (o tipo, a unidade, a origem)
     ok       está como devia (ativo, conferido, pago)
     alerta   pede atenção, não é erro (por conferir, vence hoje)
     perigo   está errado ou em falta (sem preço, em atraso, negativo)
     marca    destaque da casa, e o mais raro: use-se UM por tela

   ⚠️ Fundo lavado e texto forte — nunca o contrário. É a regra da casa:
   *"cor forte só em selo pequeno; superfície grande leva cor em traço"*, e um
   selo com fundo saturado transforma-se ele próprio em superfície. */
.selo-neutro{ background:var(--cinza-fundo); color:var(--cinza-medio); }
.selo-ok     { background:var(--verde-fundo); color:var(--verde); }
.selo-perigo { background:var(--vermelho-sinal-fundo); color:var(--vermelho-sinal); }
/* ⚠️ `--vermelho` É a cor da marca: o `layout.php` aponta-lhe o `--destaque`
   escolhido pela empresa. Escrever um hexadecimal aqui dava a cor da Dext na
   casa dele — e a folha de papel já ensinou essa lição uma vez. */
.selo-marca  { background:color-mix(in srgb, var(--vermelho) 10%, transparent);
               color:var(--vermelho); }

/* ⚠️ Os dois nomes antigos das cores ficam, e apontam para os novos: são 30
   usos em telas que já estão certas, e renomeá-los agora era mexer em trinta
   sítios para não mudar um pixel. Morrem quando alguma delas for tocada. */
.pill-ativo{ background:var(--verde-fundo); color:var(--verde); }
.pill-inativo{ background:var(--cinza-fundo); color:var(--cinza-medio); }
.vazio{ background:var(--branco); border:1px dashed var(--cinza-borda); border-radius:var(--raio); padding:40px; text-align:center; color:var(--cinza-medio); }

/* Formulário */
.form{ background:var(--branco); border:1px solid var(--cinza-borda); border-radius:var(--raio); padding:26px; box-shadow:var(--sombra); }

/* ⭐⭐ AS SECÇÕES DE UMA TELA DE DEFINIÇÕES (18/08/2026).
   Ele: *"a tela tá indo muito além do que precisa, tá indo muito pra baixo a
   rolagem."* Medido em `/pessoas/config`: **10 campos em 1.828px**.
   ⚠️ A causa não era espaçamento a mais, era FORMA: três secções numa coluna de
   640px só podem ir para baixo. Aqui elas ficam lado a lado quando há largura,
   e empilham quando não há.
   ⚠️ Sem cartão dentro de cartão: quem desenha a moldura é o `.form`; estes
   blocos só organizam. `align-items:start` para uma secção curta não esticar até
   à altura da vizinha. */
.cfg-blocos{ display:grid; gap:14px 28px; align-items:start; }
@media (min-width:900px){ .cfg-blocos{ grid-template-columns:repeat(2, minmax(0,1fr)); } }
/* ⭐⭐ A LINHA COM MARCA DE TIPO (18/08/2026, pedido dele: os cards de mesa "no tamanho
   da linha"). A cor à esquerda diz o TIPO sem gastar uma coluna — na lista de
   fichas ela substituiu a coluna "Tipo" inteira, e as 22 intermediárias
   deixaram de pagar três colunas de traços só para existir.
   ⚠️ A barra é do PRIMEIRO td e não do tr: border em <tr> não pinta igual em
   todos os browsers, e no telemóvel (tabela→cartão) o td vira a borda do
   próprio cartão sem regra nova.
   Os nomes das cores são PAPÉIS: aceso é o que a tela julga, apagado é o que
   está fora do julgamento. Outra lista pode usar os mesmos três papéis. */
🚨 O nome `linha-barra` JÁ EXISTIA (`.linha-barra{display:flex}`, das análises
   de reservas) e eu escolhi-o às cegas: as minhas linhas ficaram flex e a tabela
   perdeu o alinhamento das colunas no computador. Chama-se `linha-marca`.
   ⚠️ Classe nova pede uma busca pelo nome ANTES, não depois. */
.linha-marca > td:first-child{ border-left:3px solid var(--linha-cor, var(--cinza-borda)); }
.linha-tipo-venda{ --linha-cor:var(--destaque); }
.linha-tipo-intermedia{ --linha-cor:var(--cinza); }
.linha-tipo-revenda{ --linha-cor:var(--cinza-medio); }

/* O primeiro título de cada bloco não empurra: quem separa é a grelha. */
.cfg-bloco > .secao-titulo:first-child{ margin-top:0; }
/* ⚠️ Nem toda a secção quer meia largura. A lista de documentos MEDIU 436px a
   542 de largo e **739px** a 437: estreitá-la fazia-a crescer mais do que a
   coluna poupava. Quem tem uma lista larga por dentro fica com a linha toda. */
@media (min-width:900px){ .cfg-bloco-largo{ grid-column:1 / -1; } }

/* ⭐ O CARTÃO DA CASA (11/08/2026).
   ⚠️ **Esta classe era usada em 7 sítios do HTML e NUNCA existiu no CSS.** A
   tela das Tarefas inteira — o formulário, as subtarefas, os anexos, os
   comentários e o gerir projetos — desenhava-se como blocos transparentes sobre
   o fundo cinzento da página. É a explicação mecânica de porque ele olhou para
   o Gestor e disse *"parece que foi feito um rascunho"*: ao lado do `.form` do
   Financeiro, era mesmo outro produto.
   Mesmo corpo do `.form`, SEM padding: quem a usa (`.tar-form`, `.tar-bloco`,
   `.tar-gerir`, `.exec-desc`) já traz o seu, e impor um aqui somava dois. */
.cartao{ background:var(--branco); border:1px solid var(--cinza-borda);
  border-radius:var(--raio); box-shadow:var(--sombra); }
.form-linha{ display:grid; grid-template-columns:1fr 1fr; gap:16px; }
/* 🚨 SEM O `.form` À FRENTE — 26/08/2026, na auditoria.
   A regra estava presa a `.form`, e o `.campo input` logo acima **não está**.
   Resultado: numa tela que não abre `<form class="form">`, o campo e o seletor
   da mesma linha tinham larguras diferentes — foi a queixa dele no formulário
   da tarefa (*"tá avacalhado com os outros campos"*), que é `cartao tar-form`.

   ⚠️ Adiei a promoção nesse dia com medo do alcance, e **medi mal**: pensei em
   "dezenas de telas". Medido a sério no browser, tela a tela, eram **4
   seletores em 2 telas** — Lançamentos (3) e Receber (1). Um medo que custou
   uma regra duplicada.
   ⭐ Com isto, o `.tar-form .campo select` que eu tinha escrito à parte deixou
   de ser preciso: uma regra, e não duas a dizer o mesmo. */
.campo select{
  width:100%; padding:13px 15px; font-family:var(--fonte-texto); font-size:15px;
  border:1.5px solid var(--cinza-borda); border-radius:var(--raio-sm); background:var(--branco); color:var(--preto);
}
.campo select:focus, .campo input:focus{ outline:none; border-color:var(--preto); }
.ajuda{ display:block; font-size:12px; color:var(--cinza-medio); margin-top:6px; }
.form-acoes{ display:flex; align-items:center; gap:16px; margin-top:8px; }
/* ⚠️ O RESET VEM PRIMEIRO, e é o que faltava (26/08/2026). Esta regra dava só
   cor e peso, e num `<button>` sobrava todo o chrome do sistema operativo —
   fundo azul, borda e cantos do iPadOS. Num `<a>` nada disto existe, por isso
   os 15 usos em link nunca acusaram: **a classe dependia do elemento sem o
   dizer.** É a mesma família do botão branco sobre branco de 25/08.
   ⭐ Com o reset, ela vale nos dois — e o `padding:0`/`background:none` são
   inócuos num link, que já não tem nem um nem outro. */
.btn-cancelar{ appearance:none; -webkit-appearance:none; background:none; border:0; padding:0;
  font-family:inherit; cursor:pointer;
  color:var(--cinza-medio); text-decoration:none; font-weight:600; font-size:14px; }
.btn-cancelar:hover{ color:var(--preto); }

@media (max-width:600px){
  .form-linha{ grid-template-columns:1fr; }
  .pagina-cabecalho{ flex-direction:column; align-items:stretch; }
  /* barra de navegação + ações da escala: empilha e ocupa a largura, sem cortar */
  .escala-topo{ width:100%; }
  .escala-topo .mes-nav{ flex:1 1 100%; justify-content:space-between; }
  .escala-topo .btn, .escala-topo .inline-f, .escala-topo .inline-f .btn-mini{ width:100%; }
  .escala-topo .btn{ text-align:center; }
  /* `flex-wrap` já é o padrão do card; aqui só se manda as ações para a linha
     de baixo. Ver a nota do container query em .reserva-card. */
  .reserva-acoes{ flex:1 0 100%; justify-content:flex-start; padding-top:4px; }
  .tabela{ font-size:13px; }
  /* Botão de linha com rótulo longo ("Carregar feriados nacionais de Portugal
     2026") não cabe num telemóvel. O nowrap serve para rótulos curtos não
     partirem feio; aqui, quebrar linha é melhor do que empurrar a página toda
     para o lado. */
  .btn-inline{ white-space:normal; max-width:100%; }
  /* Navegação de período: as setas e o seletor de data já enchem a largura de um
     telemóvel, por isso o intervalo da semana passa para a linha de baixo em vez
     de espremer o campo. */
  .mes-nav{ flex-wrap:wrap; justify-content:center; }
  .mes-nav .mes-nav-faixa{ flex:1 0 100%; order:3; text-align:center; }

  /* Tabelas de AÇÃO viram cartões empilhados no celular: cada linha vira um
     bloco com rótulo por campo e as ações sempre visíveis (sem scroll lateral).
     Aplicar a classe .tabela-cards na <table> e data-label em cada <td>. */
  .tabela-cards thead{ position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0); }
  .tabela-cards, .tabela-cards tbody, .tabela-cards tr, .tabela-cards td{ display:block; width:100%; }
  .tabela-cards tr{ padding:10px 16px 12px; }
  /* ⭐⭐ UMA LINHA POR ITEM (18/08/2026). Ele, sobre as fichas: *"quero só uma
     linha. Quando clicar aparece mais informação. Tá grande igual o que eu
     falei do lançamento no financeiro estava."*
     📏 Medido antes: **389px por ficha**, 2,1 por ecrã, 76.037px de página. E
     três das sete células eram traços, porque uma intermediária não tem preço,
     CMV nem margem.
     ⭐ Fica o nome (com a barra do tipo) e o número que se compara. O resto vai
     para a ficha, que **já existia**: não inventei um segundo jeito de expandir,
     como no Diário.
     ⚠️ O toque é da LINHA inteira, sem JavaScript: o link do nome estica-se por
     cima dela. Só funciona porque aqui não há mais nada clicável na linha; numa
     lista com ações isto criava um link dentro de outro. */
  /* ⚠️ O seletor leva as DUAS classes de propósito. `.tabela-cards td` tem o
     mesmo peso e vive mais abaixo no ficheiro, portanto ganhava por ordem.
     Depender da ordem é o que faz uma regra partir-se quando alguém arruma o
     CSS; com as duas classes ela ganha esteja onde estiver. */
  .tabela-cards.tabela-compacta tr{ position:relative; display:flex; align-items:baseline;
    gap:10px; padding:11px 16px; }
  /* ⚠️ `tbody td` e não só `td`: há telas com `.tabela-cards td.td-acoes{display:flex}`,
     que empatava em peso e ganhava por vir mais abaixo. O `tbody` desempata sem
     obrigar ninguém a arrumar a ordem do ficheiro. */
  .tabela-cards.tabela-compacta tbody td{ display:none; }
  /* A caixa de seleção FICA: é o gesto que arruma o catálogo em lote, e no
     telemóvel é onde ele mais o usa. */
  .tabela-cards.tabela-compacta tbody td.col-sel{ display:block; flex:none; width:auto; padding:0; }
  /* ⚠️ O modo cartão empurra tudo para a direita (rótulo à esquerda, valor à
     direita) e põe uma linha por baixo de CADA célula. Numa linha só, o nome
     lê-se à esquerda e quem separa é a própria linha, não as células. */
  /* ⚠️ `width:auto` nas três: o modo cartão dá `width:100%` a cada célula, e num
     flex isso vira a base do cálculo — o resumo ficava com a linha toda e o
     nome com largura ZERO (o texto caía em pé, uma letra por linha). */
  .tabela-cards.tabela-compacta tbody td.td-nome{ display:block; flex:1; width:auto; min-width:0;
    padding:0; font-size:15px; text-align:left; border-bottom:none; }
  /* ⚠️ `flex:none` de propósito: o modo cartão dá `flex:1` às células, e o
     resumo esticava-se a 260px dos 343 do telemóvel, deixando o NOME com
     largura zero (o texto caía em pé, uma letra por linha). Quem manda na
     largura aqui é o nome; o número ocupa só o que precisa. */
  .tabela-cards.tabela-compacta tbody td.td-resumo{ display:block; flex:none; width:auto; padding:0;
    white-space:nowrap; border-bottom:none; text-align:right; }
  .tabela-cards.tabela-compacta tbody tr + tr{ border-top:1px solid var(--cinza-borda); }
  .tabela-cards.tabela-compacta tbody td::before{ display:none; }
  /* O detalhe que acompanha o nome sai: nas fichas era "tipo · ingredientes",
     nos produtos a unidade de compra. Está tudo a um toque.
     ⚠️ A ETIQUETA DE ESTADO fica: "inativo" não é detalhe, é o que explica por
     que aquele produto está ali apagado. */
  .tabela-cards.tabela-compacta tbody td.td-nome .lanc-sub,
  .tabela-cards.tabela-compacta tbody td.td-nome > .ajuda{ display:none; }
  .tabela-cards.tabela-compacta tbody td.td-nome .nome-link{ display:block; overflow:hidden;
    text-overflow:ellipsis; white-space:nowrap; }
  .tabela-cards.tabela-compacta tbody td.td-nome .nome-link::after{ content:''; position:absolute; inset:0; }

  /* ⚠️ A barra de tipo muda de dono no telemóvel: aqui os td perdem as bordas
     (`border:none` logo abaixo), portanto ela sobe para o CARTÃO, que é o tr. */
  .tabela-cards .linha-marca{ border-left:3px solid var(--linha-cor, var(--cinza-borda)); }
  .tabela-cards .linha-marca > td:first-child{ border-left:none; }
  .tabela-cards tbody tr + tr{ border-top:8px solid var(--fundo); }
  .tabela-cards td{ padding:5px 0; border:none; display:flex; align-items:center;
    justify-content:space-between; gap:14px; text-align:right; overflow-wrap:anywhere; }
  .tabela-cards td::before{ content:attr(data-label); font-weight:600; font-size:11px;
    text-transform:uppercase; letter-spacing:.3px; color:var(--cinza-medio); text-align:left; flex:none; }
  .tabela-cards td.td-nome{ font-size:16px; padding-bottom:8px; }

  /* ⭐⭐ O LANÇAMENTO NO TELEMÓVEL É UMA LINHA (ele, 18/08/2026: *"no celular
     cada lançamento pega a tela toda quase, se eu precisar usar o celular pra
     isso, vai ser um porre. O legal é o lançamento mostrar o básico, quando eu
     clicar em cima, aparecer mais informações."*).

     📏 Medido antes: **568px por lançamento numa tela de 812** — 70% do ecrã
     para UMA linha, e o mês dele tem 366. Nove campos rotulados, um por linha.

     ⭐ A linha mostra o que se procura de relance: **dia · descrição · valor**.
     Tocar abre a FICHA, que já existia e mostra tudo. Não se esconde nada:
     muda-se o que vem primeiro. */
  .lanc-tabela tbody tr{ padding:0; position:relative; cursor:pointer; }
  .lanc-tabela tbody tr > td{ display:none; }
  /* ⚠️ A coluna das ações precisa de ser nomeada à parte: o `.tabela-cards
     td.td-acoes` acima tem duas classes e ganhava ao `display:none` genérico.
     Media 104px sozinha — dois terços da linha "resumida". */
  .lanc-tabela tbody tr > td.td-acoes{ display:none; }
  .lanc-tabela tbody tr > td.td-l-dia,
  .lanc-tabela tbody tr > td.td-l-desc,
  .lanc-tabela tbody tr > td.td-l-valor{ display:block; }
  /* ⚠️ Sem os rótulos: "DIA 31/05" numa linha de resumo é ruído, e o que a
     coluna é vê-se pela posição e pela forma do valor. */
  .lanc-tabela tbody tr > td::before{ display:none; }
  /* A linha inteira é uma grelha de três casas: dia à esquerda, descrição a
     ocupar o que sobra, valor à direita e sem quebrar. */
  .lanc-tabela tbody tr{
    display:grid; grid-template-columns:auto 1fr auto; align-items:baseline;
    gap:2px 10px; padding:11px 16px; }
  /* ⚠️ Sem o risco por baixo de cada campo: numa linha de três casas ele
     desenhava três sublinhados soltos em vez de separar seja o que for. Quem
     separa as linhas é o fundo, que já traz a cor do tipo. */
  .lanc-tabela tbody tr > td{ padding:0; text-align:left; min-width:0; border-bottom:0; }
  .lanc-tabela tbody tr > td.td-l-dia{
    font-size:12px; color:var(--cinza-medio); font-variant-numeric:tabular-nums; }
  .lanc-tabela tbody tr > td.td-l-desc{
    font-size:14.5px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
  .lanc-tabela tbody tr > td.td-l-valor{
    text-align:right; font-weight:600; white-space:nowrap; font-variant-numeric:tabular-nums; }
  /* ⚠️ O dia traz o dia-da-semana e a competência por baixo; na linha fechada
     só cabe a data. */
  .lanc-tabela tbody tr > td.td-l-dia .lanc-sub{ display:none; }
  /* ⚠️ O resto do lançamento (tipo, categoria, forma, conta, saldo e as ações)
     não desapareceu: vive na FICHA que já abria ao tocar na linha. Ver a nota
     no `lancamentos.php`. */
  .tabela-cards td.td-acoes{ flex-wrap:wrap; justify-content:flex-start; gap:10px 20px; white-space:normal;
    border-top:1px solid var(--cinza-borda); margin-top:6px; padding-top:12px; }
  .tabela-cards td.td-acoes::before{ content:''; display:none; }
  /* cada ação é um item inteiro: nunca parte a palavra ("Acessa/r") e quebra
     para a linha seguinte como um todo se não couber */
  .tabela-cards td.td-acoes .link-acao{ font-size:15px; white-space:nowrap; overflow-wrap:normal; word-break:keep-all; }
  .tabela-cards td.td-acoes .inline-f{ display:inline-flex; }
  /* A segunda linha das células (dia da semana, grupo, serviço) é `display:block`
     no desktop; aqui a célula é flex e ela vira um item ao lado, o que até se lê
     bem ("24/07 · Sex"). O que NÃO se lê é partida a meio da palavra, porque a
     célula tem `overflow-wrap:anywhere` — daí o nowrap. E a célula passa a poder
     ter duas linhas, para o sub descer inteiro quando não couber.
     ⚠️ `flex:1 0 100%` aqui esmaga o valor principal num caractere por linha. */
  .tabela-cards td{ flex-wrap:wrap; }
  .tabela-cards td .lanc-sub{ display:inline-block; flex:none; width:auto;
    white-space:nowrap; margin-left:10px; }
  /* As larguras mínimas da tabela são para o desktop. No cartão, cada célula é
     uma linha inteira: mantê-las fazia o valor descer para uma segunda linha
     sem precisar. */
  .tabela-cards td.td-valor, .tabela-cards td.td-saldo,
  .tabela-cards td.td-forma, .tabela-cards td.td-categoria{ width:auto; min-width:0; }
}

/* ============================================================
   BATER PONTO (quiosque)
   ============================================================ */
/* ⭐⭐⭐ O RECADO É PRESO À TELA, não ao topo da página (ele, 23/08/2026).
   *"Quando eu clico em salvar, aparece aquela mensagem que foi salvo, mas
   aparece só em cima; se eu tô lá embaixo, não vejo."*

   🚨 MEDIDO em `/financeiro/config` antes de mexer: a página tem 5.691px, o
   botão de guardar é uma barra COLADA no rodapé (`.cfg-barra`, sticky) — logo
   grava-se de qualquer altura — e o navegador devolve a pessoa ao ponto onde
   estava. Guardei de y=4.880 e o recado nasceu a **4.547px acima do campo de
   visão**. Ele gravava e não recebia resposta nenhuma.
   ⚠️ Não é só das Configurações: `flash_caixa` desenha o recado de **44 telas**,
   e qualquer uma delas com mais de um ecrã de altura tinha o mesmo defeito. Por
   isso o conserto é aqui, e não numa tela.
   ⭐⭐ E repare de onde o defeito veio: de DUAS regras dele, as duas certas. A de
   06/08 — *"faço uma alteração e a tela vai lá pra cima; quero que fique onde
   está"* (`partials/manter-posicao.php`) — e a de sempre, de o recado ir no topo
   da página. Juntas, davam uma tela que grava sem responder. Por isso o conserto
   NÃO é subir a tela até ao recado: era desfazer a regra de 06/08. É trazer o
   recado até onde a pessoa está.
   ⭐ Molde da `.inst-faixa`, que já resolvia isto: `fixed`, com `safe-area` (no
   iPhone, sem ela, fica debaixo da barra do sistema) e sem nascer por baixo da
   barra lateral. */
.flash-ok, .flash-erro{
  position:fixed; z-index:70; margin:0;
  left:16px; right:16px; top:calc(14px + env(safe-area-inset-top, 0px));
  display:flex; align-items:center; gap:12px;
  padding:14px 18px; border-radius:var(--raio); font-weight:600;
  box-shadow:0 10px 32px rgba(17,17,17,.20);
}
/* Com barra lateral, o recado alinha com o CONTEÚDO — 230px é onde a `.conteudo`
   começa de verdade. (As outras faixas usam 248 no fallback; aqui isso deixava
   o recado 18px fora do prumo da coluna, e nota-se.) */
@media (min-width:981px){
  .flash-ok, .flash-erro{ left:calc(var(--sb-larg, 230px) + 16px); right:auto; max-width:620px; }
}
.flash-ok{
  background:var(--verde-fundo); border:1px solid #bfe8cf; color:var(--verde);
}
/* 🚨 O recado que diz que falhou tem de SAIR vermelho (14/08/2026): a pessoa lê
   a cor antes da frase, e um erro pintado de sucesso é pior do que erro nenhum.
   Mesma caixa do .flash-ok, cores do .alerta, que é o vermelho da casa. */
.flash-erro{
  background:#fdecef; border:1px solid #f6c9d3; color:#a3122c;
}

/* ⭐ O "gravado" SAI SOZINHO ao fim de 7s — ficar preso à tela para sempre era
   trocar um recado que não se via por um que não se despacha.
   🚨 O ERRO NÃO SAI, e a diferença é de propósito: um erro que desaparece
   sozinho é um erro que ninguém leu. Esse fecha-se com o ×, e quem não tem
   JavaScript fica com ele na tela — que é o lado seguro de falhar.
   ⚠️ O rato por cima PAUSA a contagem: sete segundos chegam para ler uma frase,
   não para ler e ainda decidir. */
.flash-ok{ animation:flash-sai .45s ease 7s forwards; }
.flash-ok:hover, .flash-ok:focus-within{ animation-play-state:paused; }
@keyframes flash-sai{ to{ opacity:0; visibility:hidden; transform:translateY(-10px); } }
/* ⚠️ Para quem pediu menos movimento, o recado continua a sair — o que se tira
   é o deslize, não o comportamento. */
@media (prefers-reduced-motion:reduce){
  .flash-ok{ animation-name:flash-sai-parado; }
}
@keyframes flash-sai-parado{ to{ opacity:0; visibility:hidden; } }

/* O × que dispensa. Nasce do JavaScript (ver partials/topo.php): desenhá-lo no
   HTML dava um botão morto em quem não tem JavaScript, e um botão que não faz
   nada é pior do que botão nenhum. */
/* ⚠️ 38px de lado, e não o tamanho do desenho: medido a 23x27 na prova, que é
   alvo de rato, não de dedo. O × é a ÚNICA saída deste recado — se falhar o
   toque, ele fica na tela. */
.flash-x{
  flex:0 0 auto; margin-left:auto; cursor:pointer; font:inherit; line-height:1;
  background:none; border:0; color:inherit; opacity:.55;
  display:inline-grid; place-items:center; min-width:38px; min-height:38px;
  border-radius:var(--raio-xs); font-size:21px;
}
.flash-x:hover{ opacity:1; background:rgba(0,0,0,.06); }

/* Grade de nomes */
.kiosk-grade{ display:grid; grid-template-columns:repeat(auto-fill,minmax(150px,1fr)); gap:14px; }
.kiosk-nome{
  display:flex; flex-direction:column; align-items:center; gap:12px; text-decoration:none;
  background:var(--branco); border:1px solid var(--cinza-borda); border-radius:var(--raio);
  padding:26px 16px; color:var(--preto); box-shadow:var(--sombra); transition:transform .12s, box-shadow .12s;
}
.kiosk-nome:hover{ transform:translateY(-2px); box-shadow:0 16px 44px rgba(17,17,17,.14); }
.kiosk-nome .ini{
  width:58px; height:58px; border-radius:50%; background:var(--preto); color:var(--branco);
  display:flex; align-items:center; justify-content:center; font-family:var(--fonte-titulo);
  font-weight:700; font-size:21px;
}
.kiosk-nome .nm{ font-weight:600; font-size:15px; text-align:center; }

/* Cartão de PIN */
.pin-card, .bater-card{
  background:var(--branco); border:1px solid var(--cinza-borda); border-radius:var(--raio);
  padding:32px; box-shadow:var(--sombra); text-align:center; max-width:420px; margin:0 auto;
}
.pin-nome, .bater-nome{ font-family:var(--fonte-titulo); font-weight:700; font-size:24px; letter-spacing:-.4px; }
.pin-sub{ color:var(--cinza-medio); margin:6px 0 22px; }
.pin-input{
  width:100%; text-align:center; letter-spacing:12px; font-size:30px; font-family:var(--fonte-titulo);
  padding:14px; border:1.5px solid var(--cinza-borda); border-radius:var(--raio-sm); margin-bottom:18px;
}
.pin-input:focus{ outline:none; border-color:var(--preto); }

/* Tela de bater */
.bater-estado{
  display:inline-block; margin-top:10px; padding:5px 14px; border-radius:999px;
  font-size:13px; font-weight:600;
}
.estado-fora{ background:var(--cinza-fundo); color:var(--cinza-medio); }
.estado-trabalhando{ background:var(--verde-fundo); color:var(--verde); }
.estado-em_pausa{ background:#fff4e5; color:#a86416; }

.gps-status{ font-size:13px; color:var(--cinza-medio); margin:20px 0; }
.gps-status.gps-ok{ color:var(--verde); }
/* leitura pouco precisa: não é erro (a batida regista à mesma), é um "espere um
   pouco" — por isso âmbar e não vermelho */
.gps-status.gps-aviso{ color:#a86416; }
.gps-status.gps-erro{ color:#a86416; }

.acoes-ponto{ display:flex; flex-direction:column; gap:12px; }
.btn-ponto{
  padding:18px; font-family:var(--fonte-texto); font-weight:700; font-size:17px;
  border:none; border-radius:var(--raio-sm); cursor:pointer; color:var(--branco); background:var(--preto);
  transition:opacity .15s;
}
.btn-ponto:hover{ opacity:.9; }
.btn-entrada{ background:var(--vermelho); }        /* ação principal: começar */
.btn-pausa_fim{ background:var(--vermelho); }      /* ação principal: retomar */
.btn-saida{ background:var(--preto); }             /* encerrar */
.btn-pausa_inicio{ background:var(--branco); color:var(--preto); border:1.5px solid var(--cinza-borda); } /* secundária */
.btn-pausa_inicio:hover{ background:var(--cinza-fundo); opacity:1; }

/* A AÇÃO QUE A ESCALA SUGERE (16/08/2026).
   ⚠️ O destaque é um anel, e não uma cor nova: as cores destes botões já
   querem dizer coisas (vermelho = começar/retomar, preto = encerrar), e trocar
   a cor da sugestão apagaria esse significado. O anel soma-se, não substitui. */
.ponto-sugestao{
  margin:0 0 12px; font-size:14px; line-height:1.45; color:var(--texto);
  background:var(--cinza-fundo); border-radius:var(--raio-sm); padding:10px 12px;
}
.btn-ponto-sugerido{ box-shadow:0 0 0 3px var(--destaque); }

.historico{ margin-top:26px; text-align:left; border-top:1px solid var(--cinza-borda); padding-top:18px; }
.hist-titulo{ font-size:12px; font-weight:600; text-transform:uppercase; letter-spacing:.5px; color:var(--cinza-medio); margin-bottom:10px; }
.hist-linha{ display:flex; align-items:center; gap:10px; padding:7px 0; font-size:14px; }
.hist-tipo{ flex:1; }
.hist-hora{ font-weight:600; }
/* ⚠️ `.hist-flag` MORREU a 28/08/2026 — a marca de quem bateu o ponto FORA do
   local, e a contagem dessas batidas no relatório.
   🚨 Também trazia `#fdecef` à mão (o `--vermelho-sinal-fundo`) sobre a cor da
   MARCA — duas famílias de vermelho misturadas na mesma pílula.
   ⭐ Foi para `alerta` e não para `perigo`, e a diferença é de leitura: bater
   fora do local **pede atenção, não é erro** — pode ser a entrega, pode ser o
   recado do gerente. Perigo é para o que está errado ou em falta. */

/* O turno que ninguém fechou: as horas dele não entram no total, por isso o
   aviso vive COLADO ao número de horas — é ali que a pergunta nasce. Discreto
   de propósito: é um pedido de correção, não um erro do sistema. */
.ponto-aberto{
  display:block; margin-top:3px; font-size:11px; font-weight:600;
  color:#8a6100; text-decoration:none; line-height:1.3;
}
.ponto-aberto:hover{ text-decoration:underline; }

/* ============================================================
   RELATÓRIO DE PONTO (Horas)
   ============================================================ */
.mes-nav{
  display:flex; align-items:center; gap:8px; background:var(--branco);
  border:1px solid var(--cinza-borda); border-radius:var(--raio-sm); padding:6px 10px;
}
.mes-nav a{ text-decoration:none; color:var(--preto); font-size:22px; line-height:1; padding:0 8px; }
.mes-nav a:hover{ color:var(--vermelho); }
/* ⭐ NO TOQUE, O ‹ E O › CRESCEM (achado do check no celular, 23/08/2026).
   📏 Medidos a 375px: **23×22px**. É o alvo mais usado destas telas — trocar de
   mês nos Lançamentos, de dia na Agenda — e 22px de altura é metade do que um
   dedo acerta com confiança.
   ⚠️ O desenho NÃO muda: o `‹` continua do mesmo tamanho, o que cresce é a área
   que responde ao toque. Aumentar a fonte fazia dois sinais grandes a competir
   com o nome do mês, que é o que ali se lê.
   ⚠️ `pointer:coarse` e não largura de tela: quem tem rato acerta 23px, e num
   tablet grande com dedo continua a precisar dos 44. A pergunta é o dedo, não o
   tamanho da tela. */
@media (pointer:coarse){
  .mes-nav a{ display:inline-grid; place-items:center; min-width:44px; min-height:44px; padding:0; }
  .mes-nav{ padding:2px 6px; }
}
.mes-nav span{ min-width:140px; text-align:center; font-size:14px; font-weight:600; }
/* intervalo da semana ao lado do seletor: acompanha, não compete com ele */
.mes-nav .mes-nav-faixa{ min-width:0; font-size:13px; font-weight:600; color:var(--cinza-medio); white-space:nowrap; }
/* SINAL DO DINHEIRO — definição única, usada pelo banco de horas, pelo Diário e
   pelo Financeiro. Verde = entrou, vermelho = saiu. Os seletores com
   .fecho-kpi strong existem porque essa regra pinta o número de preto e tem
   prioridade maior: sem eles, a cor do sinal era ignorada dentro do card. */
.saldo-pos, .fecho-kpi strong.saldo-pos{ color:var(--verde); font-weight:600; }
.saldo-neg, .fecho-kpi strong.saldo-neg{ color:var(--vermelho-sinal); font-weight:600; }
/* âmbar do semáforo (ex.: Prime Cost na zona de atenção 60–65%) */
.kpi-alerta, .fecho-kpi strong.kpi-alerta{ color:#b8860b; font-weight:600; }
/* A base da meta, ao lado do número: "escala", "proporcional", "meta do mês".
   Discreta de propósito — é a nota de rodapé do número, não um segundo número.
   Ver BancoHoras::metaDoPeriodo para o que cada uma quer dizer. */
.etiqueta-base{ display:inline-block; font-size:10px; font-weight:600; letter-spacing:.02em;
                color:var(--cinza-medio); background:var(--cinza-fundo); border-radius:999px;
                padding:1px 7px; margin-left:6px; white-space:nowrap; cursor:help; vertical-align:middle; }
/* Duas datas e um botão, na mesma linha (a vista de intervalo específico). */
.filtro-linha{ display:flex; gap:12px; align-items:end; flex-wrap:wrap; margin:0 0 14px; }
.filtro-linha label{ display:flex; flex-direction:column; gap:4px; font-size:12px; font-weight:600; color:var(--cinza-medio); }
.filtro-linha input[type=date]{ font:inherit; padding:8px 10px; border:1.5px solid var(--cinza-borda); border-radius:var(--raio-sm); background:var(--branco); }
/* ⚠️ O `.btn` da casa é `width:100%` (nasceu para formulário em coluna). Numa
   linha de filtro ele esticava-se de ponta a ponta e passava a ser a coisa mais
   pesada do ecrã — para uma ação secundária. Aqui vale o tamanho do texto. */
.filtro-linha .btn{ width:auto; padding:9px 20px; font-size:14px; }

.export-toolbar{ display:flex; gap:10px; margin-bottom:14px; flex-wrap:wrap; }
.btn-export{ display:inline-flex; align-items:center; gap:6px; font-size:13px; font-weight:600; text-decoration:none; color:var(--preto); background:var(--branco); border:1.5px solid var(--cinza-borda); border-radius:var(--raio-sm); padding:9px 14px; }
.btn-export:hover{ border-color:var(--preto); }

/* ============================================================
   ESCALAS (grade semanal)
   ============================================================ */
.escala-topo{ display:flex; gap:12px; align-items:center; flex-wrap:wrap; }
.escala-wrap{ overflow-x:auto; max-width:100%; background:var(--branco); border:1px solid var(--cinza-borda); border-radius:var(--raio); box-shadow:var(--sombra); }
/* trava a caixa à largura da tela: sem isto ela cresce até ao tamanho da
   tabela (760px) e é a PÁGINA que rola de lado; assim a rolagem fica DENTRO
   da caixa, e a coluna de nomes continua fixa. */
@media (max-width:720px){ .escala-wrap{ max-width:calc(100vw - 44px); } }
.escala-grade{ width:100%; border-collapse:collapse; font-size:13px; min-width:760px; }
.escala-grade th{ text-align:center; font-size:11px; text-transform:uppercase; letter-spacing:.4px; color:var(--cinza-medio); padding:12px 8px; border-bottom:1px solid var(--cinza-borda); font-weight:600; }
.escala-grade th.col-nome{ text-align:left; }
.escala-grade th .dia-num{ display:block; font-size:16px; color:var(--preto); margin-top:2px; }
.escala-grade th.dia-hoje .dia-num{ color:var(--vermelho); }
.escala-grade td{ border-bottom:1px solid var(--cinza-borda); border-left:1px solid var(--cinza-borda); padding:8px; vertical-align:top; }
.escala-grade td.col-nome{ border-left:none; font-weight:600; white-space:nowrap; }
/* coluna do nome congelada ao rolar os dias na horizontal (fundo opaco + sombra) */
.escala-grade th.col-nome, .escala-grade td.col-nome{
  position:sticky; left:0; background:var(--branco);
  border-right:1px solid var(--cinza-borda);
  box-shadow:2px 0 6px -4px rgba(17,17,17,.22); }
.escala-grade th.col-nome{ z-index:2; }
.escala-grade td.col-nome{ z-index:1; }
.escala-grade tbody tr:last-child td{ border-bottom:none; }
.cel-dia{ text-align:center; min-width:82px; }
/* arrastar turnos na grade */
.turno-chip[draggable]{ cursor:grab; }
.turno-chip.chip-arrastando{ opacity:.4; }
.cel-dia.cel-alvo{ background:color-mix(in srgb, var(--destaque) 12%, transparent);
  outline:2px dashed color-mix(in srgb, var(--destaque) 55%, transparent); outline-offset:-2px; }
.cel-dia.cel-carregando{ opacity:.5; }
.escala-dica{ color:var(--cinza-medio); font-size:13px; margin:0 0 12px; display:inline-flex; align-items:center; gap:7px; flex-wrap:wrap; }
/* uma dica para rato, outra para toque — trocadas por dispositivo */
.escala-dica-toque{ display:none; }
@media (hover:none), (max-width:720px){
  .escala-dica-mouse{ display:none; }
  .escala-dica-toque{ display:inline-flex; }
  /* no telemóvel o nome da pessoa vira o alvo principal: bem visível e tocável */
  .escala-grade td.col-nome .nome-link{ color:var(--vermelho); font-weight:700; }
  .escala-grade td.col-nome{ min-width:132px; }
}
.escala-dica kbd{ background:#eef0f2; border:1px solid var(--cinza-borda); border-radius:var(--raio-xs); padding:1px 6px; font-size:12px; font-family:inherit; }
.turno-chip{ display:inline-flex; align-items:center; gap:5px; background:color-mix(in srgb, var(--vermelho) 10%, transparent); color:var(--vermelho); border-radius:999px; padding:4px 8px 4px 10px; font-weight:600; font-size:12px; margin:0 auto 5px; white-space:nowrap; }
.turno-chip::before{ content:''; width:7px; height:7px; border-radius:50%; background:var(--vermelho); flex:0 0 auto; }
.turno-chip form{ display:inline; margin:0; }
/* ⭐ A hora vira botão no modo edição (ele, 18/08/2026), e tem de continuar a
   parecer a mesma etiqueta: sem fundo, sem borda, herdando cor e peso. O
   sublinhado ao passar o rato é o que diz que ali se clica. */
.chip-h-btn{ background:none; border:none; padding:0; margin:0; font:inherit; color:inherit;
  cursor:pointer; border-radius:var(--raio-xs); }
.chip-h-btn:hover{ text-decoration:underline; }
.chip-h-btn:focus-visible{ outline:2px solid var(--vermelho); outline-offset:2px; }
.turno-chip .add-pop{ font-weight:400; color:var(--texto); }
.chip-x{ background:none; border:none; cursor:pointer; color:var(--vermelho); opacity:.55; font-size:15px; line-height:1; padding:0 1px; text-decoration:none; }
.chip-x:hover{ opacity:1; }
/* ⚠️ O `+` de acrescentar turno é um `<button>`, e a borda tracejada é o
   desenho — mas sem `background:none` ficava o fundo do sistema por trás dela.
   Apanhado a 26/08 pela mesma varredura que apanhou o "Remover foto": no iPad
   os dois eram uma cápsula azul onde devia estar um traço. */
.cel-add{ display:inline-block; appearance:none; -webkit-appearance:none; background:none; padding:0;
  font-family:inherit; cursor:pointer;
  color:var(--cinza-medio); text-decoration:none; font-size:15px; font-weight:700; width:22px; height:22px; line-height:20px; border-radius:var(--raio-xs); border:1px dashed var(--cinza-borda); }
.cel-add:hover{ color:var(--vermelho); border-color:var(--vermelho); }

/* ============================================================
   DETALHE DO DIA (planejado × realizado + edição)
   ============================================================ */
.link-drill{ color:var(--preto); text-decoration:none; border-bottom:1px dotted var(--cinza-borda); }
.link-drill:hover{ color:var(--vermelho); border-color:var(--vermelho); }

.pxr{ display:grid; grid-template-columns:1fr 1fr; gap:14px; margin-bottom:20px; }
.pxr-box{ background:var(--branco); border:1px solid var(--cinza-borda); border-radius:var(--raio); padding:18px; box-shadow:var(--sombra); }
.pxr-label{ font-size:12px; font-weight:600; text-transform:uppercase; letter-spacing:.5px; color:var(--cinza-medio); }
.pxr-val{ display:block; font-family:var(--fonte-titulo); font-weight:700; font-size:26px; margin:4px 0 8px; }
.pxr-turnos{ display:flex; flex-wrap:wrap; gap:6px; }
.pxr-dif{ font-size:13px; font-weight:600; }

.card-batidas{ background:var(--branco); border:1px solid var(--cinza-borda); border-radius:var(--raio); padding:20px; box-shadow:var(--sombra); }
.batida-linha, .batida-add{ display:flex; align-items:center; gap:10px; padding:10px 0; border-bottom:1px solid var(--cinza-borda); flex-wrap:wrap; }
.batida-add{ border-bottom:none; padding-top:16px; margin-top:6px; }
.batida-tipo{ padding:9px 10px; border:1.5px solid var(--cinza-borda); border-radius:var(--raio-sm); font-family:var(--fonte-texto); font-size:14px; background:var(--branco); }
.batida-hora{ padding:9px 10px; border:1.5px solid var(--cinza-borda); border-radius:var(--raio-sm); font-family:var(--fonte-texto); font-size:14px; width:120px; }
.batida-acoes{ margin-left:auto; white-space:nowrap; }
/* ⚠️ `.tag-manual` MORREU a 28/08/2026 SEM substituto: não tinha um único uso
   em tela nenhuma. Era a sexta cápsula do CSS a existir só porque ninguém a
   veio apagar — e enquanto existia, contava como dívida de arquitetura numa
   cerca que só pode descer. */

/* ---------- Detalhe do dia: seletor de data, resumo e detalhe da batida ---------- */
.nav-data{ padding:6px 10px; border:1.5px solid var(--cinza-borda); border-radius:var(--raio-sm);
  font-family:var(--fonte-texto); font-size:14px; font-weight:600; color:var(--preto); background:var(--branco); cursor:pointer; }
.dia-aviso{ border-radius:var(--raio-sm); padding:10px 14px; margin:0 0 16px; font-size:13.5px; }
.dia-feriado{ background:#eef4ff; border:1px solid #cfe0fb; color:#274b8a; }
.dia-ausencia{ background:#fdf3e7; border:1px solid #f3d6a8; color:#8a5a12; }
/* resumo do dia — 4 mini-cartões */
.dia-stats{ display:grid; grid-template-columns:repeat(4,1fr); gap:10px; margin:0 0 20px; }
.dia-stat{ background:var(--branco); border:1px solid var(--cinza-borda); border-radius:var(--raio-sm); padding:11px 13px; box-shadow:var(--sombra); }
.dia-stat-rot{ display:block; font-size:11px; font-weight:600; text-transform:uppercase; letter-spacing:.4px; color:var(--cinza-medio); margin-bottom:3px; }
.dia-stat strong{ font-family:var(--fonte-titulo); font-weight:700; font-size:16px; }
/* cada batida: a linha (form) + a meta abaixo */
.batida-bloco{ border-bottom:1px solid var(--cinza-borda); padding:6px 0; }
.batida-bloco:last-of-type{ border-bottom:0; }
.batida-bloco .batida-linha{ border-bottom:0; padding:6px 0 2px; }
/* Batida que não pertence a turno nenhum: fundo de aviso para não se confundir
   com as boas, e o texto explica por que não conta horas. */
.batida-orfa{ background:#fff8e6; border-left:3px solid #e0a800; padding-left:10px; }
.batida-orfa-aviso{ margin:0 0 6px; font-size:12px; color:#8a6100; line-height:1.4; }
.batida-ver{ color:var(--preto); }
.batida-tipo-ver{ font-weight:600; min-width:120px; }
.batida-hora-ver{ font-family:var(--fonte-titulo); font-weight:700; }
.batida-meta{ display:flex; flex-wrap:wrap; gap:6px 10px; align-items:center; padding:0 0 4px; }
.batida-meta:empty{ display:none; }
.bm-item{ font-size:11.5px; color:var(--cinza-medio); }
.bm-ok{ color:var(--verde); }
.bm-fora{ color:var(--vermelho); font-weight:600; }
.bm-link{ color:var(--destaque); text-decoration:none; font-weight:600; }
.bm-link:hover{ text-decoration:underline; }
.bm-manual{ background:var(--cinza-fundo); padding:1px 7px; border-radius:999px; }

@media (max-width:600px){ .pxr{ grid-template-columns:1fr; } .dia-stats{ grid-template-columns:1fr 1fr; } }

/* ============================================================
   FÉRIAS & FOLGAS
   ============================================================ */
/* 🚨 O COMENTÁRIO DIZIA UMA COISA E O CÓDIGO FAZIA OUTRA (28/08/2026).
   Doze linhas abaixo, o `.selo-alerta` escreve à letra: *"a cor é a que a casa
   já usa para «à espera» (`.st-pendente`), e não uma inventada: um laranja novo
   seria a SEXTA cor de atenção do sistema."* Era a intenção certa — e este
   `.pill-pedido`, escrito no mesmo sítio, tinha `#fff4e5`/`#a86416` contra os
   `#fff3e0`/`#b26a00` do `.st-pendente`. **Um tom ao lado**, que ninguém
   escolheu: era o laranja novo que o comentário proibia, a viver colado a ele.
   ⚠️ Não se descobre isto a olho — as duas cores são indistinguíveis lado a
   lado. Descobre-se varrendo os hexadecimais contra a paleta. */
.pill-pedido{ background:var(--ambar-fundo); color:var(--ambar); }
/* 🚨 22/08/2026 — O SELO DE ALERTA NÃO PINTAVA NADA.
   `<span class="selo selo-alerta">` no painel diz *"3 cadastros aguardando"* —
   e o `.selo-alerta` **não existia no CSS**. A forma base (`.selo`) dá o
   formato de cápsula, mas de propósito **não dá cor**: quem pinta é o
   modificador. Sem ele, o aviso saía como texto solto com um bocado de padding,
   e um aviso que não se vê é um aviso que não existe.
   ⚠️ Encontrado varrendo o INVERSO do costume — classes usadas no markup que
   não têm regra nenhuma no CSS. Era a mesma família do seletor de cor que ele
   apanhou: markup sem estilo, calado.
   ⚠️ A cor é a que a casa já usa para "à espera" (`.st-pendente`), e não uma
   inventada: um laranja novo seria a sexta cor de atenção do sistema. */
.selo-alerta{ background:var(--ambar-fundo); color:var(--ambar); }
.pill-aprovado{ background:var(--verde-fundo); color:var(--verde); }
.pill-recusado{ background:#fdecef; color:#a3122c; }
.saldo-ferias{ background:var(--branco); border:1px solid var(--cinza-borda); border-radius:var(--raio); padding:20px; box-shadow:var(--sombra); margin-bottom:24px; }
.saldo-ferias .pxr-val small{ font-size:15px; font-weight:500; color:var(--cinza-medio); }
.saldo-barra{ height:8px; background:var(--cinza-fundo); border-radius:999px; overflow:hidden; margin:12px 0 6px; max-width:320px; }
.saldo-barra-fill{ height:100%; background:var(--vermelho); border-radius:999px; }

/* ============================================================
   HUB (tela inicial do suíte — escolha de módulo)
   ============================================================ */
.hub-cabecalho{ margin-bottom:28px; }
.hub-titulo{ font-family:var(--fonte-titulo); font-weight:700; font-size:30px; letter-spacing:-.6px; }
.hub-sub{ color:var(--cinza-medio); margin-top:6px; }
.hub-grade{ display:grid; grid-template-columns:repeat(auto-fit,minmax(230px,1fr)); gap:18px; }
.hub-mod{ display:block; text-decoration:none; color:inherit; background:var(--branco); border:1px solid var(--cinza-borda); border-radius:var(--raio); padding:24px; box-shadow:var(--sombra); transition:transform .12s, box-shadow .12s; position:relative; }
a.hub-mod:hover{ transform:translateY(-3px); box-shadow:0 18px 48px rgba(17,17,17,.14); }
.hub-mod.em-breve{ opacity:.62; }
.hub-ic{ width:52px; height:52px; border-radius:var(--raio); background:var(--menu); color:var(--destaque-menu); display:flex; align-items:center; justify-content:center; margin-bottom:16px; }
.hub-ic svg{ width:27px; height:27px; }
.hub-mod.em-breve .hub-ic{ background:var(--cinza-fundo); color:var(--cinza-medio); }
.hub-frente{ font-size:11px; font-weight:600; text-transform:uppercase; letter-spacing:.6px; color:var(--cinza-medio); margin-bottom:4px; }
.hub-mod h3{ font-family:var(--fonte-titulo); font-weight:700; font-size:19px; margin-bottom:4px; }
.hub-mod p{ color:var(--cinza-medio); font-size:13.5px; }
.hub-mod .tag{ position:absolute; top:20px; right:20px; margin:0; }

/* Acento vermelho nos títulos (fio da marca) */
.hub-titulo::after, .ola::after, .pagina-titulo::after{
  /* ⚠️ Fora da escala de propósito: isto é um FIO de 4px de altura, não uma
     caixa. Metade da altura é a cápsula, e é assim que ele fica com a ponta
     redonda do símbolo em vez de um canto lascado. */
  content:''; display:block; width:42px; height:4px; background:var(--destaque);
  border-radius:999px; margin-top:12px;
}
/* Hover dos cards com um toque de vermelho */
a.hub-mod:hover, a.modulo:hover{ border-color:color-mix(in srgb, var(--destaque) 45%, var(--branco)); box-shadow:0 16px 40px color-mix(in srgb, var(--destaque) 14%, transparent); }
.hub-frente{ color:var(--vermelho); }

/* ============================================================
   ESCALAS — editor semanal + mini-editor inline
   ============================================================ */

/* aviso de sucesso */
.aviso-ok{ background:#eaf7ee; border:1px solid #bfe6cb; color:#1c7a3e; padding:12px 16px; border-radius:var(--raio-sm); margin-bottom:18px; font-size:14px; }

/* chip da grade: pausa */
.turno-chip .chip-p{ color:var(--vermelho); opacity:.6; font-weight:600; margin-left:3px; }
.nome-link{ color:inherit; text-decoration:none; }
.nome-link:hover{ color:var(--vermelho); text-decoration:underline; }

/* mini-editor inline (o "+" da célula) */
.add-inline{ position:relative; display:inline-block; }
.add-pop{ position:fixed; z-index:60; width:220px; text-align:left;
  background:var(--branco); border:1px solid var(--cinza-borda); border-radius:var(--raio-sm);
  box-shadow:var(--sombra); padding:12px; }
.add-pop-linha{ display:flex; align-items:center; gap:6px; }
.add-pop-linha input{ flex:1; min-width:0; }
.add-pop input[type=time], .add-pop input[type=number]{
  padding:7px 8px; border:1px solid var(--cinza-borda); border-radius:var(--raio-sm); font:inherit; font-size:13px; }
.add-pop-pausa{ display:block; margin:8px 0; font-size:12px; color:var(--cinza-medio); }
.add-pop-pausa input{ width:56px; }
.add-pop-acoes{ display:flex; justify-content:flex-end; gap:8px; }

/* botõezinhos reutilizáveis */
/* ⚠️ `text-decoration:none` e `display:inline-flex` porque este botão também é
   usado em <a> (editar, atribuir mesa, excluir). Sem isso o <a> trazia o
   sublinhado do link e ficava mais baixo que os <button> ao lado — era o
   "Editar" sublinhado e desalinhado do cartão do salão (ele, 11/08/2026).
   O `line-height:1` iguala a altura das duas tags, que é o que faz a fila de
   ações assentar na mesma linha de base. */
/* ⚠️ `border:1px solid transparent` e não `border:none`: as variantes ghost e
   perigo têm borda de 1px, e sem a borda invisível aqui o botão sólido ficava
   2px mais baixo que os vizinhos — a fila de ações do cartão assentava torta.
   Bordas transparentes ocupam espaço; é isso que iguala as três alturas. */
.btn-mini{ border:1px solid transparent; background:var(--preto); color:#fff; border-radius:var(--raio-sm); padding:6px 12px;
  font:inherit; font-size:12.5px; font-weight:600; cursor:pointer;
  text-decoration:none; display:inline-flex; align-items:center; justify-content:center;
  line-height:1.35; white-space:nowrap; }
a.btn-mini:hover{ text-decoration:none; }
.btn-mini:hover{ background:#000; }
.btn-mini-ghost{ background:transparent; color:var(--cinza-medio); border:1px solid var(--cinza-borda); }
.btn-mini-ghost:hover{ color:var(--preto); border-color:var(--cinza-medio); }
.btn-mini-perigo{ background:transparent; color:var(--vermelho); border:1px solid color-mix(in srgb, var(--vermelho) 40%, transparent); }
.btn-mini-perigo:hover{ background:var(--vermelho); color:#fff; border-color:var(--vermelho); }

/* seletor de colaborador no editor */
.campo-colab{ max-width:340px; margin-bottom:22px; }
.campo-colab select{ width:100%; padding:11px 12px; border:1px solid var(--cinza-borda);
  border-radius:var(--raio-sm); font:inherit; background:var(--branco); }

/* grade de cartões de dia */
.editor-dias{ display:grid; grid-template-columns:repeat(auto-fill,minmax(220px,1fr)); gap:14px; }
.dia-card{ background:var(--branco); border:1px solid var(--cinza-borda); border-radius:var(--raio);
  box-shadow:var(--sombra); padding:14px; display:flex; flex-direction:column; gap:10px; }
.dia-card-hoje{ border-color:#f4b9c6; }
.dia-card-topo{ display:flex; align-items:baseline; justify-content:space-between; }
.dia-card-tit strong{ font-family:var(--fonte-titulo); font-size:14px; }
.dia-card-num{ color:var(--cinza-medio); font-size:12px; margin-left:5px; }
.dia-total{ font-size:12.5px; font-weight:700; color:var(--preto); }
.dia-card-hoje .dia-card-num{ color:var(--vermelho); }

.dia-turnos{ display:flex; flex-direction:column; gap:8px; }
.dia-turnos:empty::after{ content:'sem turno'; color:var(--cinza-medio); font-size:12px; font-style:italic; }
.turno-linha{ display:flex; align-items:center; gap:5px; flex-wrap:wrap; }
.turno-linha input[type=time]{ padding:6px 6px; border:1px solid var(--cinza-borda); border-radius:var(--raio-sm);
  font:inherit; font-size:13px; width:82px; }
.t-sep{ color:var(--cinza-medio); }
.t-pausa{ display:inline-flex; align-items:center; gap:4px; font-size:11.5px; color:var(--cinza-medio); width:100%; margin-top:2px; }
.t-pausa-in{ width:52px; padding:4px 6px; border:1px solid var(--cinza-borda); border-radius:var(--raio-xs); font:inherit; font-size:12px; }
.turno-x{ margin-left:auto; background:none; border:none; cursor:pointer; color:var(--cinza-medio);
  font-size:17px; line-height:1; padding:0 4px; }
.turno-x:hover{ color:var(--vermelho); }

.dia-acoes{ position:relative; display:flex; gap:8px; }
.copiar-menu{ position:absolute; z-index:20; top:34px; left:0; background:var(--branco);
  border:1px solid var(--cinza-borda); border-radius:var(--raio-sm); box-shadow:var(--sombra);
  padding:6px; min-width:170px; display:flex; flex-direction:column; gap:2px; }
.copiar-op{ text-align:left; background:none; border:none; cursor:pointer; font:inherit; font-size:13px;
  padding:7px 10px; border-radius:var(--raio-xs); color:var(--preto); }
.copiar-op:hover{ background:var(--cinza-fundo); }
.copiar-op[data-copiar-todos]{ font-weight:700; border-bottom:1px solid var(--cinza-borda); border-radius:0; margin-bottom:2px; }

/* barra inferior do editor */
.editor-barra{ display:flex; align-items:center; justify-content:space-between; gap:16px; flex-wrap:wrap;
  margin-top:20px; padding:16px; background:var(--branco); border:1px solid var(--cinza-borda);
  border-radius:var(--raio); box-shadow:var(--sombra); position:sticky; bottom:14px; z-index:61; }
.editor-barra-info{ display:flex; align-items:center; gap:20px; flex-wrap:wrap; font-size:14px; }
.editor-barra-info strong{ font-size:16px; }
.editor-local{ display:inline-flex; align-items:center; gap:8px; font-size:13px; color:var(--cinza-medio); }
.editor-local select{ padding:8px 10px; border:1px solid var(--cinza-borda); border-radius:var(--raio-sm); font:inherit; background:var(--branco); }
.editor-barra-acoes{ display:flex; align-items:center; gap:12px; }

/* ============================================================
   MÓDULO RESERVAS
   ============================================================ */

/* faixa de resumo (home do módulo / ficha do cliente) */
.resumo-strip{ display:flex; align-items:center; gap:14px; flex-wrap:wrap; margin:22px 0 8px; }
.resumo-item{ background:var(--branco); border:1px solid var(--cinza-borda); border-radius:var(--raio);
  box-shadow:var(--sombra); padding:14px 20px; min-width:120px; }
.resumo-num{ display:block; font-family:var(--fonte-titulo); font-weight:700; font-size:26px; line-height:1; }
.resumo-rot{ display:block; color:var(--cinza-medio); font-size:12px; margin-top:5px; }
.resumo-cta{ margin-left:auto; }

/* ⭐⭐ O TÍTULO DE SECÇÃO TEM UM ESPAÇAMENTO SÓ (18/08/2026).
   Ele: *"sem essa sensação de que alguns módulos estão mais completos que
   outros."* Medido antes de tocar em nada: 113 títulos usavam esta classe, 57
   escreviam o estilo à mão, e entre uns e outros havia **oito espaçamentos
   diferentes** para o topo do mesmo elemento (0, 4, 22, 24, 26, 28, 30, 34).
   Não é defeito nenhum; é o sistema a parecer montado por pessoas diferentes,
   que é exactamente a queixa dele.
   ⚠️ Um dos oito era `margin-top:30px` — o valor que a classe já dava. */
.secao-titulo{ font-family:var(--fonte-titulo); font-weight:700; font-size:18px; margin:30px 0 12px; }
/* ⭐ Primeiro do bloco não empurra: era isto que os `margin-top:0` à mão
   diziam, um a um. Aqui vale para todos, e para os que ainda não existem. */
.secao-titulo:first-child{ margin-top:0; }
/* A variante pequena, para o título que vive dentro de um cartão apertado. */
.secao-titulo-mini{ font-size:15px; }
/* ⚠️ O título de um DIÁLOGO é outro caso: a janela já é o contexto, e um
   espaçamento de secção lá dentro só afasta o título do que ele anuncia. */
.dext-dialog h3{ margin:0 0 4px; }

/* sub-navegação (Clientes | Mesas dentro da Agenda) */
/* As pílulas TÊM de poder quebrar linha. Sem isto, no telemóvel as sete da
   agenda somavam ~700px, esticavam o .conteudo e a página inteira passava a
   rolar de lado: o botão de nova reserva, o seletor de dia e as tabelas ficavam
   todos cortados à direita. */
.sub-nav{ display:flex; flex-wrap:wrap; gap:10px; margin-bottom:18px; }
.sub-nav a{ font-size:13px; font-weight:600; color:var(--cinza-medio); text-decoration:none;
  padding:6px 14px; border:1px solid var(--cinza-borda); border-radius:999px; background:var(--branco); }
.sub-nav a:hover{ color:var(--vermelho); border-color:var(--vermelho); }
/* A pílula ATIVA tem de se ver. A classe .ativo já estava no HTML de todos os
   sub-menus (Mês/Semana/Dia, Caixa/Competência, Clientes/Mesas) e não tinha
   estilo nenhum: os números mudavam e nada dizia em que lente se estava. */
.sub-nav a.ativo{ color:var(--branco); background:var(--preto); border-color:var(--preto); }

/* 🐞🐞 UM BOTÃO DENTRO DA SUB-NAV DEIXAVA DE PARECER UM BOTÃO (26/08/2026).
   Ele, a olhar a tela dos Produtos: *"cadê o botão de novo produto?"* — e a
   resposta era: está lá, **branco com texto cinzento**, mais fraco do que os
   dois atalhos secundários ao lado. A ação principal da tela desenhada como
   coisa desligada.
   🚨 A causa é a de sempre nesta folha: `.sub-nav a` vale (0,1,1) e `.btn`
   vale (0,1,0). A regra do CONTENTOR ganha à do COMPONENTE, esteja onde
   estiver no ficheiro — e a `.sub-nav a` foi escrita para as pílulas de
   sub-menu (Mês/Semana/Dia), não para pintar tudo o que é link lá dentro.
   ⚠️ Não se arruma com um `:not()` na regra de cima: isso sobe-a e ela passa a
   ganhar a quem hoje empata — foi o que aconteceu quando o tentei nas cores da
   marca. Aqui só se devolve ao botão o que é dele, com peso que chegue.
   ⚠️ Medido: são 2 telas (Produtos, com 7 links, e a lista de Colaboradores). */
.sub-nav a.btn{ background:var(--botao); color:var(--botao-fg); border-color:transparent; }
.sub-nav a.btn:hover{ color:var(--botao-fg); border-color:transparent; }
.sub-nav a.btn-mini{ background:var(--preto); color:#fff; border-color:transparent; }
.sub-nav a.btn-mini:hover{ color:#fff; border-color:transparent; }
.sub-nav a.btn-mini.btn-mini-ghost{ background:transparent; color:var(--cinza-medio); border-color:var(--cinza-borda); }
.sub-nav a.btn-mini.btn-mini-ghost:hover{ color:var(--preto); border-color:var(--cinza-medio); }
.sub-nav a.btn-mini.btn-mini-perigo{ background:transparent; color:var(--vermelho); }
.sub-nav a.ativo:hover{ color:var(--branco); border-color:var(--preto); }

/* ⭐ A CONTAGEM DENTRO DA PÍLULA (11/08/2026).
   ⚠️ Esta ideia já existia DUAS vezes, escrita à parte: `.fich-n` nas Fichas e
   `.tar-chip-n` nas Tarefas — cada uma com o seu componente de pílula completo
   por baixo (`.fich-aba`, `.tar-chip`), a duplicar o que a `.sub-nav` já fazia.
   Três desenhos para a mesma função, e o utilizador a ver três aparências para
   o mesmo gesto. A boa ideia das duas (número em `tabular-nums`, mais apagado
   que o rótulo) sobe para o componente da casa, e as duas cópias saem.
   O Financeiro escrevia a contagem como "(5)" à mão; passa a usar isto também. */
.sub-nav a .sub-nav-n{ font-weight:600; opacity:.62; font-variant-numeric:tabular-nums; margin-left:2px; }
.sub-nav a.ativo .sub-nav-n{ opacity:.8; }

/* ⭐ A SEGUNDA FILA (24/08/2026) — nas Fichas, o TIPO da preparação por baixo da
   finalidade. São duas perguntas diferentes ("para que serve?" / "o que é?") e
   cruzam-se: uma sobremesa DE VENDA, uma massa INTERMÉDIA. Duas filas com o
   mesmo peso liam-se como uma só, e faziam "Sobremesa" parecer alternativa a
   "Venda".
   ⚠️ Mesmo componente, menos peso: a hierarquia faz-se com o tamanho, não com
   um desenho novo. */
.sub-nav-fina{ gap:8px; margin-top:-6px; margin-bottom:16px; align-items:center; }
.sub-nav-fina a{ font-size:12px; font-weight:600; padding:4px 11px; }
.sub-nav-rot{ font-size:12px; font-weight:600; color:var(--cinza-medio); margin-right:2px; }
/* variante tracejada: a pílula que não é um filtro, é uma porta (ex.: "gerir") */
.sub-nav a.tracejado{ border-style:dashed; }
/* ⚠️ Alvo de toque no telemóvel: 29px não se acerta com o polegar em serviço.
   Vale para as 7 telas que usam a sub-nav de uma vez. */
@media (max-width:600px){
  .sub-nav a{ min-height:44px; display:inline-flex; align-items:center; }
}

/* linha de busca */
.busca-linha{ display:flex; gap:8px; margin-bottom:18px; flex-wrap:wrap; }
.busca-linha input{ flex:1; min-width:200px; padding:10px 14px; border:1px solid var(--cinza-borda);
  border-radius:var(--raio-sm); font:inherit; background:var(--branco); }

/* pílula de status da reserva */
/* .pill-status: a forma vem do .selo; as cores estão nas .st-* abaixo */
.st-pendente{ background:var(--ambar-fundo); color:var(--ambar); }
.st-confirmada{ background:#eaf7ee; color:#1c7a3e; }
.st-sentada{ background:#e8f0fe; color:#1a56db; }
.st-concluida{ background:#eef0f2; color:#5b6470; }
.st-cancelada{ background:#f2f3f5; color:#98a0aa; }
.st-nao_compareceu{ background:color-mix(in srgb, var(--vermelho) 10%, transparent); color:var(--vermelho); }

/* etiqueta de origem / VIP */
/* ⚠️ `.tag-origem` MORREU a 28/08/2026 — a origem da reserva (site, telefone).
   ⭐ Era o `selo-neutro` copiado cor a cor: mesmo `--cinza-medio` sobre mesmo
   `--cinza-fundo`. Só o tamanho da letra discordava (11px/600 contra
   11,5px/700), e discordava por acaso. A origem **classifica sem julgar**, que
   é o neutro. Ver `app/Views/reservas/agenda-corpo.php`. */
/* 🚨 A SEXTA PÍLULA, apanhada a 26/08/2026 — e o que ela ensina.
   `.tag-vip` desenhava a MESMA forma do `.selo` com nome próprio e medidas
   próprias (10px/800 contra 11,5px/700), e **sobreviveu à migração de 26/08**
   porque a cerca contava uma LISTA DE CINCO NOMES CONHECIDOS. Um sexto nome que
   ela nunca ouviu falar passa incólume — é a mesma lição do acelerador a 25/08:
   *uma cerca que guarda o que conhece não procura o que não conhece.*
   ⭐ O VIP é a definição de `selo-marca`: destaque da casa, um por tela. Migrado
   para lá, esta regra deixou de existir, e o `test-selo-unico.php` passou a
   varrer a FORMA (`border-radius:999px` fora do `.selo`) em vez de nomes. */

/* lista/cards da agenda */
/* ⭐ A LISTA É O CONTENTOR DE REFERÊNCIA do card da reserva (07/08/2026, ele:
   *"tá avacalhado ali a reserva... precisamos de uma estrutura pra não
   acontecer isso"*).
   O card foi desenhado para a AGENDA, que ocupa a tela toda. Na tela do turno
   ele cai numa coluna de 340px: a hora come 88px, os botões não encolhem abaixo
   do texto que têm, e o que sobrava para o nome eram ~80px — "Mariana Galvão da
   Costa" partia-se em quatro linhas e os botões transbordavam POR CIMA da
   etiqueta de estado.
   ⚠️ Não se resolve com `@media`: a janela está larga, quem é estreito é a
   COLUNA. É esse o caso que o container query existe para resolver, e é por
   isso que a regra vive aqui e não em cada tela — assim vale para qualquer
   sítio onde o card venha a ser posto. */
/* A LISTA REPARTE-SE PELO ESPAÇO QUE HÁ (08/08/2026). Era uma coluna só, e num
   portátil isso deixava metade do ecrã vazio com as reservas a descer sem fim.
   `auto-fill` com um mínimo de 300px: numa janela larga dá três ou quatro
   colunas, num telemóvel dá uma — sem número escrito à mão nem media query.

   ⚠️ E O CONTAINER MUDOU DE SÍTIO, obrigatoriamente. Media-lo na LISTA só
   funcionava enquanto a lista era uma coluna. Repartida, a lista tem 1000px e
   cada card tem 320px: a pergunta "esta coluna é estreita?" passou a ser
   respondida com a largura errada, e os cards voltavam ao desenho largo dentro
   de colunas estreitas — exatamente o defeito que o container query veio
   resolver. Agora quem se mede é o CARD. */
.agenda-lista{ display:grid; grid-template-columns:repeat(auto-fill, minmax(min(300px, 100%), 1fr)); gap:10px; }
/* ⚠️ `flex-wrap` deixou de ser condicional: um container query NÃO pode estilizar
   o próprio container (seria circular), e a mudança de linha é uma propriedade
   do card. Fica sempre ligada — em card largo nada se envolve, porque o corpo
   tem `flex:1` e as ações têm `min-width:0`, portanto encolhem antes de saltar.
   Quem manda mudar de linha é o `flex-basis` que a regra estreita dá às ações. */
.reserva-card{ display:flex; flex-wrap:wrap; align-items:stretch; gap:8px 16px; background:var(--branco);
  border:1px solid var(--cinza-borda); border-radius:var(--raio); box-shadow:var(--sombra); padding:14px 16px;
  container-type:inline-size; }
.reserva-term{ opacity:.62; }

/* ⭐ A reserva que veio do aviso (ele, 11/08/2026). Um realce sóbrio e PERMANENTE
   enquanto a página estiver aberta: um brilho que desaparece sozinho deixa quem
   olhou dois segundos depois sem saber qual era.
   ⚠️ `outline` e não `border`: a borda mudava a largura do cartão e empurrava o
   texto meio pixel, o que dá o efeito de "saltou" ao carregar. */
.reserva-destaque{
  outline:2px solid var(--vermelho);
  outline-offset:2px;
  border-radius:var(--raio-sm);
}
.reserva-destaque:focus{ outline:2px solid var(--vermelho); }
@media (prefers-reduced-motion: no-preference){
  .reserva-destaque{ animation:destaque-entra .5s ease-out 1; }
  @keyframes destaque-entra{
    from{ outline-color:transparent; background:color-mix(in srgb, var(--vermelho) 10%, transparent); }
    to  { outline-color:var(--vermelho); background:transparent; }
  }
}
.reserva-hora{ font-family:var(--fonte-titulo); font-weight:700; font-size:20px; min-width:56px;
  display:flex; align-items:center; border-right:1px solid var(--cinza-borda); padding-right:16px; }

/* data na hora do card, nas listas que atravessam dias (a confirmar / próximas) */
.reserva-dia{ display:block; font-size:11px; font-weight:700; text-transform:uppercase;
  letter-spacing:.4px; color:var(--cinza-medio); margin-bottom:2px; }
.reserva-corpo{ flex:1; min-width:0; display:flex; flex-direction:column; gap:5px; }
.reserva-topo{ display:flex; align-items:center; gap:9px; flex-wrap:wrap; }
/* Um nome sem espaços (um e-mail colado, um apelido comprido) não pode empurrar
   a coluna: parte-se a palavra em vez de rebentar o card. */
.reserva-nome{ font-size:15px; overflow-wrap:break-word; min-width:0; }
.reserva-meta{ display:flex; gap:14px; flex-wrap:wrap; color:var(--cinza-medio); font-size:13px; }
.reserva-obs{ font-size:13px; color:#8a6d00; background:#fffaf0; border-radius:var(--raio-sm); padding:5px 9px; display:inline-block; }
/* ⚠️ A NOTA INTERNA é da casa, o pedido é do cliente — e na agenda ficam uma
   por baixo da outra. Sem as distinguir, quem atende podia ler ao cliente uma
   nota que era SOBRE ele. Daí o cadeado e o fundo apagado. */
.reserva-nota{ background:var(--cinza-fundo, #f4f4f5); border-radius:var(--raio-xs);
  padding:3px 7px; color:var(--cinza-medio); font-style:italic; }
/* ⚠️ `min-width:0` é o que impede o transbordo: sem ele, uma caixa flex nunca
   encolhe abaixo do conteúdo, e os botões saíam para cima do que está à
   esquerda em vez de mudarem de linha. */
.reserva-acoes{ display:flex; align-items:center; gap:7px; flex-wrap:wrap;
  justify-content:flex-end; min-width:0; }
.reserva-acoes > *{ flex:0 0 auto; }

/* ── O CARD ESTREITO: a hora fica em cima, as ações numa linha só delas ──
   O mesmo desenho que a tela já usava no telemóvel, agora acionado pela LARGURA
   DA COLUNA e não pela da janela. A regra do telemóvel (@media, mais abaixo)
   fica: é ela que serve os navegadores sem container query. */
@container (max-width: 460px){
  .reserva-hora{ border-right:0; padding-right:0; min-width:0; font-size:18px; }
  .reserva-corpo{ flex:1 1 140px; }
  /* `flex:1 0 100%` e não `width:100%`: é a base de 100% que força a mudança de
     linha a partir de DENTRO, sem tocar no card. */
  .reserva-acoes{ flex:1 0 100%; justify-content:flex-start; }
}

/* Rede para quem não tem container query (Safari < 16): agora que a lista é
   sempre repartida em colunas, a coluna é sempre estreita, e a regra pode ser
   dita à mão para toda a lista — não só para a tela do turno. */
@supports not (container-type: inline-size){
  .agenda-lista .reserva-hora{ border-right:0; padding-right:0; min-width:0; }
  .agenda-lista .reserva-corpo{ flex:1 1 140px; }
  .agenda-lista .reserva-acoes{ flex:1 0 100%; justify-content:flex-start; }
}
.inline-f{ display:inline; margin:0; }
.btn-ok{ background:#1c7a3e; }
.btn-ok:hover{ background:#166432; }

/* ficha do cliente */
.ficha-box{ background:var(--branco); border:1px solid var(--cinza-borda); border-radius:var(--raio);
  box-shadow:var(--sombra); padding:16px 18px; margin-top:16px; font-size:14px; }
.ficha-box p{ margin:3px 0; }

/* mesas: form ao lado da lista */
.mesas-layout{ display:grid; grid-template-columns:300px 1fr; gap:24px; align-items:start; }
.mesas-form .secao-titulo{ margin-top:0; }
@media (max-width:760px){ .mesas-layout{ grid-template-columns:1fr; } }

.campo-check{ font-size:14px; }
.campo-check label{ display:flex; align-items:center; gap:8px; cursor:pointer; font-weight:500; }
.ajuda-inline{ color:var(--cinza-medio); font-weight:400; font-size:12px; }

/* ============================================================
   RESERVA ONLINE PÚBLICA (página do cliente, sem login)
   ============================================================ */
/* Ocupa a altura que sobra em vez de forçar 100vh: o body já garante o ecrã
   inteiro. Com 100vh fixos, um cartão mais alto do que o ecrã transbordava do
   wrap e a assinatura da Dext ficava por cima do formulário em vez de o fechar.
   safe center: em telas baixas não corta o topo do cartão (capa). */
.pub-wrap{ flex:1 0 auto; display:flex; align-items:safe center; justify-content:center; padding:32px 18px; position:relative; z-index:1; }
.pub-card{ width:100%; max-width:540px; background:var(--branco); border:1px solid var(--cinza-borda);
  border-radius:var(--raio); box-shadow:var(--sombra); overflow:hidden; }
.pub-corpo{ padding:34px 32px; }
.pub-capa{ line-height:0; background:var(--cinza-fundo); }
.pub-capa img{ display:block; width:100%; height:300px; object-fit:cover; }
@media (max-width:640px){ .pub-capa img{ height:200px; } }
.pub-capa + .pub-corpo .pub-marca{ margin-top:2px; }
.pub-marca{ display:flex; flex-direction:column; align-items:center; gap:10px; margin-bottom:22px; }
.pub-capa + .pub-corpo .pub-logo{ margin-top:-52px; background:var(--branco); border-radius:var(--raio); padding:6px 10px; box-shadow:var(--sombra); }
.pub-logo{ max-height:64px; max-width:180px; object-fit:contain; }
.pub-nome{ font-family:var(--fonte-titulo); font-weight:700; font-size:22px; text-align:center; }
.pub-titulo{ font-family:var(--fonte-titulo); font-weight:700; font-size:24px; letter-spacing:-.4px; }
.pub-sub{ color:var(--cinza-medio); font-size:14px; margin:4px 0 22px; }
.pub-card .form-linha{ display:flex; gap:12px; flex-wrap:wrap; }
.pub-card .form-linha .campo{ flex:1; min-width:140px; }
.pub-card select{ width:100%; padding:13px 12px; border:1.5px solid var(--cinza-borda); border-radius:var(--raio-sm); font:inherit; background:var(--branco); }
.pub-card .btn{ margin-top:6px; }
.pub-ok{ text-align:center; padding:10px 0; }
.pub-ok-ic{ width:60px; height:60px; margin:0 auto 16px; border-radius:50%; background:#eaf7ee; color:#1c7a3e;
  font-size:30px; font-weight:700; display:flex; align-items:center; justify-content:center; }
.pub-ok h1{ font-family:var(--fonte-titulo); font-size:22px; margin-bottom:8px; }
.pub-ok p{ color:var(--cinza-medio); font-size:14px; margin-bottom:20px; }
.pub-rodape{ text-align:center; color:var(--cinza-medio); font-size:12px; margin-top:24px; }

/* aviso do link público (área interna) */
.link-publico{ display:flex; align-items:center; gap:10px; flex-wrap:wrap; background:var(--branco);
  border:1px dashed var(--cinza-borda); border-radius:var(--raio-sm); padding:12px 16px; margin:16px 0; font-size:13px; }
.link-publico code{ background:var(--cinza-fundo); padding:3px 8px; border-radius:var(--raio-xs); font-size:13px; }

/* Grupo de ações do cabeçalho (Ver VIPs, Importar, Exportar, Novo…): quebra
   linha, senão quatro botões não cabem na largura de um telemóvel. */
.cab-acoes{ display:flex; align-items:center; flex-wrap:wrap; gap:10px; }

/* Horários da reserva online: FICHAS numa grelha, não uma fila que quebra.
   Colunas iguais dão-lhes cara de cartão escolhível — e a mão do telemóvel
   acerta num alvo de 44px sem apurar a pontaria. */
.slots-area{ display:grid; grid-template-columns:repeat(auto-fill,minmax(84px,1fr)); gap:8px; min-height:44px; }
.slots-msg{ grid-column:1/-1; color:var(--cinza-medio); font-size:13px; align-self:center; }
.slot-btn{ border:1px solid var(--cinza-borda); background:var(--branco); color:var(--preto);
  border-radius:var(--raio-sm); padding:12px 8px; font:inherit; font-size:14px; font-weight:600; cursor:pointer;
  text-align:center; transition:border-color .12s, color .12s, background .12s; }
.slot-btn:hover{ border-color:var(--vermelho); color:var(--vermelho); }
.slot-btn.sel{ background:var(--vermelho); border-color:var(--vermelho); color:#fff; }

/* ---- reserva em duas etapas (pública e widget partilham esta tela) ---- */
.pub-passos{ display:flex; align-items:center; gap:10px; list-style:none; margin:0 0 20px; padding:0;
  font-size:13px; color:var(--cinza-medio); }
.pub-passos li{ display:flex; align-items:center; gap:7px; }
.pub-passos li + li::before{ content:""; width:18px; height:1px; background:var(--cinza-borda); margin-right:3px; }
.pub-passo-n{ width:22px; height:22px; border-radius:50%; border:1px solid var(--cinza-borda);
  display:flex; align-items:center; justify-content:center; font-size:12px; font-weight:700; }
.pub-passos li.ativo{ color:var(--preto); font-weight:600; }
.pub-passos li.ativo .pub-passo-n{ background:var(--vermelho); border-color:var(--vermelho); color:#fff; }
.pub-passos li.feito .pub-passo-n{ border-color:var(--vermelho); color:var(--vermelho); }
.pub-dica{ color:var(--cinza-medio); font-size:12px; margin:8px 0 0; }
/* O telefone leva o seletor de país à frente e come metade da linha; ao lado
   dele o e-mail ficava com 140px, um canudo para escrever um endereço. Num
   cartão desta largura, os dois lado a lado não cabem: empilham. */
.pub-card .form-linha:has(.campo-tel){ display:block; }
/* o que ele já escolheu, sempre à vista na etapa 2 — e alterável dali mesmo */
.pub-escolha{ display:flex; align-items:center; justify-content:space-between; gap:12px; flex-wrap:wrap;
  background:var(--cinza-fundo); border-radius:var(--raio-sm); padding:11px 14px; margin-bottom:18px; }
.pub-escolha-txt{ font-size:14px; font-weight:600; }
.pub-alterar{ background:none; border:0; padding:0; font:inherit; font-size:13px; font-weight:600;
  color:var(--vermelho); cursor:pointer; text-decoration:underline; }

/* Formas do widget: barra lateral estreita e secção larga de página.
   A LARGURA é do container do site anfitrião (o iframe é width:100%); o que
   muda aqui é a densidade — empilhar ou espalhar, fichas mais ou menos largas. */
.pub-compacto .slots-area{ grid-template-columns:repeat(auto-fill,minmax(70px,1fr)); gap:6px; }
.pub-compacto .slot-btn{ padding:10px 6px; font-size:13px; }
.pub-compacto .pub-card .form-linha{ display:block; }
.pub-compacto .pub-titulo{ font-size:20px; }
.pub-compacto .pub-capa img{ height:150px; }
.pub-largo .slots-area{ grid-template-columns:repeat(auto-fill,minmax(104px,1fr)); gap:10px; }
.pub-largo .pub-card .form-linha .campo{ min-width:200px; }

/* tela de disponibilidade (horários por dia) */
.disp-dias{ display:flex; flex-direction:column; gap:8px; margin:10px 0 6px; }
.disp-dia{ display:grid; grid-template-columns:200px 1fr; gap:12px 18px; align-items:center;
  background:var(--branco); border:1px solid var(--cinza-borda); border-radius:var(--raio-sm); padding:12px 14px; }
.disp-dia-topo{ display:flex; align-items:center; justify-content:space-between; gap:10px; }
.disp-dia-nome{ font-weight:600; font-size:14px; }
.disp-chk{ display:inline-flex; align-items:center; gap:6px; font-size:13px; font-weight:600; color:var(--cinza-medio); cursor:pointer; user-select:none; }
.disp-chk input{ accent-color:var(--vermelho); }
.disp-horas{ display:flex; gap:16px; flex-wrap:wrap; }
.disp-janela{ display:flex; align-items:center; gap:8px; }
.disp-janela input[type=time]{ padding:7px 8px; border:1px solid var(--cinza-borda); border-radius:var(--raio-sm); font:inherit; font-size:13px; }
.disp-janela span{ color:var(--cinza-medio); }
/* turno (almoço/jantar) que se liga e desliga por dia */
.disp-turno{ display:inline-flex; align-items:center; gap:6px; font-size:13px; font-weight:600;
  color:var(--cinza-medio); cursor:pointer; user-select:none; white-space:nowrap; }
.disp-turno input{ accent-color:var(--destaque); }
.disp-turno-horas{ display:flex; align-items:center; gap:6px; }
.disp-janela.turno-off .disp-turno-horas{ display:none; }
.disp-janela.turno-off .disp-turno{ opacity:.55; font-weight:500; }
.disp-fechado-rot{ display:none; }
.disp-dia.disp-fechado{ background:var(--cinza-fundo); }
.disp-dia.disp-fechado .disp-dia-nome{ color:var(--cinza-medio); }
.disp-dia.disp-fechado .disp-chk{ color:var(--vermelho); }
.disp-dia.disp-fechado .disp-horas{ display:none; }
.disp-dia.disp-fechado .disp-fechado-rot{ display:block; color:var(--cinza-medio); font-size:13px; font-style:italic; }
@media (max-width:640px){ .disp-dia{ grid-template-columns:1fr; gap:8px; } }

/* ============================================================
   BARRA LATERAL (sidebar) — substitui a barra do topo
   ============================================================ */
.sidebar{ position:fixed; top:0; left:0; width:230px; height:100vh; background:var(--menu); color:var(--menu-fg);
  display:flex; flex-direction:column; gap:16px; padding:20px 16px; overflow-y:auto; z-index:50; }
.sb-marca{ display:flex; flex-direction:column; align-items:center; gap:16px; }
/* ⭐ A logo É o Início (19/08/2026): leva estado, como qualquer porta do menu.
   ⚠️ Discreto de propósito — é a marca, não um botão de navegação a gritar. */
.sb-dext{ display:flex; align-items:center; justify-content:center; gap:12px; text-decoration:none;
  padding:6px 10px; border-radius:var(--raio-sm); transition:background .15s; }
.sb-dext:hover{ background:var(--menu-hover); }
/* 🚨 19/08, ele: *"essa sombra atrás da logo não tinha. Pode tirar."* Eu tinha
   dado à logo o mesmo fundo de "estou aqui" dos itens do menu, com o argumento
   de que a única porta de casa não podia ser a única sem estado. O argumento
   vale — mas a logo NÃO É um item do menu, é a marca; pintá-la como item punha
   uma caixa clara por trás dela em todas as visitas ao Início.
   ⭐ O estado ficou, sem tinta: `aria-current="page"` no `topo.php`. Quem usa
   leitor de tela continua a saber; quem vê, vê a marca limpa. */
.sb-dext-ic{ width:40px; height:40px; }
.sb-dext-wm{ height:24px; width:auto; }
.sb-hamburguer{ display:none; }
/* 🚨 E o de recolher também nasce escondido, pela razão inversa: ele SÓ existe
   no computador. Sem esta linha aparecia no telemóvel como um traço solto ao
   lado da logo, ao lado do sanduíche que já lá está. Apanhado no navegador. */
.sb-recolher{ display:none; }
/* menu claro: logo Dext vai a preto para aparecer */
.sidebar.menu-claro .sb-dext-ic, .sidebar.menu-claro .sb-dext-wm{ filter:brightness(0); }

.sb-empresa{ display:flex; flex-direction:column; align-items:center; text-align:center; gap:10px;
  padding:18px 0; border-top:1px solid var(--menu-borda); border-bottom:1px solid var(--menu-borda); }
.sb-empresa-logo{ max-width:170px; max-height:80px; width:auto; object-fit:contain; }
.sb-empresa-nome{ font-family:var(--fonte-titulo); font-weight:700; font-size:19px; line-height:1.15; word-break:break-word; color:var(--destaque-menu); }

.sb-nav{ display:flex; flex-direction:column; gap:4px; }
.sb-link{ display:flex; align-items:center; gap:10px; color:var(--menu-fg-suave); text-decoration:none;
  font-weight:600; font-size:14px; padding:10px 12px; border-radius:var(--raio-sm); transition:background .15s, color .15s; }
.sb-link:hover{ background:var(--menu-hover); color:var(--menu-fg); }
.sb-link svg{ width:18px; height:18px; flex:none; }

/* ═══════════ OS MÓDULOS NA BARRA (ele, 18/08/2026) ═══════════
   *"todos os módulos, quando clica na seta, aparecem os submódulos abaixo.
   Nunca fica mais de um módulo aberto, para caber e não ficar poluído."*

   ⚠️ Quem abre e fecha é o `<details name>` do HTML, não JavaScript. Aqui só se
   desenha: o triângulo nativo sai, a seta da casa entra e gira. */
.sb-modulos{ display:flex; flex-direction:column; gap:2px; }
.sb-mod-cab{ cursor:pointer; list-style:none; user-select:none; }
.sb-mod-cab::-webkit-details-marker{ display:none; }   /* Safari desenha o dele à parte */
.sb-mod-nome{ flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.sb-seta{ width:15px !important; height:15px !important; opacity:.6; transition:transform .18s; }
.sb-mod[open] > .sb-mod-cab .sb-seta{ transform:rotate(90deg); }
.sb-mod[open] > .sb-mod-cab{ color:var(--menu-fg); }

/* ⚠️ O fio à esquerda é o que diz "isto está DENTRO do módulo". Sem ele os
   submódulos leem-se como irmãos dos módulos, que é o que se quer evitar. */
.sb-subs{ display:flex; flex-direction:column; gap:1px; margin:2px 0 6px 21px;
  padding-left:10px; border-left:1px solid var(--menu-borda); }
.sb-sub{ display:flex; align-items:center; gap:8px; color:var(--menu-fg-suave); text-decoration:none;
  font-size:13px; font-weight:500; line-height:1.35; padding:7px 10px; border-radius:var(--raio-xs);
  transition:background .15s, color .15s; }
/* ⚠️ O nome QUEBRA, não corta. Numa coluna de 230px, "Entrada de mercadoria" e
   "Busca de talentos" não cabem numa linha, e rótulo cortado parece defeito —
   foi a lição dos links da conta na barra recolhida ("Audito...", "Config..."). */
.sb-sub > span:first-child{ flex:1; min-width:0; }
.sb-sub:hover{ background:var(--menu-hover); color:var(--menu-fg); }
.sb-sub.ativo{ background:var(--menu-hover); color:var(--menu-fg); font-weight:700; }
.sb-sub-hub{ font-style:italic; }
/* "em breve" não é link e não deve parecer um: só a Administração o vê.
   ⚠️ A etiqueta desce para a linha de baixo quando não cabe ao lado: "Receituários"
   é uma palavra só e não quebra, e a etiqueta roubava-lhe a largura. */
.sb-sub-breve{ opacity:.5; cursor:default; flex-wrap:wrap; }
.sb-sub-breve > span:first-child{ flex:1 0 auto; }
.sb-sub-breve small{ flex:none; font-size:10.5px; text-transform:uppercase; letter-spacing:.04em; }

.sb-rodape{ margin-top:auto; display:flex; flex-direction:column; gap:6px;
  padding-top:14px; border-top:1px solid var(--menu-borda); }
/* ⚠️ `.sb-user` é um `<a>` desde 18/08 (a conta mora na foto). Sem estas três
   linhas o nome saía SUBLINHADO e o bloco não reagia ao rato — é a mesma falta
   que o `.btn-mini` tinha quando passou a servir para `<a>`. */
.sb-user{ display:flex; align-items:center; gap:10px; margin-bottom:6px;
  color:inherit; text-decoration:none; padding:6px 8px; margin-left:-8px; margin-right:-8px;
  border-radius:var(--raio-sm); transition:background .15s; }
.sb-user:hover{ background:var(--menu-hover); }
.sb-user-info{ display:flex; flex-direction:column; align-items:flex-start; gap:3px; min-width:0; }
.sb-user-nome{ font-weight:700; font-size:14px; color:var(--menu-fg); word-break:break-word; }
.sb-user .badge{ background:var(--menu-hover); color:var(--menu-fg-suave); padding:3px 9px;
  border-radius:999px; font-size:11px; font-weight:600; text-transform:capitalize; }
.sb-user .badge-admin{ background:color-mix(in srgb, var(--destaque-menu) 20%, transparent); color:var(--destaque-menu); }
.sb-conta-links{ display:flex; flex-direction:column; gap:2px; }
.sb-conta{ display:flex; align-items:center; gap:9px; color:var(--menu-fg-suave); text-decoration:none;
  font-size:13px; font-weight:600; padding:7px 12px; border-radius:var(--raio-sm);
  transition:background .15s, color .15s; }
.sb-conta svg{ width:16px; height:16px; flex:none; }
.sb-conta:hover{ background:var(--menu-hover); color:var(--menu-fg); }
/* ═══ assinatura da Dext no rodapé da área clara ═══
   Sai da barra escura e passa a fechar o conteúdo: discreta, alinhada com a
   coluna de texto e acompanhando o deslocamento da sidebar. */
.rodape-dext{
  display:flex; align-items:center; justify-content:center; gap:7px;
  max-width:1000px; margin:0 auto; padding:26px 22px 34px;
  font-size:12px; color:var(--cinza-medio);
}
.rodape-dext-ic{ height:17px; width:auto; fill:var(--destaque); flex:none; } /* fica no conteúdo claro, não no menu */
.rodape-dext strong{ color:var(--texto); font-weight:700; }

/* conteúdo desloca pra direita da sidebar */
/* ⚠️ `margin-right:0` não é decoração: é o que impede a PÁGINA INTEIRA de rolar
   na horizontal. O `.conteudo` tem `margin:0 auto` na regra base; com a barra
   lateral, o `margin-left` passa a 230px e o `auto` fica só à direita. Uma
   margem automática no eixo transversal **desliga o `stretch` do flex**, e o
   bloco deixa de valer "a largura disponível" para passar a valer "a largura do
   conteúdo" — numa tela com tabela larga, mais do que cabe. O `.tabela-wrap`
   rola por dentro, mas o body rolava por fora na mesma.
   Apanhado com a ficha técnica a 900px: scrollWidth 946 para clientWidth 900. */
.conteudo{ margin-left:230px; margin-right:0; flex:1 0 auto; }   /* cresce e empurra o rodapé pro fundo */
.rodape-dext{ margin-left:230px; flex:0 0 auto; } /* fica sempre no fim, colado no fundo */
/* páginas sem sidebar (ex.: logado abrindo a reserva pública): rodapé centrado normal */
/* Sem sidebar (reserva pública, cadastro por convite): volta a centrar. Tem de
   repor os DOIS lados, senão o margin-left acima vence o `margin:0 auto` e a
   assinatura cola-se à esquerda. */
body:not(:has(.sidebar)) .rodape-dext{ margin-left:auto; margin-right:auto; }
body:not(:has(.sidebar)) .conteudo{ margin-left:auto; margin-right:auto; }

/* ═══════════ BARRA RECOLHIDA (ele, 17/08/2026) ═══════════
   *"Possibilidade de esconder o menu e trazer de volta, botão menu sanduíche;
   quando retraído aparece só o símbolo da Dext, e os ícones."*

   ⚠️ Recolhida NÃO é escondida: continua a dar para navegar, só sem as palavras.
   Um menu que desaparece obriga a abri-lo para tudo, e aí ninguém o recolhe.
   ⚠️ Vale só a partir de 821px: no telemóvel a barra já é horizontal e tem o seu
   próprio sanduíche, que não se toca ([[dext-responsivo]]). */
@media (min-width:821px){
  .sb-recolher{ display:flex; align-items:center; justify-content:center; background:none; border:none;
    color:var(--menu-fg-suave); cursor:pointer; padding:6px; border-radius:var(--raio-sm); align-self:flex-end; }
  .sb-recolher:hover{ background:var(--menu-hover); color:var(--menu-fg); }
  .sb-recolher svg{ width:20px; height:20px; }

  .sidebar.sb-min{ width:70px; padding-left:10px; padding-right:10px; }
  .sidebar.sb-min + .conteudo, body:has(.sidebar.sb-min) .conteudo{ margin-left:70px; }
  body:has(.sidebar.sb-min) .rodape-dext{ margin-left:70px; }


  /* o que desaparece: as palavras. O que fica: o símbolo e os ícones. */
  .sidebar.sb-min .sb-dext-wm,
  .sidebar.sb-min .sb-empresa,
  .sidebar.sb-min .sb-empresa-nome,
  .sidebar.sb-min .sb-user-info,

  .sidebar.sb-min .sb-link span:not(.sb-badge){ display:none; }

  .sidebar.sb-min .sb-dext{ justify-content:center; }
  .sidebar.sb-min .sb-dext-ic{ width:34px; height:34px; }
  .sidebar.sb-min .sb-link{ justify-content:center; padding:10px 0; font-size:0; gap:0; }
  .sidebar.sb-min .sb-link svg{ width:20px; height:20px; }

  /* ⭐ RECOLHIDA, O SUBMENU SAI PARA O LADO (ele, 18/08/2026).
     ⭐⭐ E ABRE COM O RATO POR CIMA (ele, 19/08/2026). Eu tinha escolhido o
     clique com um argumento que a prática desmentiu — *"com o rato por cima, a
     lista saltava sempre que se atravessava a barra"*. O que saltava era a
     passagem sem intenção, e isso mede-se em tempo: o `topo.php` abre com 130ms
     de atraso e fecha com 260ms de folga. Ver lá o porquê de cada número.
     ⚠️ A lista encosta à barra (`left:70px` = a largura dela) de propósito: um
     fio de espaço entre as duas era um buraco onde o rato caía a meio caminho.
     🚨 `position:fixed` e não `absolute`: a barra tem `overflow-y:auto` e
     recortaria a lista. Fixo escapa ao recorte; o topo vem do JS. */
  .sidebar.sb-min .sb-seta{ display:none; }
  .sidebar.sb-min .sb-mod-cab{ position:relative; }
  .sidebar.sb-min .sb-subs{ margin:0; padding:0; border-left:none; }
  .sidebar.sb-min .sb-mod:not([open]) > .sb-subs{ display:none; }
  .sidebar.sb-min .sb-mod[open] > .sb-subs{
    position:fixed; left:70px; top:var(--sb-fly-top, 90px); z-index:60;
    width:216px; max-height:calc(100vh - 24px); overflow-y:auto;
    padding:8px; background:var(--menu); border:1px solid var(--menu-borda);
    border-radius:var(--raio-sm); box-shadow:0 10px 30px rgba(0,0,0,.28); }
  /* O nome do módulo viaja em `data-nome`: recolhida, a lista sozinha não diz
     de quem é. */
  .sidebar.sb-min .sb-mod[open] > .sb-subs::before{
    content:attr(data-nome); display:block; padding:2px 10px 8px;
    font-size:11px; font-weight:700; letter-spacing:.06em; text-transform:uppercase;
    color:var(--menu-fg); opacity:.65; }
  /* ⚠️ Dentro da lista o aviso volta a ser NÚMERO: a regra do ponto lá em baixo
     vale para os ícones da barra, não para um menu com palavras. */
  .sidebar.sb-min .sb-subs .sb-badge{ position:static; min-width:0; height:auto;
    padding:1px 7px; font-size:11px; }
  /* 🐞 A BUSCA RECOLHIDA (23/08/2026). Aqui o campo era `display:none` e
     sobrava a lupa, que não fazia nada — não havia como pesquisar sem abrir o
     menu. ⚠️ E `display:none` era o próprio impedimento: um campo que não
     existe não recebe foco, logo nem um rótulo o alcançava.
     ⭐ Agora ele existe sempre, encostado à barra e sem largura, e ABRE ao lado
     quando o rato passa ou quando ganha foco — o mesmo sítio e o mesmo molde da
     lista suspensa dos módulos (`.sb-fly`), para ser o gesto que já se conhece.
     ⚠️ `pointer-events:none` enquanto fechado: sem isso, um campo invisível de
     largura zero continua a apanhar cliques que eram para a lupa. */
  .sidebar.sb-min .sb-busca{ justify-content:center; padding:10px 0; }
  .sidebar.sb-min .sb-busca label{ cursor:pointer; display:inline-flex; }
  /* 🚨 `fixed` e NÃO `absolute`, e a nota já estava escrita nesta folha, umas
     linhas acima, para a lista suspensa dos módulos: **a barra tem
     `overflow-y:auto`**, e um filho absoluto dentro de um contentor com overflow
     é cortado no limite dele — o campo abria com 3px de largura, encostado à
     barra, e mais nada. Apanhado na prova no navegador, e eu tinha lido a nota.
     ⚠️ `left` fixo nos 78px porque a barra recolhida tem 70 de largura fixa;
     `top:auto` mantém a altura que o campo teria no fluxo, que é a da lupa. */
  .sidebar.sb-min .sb-busca input{
    position:fixed; left:78px; top:auto; margin:0;
    width:0; padding:0; border:1.5px solid transparent; border-radius:var(--raio-sm);
    opacity:0; pointer-events:none; z-index:60;
    background:var(--menu); color:var(--menu-fg);
    transition:width .14s ease, opacity .14s ease, padding .14s ease;
  }
  .sidebar.sb-min .sb-busca:hover input,
  .sidebar.sb-min .sb-busca:focus-within input{
    width:210px; padding:9px 12px; opacity:1; pointer-events:auto;
    border-color:var(--menu-borda); box-shadow:0 12px 32px rgba(0,0,0,.28);
  }
  .sidebar.sb-min .sb-user{ justify-content:center; }
  /* ⚠️ Os links da conta ficam só com o ÍCONE. A primeira tentativa deixou o
     texto a encolher e via-se "Audito..." e "Config..." — um rótulo cortado é
     pior do que rótulo nenhum, porque parece defeito. */
  .sidebar.sb-min .sb-conta{ justify-content:center; padding:9px 0; }
  .sidebar.sb-min .sb-conta span{ display:none; }
  .sidebar.sb-min .sb-conta svg{ width:18px; height:18px; }
  .sidebar.sb-min .sb-sair-form{ display:flex; justify-content:center; }
  .sidebar.sb-min .sb-recolher{ align-self:center; }
  /* ⭐ O aviso por ler não pode desaparecer com o rótulo: vira um ponto sobre o
     sino. É a única informação da barra que muda sozinha. */
  .sidebar.sb-min .sb-link{ position:relative; }
  .sidebar.sb-min .sb-badge{ position:absolute; top:4px; right:12px; min-width:8px; height:8px;
    padding:0; font-size:0; border-radius:999px; }
}

/* mobile: sidebar vira barra horizontal no topo */
@media (max-width:820px){
  /* ⭐⭐⭐ A BARRA FICA PRESA NO TOPO (ele, 23/08/2026: *"no celular, deixar o
     menu fixo. Se eu tô lá embaixo da página consigo sempre acessar"*).
     Era `relative` e rolava com a página: no fim de uma lista longa — e as
     listas desta casa são longas — a única porta para o resto do sistema ficava
     a mil pixels acima, e voltar ao menu era rolar tudo de novo.
     ⚠️ `sticky` e não `fixed`: a barra continua a OCUPAR o seu lugar no fluxo,
     logo o conteúdo nasce por baixo dela sem precisar de um `padding-top`
     escrito à mão — que é a linha que se esquece de acertar quando a altura da
     barra muda.
     ⚠️ `top:0` com `env(safe-area-inset-top)`: no iPhone com o sistema por cima,
     sem isto a logo ficava debaixo do relógio.
     ⚠️ O menu ABERTO precisa de poder rolar sozinho — num telemóvel deitado, a
     lista de módulos é mais alta do que a tela, e sem isto o fim dela ficava
     inalcançável. */
  /* 🚨 `fixed` e não `sticky`, e a razão foi medida: o `body` desta casa é um
     **flex container com `height` fixa** (`100dvh`), e um item `sticky` dentro
     dele desliza só dentro dessa altura — grudava 812px e depois ia-se embora
     com a página. Rolei 1.834px e a barra estava a −1.094. Ver a nota do
     `.sb-fly` umas linhas acima: é a mesma armadilha, outro sítio.
     ⚠️ Com `fixed` a barra sai do fluxo, e o conteúdo tem de ganhar o espaço
     dela de volta — é o `padding-top` do `.conteudo` aqui em baixo. Sem isso, a
     primeira linha de cada tela nasce debaixo da barra. */
  .sidebar{ position:fixed; top:0; left:0; right:0; z-index:51; width:auto; height:auto;
    flex-direction:column; gap:0; padding:0; overflow:visible; background:var(--menu);
    padding-top:env(safe-area-inset-top, 0px);
    box-shadow:0 2px 12px rgba(0,0,0,.18); }
  /* ⚠️ O menu ABERTO precisa de poder rolar sozinho: num telemóvel deitado a
     lista de módulos é mais alta do que a tela, e sem isto o fim dela ficava
     inalcançável. */
  .sidebar.aberto{ max-height:100dvh; overflow-y:auto; }
  .sb-marca{ flex-direction:row; align-items:center; gap:20px; padding:16px 18px; width:100%; }
  .sb-dext{ flex:none; }
  .sb-dext-ic{ width:28px; height:28px; }
  .sb-dext-wm{ height:17px; }
  .sb-empresa{ flex-direction:row; align-items:center; gap:14px; padding:0 0 0 20px;
    border:none; border-left:1px solid var(--menu-borda); margin-right:auto; min-width:0; }
  .sb-empresa-logo{ max-height:34px; max-width:96px; }
  .sb-empresa-nome{ font-size:15px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; max-width:42vw; }
  .sb-hamburguer{ display:flex; align-items:center; justify-content:center; background:none; border:none;
    color:var(--menu-fg); cursor:pointer; padding:6px; flex:none; }
  .sb-hamburguer svg{ width:26px; height:26px; }
  .sb-nav, .sb-rodape{ display:none; }
  .sidebar.aberto .sb-nav{ display:flex; flex-direction:column; padding:4px 12px 8px; border-top:1px solid var(--menu-borda); }
  .sidebar.aberto .sb-rodape{ display:flex; flex-direction:column; align-items:stretch; gap:4px;
    margin-top:0; padding:10px 12px 14px; border-top:1px solid var(--menu-borda); }
  .sb-user{ margin-bottom:6px; }
  .sb-conta-links{ flex-direction:column; }
  /* ⚠️ Os 72px são a ALTURA MEDIDA da barra fechada (`.sb-marca` com 16px de
     padding em cima e em baixo mais a logo). Um número escrito à mão é o preço
     de a barra ser `fixed` — e a alternativa, medir por JavaScript, punha a
     primeira linha de todas as telas na dependência de um script.
     ⚠️ `safe-area` outra vez: no iPhone a barra desce o que o sistema ocupa, e o
     conteúdo tem de descer o mesmo. */
  .conteudo{ margin-left:0; padding-top:calc(72px + env(safe-area-inset-top, 0px)); }
  .rodape-dext{ margin-left:0; }
  /* barra de salvar do editor: no celular deixa de ser fixa (não briga com o
     botão flutuante de ajuda no canto) e flui ao fim do formulário */
  .editor-barra{ position:static; }
}

/* tela muito estreita: não cabe Dext + logo + nome com folga -> esconde o nome
   e deixa só a logo. Só quando HÁ logo (sem logo, o nome permanece). */
@media (max-width:480px){
  .sb-empresa:has(.sb-empresa-logo) .sb-empresa-nome{ display:none; }
}

/* seletor de cor da marca (Configurações) */
/* ⭐⭐ O SELETOR DE COR, EM TODO O SISTEMA (22/08/2026).
   Ele, ao ver o da tela de etiquetas: *"não gostei… talvez algo mais
   arredondado, mais ícone"* — e depois: *"se tiver algum outro lugar no sistema
   que estava daquele jeito, pode deixar assim também"*.

   ⚠️ A regra é do CAMPO, não do bloco onde ele calha estar. Foi essa a lição:
   o estilo antigo vivia em `.tar-tag-form input[type=color]`, e quando aquele
   formulário deixou de existir o campo voltou ao desenho CRU do navegador sem
   ninguém dar por isso. Estilar pelo nome do formulário apaga o CSS em silêncio
   assim que o markup muda.
   ⚠️ Os três `::-*-swatch` são obrigatórios: sem eles fica um quadrado colorido
   dentro do círculo, porque cada navegador desenha o miolo no seu pseudo. */
input[type=color]{
  -webkit-appearance:none; appearance:none;
  padding:0; background:none; cursor:pointer; overflow:hidden;
  border:1px solid var(--cinza-borda); border-radius:50%;
}
input[type=color]::-webkit-color-swatch-wrapper{ padding:0; border-radius:50%; }
input[type=color]::-webkit-color-swatch{ border:none; border-radius:50%; }
input[type=color]::-moz-color-swatch{ border:none; border-radius:50%; }
input[type=color]:hover{ border-color:var(--preto); }
input[type=color]:focus-visible{ outline:2px solid var(--vermelho); outline-offset:2px; }
input[type=color]:disabled{ cursor:not-allowed; opacity:.55; }

.cor-linha{ display:flex; align-items:center; gap:10px; }
/* Só o TAMANHO por contexto: o acabamento é o de cima, e é um só. */
/* 🐞🐞 O `.campo` NO SELETOR NÃO É ENFEITE (25/08/2026) — ele mostrou o sistema
   a um possível cliente e as Configurações estavam com as amostras de cor a
   sair como OVAIS gordos. Medido: **141 × 40** onde devia ser 40 × 40.
   🚨 E não era "ganha por ordem", era por ESPECIFICIDADE — que é pior, porque
   não se vê a ler o ficheiro de cima para baixo:
     `.campo input:not([type=checkbox]):not([type=radio])`  → (0,3,1)  width:100%
     `.cor-linha input[type=color]`                          → (0,2,1)  width:40px
   A mais específica ganha esteja onde estiver no ficheiro. O campo de cor virava
   uma caixa de texto de 141px, e o miolo redondo esticado nessa largura é o oval.
   ⚠️ E a correção ÓBVIA era a errada: pôr `:not([type=color])` na regra base
   arruma a cor **e parte o resto** — sobe-a para (0,4,1) e ela passa a ganhar a
   regras que antes empatavam e venciam por ordem. Provado a doer: as caixas do
   hex saltaram de 98px para 200px no mesmo instante em que as amostras ficaram
   quadradas. Aqui só se acrescenta o `.campo` que já está no HTML, para EMPATAR
   em (0,3,1) e vencer por vir depois — sem mexer no que ninguém pediu.
   ⏭ A limpeza a sério (tirar a regra base de cima dos campos que não são de
   texto, e descer as que dependem dela) é do item 5 da estrutura, e quer-se
   medida com tempo — não na véspera de um deploy. */
/* ⚠️ E não é só a LARGURA que a regra base rouba: rouba o recheio (13px 15px
   dentro de uma caixa de 40px deixa o miolo num risco de 10px), o fundo branco,
   a borda de 1,5px e o raio — o círculo virava quadrado de cantos moles. Por
   isso esta regra devolve as cinco coisas de uma vez, e não só o tamanho. */
.campo .cor-linha input[type=color]{
  width:40px; height:40px; flex:0 0 auto;
  padding:0; background:none; border-width:1px; border-radius:50%;
}
.cor-linha input[type=text]{ width:130px; }
.cor-amostra{ width:26px; height:26px; border-radius:var(--raio-xs); border:1px solid var(--cinza-borda); flex:none; }

/* ============================================================
   AJUDA — botão flutuante + painel (manuais + contato)
   ============================================================ */
.ajuda-fab{ position:fixed; right:24px; bottom:22px; z-index:60; width:54px; height:56px;
  background:transparent; color:var(--vermelho); border:none; cursor:pointer; padding:0;
  display:flex; align-items:center; justify-content:center; transition:transform .15s; }
.ajuda-fab:hover{ transform:translateY(-2px) scale(1.06); }
.ajuda-fab .ajuda-d{ width:54px; height:56px; filter:drop-shadow(0 6px 14px rgba(17,17,17,.35)); }
.ajuda-fab .ajuda-q{ position:absolute; left:65%; top:47%; transform:translate(-50%,-50%);
  color:#fff; font-family:var(--fonte-titulo); font-weight:800; font-size:18px; line-height:1; pointer-events:none; }

.ajuda-painel{ position:fixed; right:22px; bottom:88px; z-index:60; width:380px; max-width:calc(100vw - 32px);
  max-height:76vh; background:var(--branco); border:1px solid var(--cinza-borda); border-radius:var(--raio);
  box-shadow:0 24px 60px rgba(17,17,17,.22); display:flex; flex-direction:column; overflow:hidden; }
.ajuda-cab{ display:flex; align-items:center; justify-content:space-between; padding:16px 18px;
  background:var(--menu); color:var(--menu-fg); }
.ajuda-cab strong{ font-family:var(--fonte-titulo); font-size:16px; }
.ajuda-x{ background:none; border:none; color:var(--menu-fg); font-size:24px; line-height:1; cursor:pointer; opacity:.8; }
.ajuda-x:hover{ opacity:1; }

.ajuda-abas{ display:flex; border-bottom:1px solid var(--cinza-borda); }
.ajuda-aba{ flex:1; background:none; border:none; padding:12px 8px; font:inherit; font-size:13px; font-weight:600;
  color:var(--cinza-medio); cursor:pointer; border-bottom:2px solid transparent; }
.ajuda-aba.ativa{ color:var(--vermelho); border-bottom-color:var(--vermelho); }

.ajuda-corpo{ padding:16px 18px; overflow-y:auto; }
.ajuda-intro{ font-size:13px; color:var(--cinza-medio); margin-bottom:14px; }
.ajuda-grupo{ font-size:11px; font-weight:700; text-transform:uppercase; letter-spacing:.5px;
  color:var(--cinza-medio); margin:16px 0 6px; }
.ajuda-item{ border:1px solid var(--cinza-borda); border-radius:var(--raio-sm); margin-bottom:7px; overflow:hidden; }
.ajuda-item summary{ cursor:pointer; padding:11px 14px; font-weight:600; font-size:14px; list-style:none; position:relative; }
.ajuda-item summary::-webkit-details-marker{ display:none; }
.ajuda-item summary::after{ content:'+'; position:absolute; right:14px; color:var(--cinza-medio); font-size:17px; }
.ajuda-item[open] summary::after{ content:'–'; }
.ajuda-item[open] summary{ color:var(--vermelho); }
.ajuda-conteudo{ padding:2px 14px 14px; font-size:13.5px; color:#333; }
.ajuda-conteudo p{ margin:6px 0; }
.ajuda-conteudo ul{ margin:6px 0 6px 18px; }
.ajuda-conteudo li{ margin:3px 0; }
.ajuda-conteudo code{ background:var(--cinza-fundo); padding:1px 5px; border-radius:var(--raio-xs); font-size:12px; }

.ajuda-form{ display:flex; flex-direction:column; gap:10px; }
.ajuda-form label{ display:flex; flex-direction:column; gap:5px; font-size:13px; font-weight:600; }
.ajuda-form input, .ajuda-form textarea{ padding:10px 12px; border:1px solid var(--cinza-borda);
  border-radius:var(--raio-sm); font:inherit; font-size:14px; font-weight:400; }
.ajuda-form .btn{ margin-top:4px; }
.ajuda-ok{ background:#eaf7ee; border:1px solid #bfe6cb; color:#1c7a3e; padding:12px 14px;
  border-radius:var(--raio-sm); font-size:14px; }

@media (max-width:600px){
  .ajuda-painel{ right:12px; left:12px; width:auto; bottom:82px; }
  .ajuda-fab{ right:16px; bottom:16px; }
}

/* marca d'água do "D" Dext no fundo (identidade sutil) */
body::before{ content:''; position:fixed; left:230px; top:0; right:0; bottom:0;
  background:url('/assets/img/dext-icon.svg') no-repeat center center; background-size:min(95vmin, 1300px);
  opacity:.14; pointer-events:none; z-index:0; }
@media (max-width:820px){ body::before{ left:0; } }
.conteudo{ position:relative; z-index:1; }

/* grade das 3 cores da marca (Configurações) */
.cores-grade{ display:flex; gap:18px; flex-wrap:wrap; margin-bottom:6px; }
.cor-item{ display:flex; flex-direction:column; gap:6px; }
.cor-nome{ font-size:12px; font-weight:700; color:var(--cinza-medio); text-transform:uppercase; letter-spacing:.4px; }
.cor-item .cor-linha input[type=text]{ width:98px; }
.cor-auto{ display:inline-flex; align-items:center; gap:5px; font-size:12px; color:var(--cinza-medio); cursor:pointer; }
.cor-auto input{ width:14px; height:14px; }
.cor-item .cor-pick:disabled, .cor-item .cor-linha input[type=text]:disabled{ opacity:.4; cursor:not-allowed; }

/* ============================================================
   USUÁRIOS / PERMISSÕES
   ============================================================ */
/* .pill-perfil: a forma vem do .selo; as cores estão nas .pf-* abaixo */
.pf-admin{ background:color-mix(in srgb, var(--destaque) 12%, transparent); color:var(--destaque); }
.pf-gerente{ background:#e8f0fe; color:#1a56db; }
.pf-supervisor{ background:#e7f6ee; color:#0f7a4d; }
.pf-funcionario{ background:var(--cinza-fundo); color:var(--cinza-medio); }
.td-acessos{ font-size:12.5px; color:var(--cinza-medio); text-transform:capitalize; max-width:260px; }
.acesso-tudo{ color:var(--destaque); font-weight:600; }
.acesso-nenhum{ font-style:italic; }

.perm-grade{ display:flex; flex-direction:column; gap:10px;
  background:var(--branco); border:1px solid var(--cinza-borda); border-radius:var(--raio-sm); padding:12px; }
.perm-item{ display:flex; align-items:center; gap:8px; font-size:14px; font-weight:600; cursor:pointer; }
.perm-item input{ width:16px; height:16px; flex:none; }
/* refinamento por submódulo, indentado sob o módulo */
.perm-bloco{ border-bottom:1px dashed var(--cinza-borda); padding-bottom:10px; }
.perm-bloco:last-child{ border-bottom:none; padding-bottom:0; }
.perm-subs{ margin:8px 0 0 24px; display:flex; flex-direction:column; gap:6px; }
.perm-sub{ display:flex; align-items:center; justify-content:space-between; gap:12px; }
.perm-sub-nome{ font-size:13.5px; color:var(--cinza-medio); }
.perm-sub select{ font:inherit; font-size:13px; padding:4px 8px; border:1.5px solid var(--cinza-borda);
  border-radius:var(--raio-sm); background:var(--branco); color:var(--preto); }

/* ===== Avatar (foto do usuário ou iniciais) — componente global ===== */
.avatar{ display:inline-flex; align-items:center; justify-content:center; flex:none;
  border-radius:50%; object-fit:cover; overflow:hidden; vertical-align:middle;
  font-family:var(--fonte-titulo); font-weight:700; letter-spacing:.3px; line-height:1;
  box-shadow:0 0 0 1px rgba(0,0,0,.06) inset; }
/* avatar grande com moldura (perfil/conta) */
.avatar-grande{ box-shadow:0 4px 14px rgba(17,17,17,.14), 0 0 0 3px var(--branco), 0 0 0 4px var(--cinza-borda); }
/* nome com avatar ao lado (tabelas, listas) */
.nome-avatar{ display:inline-flex; align-items:center; gap:10px; }
/* ícone inline (substitui emojis) */
.ic-inline{ width:15px; height:15px; flex:none; vertical-align:-2px; opacity:.85; }
/* topo do perfil (página Conta): foto grande + dados */
.perfil-topo{ display:flex; align-items:center; gap:18px; flex-wrap:wrap; }
.perfil-foto{ flex:none; }
.perfil-dados{ min-width:0; }
.perfil-dados p{ margin:2px 0; }
.perfil-foto-form{ margin-top:16px; padding-top:16px; border-top:1px solid var(--cinza-borda); }
.perfil-foto-campo{ display:block; }
.perfil-foto-campo input{ display:block; margin-top:6px; }
.perfil-foto-acoes{ display:flex; align-items:center; gap:12px; margin-top:12px; flex-wrap:wrap; }
/* campo de foto no formulário de usuário */
.form-foto{ display:flex; align-items:center; gap:16px; flex-wrap:wrap; }
.form-foto-preview{ flex:none; }
.form-foto-campo{ min-width:0; }
.form-foto-remover{ display:inline-flex; align-items:center; gap:6px; margin-top:8px; font-size:13px; color:var(--cinza-medio); cursor:pointer; }
.form-foto-remover input{ width:15px; height:15px; }

/* ===== Acessibilidade: foco visível ao navegar por teclado ===== */
a:focus-visible, button:focus-visible, input:focus-visible,
select:focus-visible, textarea:focus-visible, summary:focus-visible,
[tabindex]:focus-visible{
  outline:2px solid var(--destaque); outline-offset:2px; border-radius:var(--raio-xs);
}

/* ═══════════ MODO SOMENTE LEITURA ═══════════
   Quem tem nível "ver" num submódulo continua enxergando tudo, mas as ações
   de gravar somem (o servidor já barra o POST; isto tira o botão que ilude). */
.faixa-leitura {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 16px; font-size: .84rem; font-weight: 600;
  background: #fff8e6; color: #7a5b00; border-bottom: 1px solid #f0dfae;
}
.faixa-leitura svg { width: 17px; height: 17px; flex: none; }
@media (min-width: 981px) { .faixa-leitura { padding-left: calc(var(--sb-larg, 248px) + 16px); } }

/* ═══════════ CÓPIA GUARDADA NO APARELHO (PWA offline) ═══════════
   Mesma forma da faixa de só-leitura, cor mais fria: aquela é uma limitação de
   permissão, esta é um aviso de que o número pode estar velho. Aparece só quando
   o service worker serviu a página do cache (ver partials/carimbo-cache.php). */
.faixa-cache {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 16px; font-size: .84rem; font-weight: 600;
  background: #eef4fb; color: #33526f; border-bottom: 1px solid #cfdff0;
}
.faixa-cache svg { width: 17px; height: 17px; flex: none; }
.faixa-cache span { flex: 1; min-width: 0; }
.faixa-cache button {
  flex: none; font-family: inherit; font-size: .8rem; font-weight: 700;
  padding: 5px 12px; border-radius: var(--raio-sm); cursor: pointer;
  background: #33526f; color: #fff; border: none;
}
.faixa-cache button:hover { background: #24405a; }
@media (min-width: 981px) { .faixa-cache { padding-left: calc(var(--sb-larg, 248px) + 16px); } }

/* ═══════════ CONVITE DE INSTALAÇÃO (PWA) ═══════════
   Flutua no fim do ecrã, por cima do conteúdo, e sai para sempre quando a pessoa
   dispensa. ⚠️ `bottom` com safe-area: no iPhone, sem isso, o botão fica debaixo
   da barra de gestos e não se consegue tocar nele. */
.inst-faixa {
  position: fixed; z-index: 60;
  left: 16px; right: 16px; bottom: calc(16px + env(safe-area-inset-bottom, 0px));
  display: flex; align-items: center; gap: 14px;
  padding: 14px 16px; border-radius: var(--raio);
  background: var(--menu); color: var(--menu-fg);
  box-shadow: 0 8px 30px rgba(0,0,0,.28);
}
.inst-faixa .inst-ic { width: 26px; height: 27px; flex: none; fill: currentColor; opacity: .9; }
.inst-txt { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.inst-txt strong { font-size: .92rem; font-weight: 700; }
.inst-txt span { font-size: .8rem; color: var(--menu-fg-suave); line-height: 1.35; }
.inst-acoes { flex: none; display: flex; align-items: center; gap: 8px; }
.inst-faixa button { font-family: inherit; cursor: pointer; border-radius: var(--raio-sm); }
.inst-btn {
  padding: 9px 18px; border: none; font-size: .86rem; font-weight: 700;
  background: var(--botao); color: var(--botao-fg);
}
.inst-nao {
  padding: 9px 12px; font-size: .82rem; font-weight: 600;
  background: transparent; color: var(--menu-fg-suave);
  border: 1px solid var(--menu-borda);
}
.inst-nao:hover { color: var(--menu-fg); }

/* ⚠️ No telemóvel a faixa em linha esmaga o texto a uma palavra por linha (é o
   mesmo erro das colunas do Diário). Empilha. */
@media (max-width: 560px) {
  .inst-faixa { flex-wrap: wrap; }
  .inst-txt { flex: 1 0 calc(100% - 40px); }
  .inst-acoes { width: 100%; justify-content: flex-end; }
}
/* Com barra lateral, a faixa não pode nascer por baixo dela. */
@media (min-width: 981px) {
  .inst-faixa { left: calc(var(--sb-larg, 248px) + 16px); max-width: 620px; }
}

/* ═══════════ SALÃO AO VIVO ═══════════
   Quem está na casa AGORA. Desenhado para ser usado de pé, com uma mão, no
   meio do serviço: alvos grandes e nenhuma informação que não seja accionável. */
.salao-kpis { display: flex; gap: 12px; flex-wrap: wrap; margin: 4px 0 22px; }
.salao-kpi {
  flex: 1 1 140px; background: var(--branco, #fff); border-radius: var(--raio);
  padding: 14px 16px; border: 1px solid var(--cinza-borda, #e4e4e7);
}
.salao-kpi strong { display: block; font-size: 1.9rem; font-weight: 700; line-height: 1.1; }
.salao-kpi strong em { font-style: normal; font-size: 1rem; color: var(--cinza, #71717a); font-weight: 600; }
.salao-kpi span { font-size: .8rem; color: var(--cinza, #71717a); }

/* o formulário de abrir mesa: numa linha no computador, empilhado no telemóvel */
/* ⚠️ ALINHAMENTO PELO TOPO, não pelo fundo (ele, 11/08/2026: *"página tá
   desalinhada com relação aos campos"*). Era `align-items:flex-end`, e com um
   `<select size=4>` alto e uma linha de ajuda por baixo dele, os campos curtos
   desciam atrás do mais alto: os rótulos ficavam a alturas diferentes e as
   caixas nunca começavam na mesma linha.
   Agora todos os rótulos começam no mesmo sítio; o campo da mesa cresce para
   baixo, que é o que se espera de um seletor com várias linhas.
   ⚠️ O botão alinha-se com as CAIXAS e não com os rótulos: desce exactamente a
   altura de um rótulo (13px de letra × 1,3 de entrelinha + 7px de margem). É
   por isso que o número não é mágico — vem do `.campo label` aqui ao lado; se
   um mudar, muda o outro. */
.salao-form { display: flex; gap: 12px; align-items: flex-start; flex-wrap: wrap; margin-bottom: 6px; }
.salao-form .campo { flex: 1 1 180px; margin: 0; }
.salao-form .campo-pessoas { flex: 0 0 130px; }
.salao-form-acao { flex: 0 0 auto; padding-top: var(--altura-rotulo); }
@media (max-width: 560px) {
  .salao-form .campo, .salao-form .campo-pessoas, .salao-form-acao { flex: 1 1 100%; }
  .salao-form-acao .btn { width: 100%; }
  /* empilhado não há rótulo ao lado para compensar: o desconto sai */
  .salao-form-acao { padding-top: 0; }
}

.salao-mesas { display: grid; gap: 12px; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); }
.salao-cartao {
  background: var(--branco, #fff); border: 1px solid var(--cinza-borda, #e4e4e7);
  border-radius: var(--raio); padding: 14px 16px;
  display: flex; flex-direction: column; gap: 6px;
}
/* a origem lê-se pela borda, sem ter de procurar a etiqueta */
.salao-reserva { border-left: 3px solid var(--destaque); }
.salao-avulso  { border-left: 3px solid var(--cinza, #71717a); }
.salao-cartao-topo { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.salao-cartao-topo strong { font-size: 1rem; }
.salao-cartao-nome { font-size: .92rem; font-weight: 600; }
.salao-cartao-info { font-size: .82rem; color: var(--cinza, #71717a); }
.salao-cartao-hora { opacity: .7; }
/* ⚠️ Era `space-between`, que empurrava o "Excluir" para o canto oposto e fazia
   as três ações parecerem coisas de famílias diferentes (ele, 11/08/2026).
   Agora agrupam-se à esquerda, na ordem em que se usam, com o mesmo intervalo. */
.salao-cartao-acoes { display: flex; align-items: center; justify-content: flex-start;
  gap: 8px; margin-top: 4px; flex-wrap: wrap; }
/* ⚠️ Alvo de toque generoso: isto é tocado com o polegar, de pé, no rush.
   Reaproveita o .btn-mini da agenda, só cresce o alvo. */
.salao-cartao .btn-mini { padding: 9px 16px; font-size: .88rem; }

/* ═══════════ INSTALAR O DEXT (/instalar-app) ═══════════
   Serve logado (com barra lateral) e deslogado (sozinha, vinda do site). */
.inst-pagina { max-width: 720px; }
.inst-cab { text-align: center; margin: 8px 0 28px; }
.inst-marca { width: 54px; height: 56px; fill: var(--destaque); margin-bottom: 16px; }
.inst-cab .pagina-titulo { margin-bottom: 10px; }
.inst-lead { font-size: 1rem; line-height: 1.6; color: var(--cinza-medio, #52525b); margin: 0 auto; max-width: 52ch; }

.inst-agora { text-align: center; margin-bottom: 26px; }
.btn-grande { font-size: 1rem; padding: 14px 34px; }
.inst-agora .ajuda { display: block; margin-top: 8px; }

.inst-sis {
  background: var(--branco, #fff); border: 1px solid var(--cinza-borda, #e4e4e7);
  border-radius: var(--raio); margin-bottom: 10px; overflow: hidden;
}
.inst-sis > summary {
  display: flex; align-items: center; gap: 12px; cursor: pointer;
  padding: 15px 18px; font-weight: 700; font-size: .96rem; list-style: none;
}
.inst-sis > summary::-webkit-details-marker { display: none; }
.inst-sis > summary:hover { background: var(--cinza-10, #fafafa); }
.inst-ic { width: 21px; height: 21px; flex: none; color: var(--destaque); }
.inst-sis ol { margin: 0; padding: 0 18px 4px 42px; }
.inst-sis ol li { margin-bottom: 9px; line-height: 1.55; font-size: .92rem; }
.inst-sis > .ajuda { display: block; padding: 0 18px 16px 42px; }

.inst-ok {
  display: flex; flex-direction: column; gap: 4px; text-align: center;
  padding: 22px; border-radius: var(--raio);
  background: #eaf7ef; color: #1f6b3d; border: 1px solid #c6e6d3;
}
.inst-ok strong { font-size: 1.02rem; }
.inst-ok span { font-size: .9rem; opacity: .85; }

.inst-porque { margin-top: 30px; }
.inst-porque h2 { font-family: var(--fonte-titulo); font-size: 1.02rem; margin-bottom: 12px; }
.inst-porque ul { margin: 0; padding-left: 20px; }
.inst-porque li { margin-bottom: 9px; line-height: 1.55; font-size: .92rem; color: var(--cinza-medio, #52525b); }
.inst-entrar { text-align: center; margin-top: 32px; font-weight: 600; }

/* ⚠️ Dentro do app JÁ instalado, o menu não pode oferecer "instalar". Fica no
   CSS e não em JavaScript: assim nunca chega a aparecer e desaparecer. */
@media (display-mode: standalone) { .sb-instalar { display: none; } }

/* ═══════════ LISTA DE COMPRAS ═══════════
   Uma lista de quadradinhos, feita para ser tocada com o polegar. */
/* ⚠️ MESMO DEFEITO DO SALÃO, mesma correção (ele, 12/08/2026, com print).
   Era `align-items:flex-end`: o campo "Faltou o quê" tem uma linha de ajuda por
   baixo ("Comece a digitar: o catálogo sugere…") e o "Quanto" não tem, por isso
   um descia atrás do outro e nem os rótulos nem as caixas ficavam na mesma
   linha. Alinha-se pelo TOPO e o botão desce a altura de um rótulo.
   Ver [[dext-alinhamento-componentes]] — a regra é: número de alinhamento
   escrito à mão numa view é sempre defeito. */
.lc-form { display: flex; gap: 12px; align-items: flex-start; flex-wrap: wrap; margin-bottom: 20px; }
.lc-form .campo { margin: 0; }
.lc-campo-texto { flex: 1 1 260px; }
.lc-campo-qtd { flex: 0 1 160px; }
.lc-form-acao { flex: 0 0 auto; padding-top: var(--altura-rotulo); }
@media (max-width: 560px) {
  .lc-campo-texto, .lc-campo-qtd, .lc-form-acao { flex: 1 1 100%; }
  .lc-form-acao .btn { width: 100%; }
  /* empilhado não há rótulo ao lado para compensar */
  .lc-form-acao { padding-top: 0; }
}

.lc-lista { list-style: none; margin: 0; padding: 0; }
.lc-item {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 14px; background: var(--branco, #fff);
  border: 1px solid var(--cinza-borda, #e4e4e7); border-radius: var(--raio-sm);
  margin-bottom: 8px;
}
/* ⚠️ CADA AÇÃO DA LINHA É UM <form>, e era daí que vinha o desalinhamento
   (ele, 06/08/2026: *"lista de compras, desalinhado"*). Um form é um bloco
   normal: entrava na fila do flex com altura própria e a caixa do lado ficava
   um pouco mais alta do que o quadrado. Pior, as duas listas não eram iguais —
   em "a comprar" o quadrado vive dentro de um form e em "comprados" é um span
   solto, logo as margens esquerdas não batiam uma com a outra.
   Regra geral em vez de remendo por lista: todo o form filho encolhe ao
   conteúdo e centra-se como qualquer outro item. */
.lc-item > form { display: flex; align-items: center; flex: none; margin: 0; padding: 0; }
.lc-texto { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.lc-texto strong { font-size: .95rem; }
.lc-qtd { font-size: .82rem; color: var(--cinza-medio, #52525b); font-weight: 600; }
/* ⚠️ 26px de alvo mínimo: isto é tocado de pé, com pressa, no meio do serviço. */
.lc-quadrado {
  flex: none; width: 26px; height: 26px; cursor: pointer;
  border: 2px solid var(--cinza-borda, #d4d4d8); border-radius:var(--raio-xs);
  background: transparent; display: inline-flex; align-items: center; justify-content: center;
  font-size: .95rem; line-height: 1; color: var(--verde, #1f6b3d); font-family: inherit;
}
.lc-quadrado:hover { border-color: var(--cinza-medio, #71717a); }
.lc-marcado { border-color: transparent; cursor: default; }
.lc-feitos .lc-item { opacity: .62; }
.lc-feitos .lc-texto strong { text-decoration: line-through; }
.lc-apagar button { border: none; background: none; cursor: pointer; font-family: inherit; }

/* ═══════════ MODO OPERACIONAL: os blocos novos da tela do turno ═══════════ */
.op-avulso-form, .op-falta-form { display: flex; gap: 10px; align-items: flex-end; flex-wrap: wrap; }
.op-avulso-form .campo, .op-falta-form .campo { margin: 0; flex: 1 1 110px; }
.op-falta-form .campo { flex: 1 1 200px; }
.op-avulso-form .btn, .op-falta-form .btn { flex: 0 0 auto; }
.op-avulso-lista, .op-falta-lista { list-style: none; margin: 14px 0 0; padding: 0; }
.op-avulso-lista li, .op-falta-lista li {
  display: flex; align-items: center; gap: 10px; justify-content: space-between;
  padding: 8px 0; border-top: 1px solid var(--cinza-borda, #e4e4e7); font-size: .88rem;
}
.op-falta-lista li { justify-content: flex-start; }
/* ⭐ 07/08/2026, ele: *"os links Sistema completo, Nova reserva, Ver a lista
   toda e Ver o salão todo estão muito diferentes; o ideal é que fossem padrão"*.
   E estavam mesmo: eram quatro tratamentos (pílula preta, pílula fantasma, link
   sublinhado e link solto) para o MESMO papel, que é sair desta tela para a
   tela completa.
   Agora é um só. A regra da página passou a ser fácil de dizer: **cada bloco tem
   no máximo um botão cheio, que é a ação; tudo o resto que leva a outro sítio é
   um `op-link`**.
   ⚠️ Alvo de toque generoso (44px de altura efetiva) porque isto usa-se com o
   telemóvel numa mão, no meio do turno. A seta vem do CSS e não do texto, senão
   quem traduz tinha de se lembrar dela em quatro idiomas. */
.op-link{
  display:inline-flex; align-items:center; gap:6px;
  padding:12px 0; margin-top:8px;   /* 44px de alvo de toque, para o telemóvel numa mão */
  font-size:.86rem; font-weight:600; color:var(--vermelho);
  text-decoration:none; border:none; background:none;
}
.op-link::after{ content:'→'; font-weight:400; }
.op-link:hover{ text-decoration:underline; }
.op-link:focus-visible{ outline:2px solid var(--vermelho); outline-offset:3px; border-radius:var(--raio-xs); }
/* Dois seguidos (ver ponto · minha escala) respiram sem parecerem uma lista. */
.op-link + .op-link{ margin-left:18px; }
/* ⭐ 08/08/2026, ele outra vez: *"os textos/links estão muito diferentes,
   precisa estar padrão"*. O ESTILO já era um só desde 07/08; o que continuava
   diferente era o TEXTO — "Sistema completo", "+ Nova reserva", "Abrir a agenda
   completa →", "Ver o salão todo", "Abrir Processos". Quatro fórmulas para o
   mesmo gesto, e duas com a seta escrita à mão POR CIMA da seta do CSS (saía
   "Abrir a agenda completa → →").
   A regra agora é uma frase: **"Ver " + o sítio para onde vai.** A seta é do
   CSS, nunca do texto.
   E a exceção, que é a única: CRIAR não é SAIR — troca a seta por um "+". */
.op-link-novo::after{ content:none; }
.op-link-novo::before{ content:'+'; font-weight:400; }

/* ═══════════ ESTÁ A ACABAR — abaixo do mínimo (08/08/2026) ═══════════
   Duas listas no mesmo bloco (comprar · produzir) porque são duas ações com
   donos diferentes. O nome à esquerda, a falta à direita: lê-se a coluna dos
   nomes de cima a baixo e só se para no que interessa. */
.rep-sub{ font-size:.8rem; font-weight:700; text-transform:uppercase; letter-spacing:.5px;
  color:var(--cinza-medio); margin:14px 0 2px; }
.rep-sub:first-of-type{ margin-top:4px; }
.rep-lista{ list-style:none; margin:0; padding:0; }
.rep-lista li{ display:flex; align-items:baseline; justify-content:space-between; gap:12px;
  padding:9px 0; border-top:1px solid var(--cinza-borda); font-size:.9rem; }
.rep-nome{ min-width:0; overflow-wrap:anywhere; }
.rep-falta{ flex:0 0 auto; font-size:.82rem; color:var(--cinza-medio); font-variant-numeric:tabular-nums; }
/* Acabou de vez é a única coisa deste bloco que ganha cor: entre "está baixo" e
   "não há", só a segunda muda o que se faz agora. */
.rep-zerado .rep-nome{ font-weight:700; }
.rep-zerado .rep-falta{ color:var(--vermelho); font-weight:600; }

/* ═══════════ FILA DE ENVIO DA CONTAGEM (offline) ═══════════
   Fica na própria tela do inventário, junto do que a pessoa acabou de fazer. */
.fila-aviso {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  margin: 16px 0; padding: 12px 16px; border-radius: var(--raio-sm);
  font-size: .88rem; font-weight: 600; line-height: 1.4;
}
.fila-aviso span:first-child { flex: 1; min-width: 200px; }
.fila-acoes { display: flex; gap: 8px; flex: none; }
.fila-aviso button {
  font-family: inherit; font-size: .82rem; font-weight: 700; cursor: pointer;
  padding: 7px 14px; border-radius: var(--raio-sm);
  border: 1px solid currentColor; background: transparent; color: inherit;
}
.fila-aviso button:hover { background: rgba(0,0,0,.07); }
/* guardado e à espera: informativo, não é erro. Quem contou fez o trabalho todo. */
.fila-guardado { background: #eef4fb; color: #33526f; border: 1px solid #cfdff0; }
.fila-enviada  { background: #eaf7ef; color: #1f6b3d; border: 1px solid #c6e6d3; }
/* o único estado accionável: alguém tem de decidir */
.fila-recusada { background: #fdecec; color: #8a2020; border: 1px solid #f4c9c9; }

.so-leitura .conteudo form[method="post"] button[type="submit"],
.so-leitura .conteudo form[method="post"] input[type="submit"],
.so-leitura .conteudo .btn-perigo,
.so-leitura .conteudo .btn-novo,
.so-leitura .conteudo .acao-editar { display: none !important; }

/* campos ficam visíveis, porém inertes: a tela continua servindo de consulta */
.so-leitura .conteudo form[method="post"] input:not([type="hidden"]),
.so-leitura .conteudo form[method="post"] select,
.so-leitura .conteudo form[method="post"] textarea {
  pointer-events: none; background: var(--cinza-10, #f4f4f5); opacity: .75;
}

/* ═══════════ CADASTRO DE COLABORADOR ═══════════ */
.pub-card-largo { max-width: 680px; }
.pub-titulo { font-family: var(--fonte-titulo); font-size: 1.45rem; margin: 4px 0 6px; }
.pub-sub { color: var(--cinza-60, #6b7280); font-size: .92rem; margin: 0 0 18px; }
.cad-obrig { font-size: .8rem; color: var(--cinza-60, #6b7280); margin: 0 0 16px; }
.req { color: #b42318; font-weight: 700; }

.cad-sec { border: 0; border-top: 1px solid var(--linha, #e5e7eb); padding: 18px 0 4px; margin: 0; }
.cad-sec > legend {
  font-family: var(--fonte-titulo); font-size: 1rem; font-weight: 600;
  padding: 0 10px 0 0; color: var(--tinta, #1f2328);
}
.campo-erro input, .campo-erro select { border-color: #b42318; background: #fff6f5; }

/* Telefone com país: seletor de prefixo colado ao número (ver partials/campo-tel.php).
   Os seletores levam o elemento (select/input) porque as regras de formulário
   já usam `.campo select` — sem isso o select ficava com width:100%. */
.campo-tel { display: flex; gap: 8px; align-items: stretch; width: 100%; }
.campo .campo-tel select.tel-pais,
.campo-tel select.tel-pais { flex: 0 0 118px; width: 118px; min-width: 118px; font-variant-numeric: tabular-nums; }
.campo .campo-tel input.tel-numero,
.campo-tel input.tel-numero { flex: 1 1 auto; width: auto; min-width: 0; font-variant-numeric: tabular-nums; letter-spacing: .02em; }
@media (max-width: 420px) {
  .campo .campo-tel select.tel-pais, .campo-tel select.tel-pais { flex-basis: 100px; width: 100px; min-width: 100px; }
}
.campo-erro-txt { display: block; margin-top: 5px; font-size: .78rem; color: #b42318; font-weight: 600; }

.cad-doc { padding: 12px 0; border-bottom: 1px dashed var(--linha, #e5e7eb); }
.cad-doc:last-child { border-bottom: 0; }
.cad-doc-cab { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.cad-doc-nome { font-weight: 600; font-size: .92rem; }
.cad-doc-ok { font-size: .78rem; font-weight: 700; color: #067647; }
.cad-doc-arq { font-size: .78rem; color: var(--cinza-60, #6b7280); margin: 4px 0 6px; word-break: break-all; }
.cad-doc input[type="file"] { margin-top: 8px; font-size: .85rem; }
.cad-doc-falta { background: #fff8e6; border-radius:var(--raio-sm); padding: 12px; }
.cad-privacidade { display: block; margin-bottom: 12px; }
.cad-acoes { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin-top: 22px; }

.cad-convite { margin-bottom: 26px; }
.cad-convite-linha { display: flex; gap: 12px; align-items: flex-end; flex-wrap: wrap; }
.cad-convite-linha .campo { flex: 1 1 220px; margin: 0; }

.st-cad-convidado   { background: #eef2f6; color: #47536b; }
.st-cad-preenchendo { background: #fff8e6; color: #7a5b00; }
.st-cad-enviado     { background: #e8f1ff; color: #1d4ed8; }
.st-cad-aprovado    { background: #e8f6ec; color: #067647; }
.st-cad-revogado    { background: #f3f4f6; color: #6b7280; }
.txt-alerta { color: #b42318; font-weight: 600; }

.cad-ver { margin: 0 0 22px; }
.cad-ver-linha { display: flex; gap: 16px; padding: 9px 0; border-bottom: 1px solid var(--linha, #eef0f3); }
.cad-ver-linha dt { flex: 0 0 210px; color: var(--cinza-60, #6b7280); font-size: .86rem; margin: 0; }
.cad-ver-linha dd { margin: 0; font-size: .92rem; font-weight: 500; word-break: break-word; }
.cad-ver-vazio { color: #9aa3af; }

.cad-anexos { list-style: none; padding: 0; margin: 0 0 26px; }
.cad-anexo { display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 11px 0; border-bottom: 1px solid var(--linha, #eef0f3); }
.cad-anexo-nome { font-size: .9rem; font-weight: 500; }
.cad-anexo-falta .cad-anexo-nome { color: #9aa3af; }
.pub-ok-ic-erro { background: #fdecea !important; color: #b42318 !important; }

@media (max-width: 640px) {
  .cad-ver-linha { flex-direction: column; gap: 3px; }
  .cad-ver-linha dt { flex: none; }
  .cad-convite-linha { flex-direction: column; align-items: stretch; }
}

.cfg-docs { border: 1px solid var(--linha, #e5e7eb); border-radius:var(--raio-sm); overflow: hidden; margin-bottom: 20px; }
.cfg-doc { display: flex; align-items: center; justify-content: space-between; gap: 14px;
  padding: 11px 14px; border-bottom: 1px solid var(--linha, #eef0f3); flex-wrap: wrap; }
.cfg-doc:last-child { border-bottom: 0; }
.cfg-doc-nome { font-size: .9rem; font-weight: 500; }
.cfg-doc-ops { display: flex; gap: 14px; flex-wrap: wrap; }
.cfg-doc-op { display: inline-flex; align-items: center; gap: 5px; font-size: .82rem; cursor: pointer; }
@media (max-width: 560px) { .cfg-doc { flex-direction: column; align-items: flex-start; gap: 8px; } }

/* aviso de atenção: problema real que o cliente ainda não percebeu */
.alerta-atencao { background: #fff8e6; border-color: #f0dfae; color: #7a5b00; }
.smtp-tecnico { border-left: 2px solid var(--linha, #e5e7eb); padding-left: 14px; margin-bottom: 4px; }

/* ═══ o que ainda vem por aí ═══
   Faixa discreta abaixo dos módulos prontos: informa o roteiro sem competir
   com o que já funciona. */
.hub-roteiro{ margin-top:34px; padding-top:22px; border-top:1px solid var(--linha, #e5e7eb); }
.hub-roteiro-titulo{ font-size:11px; font-weight:700; letter-spacing:.12em; text-transform:uppercase;
  color:var(--cinza-medio); margin-bottom:14px; }
.hub-roteiro-grade{ display:grid; grid-template-columns:repeat(auto-fill,minmax(210px,1fr)); gap:10px; }
.hub-futuro{ display:flex; align-items:flex-start; gap:10px; padding:12px 14px;
  border:1px solid var(--linha, #e9eaec); border-radius:var(--raio-sm); background:transparent; }
.hub-futuro-ic{ flex:none; width:26px; height:26px; border-radius:var(--raio-xs); display:flex;
  align-items:center; justify-content:center; background:var(--cinza-10, #f1f1f3);
  color:var(--cinza-medio); }
.hub-futuro-ic svg{ width:15px; height:15px; }
.hub-futuro-txt{ display:flex; flex-direction:column; gap:2px; min-width:0; }
.hub-futuro-txt strong{ font-size:13.5px; font-weight:650; color:var(--cinza-medio); }
.hub-futuro-txt span{ font-size:11.5px; line-height:1.45; color:var(--cinza-medio); opacity:.75; }

/* e-mail de suporte direto, abaixo do formulário de contato da ajuda */
.ajuda-email-direto{ margin:14px 0 0; font-size:12.5px; color:var(--cinza-medio); text-align:center; }
.ajuda-email-direto a{ color:var(--vermelho); font-weight:600; text-decoration:none; white-space:nowrap; }
.ajuda-email-direto a:hover{ text-decoration:underline; }

/* resultado do teste de ligação SMTP, ao lado do botão */
.smtp-teste-res{ display:inline-block; margin-left:10px; font-size:13px; font-weight:600; }
.assinatura-preview{ margin:4px 0 2px; }
.assinatura-preview img{ display:block; max-width:100%; max-height:180px; width:auto;
  border:1px solid var(--cinza-borda); border-radius:var(--raio-sm); background:#fff; }
.smtp-teste-res.ok{ color:#15803d; }
.smtp-teste-res.erro{ color:var(--vermelho); }

/* faixa de VIP / frequência na ficha do cliente */
.vip-faixa{ display:flex; align-items:center; gap:10px; margin:14px 0 4px; font-size:14px; }
.vip-faixa.vip-sim{ color:var(--texto); }
.vip-faixa.vip-nao{ color:var(--cinza-medio); }
/* ⚠️ E o retoque que a faixa do cliente fazia por cima dele saiu junto: era
   exatamente o `.selo` (12px/700, cápsula, vermelho) escrito à mão a 2.000
   linhas de distância — a definição de peça duplicada. */
.vip-rumo{ font-size:13px; }

/* tela dedicada da lista VIP: pills de motivo e aviso neutro */
.pill-motivo-frequencia{ background:color-mix(in srgb, var(--vermelho) 12%, transparent); color:var(--vermelho); }
.pill-motivo-equipe{ background:color-mix(in srgb, #2563eb 12%, transparent); color:#1d4ed8; }
.pill-motivo-manual{ background:color-mix(in srgb, #16a34a 14%, transparent); color:#15803d; }
.pill-motivo-x{ background:var(--cinza-fundo); color:var(--cinza-medio); }
.txt-suave{ color:var(--cinza-medio); }
.aviso-neutro{ background:var(--cinza-fundo); border:1px solid var(--cinza-borda); color:var(--cinza-medio);
  padding:12px 16px; border-radius:var(--raio-sm); margin-bottom:18px; font-size:14px; }

/* divisor de módulo na tela de Configurações */
.cfg-modulo{ margin:34px 0 6px; padding-top:20px; border-top:2px solid var(--linha, #e5e7eb); }
.cfg-modulo-rot{ font-size:11px; font-weight:700; letter-spacing:.12em; text-transform:uppercase; color:var(--cinza-medio); }
.cfg-modulo-nome{ font-family:var(--fonte-titulo); font-size:1.15rem; font-weight:700; color:var(--texto); margin-top:2px; }

/* abas das configurações (como abas do navegador) */
/* ⭐ O atalho para as telas de cada módulo (17/08/2026). Fica ACIMA do cartão e
   fora das abas de propósito: quem clica sai desta tela, e uma aba dá a
   entender que o Salvar de baixo também grava aquilo. */
.cfg-modulos-atalho{ display:flex; align-items:center; gap:8px; flex-wrap:wrap; margin:0 0 18px; }
.cfg-modulos-atalho .ajuda{ margin:0 4px 0 0; }
.cfg-abas{ display:flex; gap:2px; border-bottom:1px solid var(--linha, #e5e7eb); margin:0 0 22px; flex-wrap:wrap; }
.cfg-aba{ appearance:none; background:transparent; border:0; border-bottom:2px solid transparent;
  padding:10px 16px; font-family:var(--fonte-texto); font-size:14px; font-weight:600;
  color:var(--cinza-medio); cursor:pointer; margin-bottom:-1px; border-radius:var(--raio-sm) var(--raio-sm) 0 0; }
.cfg-aba:hover{ color:var(--texto); background:var(--cinza-10, #f4f4f5); }
.cfg-aba.ativa{ color:var(--vermelho); border-bottom-color:var(--vermelho); }
.cfg-aba:focus-visible{ outline:2px solid var(--vermelho); outline-offset:2px; }

/* nome da empresa movido para o rodapé, acima do usuário */
.sb-rodape .sb-empresa-nome{ margin:0 0 10px; padding:0 2px; text-align:left; font-size:13px; }

/* ── Ajuste de imagem no envio (recorte.js): arrastar + zoom ── */
.rec-overlay{ position:fixed; inset:0; z-index:1000; background:rgba(0,0,0,.55);
  display:flex; align-items:center; justify-content:center; padding:16px; }
.rec-caixa{ background:var(--branco); border-radius:var(--raio); box-shadow:var(--sombra);
  padding:20px; width:min(560px, 100%); }
.rec-titulo{ display:block; font-family:var(--fonte-titulo); font-size:17px; margin-bottom:12px; }
.rec-moldura{ width:100%; overflow:hidden; border-radius:var(--raio-sm);
  background:var(--cinza-fundo); cursor:grab; touch-action:none; position:relative; }
.rec-moldura:active{ cursor:grabbing; }
.rec-moldura img{ display:block; max-width:none; user-select:none; -webkit-user-drag:none;
  pointer-events:none; will-change:transform; }
.rec-dica{ color:var(--cinza-medio); font-size:13px; margin:10px 0 6px; }
.rec-zoom{ display:flex; align-items:center; gap:10px; font-size:14px; margin-bottom:14px; }
.rec-zoom input{ flex:1; accent-color:var(--vermelho, #c62838); }
.rec-acoes{ display:flex; gap:12px; align-items:center; }

/* ── Preferências de avisos da gestão (Conta) ── */
.notif-grupo{ margin:14px 0; }
.notif-grupo-tit{ display:block; font-size:13px; text-transform:uppercase; letter-spacing:.4px;
  color:var(--cinza-medio); margin-bottom:8px; }
.notif-item{ display:flex; align-items:flex-start; gap:10px; padding:8px 0; border-top:1px solid var(--cinza-borda); }
.notif-item input{ flex:0 0 auto; width:17px; height:17px; }
.notif-item:first-of-type{ border-top:none; }
.notif-item input{ margin-top:3px; }
.notif-item strong{ display:block; font-weight:600; }
.notif-item .ajuda{ display:block; margin-top:2px; }

/* ⭐⭐ OS APARELHOS QUE RECEBEM AVISOS (25/08/2026) — ver `partials/push.php`.
   ⚠️ Vive DENTRO do `.link-publico`, que é `display:flex` com `flex-wrap`: sem
   `flex-basis:100%` a lista tentava caber ao lado do botão de ativar e cada
   aparelho saía numa coluna de 80px.
   ⚠️ E `min-width:0` porque o nome de um aparelho pode ser longo — sem isso um
   filho de flex recusa-se a encolher e empurra o botão para fora do cartão. */
.push-aparelhos{ flex:0 0 100%; min-width:0; margin-top:10px;
  border-top:1px solid var(--cinza-borda); padding-top:10px; }
.push-aparelhos > .ajuda{ display:block; margin-bottom:6px; }
.push-ap{ display:flex; align-items:center; gap:10px; flex-wrap:wrap;
  padding:8px 0; border-top:1px solid var(--cinza-borda); }
.push-ap:first-of-type{ border-top:none; }
.push-ap-nome{ font-weight:600; min-width:0; overflow-wrap:anywhere; }
/* O que sobra no meio empurra o botão para a direita, e é a última coisa da
   linha em qualquer largura. */
.push-ap .lanc-sub{ flex:1 1 auto; min-width:0; }
.push-ap form{ flex:0 0 auto; margin:0; }
/* ⚠️ Selo pequeno com cor forte, nunca superfície grande — a regra da casa. */
.push-ap-eu{ margin-left:6px; }

/* ⭐ O rasto do último envio, por baixo da caixa (existia sem folha desde
   19/08: a classe estava na tela e não tinha uma linha aqui). */
.push-rasto{ flex:0 0 100%; min-width:0; }

/* ── Autocompletar cliente na reserva ── */
.ac-wrap{ position:relative; }
.ac-lista{ position:absolute; z-index:30; left:0; right:0; top:100%; margin:4px 0 0; padding:4px;
  list-style:none; background:var(--branco); border:1px solid var(--cinza-borda);
  border-radius:var(--raio-sm); box-shadow:var(--sombra); max-height:260px; overflow-y:auto; }
.ac-item{ display:flex; justify-content:space-between; align-items:center; gap:10px;
  padding:9px 10px; border-radius:var(--raio-xs); cursor:pointer; }
.ac-item.ativo, .ac-item:hover{ background:var(--cinza-fundo); }
.ac-nome{ font-weight:500; }
.ac-tel{ color:var(--cinza-medio); font-size:13px; white-space:nowrap; }

/* ── Ficha do colaborador ── */
.ficha-topo{ display:flex; align-items:center; gap:16px; margin-bottom:6px; }
.ficha-topo .pagina-titulo{ margin-bottom:2px; }
.ficha-cab{ display:flex; align-items:baseline; justify-content:space-between; gap:12px; margin-top:18px; }
.ficha-cab .secao-titulo{ margin:0; }
.ficha-linha{ display:flex; gap:14px; padding:9px 0; border-bottom:1px solid var(--cinza-borda); }
.ficha-linha:last-child{ border-bottom:none; }
.ficha-rot{ flex:0 0 210px; color:var(--cinza-medio); font-size:14px; }
.ficha-val{ flex:1; font-size:14px; word-break:break-word; }
.ficha-vazio{ color:var(--cinza-medio); }
.ficha-mascara{ letter-spacing:2px; color:var(--cinza-medio); }
.ficha-doc{ display:flex; align-items:center; justify-content:space-between; gap:14px;
  padding:12px 0; border-bottom:1px solid var(--cinza-borda); flex-wrap:wrap; }
.ficha-doc:last-child{ border-bottom:none; }
.ficha-doc-info strong{ display:block; font-weight:600; }
.ficha-doc-acoes{ display:flex; align-items:center; gap:10px; flex-wrap:wrap; }
.ficha-upload input[type=file]{ max-width:190px; font-size:12px; }
@media (max-width:640px){ .ficha-linha{ flex-direction:column; gap:2px; } .ficha-rot{ flex:none; } }

/* ── Cabeçalho da grade de permissões (com "restaurar padrão") ── */
.perm-cab{ display:flex; align-items:center; justify-content:space-between; gap:12px; flex-wrap:wrap; }
.perm-cab label{ margin:0; }

/* ── Escala: coluna de Total e modo consulta ── */
.escala-grade th.col-total, .escala-grade td.col-total{ text-align:center; border-left:1px solid var(--cinza-borda);
  white-space:nowrap; background:color-mix(in srgb, var(--cinza-fundo) 60%, transparent); }
.escala-grade td.col-total{ font-weight:700; font-size:14px; vertical-align:middle; }
.escala-grade .total-h{ color:var(--preto); }
/* no modo consulta os chips não parecem clicáveis (sem cursor de arraste) */
.escala-consulta .turno-chip{ cursor:default; }

/* atalhos do bloco de ponto na operação (ver ponto · minha escala) */
.op-atalhos{ display:flex; gap:18px; flex-wrap:wrap; }

/* ---------- Financeiro · Fecho de caixa ---------- */
.flash-alerta{
  background:#fdf3e7; border:1px solid #f3d6a8; color:#8a5a12;
  padding:14px 18px; border-radius:var(--raio); font-weight:600; margin-bottom:22px;
}
/* Resumo ao vivo (total + ticket médio) */
.fecho-resumo{ display:flex; gap:14px; flex-wrap:wrap; margin-bottom:8px; }
/* ⭐ A PREMISSA DA CONTA, recolhida atrás de uma linha (22/08/2026). O CMV usa
   o preço sem IVA, e a taxa está à vista de quem quiser conferir — mas fechada,
   porque quem só quer ler o CMV não precisa de a ver todos os dias. */
.ficha-iva{ margin:-6px 0 18px; }
.ficha-iva > summary{ cursor:pointer; display:inline-block; }
.ficha-iva > summary:hover{ color:var(--preto); }
.ficha-iva form{ display:flex; align-items:center; gap:8px; flex-wrap:wrap; margin-top:8px; }
.ficha-iva label{ font-size:13px; font-weight:600; }
.ficha-iva p{ margin:6px 0 0; max-width:62ch; }

.fecho-kpi{
  flex:1 1 160px; background:var(--branco); border:1px solid var(--cinza-borda);
  border-radius:var(--raio); box-shadow:var(--sombra); padding:14px 18px;
  display:flex; flex-direction:column; gap:4px;
}
.fecho-kpi-rot{ font-size:12.5px; font-weight:600; color:var(--cinza-medio); }
.fecho-kpi strong{ font-family:var(--fonte-titulo); font-size:26px; color:var(--preto); }
/* Segunda linha do cartão: o contexto do número (quantos registos, contra o
   quê, em que dia). Sem isto um cartão com "€74,93" obriga a adivinhar. */
.fecho-kpi-sub{ font-size:12px; color:var(--cinza-medio); }
/* ⭐ O cartão do A RECEBER (06/08/2026). Fica na mesma fila das contas mas tem
   de se LER como outra coisa — é dinheiro que ainda não é de nenhuma delas —,
   por isso o fundo é tracejado em vez de sólido: distingue-se de relance sem
   precisar de cor, que aqui está reservada ao sinal do valor. */
.kpi-receber{ background:transparent; border-style:dashed; box-shadow:none; }
.kpi-receber-linha{ font-size:12px; color:var(--cinza-medio); display:block; }
.kpi-receber .btn-link{ font-size:12px; margin-top:2px; align-self:flex-start; }
/* Cartão cujo valor é um NOME e não um número: 26px de fonte de título parte
   "Vencimento/Estrago" ao meio. */
.fecho-kpi strong.kpi-texto{ font-size:17px; line-height:1.25; word-break:break-word; }
/* Banda de VÁRIOS cartões (5, 6): em flex, o que sobra para a última fila
   estica-se a ocupá-la sozinho — um cartão de "Pior dia" com meio metro de
   largura. Em grelha, todos ficam do mesmo tamanho e a última fila alinha
   com a de cima. */
.fecho-resumo.kpis-grade{
  display:grid; grid-template-columns:repeat(auto-fit, minmax(228px, 1fr));
}
.fecho-resumo.kpis-grade .fecho-kpi{ flex:none; }
/* Campo com o símbolo de moeda à esquerda */
.campo-moeda{ display:flex; align-items:center; gap:6px;
  border:1px solid var(--cinza-borda); border-radius:var(--raio-sm); padding:0 10px; background:var(--branco); }
/* 🐞 05/08/2026, ele: *"os campos estão esquisitos, quando clico ele não parece
   que seleciona"*. Eram DUAS caixas encaixadas: `.campo input:not([type=checkbox])
   :not([type=radio])` (0,3,1) ganhava a `.campo-moeda input` (0,1,1), e o input
   de dentro ficava com borda e fundo brancos próprios dentro da caixa do €.
   ⚠️ É a MESMA armadilha do seletor de país do telefone (ver dext-cadastro-ajustes):
   quem escreve uma regra base com `:not()` sobe a especificidade dela sem dar por
   isso, e as variações deixam de conseguir mandar. A correção é sempre a mesma:
   qualificar o seletor da variação até passar à frente, nunca `!important`. */
.campo .campo-moeda input:not([type=checkbox]):not([type=radio]){
  border:0; background:transparent; box-shadow:none; padding:11px 4px 11px 0; border-radius:0;
}
/* E o foco tem de SER VISTO. Só a borda a mudar de cinzento para preto passava
   despercebido num campo pequeno; o anel resolve, e é o mesmo gesto do resto. */
.campo-moeda:focus-within{ border-color:var(--preto); box-shadow:0 0 0 3px rgba(0,0,0,.10); }
.campo-moeda span{ color:var(--cinza-medio); font-weight:600; }
/* respiro à direita: alinhado à direita e colado na borda, o número parecia
   estar a sair do campo */
.campo-moeda input{ border:0; padding:11px 4px 11px 0; background:transparent; width:100%; outline:none;
  text-align:right; font-variant-numeric:tabular-nums; min-width:0; }
/* ⚠️ Piso de largura, por omissão em qualquer campo de dinheiro novo.
   Com o número alinhado à direita, um campo estreito CORTA o valor pela
   esquerda: o utilizador vê "336,3" e não percebe que falta um dígito. É pior
   do que um campo feio, porque parece um número certo. 132px é o que cabe
   "99.999,99" com o € e os espaçamentos.
   As grades COMPACTAS saem disto de propósito: nas perdas as colunas de custo
   unitário têm 92px porque quem lança um turno inteiro quer ver muitas linhas,
   e um custo unitário não chega às dezenas de milhar. */
.campo-moeda{ min-width:132px; }
.perda-linha .campo-moeda,
.fatura-linha .campo-moeda,
.cfg-linha .campo-moeda{ min-width:0; }
/* Grade de vendas: colunas de valor à direita */
/* A coluna do valor encolhe-se ao conteúdo (width:1% + nowrap) em vez de ser
   uma percentagem do total. Com 34%, num telemóvel de 390px a coluna ficava com
   ~110px e o campo cortava o valor. Quem cede espaço é a coluna do nome. */
.fecho-grade th:not(:first-child), .fecho-grade td:not(:first-child){ text-align:right; width:1%; white-space:nowrap; }
.fecho-grade .campo-moeda{ min-width:150px; max-width:190px; margin-left:auto; }
/* Retiradas: origem | valor | motivo */
.retirada-linha{ display:grid; grid-template-columns:110px 140px minmax(120px,1fr) minmax(140px,1fr) auto 34px; gap:8px; margin-bottom:10px; align-items:center; }
.retirada-linha select, .retirada-linha input{ margin:0; }
.btn-link{ background:none; border:0; color:var(--vermelho); font-weight:600; cursor:pointer; padding:4px 0; font-size:14px; }
.btn-link:hover{ text-decoration:underline; }
@media (max-width:560px){
  .retirada-linha{ grid-template-columns:110px 1fr auto 34px; }
  .retirada-linha input[name="ret_motivo[]"]{ grid-column:1 / -1; }
  /* Em cartão, cada valor tem a linha toda: o campo cresce e o número nunca
     é cortado, sem tabela a rolar de lado. A grade de VENDAS tem uma coluna
     por serviço e é a que precisa mais disto: com 2 serviços, três colunas
     lado a lado não caberiam num telemóvel sem cortar ou rolar. */
  .fecho-grade .campo-moeda{ max-width:none; min-width:132px; }
}

/* ---------- Financeiro · Diário (lançamentos) ---------- */
/* .lanc-tag: a forma vem do .selo; as cores estão nas .lanc-* abaixo */
.lanc-despesa{ color:var(--vermelho-sinal); background:var(--vermelho-sinal-fundo); }
.lanc-receita{ color:var(--verde); background:var(--verde-fundo); }
.lanc-transferencia{ color:var(--cinza-medio); background:var(--cinza-fundo); }

/* esconder de vista mantendo no DOM/form (o <select id=tipo> continua a submeter) */
.sr-only{ position:absolute; width:1px; height:1px; padding:0; margin:-1px; overflow:hidden;
  clip:rect(0,0,0,0); white-space:nowrap; border:0; }
/* Os 3 botões de NATUREZA no topo do lançamento (Entrou / Saiu / Movi) */
.lanc-natureza{ display:grid; grid-template-columns:repeat(3,1fr); gap:10px; margin-bottom:14px; }
.natbtn{ display:flex; flex-direction:column; align-items:flex-start; gap:1px; text-align:left; cursor:pointer;
  border:1.5px solid var(--cinza-borda); background:var(--branco); border-radius:var(--raio); padding:12px 14px;
  font:inherit; color:var(--cinza-medio); transition:border-color .12s, background .12s, color .12s; }
.natbtn .nb-s{ font-size:19px; font-weight:800; line-height:1; font-variant-numeric:tabular-nums; }
.natbtn em{ font-style:normal; font-weight:700; font-size:15px; color:var(--preto); }
.natbtn small{ font-size:12px; color:var(--cinza-medio); line-height:1.25; }
.natbtn:hover{ border-color:var(--cinza-medio); }
.natbtn.ativo em{ color:inherit; }
.natbtn.nb-rec.ativo{ border-color:var(--verde); background:var(--verde-fundo); color:var(--verde); }
.natbtn.nb-des.ativo{ border-color:var(--vermelho-sinal); background:var(--vermelho-sinal-fundo); color:var(--vermelho-sinal); }
.natbtn.nb-mov.ativo{ border-color:var(--cinza-medio); background:var(--cinza-fundo); color:var(--preto); }
.natbtn:focus-visible{ outline:2px solid var(--destaque); outline-offset:2px; }
@media (max-width:560px){ .lanc-natureza{ grid-template-columns:1fr; } }
.lanc-fecho{ color:var(--cinza-medio); background:var(--cinza-fundo); font-weight:600; margin-left:4px; }
/* Estorno: entrada de dinheiro que ABATE uma despesa. Âmbar, não verde nem
   vermelho — o verde/vermelho da linha é o sinal do dinheiro (ver
   classeSinal), e a etiqueta fala de outra coisa: do que ela faz ao resultado. */
.lanc-estorno{ color:#92400e; background:color-mix(in srgb, #f59e0b 18%, transparent);
  font-weight:600; margin-left:4px; }
/* .saldo-pos / .saldo-neg ficam definidas uma única vez, lá em cima. */

/* ---------- Financeiro · Resumo (dashboard) e cards ---------- */
/* ⚠️ 340px e não 280 (F11): num ecrã largo, 280 dava CINCO colunas de 296px e
   os cartões continuavam tão apertados como antes — mais colunas não é mais
   espaço. Com 340, um ecrã de 1440 dá quatro colunas de ~380px, e é aí que o
   nome da categoria deixa de se partir ao meio. */
/* 🚨 `min(340px, 100%)` e não `340px` seco (21/08/2026). O `.conteudo` tem
   `padding:40px 22px`: num telemóvel de 375 sobram **331px** de largura útil, e
   uma coluna que exige 340 não cabe — a grade estourava 9px e a página inteira
   rolava de lado. Não era só desta tela: são as CINCO que usam esta grade,
   incluindo o Financeiro → Configurações e o resumo.
   ⚠️ O `min()` deixa a coluna encolher quando não há 340; onde há, nada muda. */
.resumo-grade{ display:grid; grid-template-columns:repeat(auto-fill,minmax(min(340px,100%),1fr)); gap:16px; margin-top:8px; }
.resumo-card{ background:var(--branco); border:1px solid var(--cinza-borda); border-radius:var(--raio); box-shadow:var(--sombra); padding:18px 20px; }
.resumo-card h2{ font-family:var(--fonte-titulo); font-weight:700; font-size:14px; margin-bottom:10px; color:var(--preto); }
/* ⭐ O SEGUNDO título dentro do mesmo cartão precisa de respirar do que veio
   antes (18/08/2026). Dois deles diziam-no com `style="margin-top:16px"` à mão,
   no meio de treze irmãos sem estilo nenhum: a regra faz o mesmo para todos. */
.resumo-card h2:not(:first-child){ margin-top:16px; }
.mini-tab{ width:100%; border-collapse:collapse; font-size:13.5px; }
.mini-tab td{ padding:6px 0; border-bottom:1px solid var(--cinza-fundo); vertical-align:middle; }
/* O nome é a coluna que cede: os números têm `nowrap` (um valor partido ao meio
   não é um valor), logo é o texto que quebra quando não cabe. `anywhere` só
   para o caso extremo de uma palavra única mais larga do que a coluna. */
.mini-tab td:first-child{ overflow-wrap:anywhere; }
.mini-tab td.v{ text-align:right; font-weight:600; white-space:nowrap; font-variant-numeric:tabular-nums; padding-left:12px; }
/* 🚨 O VALOR NÃO PODE ENCOSTAR NA PERCENTAGEM (ele, 14/08/2026, com o print:
   *"os valores e as porcentagens estão muito próximos"*, e na linha do Total
   estavam mesmo colados: "€12.553,24133,7%").
   Duas causas: a coluna do valor não tinha folga à direita, e a das
   percentagens estava fixada em 64px — largura de UMA percentagem, quando esta
   tabela mostra duas ("49,0% · 36,6%"). O conteúdo estourava a caixa e o
   navegador comia a folga que não existia.
   ⚠️ A folga só entra quando há coluna a seguir: nas tabelas de duas colunas
   (Top 10) o valor continua encostado à direita, alinhado com os outros
   cartões. */
.mini-tab td.v:not(:last-child){ padding-right:14px; }
.mini-tab td.p{
  text-align:right; color:var(--cinza-medio); font-size:12px; white-space:nowrap;
  /* `width:1%` com nowrap é "dá-lhe exactamente o que ela precisa": a coluna
     mede-se pelo conteúdo em vez de fingir um número fixo. */
  width:1%; font-variant-numeric:tabular-nums;
}
/* As duas percentagens em caixas de largura igual: sem isto, "9,9% · 7,4%" e
   "49,0% · 36,6%" não se lêem em coluna, que é o que ele viu de errado. */
/* ⚠️ 4em e não 3,4em: tem de caber "116,5%" (a despesa pode passar a receita, e
   passou no mês dele). A caixa estreita alinhava as de dois dígitos e desalinhava
   justamente a linha que interessa ler. */
.mini-tab td.p b{ display:inline-block; min-width:4em; text-align:right; font-weight:inherit; }
.mini-tab tr.tot td{ border-top:1.5px solid var(--cinza-borda); border-bottom:0; font-weight:700; padding-top:8px; }
.mini-tab tr.sub td{ color:var(--cinza-medio); font-size:11.5px; text-transform:uppercase; letter-spacing:.4px; padding-top:12px; border-bottom:0; }
.mini-tab .rank{ display:inline-block; min-width:18px; color:var(--vermelho); font-weight:700; font-variant-numeric:tabular-nums; }
/* linha "pagar" da conta a pagar */
.pagar-linha{ display:inline-flex; gap:6px; align-items:center; flex-wrap:wrap; margin:0 8px 0 0; }
.pagar-linha input, .pagar-linha select{ margin:0; padding:6px 8px; font-size:13px; }

/* Setinha própria nos selects inline do Financeiro: os selects nativos são
   estreitos e o texto longo ("Categoria da comissão", "Cartão de crédito")
   corria por baixo da seta do sistema. Desenhamos a seta e reservamos o
   espaço dela à direita, para nada se sobrepor. */
.cfg-linha select, .cfg-nova select,
.pagar-linha select, .fatura-linha select,
.perda-linha select, .retirada-linha select{
  appearance:none; -webkit-appearance:none;
  background-color:var(--branco);
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%2371717a' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
  background-repeat:no-repeat; background-position:right 9px center; background-size:11px;
  padding-right:28px; text-overflow:ellipsis;
}

/* ---------- Financeiro · Configurações (catálogo editável) ---------- */
/* subcabeçalho por natureza (Receita / Despesa / Movimento interno): cor é o
   sinal — verde entra, vermelho sai, cinza é interno (não conta no resultado) */
.cfg-nat-cab{ display:flex; align-items:center; gap:8px; font-size:11.5px; font-weight:700;
  text-transform:uppercase; letter-spacing:.06em; color:var(--cinza-medio); margin:16px 0 6px; }
.cfg-nat-cab:first-child{ margin-top:2px; }
.cfg-nat-cab .dot{ width:9px; height:9px; border-radius:50%; flex:none; }
.cfg-nat-cab .ct{ font-weight:600; letter-spacing:0; text-transform:none; opacity:.7; }
.cfg-nat-cab.nat-rec{ color:#1e7a44; } .cfg-nat-cab.nat-rec .dot{ background:#1e7a44; }
.cfg-nat-cab.nat-des{ color:#b3261e; } .cfg-nat-cab.nat-des .dot{ background:#b3261e; }
.cfg-nat-cab.nat-mov{ color:#5b6470; } .cfg-nat-cab.nat-mov .dot{ background:#5b6470; }
/* caixa de reclassificação (movimento interno mal classificado nos dados antigos) */
.cfg-reclass{ display:flex; gap:16px; align-items:center; flex-wrap:wrap; justify-content:space-between;
  background:#fff8e6; border:1px solid #f0dfae; border-radius:var(--raio-sm); padding:16px 18px; margin-bottom:16px; }
.cfg-reclass-txt{ flex:1 1 320px; }
.cfg-reclass-txt strong{ display:block; color:#7a5b00; font-size:15px; margin-bottom:3px; }
.cfg-reclass-txt p{ margin:0 0 8px; font-size:13.5px; color:#7a5b00; }
.cfg-reclass-txt ul{ margin:0; padding:0; list-style:none; display:flex; flex-wrap:wrap; gap:6px 8px; }
.cfg-reclass-txt li{ font-size:13px; background:#fff; border:1px solid #f0dfae; border-radius:999px; padding:4px 10px; }
.cfg-reclass-txt li span{ color:var(--cinza-medio); }
.cfg-linha{ display:flex; gap:6px; align-items:center; flex-wrap:wrap; margin:0; }
.cfg-linha input[type=text]{ flex:1 1 120px; min-width:90px; padding:5px 8px; font-size:13px; margin:0; }
.cfg-linha select{ padding:5px 8px; font-size:12.5px; margin:0; max-width:150px; }
.cfg-nova{ display:flex; gap:6px; align-items:center; flex-wrap:wrap; margin-top:12px; padding-top:12px; border-top:1px solid var(--cinza-borda); }
.cfg-nova input, .cfg-nova select{ padding:6px 9px; font-size:13px; margin:0; }
.cfg-nova input[type=text]{ flex:1 1 130px; min-width:100px; }
.cfg-nova .btn{ padding:6px 14px; }
/* toggle de regra (checkbox + texto explicativo ao lado) */
.cfg-toggle{ display:flex; gap:10px; align-items:flex-start; cursor:pointer; }
/* ⭐ Interruptor que divide a linha com um campo rotulado: desce a altura de um
   rótulo para assentar na mesma linha da caixa ao lado. Substitui os
   `margin-top:26px` escritos à mão, que era o que desalinhava a tela. */
.cfg-toggle.alinha-campo{ margin-top:var(--altura-rotulo); }

/* Guardar de baixo, colado: a tela das Configurações é longa, e um botão que só
   aparecesse no fim obrigava a rolar tudo para gravar uma linha do topo. */
.cfg-barra{ position:sticky; bottom:0; z-index:5; display:flex; gap:12px; align-items:center;
  justify-content:flex-end; flex-wrap:wrap; margin-top:18px; padding:12px 16px;
  background:var(--branco); border:1px solid var(--cinza-borda); border-radius:var(--raio-sm);
  box-shadow:0 -6px 18px rgba(0,0,0,.06); }
.cfg-barra-txt{ flex:1 1 220px; font-size:12.5px; color:var(--cinza-medio); }
.cfg-toggle input{ margin-top:3px; width:18px; height:18px; flex:0 0 auto; accent-color:var(--destaque); }
/* checkbox inline nas linhas de conta (ex.: "no fecho") */
.cfg-checkbox{ display:inline-flex; align-items:center; gap:4px; font-size:12px; color:var(--cinza-medio); white-space:nowrap; cursor:pointer; }
.cfg-checkbox input{ width:15px; height:15px; accent-color:var(--destaque); margin:0; }

/* ---------- Fatura (conta a pagar com rateio) ---------- */
.fatura-linhas{ display:flex; flex-direction:column; gap:8px; }
.fatura-linha{ display:grid; gap:8px; align-items:center;
  grid-template-columns:minmax(150px,1.4fr) 130px minmax(120px,1.2fr) 24px; }
.fatura-linha-2{ grid-template-columns:minmax(150px,1.4fr) 145px 24px; }   /* pagamento: conta + valor */
.fatura-linha select, .fatura-linha input{ margin:0; padding:7px 9px; font-size:13.5px; }
.fatura-linha .campo-moeda{ margin:0; padding:0 8px; }
.fatura-linha .campo-moeda input{ padding:7px 0; }
.fatura-linha .js-rm{ font-size:18px; line-height:1; padding:0; }
.fatura-rodape{ display:flex; justify-content:space-between; align-items:center; flex-wrap:wrap; gap:8px; margin-top:8px; }
.fatura-total{ font-size:13.5px; color:var(--cinza-medio); }
.fatura-total strong{ color:var(--texto); font-variant-numeric:tabular-nums; }
/* itens expandidos na lista */
.fatura-itens summary{ cursor:pointer; color:var(--destaque); font-size:13px; }
.fatura-itens ul{ list-style:none; margin:6px 0 0; padding:0; font-size:13px; }
.fatura-itens li{ display:flex; justify-content:space-between; gap:10px; padding:3px 0; border-bottom:1px solid var(--cinza-fundo); }
.fatura-itens li.fatura-pagtos{ border-bottom:0; color:var(--cinza-medio); display:block; padding-top:6px; }
@media (max-width:720px){
  .fatura-linha, .fatura-linha-2{ grid-template-columns:1fr 1fr 24px; }
  .fatura-linha select{ grid-column:1 / span 2; }
}

/* atalhos de teclado do Diário */
.atalhos-caixa{ margin-top:12px; background:var(--cinza-fundo); border-radius:var(--raio-sm); padding:12px 16px; font-size:13px; }
.atalhos-caixa ul{ list-style:none; margin:8px 0; }
.atalhos-caixa li{ margin-bottom:5px; color:#444; }
.atalhos-caixa kbd{ display:inline-block; background:var(--branco); border:1px solid var(--cinza-borda);
  border-bottom-width:2px; border-radius:var(--raio-xs); padding:1px 6px; font-size:11.5px; font-weight:700; font-family:inherit; margin-right:2px; }
/* campo preenchido automaticamente (canal com conta ligada) */
.campo-auto{ background:var(--cinza-fundo); color:var(--cinza-medio); cursor:not-allowed; }

/* conferência do fecho: vendas vs contas */
.conferencia{ border-radius:var(--raio-sm); padding:10px 14px; margin:10px 0 4px; display:flex; flex-direction:column; gap:2px; }
.conf-ok{ background:var(--verde-fundo); border:1px solid #bfe8cf; color:var(--verde); }
.conf-erro{ background:#fdf3e7; border:1px solid #f3d6a8; color:#8a5a12; }
.conferencia strong{ font-size:13.5px; }

/* ---------- Financeiro · Perdas em lote ---------- */
/* Uma linha = uma perda, no formato da planilha: motivo, produto, qtd, custo,
   total, responsável, observação. Compacta de propósito — quem lança um turno
   inteiro quer ver várias linhas ao mesmo tempo. */
.perdas-linhas{ display:flex; flex-direction:column; gap:6px; margin:6px 0 4px; }
/* ⚠️ As colunas seguem a ORDEM do template: motivo · produto · sai do estoque ·
   qtd · custo un. · total · responsável · observação · ×
   Faltava aqui a coluna do "sai do estoque?" — eram nove campos para oito
   medidas, tudo escorregava um lugar, e a observação ficava com o resto. Por
   isso é que o rótulo caía fora do campo.

   `align-items:start` com o rótulo de altura fixa: "SAI DO ESTOQUE?" ocupa duas
   linhas e "QTD" uma, e com alinhamento pelo fundo as caixas ficavam a alturas
   diferentes — era o desalinhamento visível na tela. */
/* DUAS FILAS, de propósito. Nove campos numa fila só davam 100 px a cada um:
   a observação não cabia uma palavra e o custo unitário cortava os cêntimos.
   Fila 1 é O QUE se perdeu e quanto custa; fila 2 é QUEM e PORQUÊ — que é
   também a ordem por que se preenche.

   Grelha de 24 colunas porque as larguras que se querem não são múltiplos
   uns dos outros (a quantidade precisa de 2/24, a observação de 17/24). */
.perda-linha{
  display:grid; gap:8px 10px; align-items:start;
  grid-template-columns:repeat(24, minmax(0, 1fr));
}
.perda-linha .campo:nth-child(1){ grid-column:span 5; }   /* motivo         */
.perda-linha .campo:nth-child(2){ grid-column:span 6; }   /* produto        */
.perda-linha .campo:nth-child(3){ grid-column:span 5; }   /* sai do estoque */
.perda-linha .campo:nth-child(4){ grid-column:span 2; }   /* qtd            */
.perda-linha .campo:nth-child(5){ grid-column:span 3; }   /* custo un.      */
.perda-linha .campo:nth-child(6){ grid-column:span 3; }   /* total          */
.perda-linha .campo:nth-child(7){ grid-column:span 6; }   /* responsável    */
.perda-linha .campo:nth-child(8){ grid-column:span 17; }  /* observação     */
.perda-remover{ grid-column:span 1; }
/* separa visualmente uma perda da seguinte: com duas filas por perda, sem isto
   não se percebia onde acaba uma e começa a outra. Só ENTRE linhas — uma risca
   por baixo da última parece um campo que ficou por preencher. */
.perdas-linhas .perda-linha + .perda-linha{ padding-top:12px; border-top:1px dashed var(--cinza-borda); }
.perda-linha .campo{ margin:0; min-width:0; }
.perda-linha label{
  font-size:10.5px; text-transform:uppercase; letter-spacing:.3px; color:var(--cinza-medio);
  margin-bottom:3px;
  /* duas linhas de altura reservada em TODOS: os campos ficam à mesma altura
     mesmo quando só um dos rótulos quebra */
  display:block; min-height:26px; line-height:1.2;
}
.perda-linha input, .perda-linha select{ margin:0; padding:7px 8px; font-size:13.5px; }
.perda-linha .campo-moeda{ padding:0 7px; }
.perda-linha .campo-moeda span{ font-size:12px; }
.perda-linha .campo-moeda input{ padding:7px 0; }
.perda-linha .perda-qtd{ text-align:right; }
/* o total é calculado: fica visualmente mais leve que os campos que se digitam */
.perda-linha .perda-total{ font-weight:600; }
.perda-remover{ padding:0 0 7px; font-size:17px; line-height:1; }

/* Reserva do espaço da seta desenhada — vem DEPOIS das regras de padding
   acima (cfg/pagar/fatura/perda) para vencer a cascata sem !important. */
.cfg-linha select, .cfg-nova select, .pagar-linha select,
.fatura-linha select, .perda-linha select, .retirada-linha select{ padding-right:28px; }
.btn-sec{ background:var(--branco); color:var(--texto); border:1.5px solid var(--cinza-borda); }
.btn-sec:hover{ background:var(--cinza-fundo); }

@media (max-width:900px){
  /* deixa de caber em linha: cada perda vira um cartão com os campos empilhados */
  .perda-linha{ grid-template-columns:repeat(2, minmax(0,1fr)) 22px; gap:8px 10px;
    padding:12px; background:var(--cinza-fundo); border-radius:var(--raio-sm);
    border-bottom:0; }
  /* aqui as larguras de 24 colunas não valem: cada campo ocupa meia fila… */
  .perda-linha .campo{ grid-column:span 1 !important; }
  /* …menos os que precisam da fila toda para se lerem */
  .perda-linha .campo:nth-child(1), .perda-linha .campo:nth-child(2),
  .perda-linha .campo:nth-child(3), .perda-linha .campo:nth-child(8){ grid-column:1 / span 2 !important; }
  .perda-linha label{ display:block !important; min-height:0; }   /* empilhado, sem rótulo não se distingue */
  .perda-remover{ grid-row:1; grid-column:3; align-self:start; padding-top:20px; }
}

/* ✅ conferido no Diário: discreto quando por marcar, verde quando já bateu */
/* ═══════════ F9b · A DESPESA DIVIDIDA, UMA LINHA SÓ ═══════════
   A fatura repartida gera N lançamentos (é o que mantém o CMV e a DRE certos);
   a lista mostra UMA linha com a soma, e o ▸ abre as partes por baixo. */
.lanc-abrir{ background:none; border:0; cursor:pointer; padding:0 6px 0 0; margin:0;
  color:var(--cinza-medio); font-size:12px; line-height:1; transition:color .15s, transform .15s;
  display:inline-block; }
.lanc-abrir:hover{ color:var(--preto); }
.lanc-abrir[aria-expanded="true"]{ transform:rotate(90deg); color:var(--preto); }
/* A etiqueta que diz, de fora, que a linha tem partes por dentro. */
.lanc-dividida{ background:var(--cinza-fundo); color:var(--cinza-medio); font-weight:600; }
/* A parte é DETALHE da linha de cima, não uma compra a mais: letra mais miúda,
   uma barra à esquerda a dizer que pertence a algo, e a descrição recuada.
   ⚠️ A barra vai por `inset shadow` e não por `border-left`: uma borda a mais
   empurrava a célula e desalinhava a coluna do dia com as outras linhas. */
.tabela tbody tr.lanc-parte{ font-size:13px; }
.tabela tbody tr.lanc-parte > td:first-child{ box-shadow:inset 4px 0 0 var(--cinza); }
.tabela tbody tr.lanc-parte > td:nth-child(5){ padding-left:20px; }
.tabela tbody tr.lanc-parte .td-valor strong{ font-weight:600; }
/* O nº do documento é o MESMO da linha agrupada, que está logo por cima:
   repeti-lo em cada parte é ruído. */
.tabela tbody tr.lanc-parte .lanc-doc{ display:none; }
/* Meia fatura conferida: o número por baixo do tique diz quantas faltam. */
.conf-parcial{ font-size:10px; color:var(--cinza-medio); line-height:1; }

/* ═══════════ F7 · OS SEIS LUGARES DA COLUNA DE AÇÕES ═══════════
   Ele, 12/08/2026: *"ícones da linha no mesmo padrão visual dos de dar baixa e
   conciliar, e alinhados uns por baixo dos outros"*.

   ⚠️ O que fazia falta não era estilo, era GRELHA. Com a célula encostada à
   direita e um número variável de ícones, o lápis de uma linha caía debaixo do ×
   da linha de cima: para clicar era preciso ler primeiro. Seis colunas fixas
   resolvem-no, e o lugar vazio (.lanc-ico-vazio) é o que segura o alinhamento
   quando a linha não tem aquela ação.
   ⚠️ `justify-content:end` mantém o bloco encostado à direita como sempre
   esteve; o que muda é que cada ação tem coordenada certa. */
/* 🚨 17/08/2026: esta grelha é do DIÁRIO, e estava a valer para TODA a coluna
   `.td-acoes` do sistema. Nas telas cujas ações são TEXTO (utilizadores,
   colaboradores, feriados, salários, produtos, mesas, VIPs, clientes, painel),
   "Editar · Desativar · Excluir" era espremido em faixas de 30px e as três
   palavras saíam **umas por cima das outras** — o print que ele mandou.
   ⭐ Agora a grelha tem dono: `.td-acoes-icones`, que só a linha do Diário usa.
   As outras voltam ao que a coluna sempre foi (texto encostado à direita). */
.td-acoes-icones{ display:grid; grid-template-columns:repeat(6, 30px); gap:2px;
  justify-content:end; align-items:start; }
.td-acoes-icones form{ margin:0; display:grid; place-items:center; }
.lanc-slot{ display:grid; place-items:center; }
.lanc-ico-vazio{ display:block; width:30px; height:26px; }

/* O padrão único: caixa de 26px, borda leve, glifo cinza. As variantes que
   carregam ESTADO (dar baixa em âmbar, conferido em verde) pintam por cima. */
.lanc-ico{ display:inline-grid; place-items:center; box-sizing:border-box;
  width:28px; height:26px; padding:0; border:1.5px solid var(--cinza-borda); border-radius:var(--raio-xs);
  background:none; color:var(--cinza-medio); font-size:13px; line-height:1; text-decoration:none;
  cursor:pointer; transition:color .15s, border-color .15s, background .15s, opacity .15s; }
.lanc-ico:hover{ color:var(--destaque); border-color:var(--destaque); text-decoration:none; }
.lanc-ico-apagar:hover{ color:#b3261e; border-color:#b3261e; background:color-mix(in srgb, #b3261e 7%, transparent); }
/* O cadeado informa, não se clica: sem borda para não parecer botão. */
.lanc-ico.lanc-trancado{ border-color:transparent; cursor:help; opacity:.45; }

.lanc-conferir{ background:none; border:1.5px solid var(--cinza-borda); color:var(--cinza); cursor:pointer;
  width:28px; height:26px; border-radius:var(--raio-xs); font-size:13px; line-height:1; padding:0;
  vertical-align:middle; transition:color .15s, border-color .15s, background .15s; }
.lanc-conferir:hover{ border-color:var(--verde); color:var(--verde); }
.lanc-conferir.ativo{ background:var(--verde-fundo); border-color:var(--verde); color:var(--verde); font-weight:700; }

/* ---------- Financeiro · Recebido / Pago (dar baixa) ----------
   Pendente é um estado de ESPERA: âmbar, o mesmo tom do aviso do sistema. */
.lanc-receber{ color:#8a5a12; background:#fdf3e7; font-weight:700; margin-left:4px; }
/* Fieldset usado só para desligar um formulário inteiro: não deve desenhar
   nada. `min-width:0` é obrigatório — sem ele o fieldset recusa-se a encolher
   e a grade de vendas deixa de caber no telemóvel. */
.fs-plano{ border:0; margin:0; padding:0; min-width:0; }
/* Fecho guardado: faixa de consulta com o botão de reabrir à direita.
   O texto encolhe (flex:1 1 240px) para o botão ficar na mesma linha enquanto
   houver espaço; só num ecrã estreito é que passa para baixo. */
.fecho-travado{ display:flex; align-items:center; justify-content:space-between; gap:12px; flex-wrap:wrap;
  background:var(--branco); border:1px solid var(--linha); border-radius:var(--raio);
  padding:12px 14px; margin:0 0 14px; max-width:720px; }
.fecho-travado .ft-txt{ flex:1 1 240px; font-size:14px; color:var(--texto-suave); }
.fecho-travado form{ flex:0 0 auto; }
/* ⭐ "Abri no dia de ontem, e é de propósito" (23/08/2026). Mesma forma da faixa
   de fecho guardado — é o mesmo tipo de recado: o estado da tela explicado antes
   de alguém dar por ele.
   ⚠️ Cor de AVISO e não de erro: não correu nada mal, a tela só está noutro dia.
   O vermelho aqui dava um susto por uma coisa que é uma ajuda. */
.fecho-virada{ display:flex; align-items:center; justify-content:space-between; gap:12px; flex-wrap:wrap;
  background:#fff8e6; border:1px solid #f0dfae; border-radius:var(--raio);
  padding:12px 14px; margin:0 0 14px; max-width:720px; }
.fecho-virada span{ flex:1 1 240px; font-size:14px; color:#7a5b00; font-weight:600; }
.fecho-virada a{ flex:0 0 auto; }
/* Campo desligado tem de PARECER desligado, senão a tela mente sobre o estado:
   o valor lê-se bem, mas nada convida a clicar.
   ⚠️ O seletor precisa do `.campo` no meio: `.fs-plano:disabled input` sozinho
   empata em especificidade com `.form .campo input` e perde por vir antes no
   ficheiro — os campos de texto ficavam brancos e pareciam editáveis. */
.fs-plano:disabled .campo input, .fs-plano:disabled .campo select,
.fs-plano:disabled .campo textarea, .fs-plano:disabled .campo-moeda,
.fs-plano:disabled input, .fs-plano:disabled select, .fs-plano:disabled textarea{
  background:var(--fundo); color:var(--texto-suave); opacity:1; cursor:default;
  border-color:transparent; box-shadow:none; }
.fs-plano:disabled .campo-moeda input{ background:transparent; }

/* Diário: as colunas da planilha.
   Onde a planilha usa duas colunas para a mesma ideia (Data+Dia,
   Categoria+Grupo, Forma+Serviço), aqui é uma célula com uma segunda linha
   discreta — mesma informação, tabela que ainda cabe no ecrã. */
.lanc-sub{ display:block; font-size:11px; line-height:1.35; color:var(--texto-suave); font-weight:400; }
/* O Nº DO DOCUMENTO por baixo da descrição: em versalete e monoespaçado, para
   se conferir algarismo a algarismo contra a fatura na mão. É ligação (filtra o
   Diário por esta fatura), mas não se pinta de link — a coluna já tem cor a
   mais e isto é referência, não navegação a convidar. */
.lanc-doc{ font-variant-numeric:tabular-nums; letter-spacing:.2px; text-decoration:none; }
.lanc-doc:hover{ text-decoration:underline; color:var(--vermelho); }
.lanc-comp{ color:var(--texto-suave); font-variant-numeric:tabular-nums; }
.lanc-vazio{ color:var(--linha); }
.td-saldo{ font-variant-numeric:tabular-nums; white-space:nowrap; color:var(--texto-suave); }
/* Com duas colunas a mais, o valor começou a partir o sinal do número numa
   linha só dele ("−" em cima, "€364,53" em baixo). Dinheiro não se lê assim. */
.tabela .td-valor{ white-space:nowrap; font-variant-numeric:tabular-nums; }
/* Larguras: a descrição é que deve crescer; categoria e forma pedem um mínimo
   para não partirem a meio de uma palavra, e as colunas de número não crescem.

   🚨 Estas três linhas estiveram MORTAS no Diário (18/08/2026): as células
   levavam dois atributos `class` e o navegador ficava com o primeiro. Sem
   `width:1%`, Valor e Saldo repartiam a sobra da tabela e afastavam-se um do
   outro — era a queixa dele. Ver o comentário no topo de `linha-diario.php`. */
.tabela .td-forma{ min-width:96px; }
.tabela .td-categoria{ min-width:118px; }
/* ⚠️ `width:1%` numa tabela é "o mínimo que couber": o resto vai para a
   descrição, que é a coluna que deve crescer. */
.tabela .td-saldo, .tabela .td-valor{ width:1%; text-align:right; }
/* ⭐ VALOR E SALDO MAIS JUNTOS (ele, 18/08/2026: *"reduzir um pouco a distância
   entre as colunas valor e o saldo"*). São o par que se lê de uma vez ao
   conferir o extrato: o valor da linha e o saldo que ele deixou.
   📏 Medido no navegador: 36px entre os dois números → 18px.
   ⚠️ Fica preso ao Diário (`.lanc-tabela`) de propósito: `.td-valor` também
   serve nove telas do Operacional, e apertar todas por causa desta seria o
   defeito da regra escrita para um sítio que alcança outro. */
/* ⭐⭐ SEGUNDA VOLTA (ele, 23/08/2026: *"diminuir um pouco mais a distância
   entre saldo e valor; parece que os dois são os mais distantes"*).
   🚨 Fui medir para saber quanto tirar, e a medida mudou a explicação: **o vão
   não é fixo.** As duas colunas alinham à DIREITA, e cada uma tem a largura do
   maior número dela — logo, numa linha em que o saldo é um número CURTO, ele
   começa muito mais à direita e o buraco cresce.
   📏 Medido em 12 linhas, com o afastamento de 18px de 18/08:
        Valor → Saldo   mínimo 18px · média 31px · **máximo 86px**
        Conta → Valor   mínimo 58px · média 69px · máximo 81px
   ⭐ Ou seja: ele tinha razão, e a primeira volta não podia ter resolvido. Nas
   linhas de saldo curto o par Valor/Saldo é mesmo o mais afastado da tabela —
   mais do que o Conta/Valor, que parece o maior quando se olha uma linha só.
   ⚠️ O que sobra é geometria de coluna numérica, não folga a cortar: encostar
   mais só desce o chão dos 18px, não fecha o buraco das linhas curtas. Fechá-lo
   de vez pedia alinhar o saldo à esquerda, e dinheiro não se lê assim.
   ⚠️ Continua preso ao Diário (`.lanc-tabela`): `.td-valor` serve nove telas do
   Operacional, e apertar todas por causa desta era a regra escrita para um
   sítio que alcança outro. */
.lanc-tabela .td-l-valor{ padding-right:4px; }
.lanc-tabela .td-l-saldo{ padding-left:4px; }

/* ============================================================
   OPERACIONAL — fichas técnicas
   ============================================================ */
/* Abas de tipo com a contagem à frente: dá o tamanho do catálogo de relance. */
.fich-filtros{ display:flex; align-items:center; justify-content:space-between; gap:14px;
  flex-wrap:wrap; margin:0 0 16px; }
.fich-busca{ display:flex; align-items:center; gap:8px; }
.fich-busca input{ min-width:210px; }

/* CMV entre o alvo e 5 pontos acima: nem verde nem vermelho. Um terceiro
   estado evita que "ligeiramente acima" pareça uma emergência. */
.cmv-atencao{ color:#a06a00; }

/* Linha de total dentro de uma tabela de detalhe. */
.tabela tr.tot td{ border-top:1.5px solid var(--cinza-borda); font-weight:600; }

/* Onde esta ficha é usada — lista de atalhos. */
.chips{ display:flex; flex-wrap:wrap; gap:8px; }
/* ⚠️ `.chip` e não `a.chip`: em `tarefas.php` os setores são <span> e ficavam
   texto solto, sem pílula. Um seletor que exige a TAG obriga a repetir o
   componente sempre que ele não for um link. */
.chip{ display:inline-block; padding:7px 13px; border:1px solid var(--cinza-borda);
  border-radius:999px; background:var(--branco); color:var(--texto); text-decoration:none;
  font-size:13.5px; transition:border-color .15s; }
a.chip:hover{ border-color:var(--preto); }

/* ── A ETIQUETA POR ARRUMAR (22/08/2026) ──
   Ele: *"o quadrado das cores e os botões de etiqueta estão fora de padrão…
   talvez algo mais arredondado, mais ícone"*.
   ⚠️ O `+` era texto solto no fim da palavra e lia-se como parte do nome da
   etiqueta. Agora é um ÍCONE redondo, separado do nome — e é ele que cresce no
   hover, porque é ele que diz o que o clique faz. */
button.chip{ cursor:pointer; font-family:inherit; }
.chip-add{
  display:inline-flex; align-items:center; gap:7px; padding:5px 6px 5px 12px;
  transition:border-color .15s, background .15s;
}
.chip-add .chip-nome{ line-height:1; }
/* O `#` é da linguagem das etiquetas, e vive antes do nome — mas em cinzento,
   porque é gramática e não conteúdo. */
.chip-add .chip-nome::before{ content:'#'; color:var(--cinza-medio); margin-right:1px; }
.chip-add .chip-ico{
  display:inline-flex; align-items:center; justify-content:center;
  width:20px; height:20px; border-radius:50%; flex:0 0 auto;
  background:var(--cinza-claro); color:var(--cinza-medio);
  font-size:14px; line-height:1; transition:background .15s, color .15s;
}
.chip-add:hover{ border-color:var(--preto); }
.chip-add:hover .chip-ico{ background:var(--preto); color:var(--branco); }
.chip-add:focus-visible{ outline:2px solid var(--vermelho); outline-offset:2px; }

/* ⭐⭐ O RUMO DA TRANSFERÊNCIA DE COFRE (20/08/2026) — dois caminhos escritos, e
   não um "±" que só quem sabe entende. Ver `fecho.php` e Caixa::movCofre.

   ⚠️ São rádios DE VERDADE por baixo (funciona sem JavaScript e com teclado); o
   que muda é só a pintura. E a pintura é a do `.chip` que já existe na casa —
   pílula clara, ativa a preto, como as vistas das Tarefas —, porque um
   componente novo para o mesmo gesto é o que já nos apanhou noutra tela. */
.rotulo-solto{ display:block; font-size:13px; font-weight:600; color:var(--texto); margin-bottom:7px; }
.rumo-chips{ display:flex; flex-wrap:wrap; gap:8px; }
.rumo-chip{ margin:0; cursor:pointer; }
/* O rádio sai do ecrã mas continua a existir para o teclado e o leitor de ecrã.
   ⚠️ É a MESMA receita do `.visualmente-oculto` desta folha, e não um `opacity:0`
   meu: o `opacity` perdia para as regras de radio/checkbox lá de cima (medido no
   navegador — ficava a 1) e sobrava um ponto de 1px ao lado da pílula. */
.rumo-chip input{
  position:absolute; width:1px; height:1px; overflow:hidden;
  clip:rect(0 0 0 0); clip-path:inset(50%); white-space:nowrap;
}
.rumo-chip span{
  display:inline-block; padding:7px 13px; border:1px solid var(--cinza-borda);
  border-radius:999px; background:var(--branco); color:var(--texto);
  font-size:13.5px; transition:border-color .15s, background .15s, color .15s;
}
.rumo-chip:hover span{ border-color:var(--preto); }
.rumo-chip input:checked + span{ background:var(--preto); border-color:var(--preto); color:var(--branco); }
/* ⚠️ O foco tem de aparecer: com o rádio escondido, quem anda de Tab ficava sem
   saber onde está — e este é um dos poucos campos que decide para que lado o
   dinheiro vai. */
.rumo-chip input:focus-visible + span{ outline:2px solid var(--vermelho); outline-offset:2px; }

/* Modo de preparo: o receituário. Números grandes porque se lê de pé, na
   cozinha, a um braço de distância. */
.preparo{ margin:0; padding:0 0 0 4px; list-style:none; counter-reset:passo; max-width:760px; }
.preparo li{ counter-increment:passo; position:relative; padding:0 0 14px 42px; line-height:1.55; }
.preparo li::before{ content:counter(passo); position:absolute; left:0; top:-1px;
  display:grid; place-items:center; width:27px; height:27px; border-radius:50%;
  background:var(--fundo); color:var(--texto-suave); font-size:13px; font-weight:600; }

/* L de liquidez: o dia em que o dinheiro de uma plataforma deve cair. Verde é
   informação ("está a caminho"); vermelho é a única parte que pede acção
   ("devia ter caído e não caiu"). */
.lanc-liq{ background:#e8f4ec; color:#1c6b3a; }
.lanc-liq-atraso{ background:#fdecea; color:#a3231b; }

/* Aviso de variação no fecho: aparece só quando o contado difere do previsto. */
.var-aviso{ display:block; margin-top:4px; font-weight:600; }

/* ⚠️ AS AÇÕES FICAM SEMPRE À VISTA.
   Ao acrescentar as colunas Forma e Saldo, a tabela passou a ser mais larga do
   que o espaço disponível e a coluna dos botões saiu do ecrã: quem olhava
   dizia, com razão, que "os botões sumiram" — estavam a um scroll horizontal de
   distância, sem nada a indicá-lo. Presa à direita, o conferir e o editar
   voltam a estar sempre onde a mão os procura.

   ⚠️ E vale SÓ para quem pede (`tabela-acoes-fixas`). Enquanto valeu para
   `.tabela` inteira, a coluna presa tapava a vizinha em toda a tabela que
   fosse mais larga que o espaço — na tela de Usuários comia o "Estado".
   Uma regra criada para uma tabela não pode ser escrita para todas. */
.tabela-acoes-fixas th:last-child, .tabela-acoes-fixas td.td-acoes{
  position:sticky; right:0; z-index:2; background:var(--branco);
  box-shadow:-8px 0 8px -8px rgba(0,0,0,.10);
}
.tabela-acoes-fixas tbody tr:hover td.td-acoes{ background:var(--fundo); }
.tabela-acoes-fixas .linha-pendente td.td-acoes{ background:#fdf9f2; }
.tabela-acoes-fixas .linha-atrasada td.td-acoes{ background:var(--vermelho-sinal-fundo); }

/* Linhas tingidas pelo TIPO, como na planilha dele: verde entrou, vermelho
   saiu, cinza é movimento interno.
   ⭐ 05/08/2026, a pedido dele (*"deixar um pouco mais forte as cores... como da
   planilha"*): os tons subiram um degrau. Eram tão leves que num ecrã de
   portátil com pouco brilho não se distinguiam do branco, e a cor que não se vê
   não faz trabalho nenhum.
   ⚠️ Continuam abaixo do valor e do texto em peso visual: a linha dá o sentido
   do dia de relance, quem manda na leitura é o número. */
.tabela tbody tr.l-receita{ background:#e9f6ee; }
.tabela tbody tr.l-despesa{ background:#fceeee; }
.tabela tbody tr.l-transferencia{ background:#f1f1f3; }
.tabela tbody tr.l-receita:hover{ background:#dcf0e4; }
.tabela tbody tr.l-despesa:hover{ background:#f8e2e2; }
.tabela tbody tr.l-transferencia:hover{ background:#e8e8ec; }
/* ⚠️ A coluna de AÇÕES é `position:sticky` e passa por cima das outras ao rolar:
   sem repetir aqui a cor da linha, ela viajava com fundo branco e cortava a
   faixa a meio. */
.tabela tbody tr.l-receita td.td-acoes{ background:#e9f6ee; }
.tabela tbody tr.l-despesa td.td-acoes{ background:#fceeee; }
.tabela tbody tr.l-transferencia td.td-acoes{ background:#f1f1f3; }
.tabela tbody tr.l-receita:hover td.td-acoes{ background:#dcf0e4; }
.tabela tbody tr.l-despesa:hover td.td-acoes{ background:#f8e2e2; }
.tabela tbody tr.l-transferencia:hover td.td-acoes{ background:#e8e8ec; }
/* a linha pendente ("a receber") manda sobre a cor do tipo: é accionável */
.tabela tbody tr.linha-pendente{ background:#fdf9f2; }

.linha-pendente{ background:#fdf9f2; }
.linha-pendente:hover{ background:#fbf3e6; }
/* O conferir volta a #l<id>. Sem folga, a linha encosta no topo da janela e
   fica colada à borda; com ela, aterra com o cabeçalho da tabela à vista. */
.tabela tbody tr[id]{ scroll-margin-top:90px; }
.linha-atrasada{ background:var(--vermelho-sinal-fundo); }
/* tick de dar baixa: irmão do ✓ de conferir, mas com o € para o gesto de dinheiro */
.lanc-receber-btn{ background:none; border:1.5px solid #e6c58c; color:#8a5a12; cursor:pointer;
  min-width:30px; height:26px; border-radius:var(--raio-xs); font-size:12px; line-height:1; padding:0 5px;
  vertical-align:middle; font-weight:700; transition:color .15s, border-color .15s, background .15s; }
/* Dentro da grelha das ações, quem manda no tamanho é a grelha. */
.td-acoes-icones .lanc-receber-btn{ width:28px; min-width:0; padding:0; }
.lanc-receber-btn:hover{ border-color:var(--verde); color:var(--verde); background:var(--verde-fundo); }

/* ---------- F10 · A RECEBER: quanto cada plataforma deve ----------
   Cada cartão é um FILTRO: carregar nele deixa a lista de baixo só com aquela
   plataforma, e carregar outra vez desfaz. É a mesma ideia dos separadores da
   lista de tarefas — o resumo e o filtro são a mesma coisa, e ter os dois
   separados obrigava a ler duas vezes. */
.rec-kpi{ text-decoration:none; color:inherit; display:flex; flex-direction:column; gap:2px;
  border:1.5px solid var(--cinza-borda); transition:border-color .15s, box-shadow .15s; }
.rec-kpi:hover{ border-color:var(--cinza-medio); }
.rec-kpi.ativo{ border-color:var(--preto); box-shadow:0 0 0 3px var(--cinza-fundo); }
.rec-kpi .lanc-tag{ align-self:flex-start; margin-top:4px; }
.rec-filtro{ display:flex; align-items:flex-end; gap:14px; flex-wrap:wrap; margin:14px 0 6px; }
.rec-filtro .campo{ margin-bottom:0; min-width:200px; }
.rec-filtro .campo-check{ display:inline-flex; align-items:center; gap:8px; font-size:13px;
  font-weight:600; padding-bottom:12px; }
.rec-filtro .ajuda{ display:inline; }

/* ---------- F4 · a janela de LEITURA de um lançamento ----------
   Duas colunas: rótulo à esquerda, valor à direita. É uma FICHA, não um
   formulário: nada aqui se escreve, e é isso que a torna segura de abrir. */
.dlg-ficha{ width:min(520px,94vw); }
.dlg-ficha h3{ margin:0 0 4px; }
.ficha-tipo{ margin:0 0 12px; }
.ficha-lista{ display:grid; grid-template-columns:minmax(96px,34%) 1fr; gap:7px 14px;
  margin:0 0 14px; align-items:baseline; }
.ficha-lista dt{ font-size:12.5px; color:var(--cinza-medio); font-weight:600; }
.ficha-lista dd{ margin:0; font-size:14px; color:var(--preto); overflow-wrap:anywhere; }
.dlg-ficha .anexo-lista{ margin-bottom:12px; }
.dlg-ficha .secao-titulo{ margin:0 0 6px; }

/* diálogo de dar baixa / pagar — cartão centrado, mesmo tom das telas */
/* 🐞 12/08/2026 · A JANELA ABRIA NO CANTO. Um <dialog> modal é centrado pelo
   navegador com `margin:auto`, e o nosso reset (`*{ margin:0 }`, lá no topo)
   apagava-o — regra de autor ganha sempre à do navegador. Valia para TODAS as
   janelas da casa (dar baixa, conciliar, pagar), e ninguém tinha reparado
   porque uma janela no canto continua a funcionar.
   ⚠️ `margin:auto` com `inset:0` é o que centra nos dois eixos. */
.dext-dialog{ border:none; border-radius:var(--raio); box-shadow:0 12px 40px rgba(0,0,0,.22);
  padding:22px 24px; width:min(460px,92vw); color:var(--texto); margin:auto; }
.dext-dialog::backdrop{ background:rgba(17,17,17,.42); }
.dext-dialog h3{ font-family:var(--fonte-titulo); font-weight:700; font-size:16px; }
.dext-dialog .form-linha{ display:flex; gap:12px; flex-wrap:wrap; }
.dext-dialog .campo{ flex:1 1 160px; }

/* ═══ PESO DOS NÚMEROS ═══
   Valor é para LER, não para gritar. O <strong> do HTML entra a 700 e, numa
   coluna inteira de dinheiro, 700 vira uma parede escura que cansa e faz o olho
   perder a linha. A 600 continua a destacar-se do rótulo (que é 400) e lê-se
   muito melhor em bloco. Os títulos e cabeçalhos ficam onde estavam. */
.fecho-kpi strong,
.tabela td strong,
.mini-tab td.v,
.mini-tab td.v strong,
.saldo-pos, .saldo-neg,
.saldo-pos strong, .saldo-neg strong,
.fecho-kpi strong.saldo-pos, .fecho-kpi strong.saldo-neg{ font-weight:600; }
/* tabular-nums: os dígitos ficam todos com a mesma largura, por isso as colunas
   de valores alinham na vertical em vez de dançar de linha para linha */
.fecho-kpi strong, .tabela td strong, .mini-tab td.v{ font-variant-numeric:tabular-nums; }

/* diálogo de confirmação (fecho de caixa)
   ⚠️ `margin:auto` pelo mesmo motivo do `.dext-dialog` acima: a correção de
   12/08 dizia valer para TODAS as janelas e esta ficou para trás — abria no
   canto (auditoria 13/08). Um reset com `*` alcança o que o navegador estiliza
   sozinho, e é sempre aqui que se olha primeiro. */
.dlg{ border:0; border-radius:var(--raio); padding:24px 26px; max-width:420px; width:calc(100% - 32px);
  box-shadow:0 24px 70px rgba(17,17,17,.22); color:var(--texto); margin:auto; }
.dlg::backdrop{ background:rgba(17,17,17,.42); }
.dlg-titulo{ font-family:var(--fonte-titulo); font-size:17px; font-weight:700; margin-bottom:6px; }
.dlg .mini-tab{ margin:14px 0 4px; }
.dlg .conferencia{ margin-top:12px; }

/* meses de origem da despesa arrastada: linhas-filhas, recuadas e discretas.
   Mês e valor vivem na MESMA célula, em flex: com colunas separadas a tabela
   estreita empurrava o valor para a linha de baixo. */
.mini-tab tr.sub-mes td{ border-bottom:0; padding:2px 0 2px 14px;
  display:flex; justify-content:space-between; gap:10px;
  font-size:12px; color:var(--cinza-medio); }
.mini-tab tr.sub-mes td span:first-child{ white-space:nowrap; }
.mini-tab tr.sub-mes td span:last-child{ font-variant-numeric:tabular-nums; }

/* ---------- Pessoas · No turno agora ---------- */
.turno-grade{ display:grid; grid-template-columns:repeat(auto-fill,minmax(300px,1fr)); gap:16px; margin-top:8px; }
.turno-card{ background:var(--branco); border:1px solid var(--cinza-borda); border-radius:var(--raio);
  box-shadow:var(--sombra); padding:18px 20px; display:flex; flex-direction:column; }
.turno-topo{ display:flex; align-items:center; gap:12px; margin-bottom:12px; }
.turno-quem{ display:flex; flex-direction:column; min-width:0; margin-right:auto; }
.turno-quem strong{ font-size:15px; }
.pill-pausa{ background:#fdf3e7; color:#8a5a12; }
.turno-batidas{ margin-top:6px; }
.turno-batidas summary{ cursor:pointer; font-size:12.5px; color:var(--cinza-medio); padding:6px 0; }
.turno-editar{ margin-top:12px; text-align:center; }

/* lápis de editar no Diário: discreto, ao lado do conferir e do excluir */
.lanc-editar{ display:inline-block; text-decoration:none; color:var(--cinza-medio);
  font-size:15px; padding:0 6px; vertical-align:middle; transition:color .15s; }
.lanc-editar:hover{ color:var(--destaque); }
/* na grelha das ações o lápis é um .lanc-ico como os outros
   🚨 …e tinha de o dizer também no `display` (print dele, 18/08/2026: *"o botão
   de editar tá desalinhado com os outros dois"*). O `.lanc-editar` acima nasceu
   para o lápis SOLTO ao lado do texto e é `inline-block`; como vem depois na
   folha, roubava o `inline-grid` do `.lanc-ico` a quem tem as duas classes — e
   sem a grelha o `place-items:center` não corre, por isso o ícone subia dentro
   da caixa enquanto os vizinhos ficavam centrados.
   ⚠️ É o mesmo defeito do `.td-acoes` (17/08): uma regra escrita para um sítio
   a alcançar outro. Medido no navegador: era o único dos seis com
   `display:block`, os outros todos `grid`. */
.td-acoes-icones .lanc-editar{ display:inline-grid; place-items:center; padding:0; font-size:14px; }
/* 🚨 DUPLICAR NÃO É EDITAR (12/08/2026). Os dois estavam colados, com a mesma
   classe e o mesmo cinzento — e um deles CRIA uma linha nova, datada de hoje.
   Ele reportou como "entro pra editar e a data muda pra hoje", e o caminho do
   lápis está correto (test-lanc-editar-data.php prova). O que estava errado era
   os dois gestos serem indistinguíveis a um pixel de distância.
   Fica mais apagado (é o gesto secundário) e com um respiro a separá-lo. */
.lanc-dup{ opacity:.55; }
.lanc-dup:hover{ opacity:1; }
/* linha gerada noutro módulo (fecho, fatura, taxa): sem lápis nem ×, com o
   cadeado a dizer porquê. Apagado de propósito — informa, não chama. */
.lanc-trancado{ display:inline-block; padding:0 6px; font-size:13px;
  vertical-align:middle; opacity:.45; cursor:help; }

/* ---------- Configurações · aba Notificações ----------
   Um bloco por tipo de aviso, para se ver de relance o que existe.
   Prefixo cfgn- de propósito: .notif-grupo já é da tela Conta. */
.cfgn-bloco{ border:1px solid var(--cinza-borda); border-radius:var(--raio); padding:18px 20px; margin-bottom:16px; background:var(--branco); }
.cfgn-cab{ display:flex; align-items:center; gap:9px; font-weight:700; font-size:15px; color:var(--preto); margin-bottom:4px; }
.cfgn-ic{ display:inline-grid; place-items:center; width:26px; height:26px; border-radius:var(--raio-sm); flex:none; background:var(--cinza-fundo); font-size:14px; }
@media (max-width:560px){ .cfgn-bloco{ padding:15px 16px; } }

/* campo curto com sufixo colado (dias, %) — formas de pagamento */
.campo-sufixo{ display:inline-flex; align-items:center; gap:4px; border:1px solid var(--cinza-borda);
  border-radius:var(--raio-sm); padding:0 8px; background:var(--branco); flex:0 0 auto; }
.campo-sufixo input{ border:0; outline:none; background:transparent; width:56px; padding:5px 0;
  font:inherit; font-size:13px; text-align:right; font-variant-numeric:tabular-nums; }
.campo-sufixo span{ font-size:12px; color:var(--cinza-medio); font-weight:600; }
.campo-sufixo:focus-within{ border-color:var(--preto); }

/* ---------- Diário: editor recolhível e extras discretos ----------
   Quem abre o Diário quer ver os lançamentos. O formulário fica atrás de um
   botão "+ Novo"; criar conta / conta a pagar ficam discretos. */
.lanc-editor{ margin:6px 0 4px; }
.lanc-novo-btn{ display:inline-flex; align-items:center; gap:9px; cursor:pointer; list-style:none;
  background:var(--botao,var(--preto)); color:var(--botao-texto,#fff); border-radius:var(--raio-sm);
  padding:11px 20px; font-weight:700; font-size:15px; user-select:none; }
.lanc-novo-btn::-webkit-details-marker{ display:none; }
.lanc-novo-btn .mais{ font-size:18px; line-height:1; font-weight:800; }
.lanc-novo-btn:hover{ filter:brightness(1.08); }
.lanc-editor[open] .lanc-novo-btn{ border-radius:var(--raio-sm) var(--raio-sm) 0 0; }
.lanc-editor > .form{ margin-top:0; border-top-left-radius:0; }
/* extras (nova conta, nova conta a pagar): presentes, sem disputar atenção */
.lanc-extra{ margin:10px 0 0; }
.lanc-extra > summary{ cursor:pointer; font-size:13px; color:var(--cinza-medio); font-weight:600;
  display:inline-block; padding:4px 0; }
.lanc-extra > summary:hover{ color:var(--preto); }
.lanc-extra[open]{ border:1px solid var(--cinza-borda); border-radius:var(--raio); padding:12px 16px;
  background:var(--branco); max-width:760px; }

/* ---------- Widget de reservas (Configurações → Clientes) ---------- */
.wid-caixa{ border:1px solid var(--cinza-borda); border-radius:var(--raio); overflow:hidden; background:var(--cinza-fundo); }
.wid-codigo{ margin:0; padding:14px 16px; font-family:ui-monospace,SFMono-Regular,Menlo,monospace;
  font-size:12.5px; line-height:1.55; color:var(--preto); white-space:pre; overflow-x:auto; }
.wid-acoes{ display:flex; gap:8px; padding:10px 16px; border-top:1px solid var(--cinza-borda); background:var(--branco); }
.wid-passos{ margin:14px 0 8px; padding-left:20px; font-size:14px; color:var(--cinza-medio); }
.wid-passos li{ margin:5px 0; }
.wid-passos strong{ color:var(--preto); }

/* ============================================================
   MANUAL DO SISTEMA (/manual) — a versão longa da ajuda.
   O documento reaproveita as classes do manual impresso (.topico, .callout,
   .perfil, .cap-cab): é o MESMO conteúdo do PDF, por isso a marcação é a
   mesma e só a moldura muda. As de ecrã levam prefixo man-.
   ============================================================ */
.man{ display:grid; grid-template-columns:264px minmax(0,1fr); gap:38px; align-items:start; }

/* sumário fixo: num documento longo, saber onde se está vale mais do que o espaço */
.man-toc{ position:sticky; top:18px; max-height:calc(100vh - 36px); overflow-y:auto;
  background:var(--branco); border:1px solid var(--cinza-borda); border-radius:var(--raio); padding:16px 14px; }
.man-toc-cab{ display:flex; align-items:baseline; justify-content:space-between; gap:8px; margin-bottom:12px; }
.man-kicker{ font-size:10px; font-weight:700; letter-spacing:2.4px; text-transform:uppercase; color:var(--vermelho); }
.man-versao{ font-family:var(--fonte-titulo); font-size:11px; font-weight:700; color:var(--cinza-medio); }
.man-busca{ display:flex; align-items:center; gap:7px; border:1px solid var(--cinza-borda); border-radius:var(--raio-sm);
  padding:7px 10px; margin-bottom:12px; color:var(--cinza-medio); }
.man-busca svg{ width:15px; height:15px; flex:0 0 auto; }
.man-busca input{ border:0; outline:0; width:100%; font:inherit; font-size:13px; background:none; color:var(--preto); }
.man-toc-lista{ display:flex; flex-direction:column; }
.man-toc-cap{ margin-bottom:12px; }
.man-toc-t{ display:flex; gap:9px; align-items:baseline; font-family:var(--fonte-titulo); font-weight:700;
  font-size:13.5px; color:var(--preto); text-decoration:none; margin-bottom:4px; }
.man-n{ color:var(--vermelho); font-size:11px; letter-spacing:.5px; flex:0 0 auto; }
.man-toc-i{ display:block; font-size:12.5px; color:var(--cinza-medio); text-decoration:none;
  padding:3px 0 3px 21px; border-left:2px solid transparent; margin-left:2px; line-height:1.35; }
.man-toc-i:hover{ color:var(--preto); }
.man-toc-i.ativo{ color:var(--preto); font-weight:600; border-left-color:var(--vermelho); }
.man-toc-vazio{ font-size:12.5px; color:var(--cinza-medio); margin:4px 0 0; }

.man-doc{ min-width:0; max-width:760px; }
.man-cab{ display:flex; align-items:flex-start; justify-content:space-between; gap:18px; flex-wrap:wrap; margin-bottom:26px; }
.man-cab h1{ font-family:var(--fonte-titulo); font-weight:700; font-size:30px; letter-spacing:-.8px; margin:6px 0 4px; }
.man-lead{ color:var(--cinza-medio); font-size:14px; max-width:52ch; margin:0; }
.man-pdf{ flex:0 0 auto; }
.man-idioma{ margin-bottom:22px; }

/* Um capítulo por bloco, com a mesma cabeça do impresso. */
.man-cap{ padding-top:8px; margin-bottom:44px; scroll-margin-top:18px; }
.man-cap .cap-cab{ margin-bottom:22px; }
.man-cap .cap-cab .lab{ font-size:10px; font-weight:700; text-transform:uppercase; letter-spacing:2.6px; color:var(--vermelho); }
.man-cap .cap-cab h2{ font-family:var(--fonte-titulo); font-weight:700; font-size:25px; letter-spacing:-.6px; margin:7px 0 5px; }
.man-cap .cap-cab p{ color:var(--cinza-medio); font-size:14px; margin:0 0 12px; }
.man-cap .cap-cab .rule{ height:2px; background:var(--preto); }

.man-doc .intro-lead{ font-size:15.5px; line-height:1.65; color:var(--preto); font-weight:500; margin:0 0 18px; }
.man-doc .topico{ margin:0 0 24px; scroll-margin-top:18px; }
.man-doc .topico h3{ font-family:var(--fonte-titulo); font-weight:700; font-size:16px; color:var(--preto); margin:0 0 4px; scroll-margin-top:18px; }
.man-doc .topico h3 .onde{ display:block; font-family:var(--fonte-texto); font-weight:700; font-size:10.5px;
  text-transform:uppercase; letter-spacing:.7px; color:var(--vermelho); margin-bottom:3px; }
.man-doc p{ margin:9px 0; line-height:1.68; }
.man-doc ul{ margin:9px 0; padding-left:0; list-style:none; }
.man-doc li{ position:relative; padding-left:17px; margin:6px 0; line-height:1.6; }
.man-doc li::before{ content:""; position:absolute; left:3px; top:10px; width:4px; height:4px; border-radius:50%; background:var(--vermelho); }
.man-doc em{ font-style:normal; color:var(--vermelho); font-weight:600; }
.man-doc kbd{ font-family:var(--fonte-titulo); font-weight:700; font-size:12px; background:var(--branco);
  border:1px solid var(--cinza-borda); border-bottom-width:2px; border-radius:var(--raio-xs); padding:1px 6px; color:var(--preto); }

.man-doc .callout{ border-radius:var(--raio-sm); padding:12px 16px; margin:13px 0; font-size:13.5px; line-height:1.6;
  background:var(--cinza-fundo); border:1px solid var(--cinza-borda); }
.man-doc .callout .lab{ display:block; font-family:var(--fonte-titulo); font-weight:700; font-size:10.5px;
  text-transform:uppercase; letter-spacing:.8px; margin-bottom:3px; }
.man-doc .dica{ border-left:3px solid var(--preto); }
.man-doc .dica .lab{ color:var(--preto); }
.man-doc .atencao{ background:#fdf1f3; border-color:#f6d4dc; border-left:3px solid var(--vermelho); }
.man-doc .atencao .lab{ color:var(--vermelho); }

.man-doc .grid2{ display:grid; grid-template-columns:1fr 1fr; gap:12px; margin:16px 0; }
.man-doc .perfil{ border:1px solid var(--cinza-borda); border-radius:var(--raio-sm); padding:12px 14px; background:var(--branco); }
.man-doc .perfil h4{ font-family:var(--fonte-titulo); font-size:13.5px; margin:0 0 3px; }
.man-doc .perfil h4 span{ color:var(--vermelho); }
.man-doc .perfil p{ margin:0; font-size:12.5px; color:var(--cinza-medio); }

.man-fim{ text-align:center; color:var(--cinza-medio); font-size:12.5px; border-top:1px solid var(--cinza-borda);
  padding-top:22px; margin-top:10px; }
.man-fim-logo{ height:24px; width:auto; margin-bottom:8px; }

/* Sem espaço para duas colunas, o sumário vira um bloco no topo. */
@media (max-width:900px){
  .man{ grid-template-columns:1fr; gap:22px; }
  .man-toc{ position:static; max-height:none; }
  .man-doc .grid2{ grid-template-columns:1fr; }
  .man-cab h1{ font-size:25px; }
}

/* "Sair" é um <button> dentro de um form (POST com CSRF), mas continua a ter
   de parecer o link que sempre foi, ao lado de Conta e Configurações. */
.sb-sair-form{ display:contents; }
/* ⚠️ `button.sb-conta` tem MAIS especificidade do que `.sb-conta`: aqui só se
   tira a cara de botão. Repor font/padding aqui sobrepunha-se ao estilo do
   link e o "Sair" saía com outro tamanho e outro peso do que os vizinhos. */
/* Só `font-family` é preciso: o navegador impõe Arial aos <button> e isso ganha
   à herança. Tamanho e peso NÃO se declaram aqui: `inherit` puxaria os 16px do
   contentor em vez dos 13px/600 que a regra .sb-conta já dá. */
button.sb-conta{ background:none; border:0; cursor:pointer; text-align:left; width:100%;
  font-family:inherit; }

/* ═══ A reserva vista pelo próprio cliente (página pública com token) ═══
   ⭐ Cancelar é DISCRETO de propósito: fechado, no fim, cor de texto normal.
   Pôr um botão vermelho de cancelar à frente de quem só estava a hesitar é
   ajudar a desistir. Quem quer mesmo, abre e confirma — dois toques. */
.cli-cancelar{ margin-top:26px; border-top:1px solid var(--cinza-borda); padding-top:14px; }
.cli-cancelar summary{
  cursor:pointer; font-size:13.5px; color:var(--cinza-medio);
  list-style:none; display:inline-block; padding:2px 0;
}
.cli-cancelar summary::-webkit-details-marker{ display:none; }
.cli-cancelar summary:hover{ color:var(--texto); text-decoration:underline; }
.cli-cancelar[open] summary{ color:var(--texto); font-weight:600; }

/* ═══ PRODUTOS — catálogo à esquerda, edição ao lado ═══
   Editar num painel lateral (e não noutra página) porque quem corrige preço
   corrige vários seguidos: mudar de página a cada um faz perder o lugar na
   lista. Abaixo de 1000px o painel vai para cima, que é onde a mão chega. */
.prod-layout{ display:grid; grid-template-columns:minmax(0,1fr); gap:18px; align-items:start; }
.prod-layout:has(.prod-painel){ grid-template-columns:minmax(0,1.6fr) minmax(320px,1fr); }
/* 🚨 21/08/2026, ELE: *"quando eu clico em editar e rolo pra baixo, não vai até
   o fim na janela de editar o produto, só vai até aí."*

   A causa é o `sticky` sem teto. Um elemento grudado que é MAIS ALTO que a tela
   prende o topo dele nos 16px e nunca mais sobe — então o fundo do painel fica
   permanentemente abaixo da janela, e rolar a página não o alcança. Quanto mais
   campos o produto tem, mais fundo fica escondido: os últimos (mínimo em
   estoque, repor até) eram inalcançáveis.
   ⭐ O conserto é dar-lhe um teto e barra própria: fica grudado enquanto cabe, e
   rola por dentro quando não cabe.
   ⚠️ `100dvh` e não `100vh`: no celular a barra do navegador aparece e some, e
   com `vh` o fim do painel some junto com ela. */
.prod-painel{
  background:var(--branco); border:1px solid var(--cinza-borda);
  border-radius:var(--raio); box-shadow:var(--sombra); padding:18px 20px;
  position:sticky; top:16px;
  max-height:calc(100dvh - 32px); overflow-y:auto;
  /* a barra só aparece quando é precisa, e sem saltar o conteúdo de lado */
  scrollbar-gutter:stable;
}
.prod-fichas{ list-style:none; padding:0; margin:8px 0 0; font-size:13.5px; }
.prod-fichas li{ padding:4px 0; border-bottom:1px dashed var(--cinza-borda); }
.prod-fichas li:last-child{ border-bottom:0; }
.prod-desativar{ margin-top:22px; padding-top:14px; border-top:1px solid var(--cinza-borda);
  display:flex; gap:10px; align-items:center; flex-wrap:wrap; }
/* ⭐ TROCAR O PRODUTO EM TODAS AS FICHAS (26/08/2026). Mora colada à lista das
   fichas de propósito: a pergunta *"e agora, como mudo isto nas doze?"* nasce
   ao ler a lista, e a resposta tem de estar onde a pergunta nasce. */
/* ⚠️ `display:contents` e não `inline-flex`: o grupo existe para se poder
   esconder de uma vez, mas os filhos têm de continuar a ser itens do flex da
   barra — envolvê-los numa caixa própria fazia-os deixar de quebrar linha com
   os irmãos e a barra passava a transbordar em vez de embrulhar. */
.barra-sel-grupo{ display:contents; }
.barra-sel-grupo[hidden]{ display:none; }
.prod-subst{ margin-top:14px; padding-top:12px; border-top:1px dashed var(--cinza-borda); }
.prod-subst .campo{ margin-bottom:10px; }
/* ⚠️ A tela de consequências é um BLOCO, não um parágrafo solto: o que ela diz
   decide se ele carrega ou não, e texto sem moldura lê-se como comentário. */
.prod-subst-previa{
  margin-top:14px; padding:14px; border-radius:var(--raio-sm);
  border:1.5px solid var(--preto); background:var(--cinza-claro, #f0f0f2);
}
.prod-subst-previa h4{ margin:0 0 8px; }
.prod-subst-previa p{ margin:0 0 8px; font-size:14px; }
/* ⚠️ `.pill-inativo` estava definido DUAS vezes, igual, a 2.500 linhas de
   distância. Fica a de cima, junto das irmãs. */
@media (max-width:1000px){
  .prod-layout:has(.prod-painel){ grid-template-columns:minmax(0,1fr); }
  /* ⚠️ Aqui ele deixa de ser grudado, logo o teto tem de sair com ele: um
     painel estático com `max-height` criaria uma segunda barra de rolagem
     dentro da página, que é pior do que o defeito que se veio consertar. */
  .prod-painel{ position:static; order:-1; max-height:none; overflow:visible; }
}

/* ============================================================
   FECHO — mudar a data, e o aviso da data na confirmação
   ============================================================ */
/* ⚠️ Escondido atrás de um <details>: mudar a data de um fecho arrasta o Diário
   do dia atrás dele. Tem de estar à mão de quem precisa, sem ser um botão que
   se carrega por engano ao lado do Guardar. */
.fecho-mover{ margin:0 0 18px; }
.fecho-mover > summary{
  display:inline-block; cursor:pointer; font-size:13px; font-weight:600;
  color:var(--cinza-medio); background:var(--branco); border:1px solid var(--cinza-borda);
  padding:7px 14px; border-radius:999px; list-style:none;
}
.fecho-mover > summary::-webkit-details-marker{ display:none; }
.fecho-mover > summary:hover{ color:var(--vermelho); border-color:var(--vermelho); }
.fecho-mover[open] > summary{ margin-bottom:12px; }
.fecho-mover-form{
  display:flex; gap:10px; align-items:center; flex-wrap:wrap;
  background:var(--branco); border:1px solid var(--cinza-borda); border-radius:var(--raio);
  padding:14px 16px; box-shadow:var(--sombra);
}
.fecho-mover-form label{ font-size:13px; font-weight:600; }
.fecho-mover .ajuda{ margin-top:8px; }

/* APAGAR O FECHO: só o botão, à altura do "A data está errada?" que vem antes.
   Sem gaveta e sem texto — o aviso do que leva consigo está na tela da senha. */
.fecho-apagar{ margin:0 0 18px; }

/* A DATA no diálogo de confirmação: é o engano mais fácil desta tela. */
.dlg-data{
  display:flex; align-items:baseline; gap:10px; flex-wrap:wrap;
  background:var(--cinza-fundo); border-radius:var(--raio-sm);
  padding:10px 14px; margin:0 0 12px;
}
.dlg-data-rot{ font-size:13px; color:var(--cinza-medio); }
.dlg-data strong{ font-family:var(--fonte-titulo); font-weight:700; font-size:20px; letter-spacing:-.3px; }
.dlg-data-dia{ font-size:12.5px; color:var(--cinza-medio); }

/* Atalho entre telas irmãs (Diário ↔ Resumo do mês). O par fica na mesma linha
   do "voltar": é navegação lateral, não uma ação da tela. */
.atalho-par{ display:flex; gap:10px; align-items:center; flex-wrap:wrap; }
.voltar-ir{ margin-left:auto; }
@media (max-width:600px){ .voltar-ir{ margin-left:0; } }

/* A taxa aponta para a venda que a gerou. Discreta: é rasto, não ação. */
.lanc-taxa-de{ display:block; color:var(--cinza-medio); text-decoration:none; }
.lanc-taxa-de:hover{ color:var(--vermelho); text-decoration:underline; }
.rec-taxa{ margin-top:4px; }

/* Remover a linha de retirada, antes de gravar o fecho. Discreto e do tamanho
   do dedo: fica ao lado de campos que se preenchem com pressa. */
.ret-remover{
  border:1px solid var(--cinza-borda); background:var(--branco); color:var(--cinza-medio);
  width:34px; height:34px; border-radius:var(--raio-sm); font-size:17px; line-height:1; cursor:pointer;
  flex:0 0 auto; transition:color .15s, border-color .15s;
}
.ret-remover:hover{ color:var(--vermelho); border-color:var(--vermelho); }

/* ============================================================
   SELEÇÃO EM LOTE no Diário
   ============================================================ */
.col-sel{ width:34px; text-align:center; padding-right:0 !important; }
.col-sel input[type=checkbox]{ width:17px; height:17px; margin:0; cursor:pointer; }
/* ⭐ A ÁREA DE TOQUE DA CAIXA (24/08/2026), medida a 375px na lista de fichas:
   17×17px é metade do que um dedo acerta com confiança.
   ⚠️ Cresce a ÁREA e não o desenho — a mesma decisão do `?` das dicas, que tem
   15px de círculo e 44 de alvo: caixas de 44px numa lista de 177 linhas viravam
   uma parede de quadrados.
   ⭐ E a régua é `pointer:coarse`, não largura de tela: quem tem rato acerta os
   17px; num tablet grande com dedo, não. A pergunta é o dedo.
   ⚠️ A margem negativa devolve ao layout o espaço que o alvo tomou, para a
   linha não engordar por causa de uma área que ninguém vê. */
.alvo-toque{ display:inline-flex; align-items:center; justify-content:center; cursor:pointer; }
@media (pointer:coarse){
  .alvo-toque{ min-width:44px; min-height:44px; margin:-13px; }
}
/* ⚠️ Em cartão (telemóvel) a caixa não faz sentido sozinha numa "célula": passa
   a canto superior da linha, junto do dia.
   🐞 O ponto era 820px e os cartões só nascem aos 600: entre os dois, a regra
   mexia na TABELA normal e a coluna da caixa perdia a largura e a centragem
   (auditoria 13/08). O ponto tem de ser o mesmo em que a tabela vira cartão. */
@media (max-width:600px){
  .tabela-cards .col-sel{ width:auto; text-align:left; }
}
/* ⭐ 21/08/2026, ELE: *"Essa janela que aparece quando selecionamos algum item,
   tanto aqui quanto no financeiro, e seja lá onde mais tiver. Ela fica muito
   ruim de ver com o verde de fundo."*

   Era a cor do menu (escura) com texto branco. Numa barra que flutua por cima de
   uma tela clara, isso é um bloco escuro no meio do caminho — e o que está
   dentro dela (um seletor branco, botões com contorno) fica com contraste
   trocado: o formulário claro brilha e o texto some.

   ⭐ Passa a ser a MESMA LINGUAGEM DOS CARTÕES do sistema: fundo branco, borda
   fina e sombra. É o que já está na caixa dos filtros e nos cartões do painel.
   ⚠️ Ele disse "a mesma cor do fundo do sistema" — e o fundo é cinza. Uma barra
   cinza por cima de uma tela cinza desaparece, que é o oposto do pedido. Branco
   sobre o cinza da página é o mesmo par que a casa usa em todo o lado, e é o que
   se lê melhor. Se preferir o cinza mesmo, é uma linha.
   ⚠️ Uma barra é uma barra em todo o sistema: esta regra vale no Operacional, no
   Financeiro e onde mais aparecer — por isso não há cor por tela. */
/* 🐞 A BARRA PARTIA-SE AO MEIO SEM PRECISAR (24/08/2026, visto na tela das
   fichas com seis controlos).
   🚨 Sendo `fixed` com `left:50%` e SEM `right`, o espaço que o navegador lhe
   dá para encolher é da metade da tela até à borda direita — 640px num ecrã de
   1280 —, e o `max-width` de baixo não o corrige: ele é um TETO, não um chão. A
   barra quebrava em duas linhas com 900px de conteúdo e 1244px disponíveis, e
   tapava a lista por trás.
   ⭐ `width:max-content` pede a largura do conteúdo, e o `max-width` continua a
   segurá-la no telemóvel — onde quebrar em duas linhas é o que se quer. */
.barra-sel{
  position:fixed; left:50%; transform:translateX(-50%); bottom:22px; z-index:60;
  display:flex; align-items:center; gap:14px; flex-wrap:wrap;
  background:var(--branco); color:var(--texto);
  border:1px solid var(--cinza-borda);
  padding:12px 18px; border-radius:999px; box-shadow:0 18px 46px rgba(17,17,17,.16);
  width:max-content; max-width:calc(100% - 36px);
}
.barra-sel[hidden]{ display:none; }
/* 🚨 O BALÃO DA AJUDA SAI DA FRENTE ENQUANTO HÁ SELEÇÃO (26/08/2026).
   Os dois são `position:fixed` no mesmo canto e no MESMO `z-index:60` — quem
   fica por cima decide-se pela ordem no documento, que ninguém escolheu.
   ⚠️ Medido no browser, e já era assim antes de hoje: a 375px a barra chega a
   x=357 e o `.ajuda-fab` começa em 305, logo o "?" desenhava-se **em cima** da
   pílula branca. Hoje passou a tapar um controlo: o `Apagar de vez…` acaba em
   1210 e o balão começa em 1202 — 8px de um botão que apaga catálogo.
   ⭐ Esconder é a resposta certa e não um remendo: a barra é um MODO, dura o
   tempo da seleção, e a ajuda volta sozinha no gesto seguinte. Levantar o balão
   por cima dela precisaria da altura da barra, que muda com a quebra de linha
   (75px a 1280, 207px a 375) — uma conta que fica errada no primeiro botão novo.
   ⚠️ Alcance MEDIDO, não estimado: `.barra-sel` existe em três telas — fichas,
   produtos e lançamentos — e o balão vem do parcial global `ajuda.php`. */
body:has(.barra-sel:not([hidden])) .ajuda-fab{ display:none; }
/* 🐞 E NASCIA MEIO DEBAIXO DO MENU (mesma tela, mesmo dia).
   Ela centrava-se na JANELA e não na ÁREA DE CONTEÚDO: com o menu de 230px à
   esquerda, o seu começo ficava por trás dele. Numa barra curta ninguém
   reparava; na das fichas, com seis controlos, o "2" de "2 marcadas" sumia.
   ⭐ O centro passa a ser o do conteúdo — como já acontece com o `.conteudo` e o
   `.rodape-dext`, e pelo mesmo `:has` que a casa já usa em 21 sítios.
   🚨 E VIVE AQUI, a seguir ao componente, não lá em cima com os irmãos: escrito
   antes da definição de `.barra-sel`, perdia para ela na cascata (mesma
   especificidade, quem vem depois ganha) e não fazia nada — o que é pior do que
   não existir, porque parece feito.
   ⚠️ Só a partir de 821px: abaixo disso o menu é uma barra no topo, não há
   coluna à esquerda, e centrar na janela é o certo. */
@media (min-width:821px){
  .barra-sel{ left:calc(50% + 115px); }
  body:has(.sidebar.sb-min) .barra-sel{ left:calc(50% + 35px); }
}
.barra-sel-txt{ font-size:14px; color:var(--cinza-medio); }
.barra-sel-txt strong{ font-size:16px; color:var(--texto); }
/* ⚠️ Os links deixam de ser a cor de destaque do menu escuro: em fundo claro
   ela quase não se via. Passam à cor de marca, como todo o link da casa. */
.barra-sel .btn-link{ color:var(--vermelho); }
.barra-sel .btn{ padding:8px 16px; }
/* ⚠️ O seletor dentro da barra deixa de ser uma mancha branca sobre escuro. */
.barra-sel select{ background:var(--branco); border:1px solid var(--cinza-borda); }

/* Rateio da despesa dentro do formulário do Diário. Fechado por omissão: quem
   lança uma despesa simples não pode tropeçar em duas grelhas. */
.rateio{ margin:6px 0 16px; }
.rateio > summary{ cursor:pointer; font-size:13.5px; font-weight:600; color:var(--vermelho); }
.rateio[open] > summary{ margin-bottom:8px; }
.rateio .secao-titulo{ font-size:14px; margin:14px 0 8px; }
.rateio .fatura-total{ font-size:13px; color:var(--cinza-medio); margin-top:6px; }

/* Dividir a retirada do fecho por categorias e contas. O botão é discreto: a
   esmagadora maioria das retiradas é uma categoria e o caixa. */
.ret-dividir{
  border:1px solid var(--cinza-borda); background:var(--branco); color:var(--cinza-medio);
  padding:7px 12px; border-radius:var(--raio-sm); font-size:12.5px; font-weight:600; cursor:pointer;
  white-space:nowrap; transition:color .15s, border-color .15s;
}
.ret-dividir:hover{ color:var(--vermelho); border-color:var(--vermelho); }
/* Linha já dividida: o valor passa a ser a soma dos itens, e vê-se que é. */
.retirada-linha.linha-dividida .ret-dividir{ color:var(--vermelho); border-color:var(--vermelho); }
.retirada-linha.linha-dividida input[name="ret_valor[]"]{ background:var(--cinza-fundo); }
#dlg-ret-dividir{ max-width:640px; width:calc(100% - 32px); }
#dlg-ret-dividir .secao-titulo{ font-size:14px; margin:14px 0 8px; }
#dlg-ret-dividir .fatura-total{ font-size:13px; color:var(--cinza-medio); margin-top:6px; }

/* ============================================================
   FILTROS do Diário
   ============================================================ */
/* Recolhidos por omissão: um painel sempre aberto rouba o ecrã à lista, que é
   o que se veio ver. Abre-se sozinho quando há algum filtro ligado. */
.filtros{ margin:18px 0 0; }
.filtros > summary{
  display:inline-flex; align-items:center; gap:8px; cursor:pointer; list-style:none;
  font-size:13px; font-weight:600; color:var(--cinza-medio);
  background:var(--branco); border:1px solid var(--cinza-borda);
  padding:8px 15px; border-radius:999px; box-shadow:0 2px 8px rgba(17,17,17,.05);
}
.filtros > summary::-webkit-details-marker{ display:none; }
.filtros > summary:hover{ color:var(--vermelho); border-color:var(--vermelho); }
.filtros[open] > summary{ color:var(--vermelho); border-color:var(--vermelho); margin-bottom:12px; }
.filtros-selo{
  background:var(--vermelho); color:var(--branco); border-radius:999px;
  padding:1px 8px; font-size:11.5px; font-weight:700;
}
.filtros-form{
  display:grid; grid-template-columns:repeat(auto-fit,minmax(180px,1fr)); gap:12px 14px;
  background:var(--branco); border:1px solid var(--cinza-borda); border-radius:var(--raio);
  padding:18px 20px; box-shadow:var(--sombra); align-items:start;
}
/* ⚠️ `align-items:start` e não `end`: um campo com linha de ajuda é mais alto
   que os outros, e alinhado ao fundo empurrava a etiqueta dele para cima,
   fazendo a fila parecer desalinhada. */
/* 🚨 21/08/2026 — CAMPO EM CIMA DO OUTRO (ele: *"Arruma o filtro, tem campo em
   cima do outro"*). A Categoria tapava a Conta.
   ⚠️ **A causa não é a grelha, é o `min-width` implícito.** Um item de grid tem
   `min-width:auto`, o que quer dizer *"não encolho abaixo do meu conteúdo"*. O
   select da Categoria tem nomes de grupo e de categoria longos, portanto o seu
   min-content é muito maior que os 180px da coluna — e em vez de encolher,
   transborda POR CIMA do vizinho. Os outros campos não dão nisto porque o
   conteúdo deles é curto: o defeito só aparece na base de quem tem 41
   categorias, e é por isso que passou aqui despercebido.
   ⭐ `min-width:0` devolve à coluna o direito de mandar; o `max-width` nos
   controlos garante que nenhum filho volta a esticar a caixa. */
.filtros-form .campo{ margin:0; min-width:0; }
.filtros-form .campo > select,
.filtros-form .campo > input,
.filtros-form .campo > .ajuda{ max-width:100%; }
.filtros-form .campo > select,
.filtros-form .campo > input{ width:100%; box-sizing:border-box; }
/* ⚠️ E o texto de ajuda quebra em vez de esticar a coluna. */
.filtros-form .campo > .ajuda{ overflow-wrap:anywhere; }
.filtros-acoes{ display:flex; gap:12px; align-items:center; }
/* O que ficou à vista, somado: filtrar por uma categoria responde "quais", e a
   pergunta seguinte é sempre "quanto". */
.filtros-resumo{
  display:flex; gap:18px; flex-wrap:wrap; align-items:baseline;
  margin:14px 0 0; padding:12px 18px;
  background:var(--cinza-fundo); border-radius:var(--raio-sm); font-size:14px;
}
@media (max-width:600px){ .filtros-form{ grid-template-columns:1fr; } }

/* ============================================================
   CONFIGURAÇÕES — listas com altura e o × dentro do cartão
   ============================================================ */
/* ⭐ Pedido dele (03/08): "quero que as outras tabelas fiquem igual essa de
   categorias, com a barra de descer e subir, assim não fica tão grande".
   Uma lista de 41 categorias ou de 8 contas não pode esticar o cartão até ao
   infinito: com todas à mesma altura, o ecrã fica previsível e comparável. */
.cfg-lista{
  max-height:300px; overflow-y:auto; overflow-x:hidden;
  margin:0 -4px 10px; padding:0 4px;
  /* a barra só aparece quando é precisa, e sem saltar o conteúdo de lado */
  scrollbar-gutter:stable;
}
.cfg-lista-alta{ max-height:520px; }
/* ⚠️ Sombra de continuação: sem ela, uma lista cortada a meio parece uma lista
   que acabou, e ninguém procura o que está por baixo. No macOS a barra de
   scroll só aparece ao rolar, portanto não serve de pista.
   ⚠️ Feita com o truque do `background-attachment` e NÃO com um `mask` que
   esbate o fundo: o mask apagava a última linha mesmo numa lista curta, que não
   tem nada por baixo. Aqui as duas camadas `local` viajam com o conteúdo e
   tapam as `scroll`, portanto a sombra só se vê quando há mesmo mais lista. */
.cfg-lista{
  background:
    linear-gradient(var(--branco) 30%, rgba(255,255,255,0)) top    / 100% 14px no-repeat local,
    linear-gradient(rgba(255,255,255,0), var(--branco) 70%) bottom / 100% 14px no-repeat local,
    radial-gradient(farthest-side at 50% 0,    rgba(17,17,17,.09), transparent) top    / 100% 7px no-repeat scroll,
    radial-gradient(farthest-side at 50% 100%, rgba(17,17,17,.09), transparent) bottom / 100% 7px no-repeat scroll;
}

/* 🔴 O × SAÍA PARA FORA DO CARTÃO. A `mini-tab` é `auto`: a primeira coluna
   crescia com o formulário lá dentro (nome + tipo + duas caixas + salvar), a do
   saldo tem `nowrap`, e a soma passava a largura do cartão, empurrando a coluna
   das ações para fora. `table-layout:fixed` inverte a lógica — as colunas têm a
   largura que se lhes dá e o conteúdo é que se arruma dentro. */
/* ⚠️ SÓ dentro de `.cfg-lista`, e isto é o essencial da regra. À primeira
   tentativa isto estava em `.resumo-card .mini-tab`, e o `.resumo-card` é o
   cartão de TODO o sistema: o Resumo do mês, as Perdas e a ficha usam-no
   também. Resultado, no ecrã dele: os saldos por conta cortados à direita e o
   "€2.773,44" a cair um algarismo por linha, porque com `table-layout:fixed`
   sem larguras as colunas repartem-se por igual e o `anywhere` parte o número.
   A lista de configuração é a única que precisa disto, e é a única que leva. */
.cfg-lista .mini-tab{ table-layout:fixed; width:100%; }
.cfg-lista .mini-tab td{ overflow-wrap:anywhere; }
.cfg-lista .mini-tab td.v{ width:84px; }
.cfg-lista .mini-tab tr > td:last-child{ width:24px; padding-left:6px; }
.cfg-linha{ min-width:0; }
.cfg-linha input[type=text], .cfg-linha select, .cfg-linha .campo-moeda{ max-width:100%; }

/* ⭐ PESO DA LETRA DO DIÁRIO (ele, 05/08/2026: "ter como configurar a fonte dos
   lançamentos no financeiro, mais bold"). Configurável em Financeiro →
   Configurações → Regras, porque conforto de leitura depende do ecrã e da vista
   de cada um. Só o CORPO da tabela muda: o cabeçalho e os totais já têm o peso
   deles, e subi-los junto tirava a hierarquia que faz a tabela ler-se. */
.tabela.lanc-peso-medio tbody td{ font-weight:500; }
.tabela.lanc-peso-forte tbody td{ font-weight:600; }
/* ⚠️ A segunda linha da célula (categoria, forma, selos) fica um degrau ATRÁS,
   senão a linha inteira vira negrito e deixa de haver primeiro plano. */
.tabela.lanc-peso-medio tbody td .lanc-sub{ font-weight:400; }
.tabela.lanc-peso-forte tbody td .lanc-sub{ font-weight:500; }

/* ⭐ Os DOIS saldos de uma transferência (ele, 05/08/2026). Empilhados, cada um
   com o nome da conta à esquerda em cinzento: a coluna é estreita e o número
   tem de continuar a ser o que salta à vista. */
.saldo-par{ display:flex; flex-direction:column; gap:2px; align-items:flex-end; }
.saldo-par > span{ display:flex; gap:6px; align-items:baseline; justify-content:flex-end; white-space:nowrap; }
.saldo-conta{ color:var(--cinza-medio); font-size:11.5px; font-weight:500; }
/* % dedutível do IVA na linha da categoria: pequeno, encostado ao resto */
.cfg-pct{ display:inline-flex; align-items:center; gap:4px; font-size:12px; color:var(--cinza-medio); }
.cfg-pct input{ width:58px; text-align:right; }

/* ⭐ Data da conciliação, debaixo do tique ✓ (ele, 05/08/2026: "de forma sutil").
   Pequena e cinzenta: quem lê a linha quer o valor, não a data do extrato; ela
   está ali para quando se procura por ela. Clicar abre o campo para corrigir. */
.conf-data{ display:inline-block; vertical-align:middle; margin-left:2px; position:relative; }
.conf-data > summary{ list-style:none; cursor:pointer; font-size:10.5px; color:var(--cinza-medio);
  line-height:1; padding:1px 3px; border-radius:var(--raio-xs); }
.conf-data > summary::-webkit-details-marker{ display:none; }
.conf-data > summary:hover{ color:var(--preto); background:var(--cinza-fundo); }
.conf-data[open] > summary{ color:var(--preto); }
/* O campo abre POR CIMA da tabela, não dentro da célula: a coluna é estreita e
   empurrar a linha inteira para baixo movia tudo o que ele estava a ler. */
.conf-data-form{ position:absolute; right:0; top:100%; z-index:30; display:flex; gap:6px; align-items:center;
  background:var(--branco); border:1px solid var(--cinza-borda); border-radius:var(--raio-sm);
  padding:8px; box-shadow:0 6px 20px rgba(0,0,0,.12); }
.conf-data-form input[type=date]{ font-size:12.5px; padding:5px 7px; border:1px solid var(--cinza-borda);
  border-radius:var(--raio-sm); }
/* prefixo dos atalhos, escrito conforme o computador (⌥⇧ no Mac) */
.atalhos-como{ margin:6px 0 10px; font-size:12.5px; color:var(--cinza-medio); }
.atalhos-caixa kbd .dext-mod, .atalhos-caixa kbd .dext-ctrl{ font:inherit; }
/* soma das linhas marcadas, na barra da seleção */
.barra-sel-soma{ font-weight:700; font-variant-numeric:tabular-nums; margin-left:10px; }
.barra-sel-nota{ font-size:12px; color:var(--cinza-medio); margin-left:8px; }
/* conciliar saldo: o botão discreto no cartão da conta e a prévia da diferença */
.fecho-kpi .conc-abrir{ font-size:11.5px; padding:0; margin-top:2px; align-self:flex-start; }
.conc-previa{ margin:2px 0 10px; font-size:13px; font-weight:600; }
.conc-previa.ok{ color:var(--cinza-medio); font-weight:500; }

/* ═══════════ RELATÓRIOS GERENCIAIS (ecrã) ═══════════
   ⚠️ As classes são as MESMAS da folha A4 (app/Views/relatorios/imprimir.php),
   porque o corpo do relatório é um ficheiro só, servido aos dois. Mexer numa
   sem olhar à outra é como o papel começa a sair diferente do ecrã. */
.rel-periodo { display: flex; gap: 12px; align-items: flex-end; flex-wrap: wrap; margin-bottom: 20px; }
.rel-periodo .campo { margin: 0; }
.rel-corpo { background: var(--branco, #fff); border: 1px solid var(--cinza-borda, #e4e4e7);
             border-radius: var(--raio-sm); padding: 22px 24px; }
.rel-secao { font-size: 1.05rem; font-weight: 700; margin: 26px 0 10px; padding-bottom: 6px;
             border-bottom: 1px solid var(--cinza-borda, #e4e4e7); }
.rel-corpo > .rel-secao:first-child { margin-top: 0; }
.rel-secao span { display: inline-block; min-width: 22px; color: var(--vermelho, #e81840); }
.rel-sub { font-size: .92rem; font-weight: 600; margin: 18px 0 6px; }
.rel-kpis { display: flex; flex-wrap: wrap; gap: 0; border: 1px solid var(--cinza-borda, #e4e4e7);
            border-radius: var(--raio-sm); margin: 12px 0 14px; }
.rel-kpi { flex: 1 1 150px; padding: 11px 14px; border-right: 1px solid var(--cinza-borda, #e4e4e7); }
.rel-kpi:last-child { border-right: none; }
.rel-kpi span { display: block; font-size: .68rem; letter-spacing: .08em; text-transform: uppercase;
                color: var(--cinza-medio, #71717a); }
.rel-kpi strong { font-size: 1.25rem; }
.rel-tab { width: 100%; border-collapse: collapse; margin: 8px 0 6px; font-size: .86rem; }
.rel-tab th { background: var(--preto, #111); color: #fff; font-weight: 600; text-align: left;
              padding: 7px 10px; font-size: .72rem; letter-spacing: .03em; }
.rel-tab td { padding: 6px 10px; border-bottom: 1px solid var(--cinza-borda, #e4e4e7); }
.rel-num { text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
.rel-dre-forte td { font-weight: 700; background: var(--cinza-fundo, #fafafa); }
.rel-dre-grupo td { font-weight: 700; color: var(--vermelho, #e81840); font-size: .72rem;
                    text-transform: uppercase; letter-spacing: .05em; padding-top: 12px; }
.rel-vazio { color: var(--cinza-medio, #71717a); font-style: italic; }
.rel-nota { font-size: .76rem; color: var(--cinza-medio, #71717a); margin: 2px 0 10px; font-style: italic; }
.rel-linha-texto { margin: 8px 0; }
.rel-aviso { border-left: 3px solid var(--vermelho, #e81840); background: var(--cinza-fundo, #fafafa);
             padding: 9px 12px; margin: 8px 0; font-size: .87rem; border-radius: 0 4px 4px 0; }
.rel-aviso-perigo { border-left-color: #b91c1c; }
/* o que ainda não existe diz-se, em vez de parecer um link partido */
.sub-nav-embreve { font-size: 13px; font-weight: 600; color: var(--cinza-medio, #a1a1aa);
                   padding: 6px 12px; border: 1px dashed var(--cinza-borda, #e4e4e7); border-radius: 999px; }
/* a tabela larga do relatório rola sozinha no telemóvel, sem partir a página */
@media (max-width: 640px) { .rel-corpo { padding: 16px 12px; } .rel-tab { font-size: .8rem; } }

/* ═══════════ GESTOR · processos (POPs) ═══════════ */
.pro-setores { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-bottom: 6px; }
.pro-setor { display: flex; gap: 4px; align-items: center; }
.pro-setor input { width: 150px; padding: 6px 9px; font-size: .86rem; }
.pro-setor-x { display: flex; margin-left: -6px; }
.pro-setor-novo input { border-style: dashed; }
/* o editor ao lado da pré-visualização: é para se ver o efeito ao escrever */
.pro-editor-cols { display: flex; gap: 22px; align-items: flex-start; }
.pro-editor-form { flex: 1 1 520px; min-width: 0; }
.pro-previa { flex: 0 0 290px; position: sticky; top: 16px; }
.pro-previa-tel { border: 1px solid var(--cinza-borda, #e4e4e7); border-radius:var(--raio);
                  background: var(--branco, #fff); padding: 14px; min-height: 220px; }
.pro-previa-topo { border-bottom: 1px solid var(--cinza-borda, #e4e4e7); padding-bottom: 8px; margin-bottom: 10px; }
.pro-previa-topo strong { display: block; font-size: .95rem; }
.pv-item { border-bottom: 1px solid var(--cinza-fundo, #f4f4f5); padding: 9px 0; }
.pv-item:last-child { border-bottom: none; }
.pv-item-t { font-size: .88rem; font-weight: 600; }
.pv-obrig { color: var(--vermelho, #e81840); margin-left: 3px; }
.pv-item-r { font-size: .76rem; color: var(--cinza-medio, #71717a); margin-top: 2px; }
.pv-foto { font-size: .72rem; color: var(--cinza-medio, #71717a); margin-top: 3px; }
/* os itens do editor */
.pro-itens { display: flex; flex-direction: column; gap: 8px; }
.pro-item { display: flex; gap: 8px; align-items: flex-start; padding: 10px;
            border: 1px solid var(--cinza-borda, #e4e4e7); border-radius: var(--raio-sm);
            background: var(--branco, #fff); }
.pro-item.a-arrastar { opacity: .45; }
.pro-arrasta { cursor: grab; color: var(--cinza-medio, #a1a1aa); font-size: 1.05rem; line-height: 1.6; user-select: none; }
.pro-item-corpo { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 6px; }
.pro-item-corpo input[type=text] { width: 100%; }
.pro-item-opcoes { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; font-size: .78rem; }
.pro-item-opcoes input[type=number] { width: 62px; }
.pro-item-opcoes .js-l { flex: 1 1 160px; min-width: 120px; }
.pro-chk { display: inline-flex; gap: 4px; align-items: center; }
.pro-item-acoes { display: flex; flex-direction: column; gap: 2px; }
.pro-janela { border: 1px solid var(--cinza-borda, #e4e4e7); border-radius: var(--raio-sm);
              padding: 10px 14px 4px; margin-top: 10px; }
.pro-janela legend { font-size: .78rem; font-weight: 700; text-transform: uppercase; letter-spacing: .05em;
                     color: var(--cinza-medio, #71717a); padding: 0 6px; }
/* no telemóvel a pré-visualização vai para baixo: o editor precisa da largura */
@media (max-width: 900px) {
  .pro-editor-cols { flex-direction: column; }
  .pro-previa { flex: 1 1 auto; position: static; width: 100%; max-width: 340px; }
}

/* ═══════════ AGENDA · quem veio sem reserva ═══════════
   ⭐ Em GRELHA e não em coluna (ele, 06/08/2026): onze grupos numa lista
   vertical empurravam o resto da página para muito longe. Os cartões são os
   MESMOS das reservas (.reserva-card), só que dispostos lado a lado.
   ⚠️ `auto-fill` com mínimo de 300px: em ecrã largo dá três ou quatro colunas,
   no telemóvel cai sozinho para uma, sem breakpoint escrito à mão. */
.agenda-grade { display: grid; gap: 10px; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); }
.agenda-grade .reserva-hora { min-width: 48px; font-size: 17px; padding-right: 12px; }
.agenda-grade .reserva-card { padding: 12px 14px; }
.agenda-acoes-av { display: flex; gap: 6px; margin-top: 4px; }

/* ── TEXTO COM FORMATO (06/08/2026 · faixa em 21/08/2026) ──
   A barra vive COLADA ao campo, e não flutuando por cima: um textarea que muda
   de altura com o conteúdo levava a barra a saltar. Ver Core/Texto.php.

   ⚠️ **UMA FAIXA, e não botões soltos com borda cada um** — foi o pedido dele
   ao ver o TickTick. Por isso a borda é da faixa e os botões, por dentro, não
   têm nenhuma. Os grupos separam-se por um fio (`.txt-sep`), que é o que faz
   "título", "texto", "blocos" e "resto" lerem-se como quatro coisas.

   ⚠️ **O PADRÃO É QUEBRAR, e não rolar.** Medido a 21/08: o `body` do sistema é
   um flex, a faixa tem 471px de largura mínima, e num celular de 375 ela
   empurrava a COLUNA INTEIRA para 515px — o `overflow-x` sozinho não segura
   nada, porque quem cresce é o ancestral, não ela. Quebrar em duas linhas é
   feio; empurrar a tela de lado é pior. */
.txt-barra{
  display:flex; flex-wrap:wrap; align-items:center; gap:1px;
  padding:3px 4px; margin-bottom:-1px; min-width:0; max-width:100%;
  border:1px solid var(--cinza-borda); border-bottom:none;
  border-radius:var(--raio-sm) var(--raio-sm) 0 0;
  background:var(--branco);
}
/* ⭐ Onde há `contain`, a faixa volta a ser UMA linha que rola de lado — que é
   o desenho certo: uma barra que muda de altura empurra o campo para baixo a
   cada rotação da tela, e o dedo já está na altura errada quando isso acontece.
   `inline-size` é o que faz a largura dela deixar de contar para o ancestral.
   Safari 15.4+ e Chrome 105+; abaixo disso fica a quebra de linha acima. */
@supports (contain: inline-size) {
  .txt-barra{ flex-wrap:nowrap; overflow-x:auto; contain:inline-size; scrollbar-width:none; }
  /* ⚠️ A barra de rolagem fica escondida de propósito: um fio cinzento debaixo
     dos botões lê-se como uma linha de separação e não como "há mais coisa aqui".
     O que diz que há mais é o ícone cortado na borda, que é como o dedo aprende. */
  .txt-barra::-webkit-scrollbar{ display:none; }
}
.txt-btn{
  border:none; border-radius:var(--raio-sm); background:transparent; cursor:pointer;
  min-width:30px; height:26px; padding:0 5px; flex:0 0 auto;
  display:inline-flex; align-items:center; justify-content:center;
  font-size:13px; line-height:1; color:var(--cinza-medio);
}
.txt-btn:hover{ color:var(--preto); background:var(--cinza-claro); }
.txt-btn:focus-visible{ outline:2px solid var(--vermelho); outline-offset:-2px; }
.txt-btn svg{ display:block; }
.txt-btn sub{ font-size:9px; vertical-align:baseline; }
.txt-sep{
  flex:0 0 auto; width:1px; height:16px; margin:0 4px;
  background:var(--cinza-borda);
}
.txt-barra + textarea{ border-top-left-radius:0; border-top-right-radius:0; }
.txt-dica{ margin-top:4px; font-size:11.5px; }

/* ── A DICA RECOLHIDA (21/08/2026) ──
   O texto de ajuda de um campo passa a viver atrás de um "?" ao lado do rótulo.
   Pedido dele: *"acho muito texto (…) que apareça quando ficar com o mouse em
   cima"*. Ver `assets/js/dica.js`, onde está escrito o critério do que recolhe.

   ⚠️ O ESCONDER É DO JAVASCRIPT, não daqui: `.dica-oculta` só existe depois de
   o script correr. Se ele falhar, o texto fica à vista, como sempre esteve —
   uma dica escondida por CSS num sistema sem JS seria uma dica perdida. */
.dica-oculta{
  position:absolute; width:1px; height:1px; overflow:hidden;
  clip-path:inset(50%); white-space:nowrap;
}
/* ⚠️ Um círculo pequeno e cinzento, colado ao rótulo: tem de se ver que há mais
   para saber, sem competir com o nome do campo. */
.dica-btn{
  appearance:none; -webkit-appearance:none;
  margin-left:6px; width:15px; height:15px; padding:0; vertical-align:middle;
  border:1px solid var(--cinza-borda); border-radius:50%; background:var(--branco);
  color:var(--cinza-medio); font-size:10px; font-weight:700; line-height:1;
  cursor:pointer; flex:0 0 auto;
}
.dica-btn:hover, .dica-btn[aria-expanded="true"]{ color:var(--branco); background:var(--cinza-medio); border-color:var(--cinza-medio); }
.dica-btn:focus-visible{ outline:2px solid var(--vermelho); outline-offset:2px; }
/* ⭐ O `?` também cresce no toque (mesmo check, mesmo dia). 📏 15×15px medidos —
   e há 54 deles só na tela de Configurações do Financeiro.
   ⚠️ Aqui o círculo tem de continuar com 15px: ele fica ao lado do rótulo de um
   campo e um círculo de 44px ao lado de cada rótulo vira uma parede de bolinhas.
   ⭐ Por isso cresce a ÁREA e não o desenho — um pseudo-elemento invisível por
   cima, centrado no botão. É o mesmo truque que a casa usa nos ícones pequenos.
   ⚠️ `position:relative` no botão para o pseudo se ancorar nele. */
@media (pointer:coarse){
  .dica-btn{ position:relative; }
  .dica-btn::after{
    content:''; position:absolute; left:50%; top:50%; transform:translate(-50%, -50%);
    width:44px; height:44px; border-radius:50%;
  }
}

/* ⚠️ O balão vive no <body> e é posicionado em coordenadas de PÁGINA. É o que o
   impede de ser cortado pelo `overflow` de um cartão ou de uma janela. */
.dica-balao{
  position:absolute; z-index:60; max-width:min(300px, calc(100vw - 24px));
  padding:8px 10px; border-radius:var(--raio-sm);
  background:var(--menu); color:var(--menu-fg);
  font-size:12.5px; line-height:1.45; box-shadow:var(--sombra);
  pointer-events:none;
}
.dica-balao[hidden]{ display:none; }


/* ── A FAIXA RECOLHIDA (prints do TickTick, 21/08/2026) ──
   ⚠️ Os botões ESCONDEM-SE, a faixa FICA. É a mesma altura aberta e fechada: se
   ela nascesse do nada ao clicar, o campo saltava para baixo com o cursor já lá
   dentro — e num celular isso é o teclado tapando aquilo que se ia escrever. */
.txt-recolhida > *:not(.txt-chamar){ display:none; }
/* ⚠️ Um `A` SUBLINHADO, e não o mesmo `A` do destaque: são dois botões na mesma
   faixa, e com o mesmo desenho quem clica com pressa acerta no errado. */
.txt-chamar-a{
  font-weight:700; font-size:13px; line-height:1;
  border-bottom:1.5px solid currentColor; padding-bottom:1px;
}
.txt-chamar[aria-expanded="true"]{ background:var(--cinza-claro); color:var(--preto); }

/* O texto já formatado, onde quer que apareça. Margens curtas de propósito:
   isto vive dentro de cartões e do telemóvel, não numa página de artigo. */
.texto-rico p{ margin:0 0 6px; }
.texto-rico p:last-child{ margin-bottom:0; }
.texto-rico ul, .texto-rico ol{ margin:0 0 6px; padding-left:18px; }
/* ⚠️ Explícito: dentro de um <li> ou de um cartão, o browser herda o estilo do
   nível de cima e desenha círculos ocos, que se leem como sub-item de alguma
   coisa que não existe. */
.texto-rico ul{ list-style:disc; }
.texto-rico ol{ list-style:decimal; }
.texto-rico li{ margin:1px 0; }
.texto-rico strong{ font-weight:600; }

/* ── O QUE A MARCAÇÃO NOVA DESENHA ──
   Margens curtas de propósito, pela mesma razão dos parágrafos: isto vive dentro
   de cartões e do celular, não numa página de artigo. */
.texto-rico h4, .texto-rico h5{ margin:8px 0 4px; line-height:1.25; }
.texto-rico h4{ font-size:15px; font-weight:700; }
.texto-rico h5{ font-size:13.5px; font-weight:600; color:var(--cinza-medio); }
.texto-rico > h4:first-child, .texto-rico > h5:first-child{ margin-top:0; }
.texto-rico blockquote{
  margin:0 0 6px; padding:2px 0 2px 10px;
  border-left:3px solid var(--cinza-borda); color:var(--cinza-medio);
}
.texto-rico blockquote p:last-child{ margin-bottom:0; }
.texto-rico code{
  font-family:ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size:0.9em; padding:1px 4px; border-radius:var(--raio-xs);
  background:var(--cinza-claro); word-break:break-word;
}
/* ⭐ O MARCA-TEXTO É A COR DA EMPRESA, diluída (pedido dele, 21/08: *"seria
   baseado na cor do sistema daí, no caso das cores padrão dext, o vermelho"*).
   O amarelo fixo que estava aqui era a única cor do editor que não vinha da
   marca — numa empresa de marca azul ficava um pós-it amarelo no meio.
   ⚠️ `--destaque` e não `--vermelho-sinal`: identidade, não sinal. Um realce
   não quer dizer "erro". Ver o :root, onde essa diferença está escrita.
   ⚠️ `color-mix` já é régua da casa — o `layout.php` calcula o `--vermelho-hover`
   com ele desde que o white-label existe. */
.texto-rico mark, .txt-mk mark{
  background:color-mix(in srgb, var(--destaque) 22%, transparent);
  color:inherit; padding:0 2px; border-radius:var(--raio-xs);
}
.texto-rico del{ color:var(--cinza-medio); }
.texto-rico hr{ border:none; border-top:1px solid var(--cinza-borda); margin:8px 0; }
/* ⚠️ O link abre noutra aba e vai sempre com `rel=noopener` — quem escreve a
   descrição não é necessariamente quem a lê. */
.texto-rico a{ color:var(--vermelho); text-decoration:underline; word-break:break-word; }

/* A lista de caixas não leva marcador: a caixa JÁ é o marcador. */
.texto-rico ul.tr-check{ list-style:none; padding-left:2px; }
.texto-rico ul.tr-check li{ display:flex; gap:6px; align-items:flex-start; }
/* ⚠️ Tamanho travado: o ☐ e o ☑ vêm de fontes diferentes conforme o sistema, e
   sem isto uma linha ficava mais alta do que a outra na mesma lista. */
.texto-rico .tr-cx{ flex:0 0 auto; width:1.1em; line-height:1.35; font-size:1.05em; }
/* ⚠️ Riscar o que está feito, mas sem apagar: numa lista de preparo, o que já
   se fez continua sendo a prova de que foi feito.
   ⚠️ E o risco NÃO atravessa a caixa — riscar a própria caixa fazia o ☑ parecer
   um ☒, que é outra coisa. */
.texto-rico .tr-feito{ color:var(--cinza-medio); }
.texto-rico .tr-feito .tr-txt{ text-decoration:line-through; }
.pro-previa-desc{ font-size:12.5px; color:var(--cinza-medio); padding:0 0 8px; }
.pro-previa-desc:empty{ display:none; }

/* Faixa do item numérico: três campos curtos que só aparecem no tipo certo. */
.pro-faixa{ display:flex; gap:8px; align-items:center; flex-wrap:wrap; }
.pro-faixa label{ display:flex; align-items:center; gap:4px; font-size:12px; color:var(--cinza-medio); }
.pro-faixa input{ width:70px; }
.pro-rascunhos{ margin:2px 0 16px; }
.pro-rascunhos .ajuda{ margin-top:2px; max-width:62ch; }

/* ═══════════ AS TAREFAS (v0.68.0) ═══════════
   A lista tem de responder a duas perguntas de relance, e é por elas que a cor
   existe aqui: o que está ATRASADO, e o que veio do sistema em vez de uma
   pessoa. Tudo o resto é cinzento de propósito. */

.tar-lista{ list-style:none; margin:0; padding:0; }
.tar-item{
  display:flex; gap:14px; align-items:flex-start; justify-content:space-between;
  padding:14px 0 14px 12px; border-top:1px solid var(--cinza-borda);
  border-left:3px solid transparent;
}
.tar-item:last-child{ border-bottom:1px solid var(--cinza-borda); }
/* ⚠️ A prioridade alta marca-se na BORDA, não no fundo: um fundo colorido numa
   lista de vinte linhas transforma-se em ruído e deixa de significar nada. */
.tar-p-alta{ border-left-color:var(--vermelho); }
.tar-atrasada .tar-prazo-tarde{ color:var(--vermelho); font-weight:700; }
/* Fechada continua a ler-se, mas recua: o histórico serve para conferir, não
   para competir com o que está por fazer. */
.tar-fechada{ opacity:.55; }
.tar-fechada .tar-topo strong{ text-decoration:line-through; }

.tar-corpo{ flex:1 1 auto; min-width:0; }

/* ══════ ⭐⭐ A COR DA ARRUMAÇÃO NO GESTOR DE TAREFAS (25/08/2026) ══════
   Ele: *"vamos colocar possibilidade de cor nos projetos, seções, setores (…)
   pode ser sutil (…) tem que ter cuidado pra não ficar brega ou poluído
   demais."*

   🚨 A REGRA QUE EVITA O PAINEL DE AEROPORTO, e é uma só:
   **cor forte só em selo pequeno; superfície grande leva cor em TRAÇO.**
   É o que a tabela de lançamentos já faz — o vermelho está no número, não no
   fundo da linha. Aqui: o setor é um fio de 3px, o responsável é um selo, o
   projeto é um ponto de 6px. Três sinais, três tamanhos, nenhum a competir.

   ⚠️ E a cor vem SEMPRE de `Config::PALETA`, que é fechada: oito tons
   dessaturados no mesmo degrau de luminosidade. Cor livre é o que fica brega —
   basta uma pessoa escolher magenta puro e a tela inteira perde. */
.tar-corpo-cor{ position:relative; padding-left:11px; }
.tar-corpo-cor::before{
  content:''; position:absolute; left:0; top:1px; bottom:1px; width:3px;
  border-radius:var(--raio-xs); background:var(--tar-setor); opacity:.85;
}

/* O RESPONSÁVEL. Ele pediu-o "mais evidente, igual o reserva confirmada" — e
   é a mesma forma `.selo`, só com a cor do nível hierárquico.
   ⚠️ Fundo a 12% e texto na cor cheia: o anel desenha-se sozinho pelo contraste
   e não precisa de borda. Um `border` a mais aqui engorda a linha inteira. */
.selo-pessoa{ background:var(--cinza-fundo); color:var(--cinza-medio); }
.selo-pessoa-cor{
  background:color-mix(in srgb, var(--c) 12%, transparent);
  color:var(--c);
  box-shadow:inset 0 0 0 1px color-mix(in srgb, var(--c) 24%, transparent);
}

/* O PROJETO: um ponto, e mais nada. Duas superfícies coloridas na mesma linha
   (o fio do setor e um fundo do projeto) é exatamente onde isto ficava poluído. */
.tar-ponto{
  display:inline-block; width:6px; height:6px; border-radius:50%;
  background:var(--c); margin-right:5px; vertical-align:middle;
}

/* A amostra da paleta, na tela de configurações. */
.paleta{ display:flex; flex-wrap:wrap; gap:6px; align-items:center; }
/* 🚨 A PALETA ENCOSTAVA NO CAMPO DE CIMA — ele, com o print dos Setores:
   *"arruma, tá um em cima do outro."* Medido no browser antes de mexer: a folga
   entre o fundo do `<input>` e o topo das amostras era **0 px**, exactamente.
   ⚠️ Alcance MEDIDO, não estimado: a peça vive em duas secções da mesma tela
   (Setores e Cor por nível) — 17 paletas ao todo. As dos níveis são o PRIMEIRO
   elemento do seu bloco e não têm nada por cima; por isso a regra é
   `:not(:first-child)` e não um `margin-top` cego, que abriria um buraco lá.
   ⭐ 8px é a distância que a casa já usa entre um campo e a sua ajuda. */
.paleta:not(:first-child){ margin-top:8px; }
.paleta input{ position:absolute; opacity:0; pointer-events:none; }
.paleta label{ cursor:pointer; line-height:0; }
.paleta span{
  display:block; width:22px; height:22px; border-radius:50%; background:var(--c);
  box-shadow:inset 0 0 0 1px rgba(0,0,0,.12);
}
/* ⚠️ O escolhido marca-se com um ANEL de fora, e não com um visto por cima: um
   visto branco some no ámbar e some no oliva. O anel lê-se em todos os oito. */
.paleta input:checked + span{ box-shadow:0 0 0 2px var(--branco), 0 0 0 4px var(--c); }
.paleta .paleta-sem span{ background:var(--cinza-fundo); }
/* ⭐ A NONA amostra é a cor livre: mostra o lápis quando ainda não foi usada e
   passa a mostrar a cor escolhida depois. ⚠️ O `input type=color` fica por
   cima, invisível: assim o clique cai no seletor do sistema operativo sem
   precisar de um segundo botão ao lado. */
.paleta-livre{ position:relative; }
.paleta-livre span{ display:grid; place-items:center; color:var(--cinza-medio);
  box-shadow:inset 0 0 0 1px var(--cinza-borda); }
.paleta-livre span svg{ width:13px; height:13px; }
.paleta-conta-gotas{ position:absolute; inset:0; opacity:0; width:100%; height:100%;
  padding:0; border:0; cursor:pointer; }
.tar-topo{ display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
.tar-desc{ font-size:.86rem; color:var(--cinza-medio); margin:4px 0 0; }
/* ⭐ A descrição nasce RETRAÍDA em duas linhas (ele, 13/08/2026). Uma tarefa com
   meia página de pesquisa dentro empurrava as dez seguintes para fora do ecrã.
   ⚠️ O corte é do CSS, e por isso vale mesmo sem JavaScript; o "ver mais" só
   acrescenta o gesto. E a tarefa continua a abrir-se para ler tudo: retrair é
   conforto, nunca a única porta para o conteúdo. */
.tar-desc-corta{ display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical;
  overflow:hidden; }
.tar-desc-corta.tar-desc-aberta{ display:block; -webkit-line-clamp:none; overflow:visible; }
/* O primeiro parágrafo colado ao título; sem isto o texto rico abre com margem
   e a primeira das duas linhas era espaço vazio. */
.tar-desc-corta > *:first-child{ margin-top:0; }
.tar-desc-mais{ background:none; border:0; padding:2px 0; margin:2px 0 0; cursor:pointer;
  font:inherit; font-size:.8rem; font-weight:600; color:var(--cinza-medio); }
.tar-desc-mais:hover{ color:var(--preto); text-decoration:underline; }
.tar-meta{ display:flex; flex-wrap:wrap; gap:12px; margin-top:6px; font-size:.79rem; color:var(--cinza-medio); }
.tar-tag{ color:var(--cinza-medio); text-decoration:none; }
.tar-tag:hover{ color:var(--preto); }
.tar-recusa{ font-style:italic; }
.tar-tag-motor{ background:var(--cinza-claro); color:var(--cinza-medio); }
.tar-tag-alta{ background:var(--vermelho); color:#fff; }

.tar-acoes{ display:flex; align-items:center; gap:6px; flex-wrap:wrap; flex:0 0 auto; }
/* ⭐ Os seis formulários das ações da lista (22/08/2026, achado A6). Não têm
   nada dentro para mostrar — só o csrf, a ação e a lente — e o botão de cada
   card aponta para eles pelo `form=`. Sem isso ficava uma caixa vazia ocupando
   espaço entre a lista e o menu do lote. */
.tar-acoes-formularios{ display:none; }
/* ⭐ O painel da recusa é UM SÓ e vai até o card. Dentro das ações ele ocupa a
   linha inteira, que é onde a caixa abria antes de existir painel. */
.tar-recusar-painel{ flex:1 0 100%; }
.tar-recusar-form{ display:flex; flex-wrap:wrap; gap:6px; margin-top:8px; }
.tar-recusar-form select, .tar-recusar-form input{ font-size:.85rem; }
.tar-linha{ display:flex; gap:14px; flex-wrap:wrap; }
/* 🚨 `min-width:0` — 26/08/2026, ele com uma foto do iPad: *"tá avacalhado com
   os outros campos, hora e projeto."*
   A causa é a armadilha clássica do flex: um item nasce com `min-width:auto`,
   ou seja **não encolhe abaixo do seu conteúdo**. Num computador não se nota,
   porque um `input[type=date]` mede pouco; no iPad o controlo nativo de data e
   o de hora têm largura intrínseca grande, a célula recusa encolher e as caixas
   montam umas nas outras — a data curta, a hora a passar por baixo do projeto.
   ⚠️ É a MESMA causa do quadro das tarefas a esticar a página nesta mesma
   manhã: um controlo do sistema com tamanho próprio a escapar do contentor.
   Vale a pena guardar a lição: *num flex, quem tem controlo nativo dentro
   precisa de `min-width:0` — sempre.* */
/* ⚠️ E um TECTO, senão a correção do `<select>` virava outro defeito: com os
   seletores a preencher a célula, um campo sozinho na linha (o *Avisar antes*,
   o *Repetir*) passava a atravessar o cartão de ponta a ponta — media ~305px
   antes e ficava com 740. Um campo que cresce com o espaço que sobra diz que ali
   cabe muito mais do que cabe. Com três na linha o tecto nem chega a tocar
   (227px cada); com um, segura-o onde sempre esteve. */
.tar-linha .campo{ flex:1 1 190px; min-width:0; max-width:320px; }
/* ⚠️ A regra própria que esta tela tinha para os `<select>` saiu a 26/08: a
   regra da casa deixou de estar presa a `.form` e passou a servi-la também.
   Ver `.campo select` lá em cima. */
.tar-form{ padding:20px; margin-bottom:8px; }

@media (max-width:640px){
  /* No telemóvel as ações passam para baixo: espremidas à direita ficavam com
     alvos de toque de meio dedo. */
  .tar-item{ flex-direction:column; }
  .tar-acoes{ width:100%; }
}

/* Projetos e secções. A fila dos projetos é OUTRA fila, separada dos estados:
   juntá-las dava uma barra de vinte fichas onde nada se acha. */
.tar-projetos{ margin-top:-6px; }
.tar-secao-cab{
  list-style:none; padding:16px 0 4px; font-size:.78rem; font-weight:700;
  letter-spacing:.06em; text-transform:uppercase; color:var(--cinza-medio);
}
.tar-gerir{ padding:20px; margin-bottom:14px; }
.tar-gerir-linha{ display:flex; align-items:center; gap:10px; flex-wrap:wrap; padding:10px 0; border-top:1px solid var(--cinza-borda); }
.tar-gerir-linha.arquivado{ opacity:.55; }
.tar-secoes{ display:flex; align-items:center; gap:8px; flex-wrap:wrap; width:100%; padding-left:6px; }
.tar-secao-chip{ display:inline-flex; align-items:center; gap:2px; padding:3px 9px;
  background:var(--cinza-claro); border-radius:999px; font-size:.79rem; color:var(--cinza-medio); }

/* Passos e comentários dentro da tarefa. */
/* ⭐⭐⭐ A JANELA SUSPENSA DA TAREFA — 26/08/2026.
   Ele: *"anexo, comentário, subtarefa, coloca tudo anexado na mesma janela em
   algum botão de opções de forma mais compacta, tá muito espalhado."*
   Eram quatro cartões empilhados; passaram a um `<details>` só.
   ⚠️ O `summary` é um ALVO DE DEDO: 44px, a régua da casa. Um `⋯` de 20px é o
   gesto mais falhado que há num telemóvel. */
.tar-mais{ border:1px solid var(--cinza-borda); border-radius:var(--raio); background:var(--branco);
  margin-top:12px; overflow:hidden; }
.tar-mais-sum{ display:flex; align-items:center; gap:10px; min-height:44px; padding:0 14px;
  cursor:pointer; list-style:none; font-size:13.5px; font-weight:600; color:var(--cinza-medio); }
.tar-mais-sum::-webkit-details-marker{ display:none; }
.tar-mais-sum:hover{ color:var(--preto); }
.tar-mais-ic{ display:inline-flex; width:18px; height:18px; flex:none; }
.tar-mais-ic svg{ width:18px; height:18px; }
/* ⚠️ O resumo pode ser longo numa tarefa com muita coisa: corta-se com
   reticências em vez de partir a barra em duas linhas. */
.tar-mais-txt{ min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
/* ⭐ Aberto, a barra ganha um fio por baixo: é o que separa o botão do que ele
   abriu, sem precisar de uma segunda moldura lá dentro. */
.tar-mais[open] .tar-mais-sum{ border-bottom:1px solid var(--cinza-borda); color:var(--preto); }
.tar-mais-corpo{ padding:4px 14px 14px; }
/* ⚠️ Os três blocos lá dentro já não são cartões — a moldura é a da janela.
   Um cartão dentro de um cartão é uma caixa a dizer o que a de fora já disse. */
.tar-mais-corpo .tar-bloco{ padding:12px 0; }
.tar-mais-corpo .tar-bloco + .tar-bloco{ border-top:1px solid var(--cinza-borda); }
.tar-mais-tit{ font-family:var(--fonte-titulo); font-size:13px; font-weight:700; letter-spacing:.02em;
  text-transform:uppercase; color:var(--cinza-medio); margin:0 0 10px;
  display:flex; align-items:center; gap:8px; }

.tar-bloco{ padding:18px 20px; margin-bottom:12px; }
.tar-prog{ font-size:.78rem; font-weight:600; color:var(--cinza-medio); }
.tar-subs{ list-style:none; margin:0 0 10px; padding:0; }
.tar-subs li{ display:flex; align-items:center; gap:8px; padding:5px 0; }
.tar-subs li.feita span{ text-decoration:line-through; color:var(--cinza-medio); }
/* O tique é um alvo a sério: usa-se com o polegar, no meio do turno. */
.tar-sub-tique{
  width:22px; height:22px; border:1.5px solid var(--cinza-borda); border-radius:var(--raio-xs);
  background:var(--branco); cursor:pointer; font-size:13px; line-height:1; color:var(--verde, #1c7c3c);
}
.tar-sub-tique:hover{ border-color:var(--cinza-medio); }
.tar-sub-tique svg{ width:14px; height:14px; }
/* O tique de uma subtarefa já feita não é botão: é marca. Sem borda, para não
   convidar a um clique que não faz nada. */
.tar-sub-tique-feito{ display:inline-flex; align-items:center; justify-content:center;
  border-color:transparent; color:var(--cinza-medio); }

/* ⭐ AS SUBTAREFAS (tarefas a sério, `mae_id`) — 14/08/2026.
   ⚠️ O recuo é a ÚNICA marca da filha na lista: nem cor, nem fundo, nem
   segunda borda. A borda esquerda já é da prioridade e o fundo já é do
   atrasado; uma terceira linguagem na mesma linha e ninguém lê nenhuma. */
.tar-filha-linha{ padding-left:34px; position:relative; }
.tar-filha-linha::before{
  content:''; position:absolute; left:18px; top:0; bottom:50%;
  border-left:1px solid var(--cinza-borda); border-bottom:1px solid var(--cinza-borda);
  width:9px; border-bottom-left-radius:6px;
}
/* A marca de "isto pertence a outra" para a filha que ficou sozinha na lista. */
.tar-de-mae{ color:var(--cinza-medio); }
.tar-mae-de{ margin:0 0 8px; }
.tar-filhas{ list-style:none; margin:0 0 10px; padding:0; }
.tar-filhas li{ display:flex; align-items:center; gap:8px; padding:6px 0;
  border-top:1px solid var(--cinza-borda); }
.tar-filhas li:first-child{ border-top:none; }
.tar-filhas li.feita .tar-filha-nome{ text-decoration:line-through; color:var(--cinza-medio); }
.tar-filhas li.tar-atrasada .lanc-sub{ color:var(--vermelho); font-weight:600; }
.tar-filha-nome{ flex:1 1 auto; min-width:0; }
/* Os dois contadores da linha lêem-se juntos, e é por isso que cada um traz o
   seu desenho colado ao número. */
.tar-prog{ display:inline-flex; align-items:center; gap:3px; }
.tar-prog svg{ width:13px; height:13px; }
.tar-prog-filhas svg{ transform:rotate(90deg); }
.tar-coments{ list-style:none; margin:0 0 12px; padding:0; }
/* ⚠️ `> li` e não `li`: o comentário tem listas por dentro (o texto é
   formatado), e sem o filho direto cada ponto da lista ganhava o espaçamento e
   a linha de um comentário inteiro. */
.tar-coments > li{ padding:10px 0; border-top:1px solid var(--cinza-borda); }
.tar-coments > li:first-child{ border-top:none; }
.tar-coment-cab{ display:flex; gap:8px; align-items:baseline; margin-bottom:2px; }

/* Repetir: os dias da semana como sete alvos pequenos e iguais. */
.tar-dias{ display:flex; gap:4px; flex-wrap:wrap; }
.tar-dia{ display:inline-flex; }
.tar-dia input{ position:absolute; opacity:0; width:0; height:0; }
/* ⭐⭐ 22/08/2026 — O PADDING É DA BASE, e isto conserta uma classe inteira.
   O `.tar-dia` nasceu para os DIAS DA SEMANA: uma palavra de três letras,
   `min-width:38px` e centrada, **sem padding lateral nenhum**. Depois passou a
   servir para NOMES de pessoa, nomes de SETOR e até frases ("Mostrar o campo",
   no Financeiro → Configurações) — e em todos esses o texto ficava colado às
   bordas e parecia estar a sair do botão. Foi o que ele viu a 22/08, e o que
   ele mandou procurar noutros sítios: *"se tiver algum outro lugar no sistema
   que estava daquele jeito, pode deixar assim também"*.

   ⚠️ O padding **não muda os dias**: com uma palavra de três letras o
   `min-width` continua a mandar. Só cresce onde o conteúdo é maior — que é
   exatamente onde estava errado.

   ⚠️ E o `capitalize` saiu: era redundante (os dias já vêm capitalizados do
   ficheiro de idioma, `dow.1 => 'Seg'`) e estragava as frases — "Mostrar o
   campo" aparecia como "Mostrar O Campo". */
.tar-dia span{
  display:inline-flex; align-items:center; justify-content:center;
  min-width:38px; height:34px; padding:0 12px;
  border:1px solid var(--cinza-borda); border-radius:var(--raio-sm); cursor:pointer;
  font-size:.78rem; font-weight:600; color:var(--cinza-medio);
}
.tar-dia input:checked + span{ background:var(--preto); border-color:var(--preto); color:#fff; }
.tar-dia input:focus-visible + span{ outline:2px solid var(--vermelho); outline-offset:2px; }
.tar-tag-rep{ background:var(--cinza-claro); color:var(--cinza-medio); }

/* Anexos: a lista é para reconhecer o ficheiro, não para o admirar. */
.anexo-lista{ list-style:none; margin:0 0 10px; padding:0; }
.anexo-lista li{ display:flex; align-items:center; gap:10px; padding:6px 0; flex-wrap:wrap; }
.anexo-lista a{ display:inline-flex; align-items:center; gap:6px; font-size:.88rem; }
.anexo-icone{ font-size:15px; }

/* ---------- O anexo DENTRO do editor do lançamento (F3/F8) ----------
   O campo de ficheiro e o botão da câmara na mesma linha, por baixo do
   documento e da competência: é a fatura que prova os dois. */
.lanc-anexo-campo .anexo-lista{ margin-bottom:8px; }
.anexo-escolher{ display:flex; align-items:center; gap:10px; flex-wrap:wrap; }
.anexo-escolher input[type=file]{ flex:1 1 220px; min-width:0; font-size:.82rem; }
/* Botão de escanear: é um <label> a vestir um <input type=file>, porque um
   input de ficheiro não se pode estilizar por dentro. O input fica por cima,
   invisível, para o toque cair nele em qualquer ponto do botão. */
.lanc-scan{ position:relative; overflow:hidden; display:inline-flex; align-items:center; gap:6px;
  cursor:pointer; flex:none; }
.lanc-scan input[type=file]{ position:absolute; inset:0; width:100%; height:100%; opacity:0; cursor:pointer; }

/* ═══════════ O BLOCO DO GESTOR na tela do turno ═══════════
   Processos em cima, tarefas em baixo. A separação é a mensagem: o processo tem
   janela e é da casa; a tarefa é avulsa. */
.op-bloco{ margin-bottom:22px; }
.opg-lista{ list-style:none; margin:8px 0 0; padding:0; }
.opg-item{
  display:flex; align-items:center; justify-content:space-between; gap:12px;
  padding:11px 0 11px 10px; border-top:1px solid var(--cinza-borda);
  border-left:3px solid transparent;
}
.opg-item:last-child{ border-bottom:1px solid var(--cinza-borda); }
.opg-corpo{ min-width:0; }
.opg-meta{ display:flex; gap:10px; flex-wrap:wrap; font-size:.78rem; color:var(--cinza-medio); margin-top:2px; }
/* A janela fechada e a tarefa atrasada são as duas únicas coisas accionáveis de
   relance: só elas ganham cor. */
.opg-j-fechada, .opg-atrasada{ border-left-color:var(--vermelho); }
.opg-tarde{ color:var(--vermelho); font-weight:700; }
.opg-e-concluida{ opacity:.55; }
.opg-feito{ font-size:.82rem; font-weight:600; color:var(--verde, #1c7c3c); }
.opg-sem-dono{ font-style:italic; }
.opg-acao{ flex:0 0 auto; }

/* ═══════════ EXECUTAR UM PROCESSO ═══════════
   Telemóvel numa mão: um passo por bloco, alvos grandes, sem scroll lateral. */
.exec-desc{ padding:16px 18px; margin-bottom:14px; font-size:.9rem; color:var(--cinza-medio); }
.exec-passos{ list-style:none; margin:0; padding:0; counter-reset:passo; }
.exec-passo{ padding:16px 0; border-top:1px solid var(--cinza-borda); }
.exec-passo:last-child{ border-bottom:1px solid var(--cinza-borda); }
.exec-passo.bloqueado{ opacity:.45; }
.exec-passo.respondido .exec-passo-cab strong{ color:var(--cinza-medio); }
.exec-passo.nao-conforme{ border-left:3px solid var(--vermelho); padding-left:10px; }
.exec-passo-cab{ display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
.exec-n{
  display:inline-flex; align-items:center; justify-content:center; width:24px; height:24px;
  border-radius:50%; background:var(--cinza-claro); font-size:.76rem; font-weight:700; color:var(--cinza-medio);
}
.exec-obrig{ color:var(--vermelho); font-weight:700; }
.exec-faixa{ margin:4px 0 0 32px; font-size:.8rem; color:var(--cinza-medio); }
.exec-form, .exec-evidencia{ margin:10px 0 0 32px; }
.exec-botoes{ display:flex; gap:8px; flex-wrap:wrap; }
/* 44px de alvo: usa-se com o polegar, de pé, no meio do serviço. */
.exec-botoes .btn-mini{ min-height:44px; min-width:110px; font-size:.9rem; }
.exec-linha{ display:flex; gap:8px; flex-wrap:wrap; align-items:center; }
.exec-linha input{ min-height:44px; flex:1 1 180px; }
.exec-resposta{ margin:6px 0 0 32px; font-weight:600; }
.exec-evidencia{ display:flex; gap:10px; flex-wrap:wrap; align-items:center; }
.exec-foto{ display:inline-flex; align-items:center; gap:2px; font-size:.84rem; }
.exec-concluir{ margin-top:24px; }
.exec-fechada{ display:flex; gap:10px; flex-wrap:wrap; align-items:center; }
.exec-fora{ color:var(--vermelho); }
/* ⚠️ O SELETOR DE FICHEIRO empurrava a página para o lado no telemóvel: o texto
   "Nenhum ficheiro escolhido" é desenhado pelo browser e não cabe em 375px.
   `max-width` não chegava porque a largura intrínseca dele é maior que o pai;
   é preciso `width:100%` + `min-width:0` para ele poder encolher dentro do flex.
   Medido: a página rolava 8px de lado. Ver [[dext-responsivo]]. */
.exec-evidencia input[type=file], .anexo-lista input[type=file], .tar-bloco input[type=file]{
  width:100%; min-width:0; max-width:100%; font-size:.82rem;
}
/* ⚠️ `>` (FILHO DIRETO), não descendente (ele, 12/08/2026, com print).
   Esta regra existe para o formulário de ACRESCENTAR (passo, anexo), que ocupa a
   linha toda. Como descendente, apanhava também os dois forminhas de dentro de
   CADA passo — o tique e o × — e dava a cada um `flex:1 1 100%`: os dois
   ficavam com 408px e espremiam o texto do passo em 81px, partido em três
   linhas e encostado à direita, com o × longe.
   O formulário de acrescentar é filho direto de `.tar-bloco`; os do passo estão
   dentro de `ul.tar-subs > li`. O `>` separa-os sem precisar de classe nova. */
.exec-evidencia form, .tar-bloco > form.inline-f{ flex:1 1 100%; display:flex; gap:8px; flex-wrap:wrap; align-items:center; }
/* o texto do passo é que deve crescer, e não os botões ao lado dele */
.tar-subs li > span{ flex:1 1 auto; min-width:0; }
/* A rede final: nesta tela nada tem licença para alargar a página. */
.exec-passo, .exec-evidencia{ max-width:100%; overflow-wrap:anywhere; }

/* ⭐ AS PARCELAS POR BAIXO DA NOTA, no painel.
   ⚠️ `display:block` e uma medida própria: dentro da célula da nota, sem isto,
   a frase encostava-se ao número e lia-se como parte dele. */
.dash-nota-partes{
  display:block; margin-top:4px; line-height:1.4;
  font-size:11px; font-weight:400; color:var(--texto-suave);
  /* ⚠️ Estreita de propósito: a frase quebra em duas ou três linhas e a coluna
     não se alarga, que é o que faria a tabela rolar de lado.
     ⚠️ `white-space:normal` escrito à mão porque a célula da nota não o herda. */
  max-width:24ch; white-space:normal;
}

/* ⭐⭐⭐ ARRUMAR O PAINEL (20/08/2026) — o painel passou a ser da casa. */
.dash-arrumar{ margin-left:auto; }
.pa-secoes{ display:flex; flex-direction:column; gap:14px; }
.pa-secao{ padding:14px 16px; }
.pa-secao-cab{ display:flex; align-items:center; gap:10px; }
.pa-secao-cab .secao-titulo{ margin:0; }
.pa-pecas{ list-style:none; margin:10px 0 0; padding:0; }
.pa-peca{
  display:flex; align-items:center; gap:10px; padding:8px 0;
  border-top:1px solid var(--cinza-borda);
  /* 44px de alvo: arrasta-se com o dedo, e o dedo não é um rato. */
  min-height:44px;
}
.pa-peca .pro-chk{ flex:1 1 auto; min-width:0; }
.pa-peca-nome{ overflow-wrap:anywhere; }
/* ⚠️ A peça desmarcada APAGA-SE em vez de sumir: quem a desligou tem de a ver
   para a poder voltar a ligar. Esconder o que se escondeu é uma porta sem
   maçaneta — já nos aconteceu com a volta do cofre. */
.pa-oculta{ opacity:.45; }
.pa-tipo{ background:var(--cinza-fundo); color:var(--cinza-medio); }
/* As setas: o mesmo gesto do arrastar, para quem usa o dedo ou o teclado. */
.pa-setas{ display:flex; gap:4px; margin-left:auto; flex:none; }
.pa-secao-cab .pa-setas{ margin-left:auto; }
/* Enquanto se arrasta: a peça levanta-se do papel, para se ver o que se agarrou. */
.a-arrastar{ opacity:.5; }
.pa-secao[draggable], .pa-peca[draggable]{ cursor:grab; }

/* ⭐⭐⭐ OS TRÊS PAPÉIS DE UMA `.ajuda` (20/08/2026).
   🚨 Havia **117 espaçamentos escritos à mão** em `style="..."`, espalhados por
   34 telas — e vinte valores diferentes para o que, olhando de perto, são só
   TRÊS situações. Cada um foi chutado no dia em que a tela nasceu, e chutado
   diferente: é a mesma doença que o `--altura-rotulo` já curou noutro sítio.
   ⚠️ Os números abaixo NÃO são uma média nem uma invenção: são os valores que já
   dominavam cada situação (25, 6 e 5 telas respetivamente). Converter para eles
   não move um pixel — e é isso que faz esta arrumação ser barata de conferir.
   ⏭ As restantes migram devagar; o `test-ajuda-espacamento` conta-as e não as
   deixa crescer. */

/* Antes de um bloco: a ajuda explica o que vem A SEGUIR e precisa de ar por baixo. */
.ajuda-antes{ margin-bottom:10px; }
/* Depois de um campo: cola-se ao que acabou de explicar, com um respiro só. */
.ajuda-depois{ margin-top:8px; }
/* Sob um título: sobe para não parecer um parágrafo solto, e afasta o que vem. */
.ajuda-titulo{ margin:-6px 0 12px; }

/* ⭐ O FILTRO PELA FASE DO TURNO, na lista de processos.
   ⚠️ Chips e não um `select`: é um gesto único, vive no endereço (dá para
   guardar e para mandar a alguém) e não precisa de JavaScript nenhum. */
.pro-fases-filtro{ display:flex; gap:8px; flex-wrap:wrap; margin:0 0 14px; }
/* A etiqueta da fase na linha da lista: ao lado da janela, e sem cor de alarme —
   é um rótulo, não um estado. */
/* Os seletores da linha: discretos, porque a lista continua a ser para LER —
   editar ali é o gesto ocasional, não o principal. */
.pro-lista-sel{ min-height:38px; max-width:100%; font-size:13px; }

/* ⭐ AS PERGUNTAS DO CICLO, no topo da tela dos Processos.
   ⚠️ Os dois botões lado a lado e do mesmo tamanho: a resposta honesta é tantas
   vezes "não muda" como "muda", e desenhar um deles como o principal era pedir
   essa resposta em vez de perguntar. */
.pro-ciclo{ margin-bottom:18px; }
.pro-ciclo-l{ list-style:none; margin:10px 0 0; padding:0; }
.pro-ciclo-i{
  display:flex; gap:12px; flex-wrap:wrap; align-items:center;
  justify-content:space-between; padding:10px 0;
  /* ⚠️ `--cinza-borda` e não `--linha`: `--linha` é usado em quatro sítios desta
     folha e **não está definido em lado nenhum** — o fio desenhado com ele não
     aparece. Não somei um quinto uso a um símbolo que não existe. */
  border-top:1px solid var(--cinza-borda);
}
.pro-ciclo-corpo{ flex:1 1 260px; min-width:0; }
.pro-ciclo-acoes{ display:flex; gap:8px; flex-wrap:wrap; }
.pro-ciclo-acoes .btn-mini{ min-height:36px; }

/* ⭐ O PASSO CRÍTICO e o PASSO QUE NÃO SE APLICA.
   ⚠️ O crítico usa a cor do sinal; o "não se aplica" **apaga** o passo em vez de
   o pintar. É deliberado: um passo que não se aplicava não é um problema, e
   dar-lhe cor de alarme ensinava a equipa a evitá-lo — que é exatamente o que
   ele existe para não acontecer. */
.exec-tag-critico{ background:var(--vermelho); color:#fff; }
.exec-passo.exec-na{ opacity:.62; }
/* ⚠️ Um `<details>` e não um terceiro botão: um gesto a mais não impede quem tem
   razão, e chega para quem só queria despachar o passo chato. */
.exec-na-menu{ margin:8px 0 0 32px; }
.exec-na-menu > summary{
  cursor:pointer; font-size:.84rem; color:var(--cinza-medio);
  /* 44px de alvo, como o resto desta tela: usa-se com o polegar, de pé. */
  min-height:32px; display:inline-flex; align-items:center; padding:4px 0;
}
.exec-na-form{ display:flex; gap:8px; flex-wrap:wrap; align-items:center; margin-top:6px; }
.exec-na-form select, .exec-na-form input[type=text]{ min-height:44px; flex:1 1 160px; min-width:0; }
.exec-na-form .ajuda{ flex:1 1 100%; margin:0; }

/* ⭐ O CICLO À VISTA na folha fechada: o passo que saiu do padrão e a tarefa que
   nasceu dele. A cor é a do sinal — vermelho, porque é um desvio —, mas o BLOCO
   não é um alarme: é o recibo de que alguém vai tratar disto. */
.exec-desvios{ margin:14px 0 0; padding:16px 18px; border-left:3px solid var(--vermelho); }
.exec-desvios-t{ margin:0 0 4px; font-size:.98rem; }
.exec-desvios-l{ list-style:none; margin:10px 0 0; padding:0; }
.exec-desvios-l li{
  padding:8px 0; border-top:1px solid var(--cinza-borda);
  display:flex; gap:8px; flex-wrap:wrap; align-items:baseline;
  /* a mesma rede do resto da tela: nada alarga a página no telemóvel */
  max-width:100%; overflow-wrap:anywhere;
}
.exec-desvio-v{ font-size:.84rem; color:var(--cinza-medio); }
/* ⚠️ Leva `.btn-link` junto, e é ele que dá a cor da casa. Sem essa classe o
   link saía com o AZUL SUBLINHADO do navegador (rgb(0,0,238)) — medido na tela,
   e é o tipo de coisa que nenhum teste de motor vê. */
.exec-desvio-t{ margin-left:auto; font-size:.84rem; white-space:nowrap; text-decoration:none; }

/* Quem é de que setor: uma linha por pessoa, os setores como fichas. */
.pro-equipa{ margin:16px 0 22px; }
.pro-equipa summary{ cursor:pointer; font-weight:600; }
.pro-equipa-linha{ display:flex; align-items:center; gap:12px; flex-wrap:wrap; padding:9px 0; border-top:1px solid var(--cinza-borda); }
.pro-equipa-nome{ min-width:150px; font-weight:600; font-size:.9rem; }
/* ⚠️ Onde o `.tar-dia` mostra uma PESSOA, a largura é só a do nome (sem o
   mínimo dos dias), e um nome muito comprido corta com reticências em vez de
   esticar a fila toda. O resto — o padding — já vem da base. */
.pro-equipa .tar-dia span,
.tar-equipa .tar-dia span{
  min-width:auto; max-width:14ch;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
.pro-atribuir{ margin-top:18px; padding-top:14px; border-top:1px solid var(--cinza-borda); }
.tar-equipa{ display:flex; align-items:center; gap:8px; flex-wrap:wrap; width:100%; padding:6px 0 0 6px; }

/* Quem faz anos nos próximos dias, na lista de clientes. Uma faixa e não um
   card: é um lembrete de passagem, não uma secção da tela. */
.cli-aniv{ display:block; }
.cli-aniv-lista{ list-style:none; margin:8px 0 0; padding:0; display:flex; flex-wrap:wrap; gap:6px 18px; }
.cli-aniv-lista li{ display:flex; align-items:baseline; gap:6px; font-size:13.5px; }
.cli-aniv-lista a{ font-weight:600; }

/* ── A linha da FORMA DE PAGAMENTO (08/08/2026) ──
   Nome em cima, a conta onde cai logo debaixo, e os ticks a revelar só o que
   lhes pertence. Empilhado de propósito: em linha, os campos de plataforma
   espremiam o nome e faziam toda forma parecer mal configurada. */
.forma-linha{ display:flex; flex-direction:column; gap:7px; padding:2px 0; }
.forma-topo{ display:flex; align-items:center; gap:6px; }
.forma-nome{ flex:1 1 auto; min-width:0; }
.forma-x{ flex:0 0 auto; }
.forma-ticks{ display:flex; flex-wrap:wrap; gap:4px 14px; align-items:center; }
.forma-opcoes{ display:flex; flex-wrap:wrap; gap:6px; align-items:center;
  padding-left:10px; border-left:2px solid var(--cinza-borda); }
.forma-opcoes[hidden]{ display:none; }
.forma-opcoes select{ max-width:190px; }

/* Processos e tarefas do dia ocupam a largura toda da grade do turno: são
   listas com texto de um lado e ação do outro, e na coluna de 340px ficavam
   espremidas (o mesmo aperto do card da reserva). */
.op-bloco-largo{ grid-column:1/-1; }

/* ═══════════ PRODUÇÃO — a tela da cozinha (08/08/2026) ═══════════
   Usa-se de pé, com o celular numa mão. Campos em linha enquanto couberem,
   e alvos de 44px porque é o que se acerta com o polegar sujo de farinha. */
.prod-form{ display:flex; gap:12px; align-items:flex-end; flex-wrap:wrap; }
.prod-form .campo{ margin:0; flex:1 1 150px; }
/* ⚠️ `width:auto` explícito: o `.btn` do sistema nasce com `width:100%`, que é
   o certo num formulário empilhado e errado aqui — empurrava o botão sozinho
   para uma linha e afastava-o dos campos que ele grava. */
.prod-form .btn{ flex:0 0 auto; width:auto; padding:14px 28px; min-height:46px; }
.prod-form input, .prod-form select{ min-height:46px; }
/* Abaixo do mínimo é a única linha que ganha cor: é a que muda o que se faz
   agora. O resto da tabela fica calma de propósito. */
.prod-falta td:first-child{ border-left:3px solid var(--vermelho); padding-left:9px; }
/* O interruptor na ficha: separado do resto por uma linha, porque é operação
   e não receita — mexe em quando avisar, nunca no que a preparação leva. */
.ficha-pronto{ border-top:1px solid var(--cinza-borda); padding-top:16px; margin-top:6px; max-width:560px; }
.ficha-pronto .form-linha{ margin-top:12px; }

/* Perda de preparação: gaveta fechada, mesmo desenho do mover-fecho. E o aviso
   do "preso no pronto" no inventário, discreto mas visível antes de contar. */
.prod-perda{ margin:18px 0; }
.prod-perda > summary{
  display:inline-block; cursor:pointer; font-size:13px; font-weight:600;
  color:var(--cinza-medio); background:var(--branco); border:1px solid var(--cinza-borda);
  padding:7px 14px; border-radius:999px; list-style:none;
}
.prod-perda > summary::-webkit-details-marker{ display:none; }
.prod-perda > summary:hover{ color:var(--vermelho); border-color:var(--vermelho); }
.prod-perda[open] > summary{ margin-bottom:12px; }
.inv-preso{ color:#8a6d00; }

/* Perda rápida no turno: os mesmos três campos em linha do "faltou alguma
   coisa". Um formulário curto de propósito — cada campo a mais no meio do
   serviço é uma perda que ninguém lança. */
.op-perda-form{ display:flex; gap:10px; align-items:flex-end; flex-wrap:wrap; }
.op-perda-form .campo{ margin:0; flex:1 1 130px; }
.op-perda-form .btn{ flex:0 0 auto; width:auto; padding:13px 22px; }

/* Aviso de preço divergente na fatura. Vive dentro de .alerta, mas a lista
   precisa de respirar: nome à esquerda, números no meio, ação à direita. */
.cmp-div-lista{ list-style:none; margin:10px 0 0; padding:0; }
.cmp-div-lista li{
  display:flex; align-items:center; gap:12px; flex-wrap:wrap;
  padding:9px 0; border-top:1px solid var(--cinza-borda);
}
.cmp-div-nome{ font-weight:600; flex:1 1 160px; min-width:0; overflow-wrap:anywhere; }
.cmp-div-nums{ display:flex; align-items:baseline; gap:8px; font-size:.85rem;
  color:var(--cinza-medio); font-variant-numeric:tabular-nums; }

/* Perda: um campo só para o produto, com o selo que diz o que o sistema
   entendeu. O selo é a resposta visível à pergunta "isto vai sair do estoque
   ou é só despesa?" — a pergunta que antes era um segundo campo. */
.campo-produto{ position:relative; }
.perda-selo{ display:block; font-size:11px; line-height:1.4; margin-top:3px;
  color:var(--cinza-medio); min-height:15px; }
.perda-selo-ok{ color:#1c7a3e; font-weight:600; }
.campo-qtd{ max-width:110px; }
.campo-un{ max-width:92px; }

/* O destinatário do update: fica por baixo do campo, discreto. A ajuda é que
   carrega o peso — "marcar avisa SÓ ela" é contra-intuitivo e tem de estar
   escrito, não deduzido. */
.tar-update-para{ display:flex; align-items:center; gap:8px; flex-wrap:wrap; margin:6px 0 10px; }
.tar-update-para label{ font-size:13px; font-weight:600; }
.tar-update-para select{ max-width:220px; }
.tar-update-para .ajuda{ flex:1 1 100%; margin:0; }
.tar-para{ background:#fff4e5; color:#8a5a00; }

/* Lista de compras agrupada por fornecedor: a compra faz-se fornecedor a
   fornecedor, e é assim que a planilha dele está montada (uma aba por cada). */
.lc-grupo{ font-size:13px; font-weight:700; text-transform:uppercase; letter-spacing:.04em;
  color:var(--cinza-medio); margin:18px 0 6px; }
.lc-grupo:first-of-type{ margin-top:6px; }

/* "+ novo" ao lado de um seletor (ver partials/criar-rapido.php). Discreto: é
   um atalho para quem já sabe que falta a opção, não uma chamada de atenção. */
.cr-novo{ margin-left:8px; font-size:12.5px; white-space:nowrap; }
/* O painel do "+ novo": um formulário pequeno DENTRO de outro formulário, e por
   isso visualmente recuado — tem de se ler como um parêntesis, não como mais
   uma secção da tela. */
.cr-painel{ border:1px solid var(--cinza-borda); border-radius:var(--raio-sm); padding:12px 14px;
  margin-top:8px; background:var(--cinza-fundo); display:grid; gap:10px; }
.cr-painel .campo{ margin:0; }
.cr-acoes{ display:flex; gap:10px; align-items:center; }
/* "Mista": a linha tem mais do que uma categoria por dentro. Etiqueta neutra,
   e não uma cor de tipo — não é receita nem despesa, é a ausência de UMA
   categoria. Ver a nota em Lancamentos::garantirEsquema. */
.lanc-mista{ background:var(--cinza-fundo); color:var(--cinza-medio); border:1px dashed var(--cinza-borda); }
/* O clipe da linha: é um LINK e tem de o parecer, mas sem gritar. Mesmo peso
   visual dos outros ícones de ação da linha (ver .lanc-editar). */
.lanc-clipe{ text-decoration:none; color:var(--cinza-medio); font-size:12.5px;
  white-space:nowrap; transition:color .15s; }
.lanc-clipe:hover{ color:var(--destaque); }
/* Mais do que um anexo: o número em índice, para o clipe caber no mesmo
   quadrado dos outros e a coluna não abrir por causa de "📎 3". */
.lanc-clipe-n{ font-size:9px; font-weight:700; margin-left:1px; align-self:flex-start; }

/* Em cartão (telemóvel) a coluna deixa de ser coluna: os ícones passam a ser
   uma fila de botões e os lugares vazios não têm o que segurar. */
/* ⚠️ 600px, o MESMO ponto em que a tabela vira cartões (ver o bloco lá em
   cima): num cartão a coluna deixa de ser coluna e os lugares vazios não têm o
   que alinhar — só ocupavam espaço numa tela estreita. */
@media (max-width:600px){
  .tabela-cards td.td-acoes{ display:flex; }
  .tabela-cards td.td-acoes .lanc-ico-vazio{ display:none; }
  /* ⚠️ No celular quem clica é o POLEGAR, e estes são os botões que ele usa em
     serviço (dar baixa, conferir, anexo, duplicar, editar, excluir). 28×26px é
     alvo de rato; a régua da casa são 40px (auditoria 13/08). */
  .tabela-cards td.td-acoes .lanc-ico{ min-width:40px; min-height:40px; font-size:15px; }
  /* O ▸ que abre as partes de uma fatura era um glifo de 12px encostado ao
     texto: no cartão, acertar-lhe é sorte. */
  .lanc-abrir{ min-width:40px; min-height:40px; font-size:15px; padding:0;
    display:inline-grid; place-items:center; }
}


/* ============================================================
   TAREFAS · O PAINEL (pasta → projeto)
   ⭐ Ele, 13/08/2026: "painel separado com acesso a todas as pastas e
   projetos". É a barra lateral do TickTick/Todoist, e substituiu a fila
   horizontal de fichas: com vinte projetos aquilo era uma barra onde nada se
   achava, e não tinha onde caber a pasta.
   ============================================================ */
.tar-quadro{ display:grid; grid-template-columns:250px minmax(0,1fr); gap:22px; align-items:start; }
.tar-painel{ position:sticky; top:16px; display:flex; flex-direction:column; gap:1px;
  background:var(--branco); border:1.5px solid var(--cinza-borda); border-radius:var(--raio);
  padding:8px; max-height:calc(100dvh - 40px); overflow-y:auto; }
.tar-pn-item{ display:flex; align-items:center; gap:7px; padding:7px 9px; border-radius:var(--raio-sm);
  text-decoration:none; color:var(--texto); font-size:13.5px; font-weight:500; line-height:1.25; }
.tar-pn-item:hover{ background:var(--cinza-fundo); text-decoration:none; }
.tar-pn-item.ativo{ background:var(--preto); color:var(--branco); font-weight:600; }
.tar-pn-item.ativo .tar-pn-n{ color:var(--branco); opacity:.75; }
/* ⚠️ `min-width:0` + reticências: nome de projeto comprido empurrava a
   contagem para fora do painel e ela deixava de se ver. */
.tar-pn-nome{ flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.tar-pn-n{ font-size:11.5px; font-weight:600; color:var(--cinza-medio); font-variant-numeric:tabular-nums; }
.tar-pn-ic{ font-size:13px; line-height:1; }
/* O ponto da cor só aparece quando há cor: um ponto cinzento em todo o lado é
   ruído que não diz nada. */
.tar-pn-ponto{ width:7px; height:7px; border-radius:50%; flex:0 0 auto; }
.tar-pn-ponto:not([style]){ display:none; }
.tar-pn-pasta > summary{ display:flex; align-items:center; gap:7px; padding:7px 9px; cursor:pointer;
  border-radius:var(--raio-sm); font-size:11.5px; font-weight:700; text-transform:uppercase;
  color:var(--cinza-medio); list-style:none; }
.tar-pn-pasta > summary::-webkit-details-marker{ display:none; }
.tar-pn-pasta > summary::before{ content:'›'; font-size:14px; transition:transform .15s; }
.tar-pn-pasta[open] > summary::before{ transform:rotate(90deg); }
.tar-pn-pasta > summary:hover{ background:var(--cinza-fundo); color:var(--preto); }
.tar-pn-proj{ padding-left:22px; }
.tar-pn-vazia{ margin:0; padding:4px 9px 8px 22px; font-size:12px; color:var(--cinza-medio); }
.tar-pn-gerir{ margin-top:6px; padding:7px 9px; border-top:1px dashed var(--cinza-borda);
  font-size:12.5px; font-weight:600; color:var(--cinza-medio); text-decoration:none; }
.tar-pn-gerir:hover{ color:var(--destaque); }
/* No telemóvel o painel deixa de ser coluna: vira uma gaveta no topo, fechada,
   para não empurrar a lista para baixo da dobra. */
@media (max-width:820px){
  .tar-quadro{ grid-template-columns:minmax(0,1fr); gap:14px; }
  .tar-painel{ position:static; max-height:none; }
}


/* ============================================================
   TAREFAS · A JANELA EXPANDIDA (o card abre por cima, sem recarregar)
   ⭐ 14/08/2026. O card é o resumo; a janela é a tarefa inteira. O conteúdo vem
   do servidor (rota `/detalhe`), o JavaScript só o põe cá dentro.
   ============================================================ */
.tar-abrir{ color:inherit; text-decoration:none; }
/* A do motor é botão e não link (não se edita): mesma aparência, gesto igual. */
.tar-abrir-btn{ background:none; border:0; padding:0; margin:0; font:inherit; text-align:left; cursor:pointer; }
.tar-abrir:hover{ color:var(--destaque); text-decoration:none; }
.tar-abrir:hover strong{ text-decoration:underline; }
/* A janela é maior que os diálogos de confirmação da casa: leva a tarefa toda.
   ⚠️ `max-height` + scroll interno, senão num telemóvel a tarefa com dez
   comentários passava da altura útil e o fim ficava inalcançável. */
.tar-janela{ width:min(760px, 94vw); max-height:88dvh; overflow-y:auto; padding:0; }
.tar-janela-cab{ position:sticky; top:0; z-index:2; display:flex; align-items:center; gap:12px;
  padding:18px 22px 12px; background:var(--branco); border-bottom:1.5px solid var(--cinza-borda); }
.tar-janela-cab h3{ flex:1; min-width:0; margin:0; font-family:var(--fonte-titulo);
  font-size:17px; font-weight:700; line-height:1.25; }
.tar-janela-cab .btn-link{ font-size:22px; line-height:1; padding:0 4px; color:var(--cinza-medio); }
.tar-janela-cab .btn-link:hover{ color:var(--preto); }
.tar-janela-corpo{ padding:16px 22px 22px; }
/* Dentro da janela os blocos já não precisam de moldura própria: a janela é a
   moldura. Sem isto ficavam cartões dentro de um cartão. */
.tar-janela-corpo .tar-bloco{ border:0; box-shadow:none; padding:0; margin:0 0 22px; }
.tar-janela-corpo .tar-bloco:last-child{ margin-bottom:0; }

/* O cabeçalho da tarefa dentro da janela: o que ela É, antes do que tem por
   baixo. A descrição vai inteira (o corte de duas linhas é da lista, onde ela
   compete com as outras dez). */
.tar-jn-cab{ margin-bottom:20px; }
.tar-jn-desc{ font-size:14.5px; line-height:1.55; margin-bottom:14px; }
.tar-jn-desc > *:first-child{ margin-top:0; }
.tar-jn-meta{ display:grid; grid-template-columns:repeat(auto-fit,minmax(150px,1fr)); gap:10px 18px; margin:0; }
.tar-jn-meta div{ min-width:0; }
.tar-jn-meta dt{ font-size:11px; font-weight:700; text-transform:uppercase; color:var(--cinza-medio); margin:0 0 1px; }
.tar-jn-meta dd{ margin:0; font-size:13.5px; font-weight:500; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.tar-jn-tags{ display:flex; flex-wrap:wrap; gap:6px; margin:14px 0 0; }
.tar-jn-tags .lanc-tag{ text-decoration:none; }

/* ============================================================
   TAREFAS · O TAMANHO DO CARD (pequeno · médio · grande)
   ⭐ Ele, 14/08/2026: "tarefa em cards pequenos (o que também pode ser
   configurável médio, ou maior, nas configurações)".
   Nasce em PEQUENO, como o TickTick e o Todoist: numa lista o que se procura é
   a próxima linha, não o conteúdo de uma.
   ⚠️ A classe governa a LISTA inteira, não cada linha: trocar de tamanho é
   trocar uma palavra, e as vinte linhas obedecem juntas.
   ============================================================ */
/* PEQUENO — o padrão. Uma linha de título, a descrição some, a meta fica.
   A descrição não desaparece do sistema: está na janela, a um clique. */
.tar-lista-pequeno .tar-item{ padding-top:9px; padding-bottom:9px; }
.tar-lista-pequeno .tar-desc,
.tar-lista-pequeno .tar-desc-mais{ display:none; }
.tar-lista-pequeno .tar-topo strong{ font-size:14px; }
.tar-lista-pequeno .tar-meta{ font-size:12px; }

/* MÉDIO — o que estava antes desta versão: duas linhas de descrição. */
.tar-lista-medio .tar-item{ padding-top:14px; padding-bottom:14px; }

/* GRANDE — a descrição inteira na lista, para quem lê a lista como plano. */
.tar-lista-grande .tar-item{ padding-top:18px; padding-bottom:18px; }
.tar-lista-grande .tar-desc-corta{ display:block; -webkit-line-clamp:none; overflow:visible; }
.tar-lista-grande .tar-desc-mais{ display:none; }
.tar-lista-grande .tar-topo strong{ font-size:15.5px; }

/* ============================================================
   TAREFAS · O MENU DA TAREFA (o ⋯ do TickTick)
   ⚠️ `<details>` nativo: abre sem JavaScript e fecha com Esc. Só entram itens
   que EXISTEM — um "guardar como template" que não faz nada é pior do que não
   ter o item.
   ============================================================ */
.tar-menu{ position:relative; }
.tar-menu > summary{ list-style:none; cursor:pointer; display:inline-grid; place-items:center;
  min-width:28px; height:26px; border-radius:var(--raio-xs); color:var(--cinza-medio); font-size:16px; line-height:1; }
.tar-menu > summary::-webkit-details-marker{ display:none; }
.tar-menu > summary:hover{ color:var(--preto); background:var(--cinza-fundo); }
.tar-menu-lista{ position:absolute; right:0; top:calc(100% + 4px); z-index:30; min-width:190px;
  display:flex; flex-direction:column; padding:6px; background:var(--branco);
  border:1.5px solid var(--cinza-borda); border-radius:var(--raio-sm); box-shadow:0 12px 32px rgba(17,17,17,.16); }
.tar-menu-lista form{ display:block; margin:0; }
.tar-menu-i{ display:block; width:100%; text-align:left; background:none; border:0; cursor:pointer;
  font:inherit; font-size:13.5px; padding:8px 10px; border-radius:var(--raio-xs); color:var(--texto); text-decoration:none; }
.tar-menu-i:hover{ background:var(--cinza-fundo); color:var(--preto); text-decoration:none; }
.tar-menu-perigo{ color:var(--vermelho); }
.tar-menu-perigo:hover{ color:var(--vermelho); background:#fdecef; }
/* A fixada diz-se na lista, senão o "fixar" era um gesto sem resposta. */
/* ⚠️ O pin era um EMOJI escrito no `content` do CSS, e emoji muda de desenho
   conforme o aparelho (o 📌 do iPhone não é o do Mac). Agora é o mesmo desenho
   do resto da casa, posto no HTML pelo `icone('pin')`. */
/* ⭐ O CALENDÁRIO DO PAINEL (14/08/2026). Cabe nos 250px do painel e não tem
   uma linha de JavaScript: cada dia é um link.
   ⚠️ 42 casas fixas, sempre: uma grelha que muda de altura conforme o mês faz a
   lista ao lado saltar quando se navega. */
.tar-cal{ margin-top:14px; padding-top:12px; border-top:1px solid var(--cinza-borda); }
/* ⭐ Fecha-se e abre-se, como as pastas aqui de cima: no telemóvel o mês inteiro
   antes da lista é meia tela de rolagem antes de chegar ao trabalho. */
.tar-cal-sum{
  display:flex; align-items:center; justify-content:space-between; gap:8px;
  cursor:pointer; list-style:none; padding:4px 2px; margin-bottom:4px;
  font-size:.78rem; font-weight:600; color:var(--cinza-medio);
}
.tar-cal-sum::-webkit-details-marker{ display:none; }
.tar-cal-sum::after{
  content:''; width:7px; height:7px; margin-left:auto; flex:0 0 auto;
  border-right:1.5px solid currentColor; border-bottom:1.5px solid currentColor;
  transform:rotate(45deg); transition:transform .15s;
}
.tar-cal[open] > .tar-cal-sum::after{ transform:rotate(-135deg); }
/* O mês só aparece no resumo quando está fechado: aberto, ele já está lá dentro,
   entre as setas. */
.tar-cal-sum-mes{ font-style:normal; font-weight:500; text-transform:capitalize; }
.tar-cal[open] > .tar-cal-sum .tar-cal-sum-mes{ display:none; }
.tar-cal-cab{ display:flex; align-items:center; justify-content:space-between; gap:4px; margin-bottom:8px; }
.tar-cal-mes{ font-size:.82rem; font-weight:600; text-transform:capitalize; }
/* A seta é uma só, virada: dois desenhos para o mesmo gesto é o que faz um
   ícone novo aparecer sem ninguém decidir. */
.tar-cal-nav svg{ transform:rotate(180deg); }
.tar-cal-prox svg{ transform:none; }
.tar-cal-grelha{ display:grid; grid-template-columns:repeat(7, 1fr); gap:1px; }
.tar-cal-dow{ text-align:center; font-size:.62rem; text-transform:uppercase;
  color:var(--cinza-medio); padding-bottom:3px; }
.tar-cal-dia{
  position:relative; display:flex; align-items:center; justify-content:center;
  aspect-ratio:1/1; border-radius:var(--raio-xs); font-size:.74rem; color:var(--preto);
  text-decoration:none;
}
.tar-cal-dia:hover{ background:var(--cinza-claro); }
.tar-cal-dia.fora{ color:var(--cinza-borda); }
/* Hoje marca-se com o contorno, e o dia ESCOLHIDO com o cheio: são duas
   perguntas diferentes (onde estou no tempo, o que estou a ver). */
.tar-cal-dia.hoje{ box-shadow:inset 0 0 0 1.5px var(--cinza-medio); font-weight:700; }
.tar-cal-dia.ativo{ background:var(--preto); color:var(--branco); font-weight:700; }
.tar-cal-dia.ativo:hover{ background:var(--preto); }
.tar-cal-ponto{ position:absolute; bottom:3px; width:4px; height:4px; border-radius:50%;
  background:var(--cinza-medio); }
.tar-cal-dia.tem .tar-cal-ponto{ background:var(--cinza-medio); }
/* Trabalho por fazer num dia que já passou é atraso, e o vermelho aqui promete
   o mesmo que na lista. */
.tar-cal-dia.tarde .tar-cal-ponto{ background:var(--vermelho); }
.tar-cal-dia.ativo .tar-cal-ponto{ background:var(--branco); }
.tar-cal-limpar{ display:inline-block; margin-top:8px; font-size:.76rem; color:var(--cinza-medio); }
/* O campo curto que nasce quando se escolhe um dia. */
.tar-dia-nova{ padding:12px 16px; margin-bottom:12px; }
.tar-dia-nova label{ display:block; font-size:.78rem; font-weight:600; margin-bottom:6px; }
.tar-dia-nova input[type=text]{ flex:1 1 220px; min-width:0; }

.tar-fixa-marca{ display:inline-flex; color:var(--cinza-medio); flex:0 0 auto; }
.tar-fixa-marca svg{ width:14px; height:14px; }
@media (max-width:600px){
  .tar-menu > summary{ min-width:40px; height:40px; font-size:18px; }
  /* 🚨 23/08/2026 — O MENU SAÍA PELA TELA, e nenhum LADO fixo resolve isso.
     Aqui estava `right:auto; left:0`, e no celular o ⋯ não fica sempre no
     mesmo lugar: quando a linha de ações QUEBRA ele desce para a esquerda (e
     aí alinhar à esquerda está certo), mas quando NÃO quebra ele fica
     encostado à direita e o menu abria 92px para fora — com os rótulos
     cortados no meio da palavra e a página rolando de lado, que era
     exatamente o que o A6 tinha consertado.
     📉 Medido nos 47 menus desta tela: 11 saíam pela direita; trocar para
     `right:0` fazia 36 saírem pela esquerda. Escolher um lado é só escolher
     qual metade quebra.
     ⭐ Por isso o menu deixou de se ancorar no BOTÃO e passou a ancorar-se no
     CARD: ocupa a largura dele, e a largura do card cabe sempre na tela, venha
     o ⋯ de onde vier. Zero fora da tela, dos dois lados.
     ⚠️ O menu da BARRA da lista não vive dentro de um card — esse mantém a
     âncora no botão, alinhado à DIREITA, que é o lado onde ele fica. */
  .tar-acoes{ position:relative; }
  .tar-menu{ position:static; }
  .tar-menu-lista{ right:0; left:0; min-width:0; }
  .tar-lista-menu{ position:relative; }
  .tar-lista-menu > .tar-menu-lista{ left:auto; right:0; min-width:190px; }
}

/* ============================================================
   BOTÃO DE ÍCONE  ·  `.ic-btn`
   ⭐ Ele, 14/08/2026: *"esses ícones… está parecendo um scratch por cima.
   Queria algo que parecesse mais ícone, design mais fluído, arredondado. No
   estilo desses do Tick. E quando passa o mouse por cima do ícone, ele
   acende."*
   ⚠️ O problema não era o tamanho: era serem CARACTERES de texto (`×`, `✎`).
   Um caractere herda a fonte, muda de desenho conforme o sistema operativo e
   não tem espessura de traço — por isso lia-se como rabisco. Agora são SVG do
   `icone()`, com o traço arredondado de toda a família.
   ⚠️ Alvo de 32px no rato e 40px no polegar: a área é maior que o desenho, que
   é o que faz um ícone pequeno continuar fácil de acertar.
   ============================================================ */
.ic-btn{
  display:inline-grid; place-items:center; box-sizing:border-box;
  width:32px; height:32px; padding:0; border:0; border-radius:var(--raio-sm);
  background:transparent; color:var(--cinza-medio); cursor:pointer;
  text-decoration:none; line-height:0;
  transition:color .15s ease, background-color .15s ease;
}
.ic-btn svg{ width:18px; height:18px; }
/* ⭐ "Acende": o ícone ganha cor e um fundo suave por baixo. O fundo é o que dá
   a sensação de botão sem precisar de moldura permanente — moldura em seis
   ícones por linha vira grade, e a lista deixa de se ler. */
.ic-btn:hover, .ic-btn:focus-visible{ color:var(--preto); background:var(--cinza-fundo); text-decoration:none; }
.ic-btn:focus-visible{ outline:2px solid var(--preto); outline-offset:1px; }
.ic-btn:active{ transform:scale(.94); }
/* Dentro de uma linha de passo/anexo o alvo é menor: ali o ícone acompanha uma
   linha de texto e não uma fila de ações. */
.ic-btn-mini{ width:26px; height:26px; border-radius:var(--raio-xs); }
.ic-btn-mini svg{ width:15px; height:15px; }
/* O que apaga acende em vermelho: a cor só aparece na intenção, nunca em
   repouso — seis vermelhos numa lista de vinte linhas é ruído. */
.ic-btn-perigo:hover, .ic-btn-perigo:focus-visible{ color:var(--vermelho); background:#fdecef; }
/* O ⋯ do menu usa o mesmo desenho. */
.tar-menu > summary{ width:32px; height:32px; border-radius:var(--raio-sm); color:var(--cinza-medio);
  transition:color .15s ease, background-color .15s ease; }
.tar-menu > summary svg{ width:18px; height:18px; }
.tar-menu > summary:hover, .tar-menu[open] > summary{ color:var(--preto); background:var(--cinza-fundo); }
@media (max-width:600px){
  .ic-btn{ width:40px; height:40px; }
  .ic-btn svg{ width:20px; height:20px; }
  .tar-menu > summary{ width:40px; height:40px; }
}

/* Os ícones que vivem em caixas próprias (as seis casas do Diário, o × dos
   chips da escala, o do turno) passaram a ser SVG na v0.106. Aqui só se lhes dá
   tamanho e o "acende" — a caixa e o alinhamento continuam a ser deles, que foi
   trabalho feito à medida (F7) e não se toca. */
.lanc-ico svg, .turno-x svg, .chip-x svg, .aviso-excluir svg,
.rd-rm svg, .perda-remover svg, .js-rm svg{ width:16px; height:16px; }
.lanc-ico{ transition:color .15s ease, border-color .15s ease, background-color .15s ease; }
.lanc-ico:hover{ background:var(--cinza-fundo); }
/* O que apaga acende em vermelho, e só na intenção. */
.lanc-ico-apagar:hover{ color:var(--vermelho); border-color:var(--vermelho); background:#fdecef; }

/* O clipe e o cadeado vivem colados a um número ou a nada: alinham pela caixa
   da letra, não pela linha. Sem isto ficavam a flutuar meio ponto acima. */
.lanc-clipe svg, .lanc-trancado svg{ vertical-align:-3px; }
.tar-meta svg{ width:14px; height:14px; vertical-align:-2px; }

/* ⭐ MODELOS DE TAREFA (14/08/2026): a fila de escolhas por cima do formulário
   de criar. Cada modelo é um chip que é um LINK, e o escolhido fica marcado. */
.tar-modelos{ display:flex; align-items:center; gap:8px; flex-wrap:wrap; padding:12px 16px; margin-bottom:12px; }
.tar-modelos-rot{ font-size:.8rem; font-weight:600; color:var(--cinza-medio); }
.tar-modelos .chip{ text-decoration:none; display:inline-flex; align-items:center; gap:6px; }
.tar-modelos .chip:hover{ background:var(--cinza-borda); }
.tar-modelos .chip.ativo{ background:var(--preto); color:var(--branco); }
.tar-modelos .chip.ativo .lanc-sub{ color:var(--branco); opacity:.75; }
/* As subtarefas que o modelo traz dentro, na gestão dos modelos. */
.tar-modelo-filhas{ display:flex; flex-wrap:wrap; gap:6px; flex-basis:100%; margin-top:4px; }
/* ⭐ A COR DA ETIQUETA (14/08/2026). A cor vem do catálogo por variável, e o
   texto continua a ser lido pelo contraste do fundo claro: pintar o fundo
   inteiro com a cor escolhida pelo cliente dava chips ilegíveis quando ele
   escolhesse amarelo. */
.tar-tag-cor{ border-color:var(--tag-cor); color:var(--tag-cor); }
.tar-tag-cor::before{ content:''; display:inline-block; width:6px; height:6px; border-radius:50%;
  background:var(--tag-cor); margin-right:5px; vertical-align:middle; }
/* 🚨 22/08/2026 — ESTE SELETOR FICOU ÓRFÃO e ninguém deu por isso.
   Quando a tela de gerenciar virou UM formulário só (item 8), o
   `.tar-tag-form` deixou de existir — e com ele foi-se o estilo do seletor de
   cor, que voltou ao desenho CRU do navegador: um retângulo cinzento com
   borda dupla, do tamanho que o sistema operativo quisesse.
   ⚠️ É a armadilha de estilar pelo nome do FORMULÁRIO em vez de pelo campo:
   mexer no markup apaga o CSS em silêncio. Agora o seletor é o campo. */
/* Só o tamanho: o acabamento é a regra base de `input[type=color]`. */
.cfg-linha input[type=color], .cfg-nova input[type=color]{
  width:30px; height:30px; flex:0 0 auto;
}

/* ⭐⭐ O QUADRO (kanban) POR SECÇÕES — 14/08/2026.
   ⚠️ As colunas rolam na HORIZONTAL dentro do quadro, e não a página: quem tem
   sete secções não pode empurrar a tela inteira para o lado. No telemóvel cada
   coluna ocupa quase o ecrã, e passa-se com o dedo. */
.tar-quadro-kanban{
  display:flex; gap:12px; align-items:flex-start;
  overflow-x:auto; padding-bottom:8px; scroll-snap-type:x proximity;
  /* 🚨 26/08/2026 — O QUADRO ESTICAVA A PÁGINA, e o `overflow-x:auto` aqui em
     cima NÃO chegava. Medido a 375px: com o quadro à vista o `scrollWidth` do
     documento ia a **1.531px** e a página rolava de lado 31,5px; escondendo só
     os `<select>` de mover, voltava a 375. É o tamanho intrínseco do controlo a
     escapar do contentor de rolagem e a esticar a viewport — e a barra do menu,
     que é `fixed` com `left:0;right:0`, esticava atrás dele até 1.500px,
     piorando o que já estava mau.
     ⚠️ **Já era assim desde 14/08**, quando o quadro nasceu: com três colunas
     dava 641px e não chegava a rolar, por isso ninguém viu. O quadro do SETOR,
     com seis, foi só quem o pôs à vista.
     ⭐ `contain:paint` resolve porque diz o que já era verdade: **o que se
     desenha aqui dentro fica aqui dentro**. Não corta nada de novo — o
     `overflow-y` desta caixa já computa `auto` (uma caixa com um eixo cortado
     corta os dois), e os menus dos cards são `static`.
     ⚠️ Provado a sério, como manda a lição de 25/08: `scrollLeft = 999` e a
     página não se move. Comparar larguras não prova transbordo. */
  contain:paint;
}
.tar-coluna{
  flex:0 0 300px; max-width:300px; scroll-snap-align:start;
  background:var(--cinza-fundo); border-radius:var(--raio); padding:10px 10px 4px;
}
.tar-coluna-cab{
  display:flex; align-items:center; justify-content:space-between; gap:8px;
  font-size:.82rem; font-weight:700; margin:2px 4px 10px; text-transform:none;
}
.tar-coluna-n{ font-weight:600; color:var(--cinza-medio); font-variant-numeric:tabular-nums; }
/* ⭐ DE QUE PROJETO É A COLUNA — só no quadro de um SETOR, onde as secções dos
   projetos presos a ele entram no fim (26/08/2026, o modelo dele).
   ⚠️ É o nome do DONO da coluna, não o título dela: fica em traço fino e a
   empurrar o contador, para se ler como legenda e nunca competir com o nome da
   secção. Cor forte só em selo pequeno — regra da casa. */
.tar-coluna-de{
  flex:1; min-width:0; font-style:normal; font-weight:500; font-size:.74rem;
  color:var(--cinza-medio); white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.tar-coluna-de::before{ content:'· '; }
.tar-coluna-vazia{ margin:0 4px 10px; }
/* O card no quadro é o MESMO da lista, sem as bordas de linha: dentro da coluna
   ele é um cartão, não uma linha de tabela. */
.tar-card{
  display:block; background:var(--branco); border:1px solid var(--cinza-borda);
  border-left-width:3px; border-radius:var(--raio-sm); padding:10px 12px; margin-bottom:8px;
}
.tar-card .tar-acoes{ flex-wrap:wrap; margin-top:8px; }
.tar-mover{ margin-top:8px; }
.tar-mover select{ flex:1 1 auto; min-width:0; padding:5px 8px; font-size:12.5px; }
.tar-vista{ display:flex; gap:6px; margin:0 0 12px; }
.tar-vista .chip{ cursor:pointer; border:1px solid var(--cinza-borda); background:var(--branco); }
.tar-vista .chip.ativo{ background:var(--preto); color:var(--branco); border-color:var(--preto); }

/* ⭐⭐⭐ A SELEÇÃO MÚLTIPLA, no desenho que ELE ditou (20/08/2026, com dois
   prints do TickTick). Ver [[dext-selecao-padrao-da-casa]].

   🚨 **A seleção é um ESTADO DO CARD, não uma coluna nova.** No Diário a caixa
   de seleção existe SEMPRE e ocupa uma coluna em todas as linhas; ele foi ver e
   recusou esse molde. Aqui, sem seleção não há um pixel a mais no ecrã.

   ⚠️ E marca-se por DENTRO (`inset`), nunca com borda: uma borda de 1,5px
   empurrava as vinte linhas de lado a cada clique, e "a lista não salta" é
   regra da casa desde 18/08. */
.tar-sel{ background:var(--cinza-fundo); box-shadow:inset 0 0 0 1.5px var(--preto); border-radius:var(--raio-sm); }
/* Enquanto se marca, o card inteiro é o alvo: os links e botões de dentro
   deixam de apanhar o toque, senão um dedo grosso no "Feita" fechava a tarefa
   em vez de a marcar. O texto também não se arrasta — selecionar palavras no
   meio de uma seleção de cards não é gesto nenhum. */
body.tar-selecionando .tar-item{ cursor:pointer; -webkit-user-select:none; user-select:none; }
body.tar-selecionando .tar-item a,
body.tar-selecionando .tar-item button,
body.tar-selecionando .tar-item summary,
body.tar-selecionando .tar-item select,
body.tar-selecionando .tar-item input{ pointer-events:none; }

/* O `⋯` da lista — a porta disto no telemóvel. */
.tar-barra{ display:flex; justify-content:flex-end; align-items:center; margin:0 0 6px; }

/* ⚠️ **Barra fixa no rodapé, NUNCA** — foi o que ele recusou por nome. Este
   bloco vive onde o dedo/rato está: `position:fixed` com as coordenadas do
   clique, ou encostado ao `⋯`. */
.tar-lote-menu{
  position:fixed; z-index:60; min-width:236px; max-width:min(340px, calc(100vw - 16px));
  max-height:calc(100vh - 24px); overflow:auto;
  display:flex; flex-direction:column; gap:2px; padding:6px;
  background:var(--branco); border:1.5px solid var(--cinza-borda);
  border-radius:var(--raio-sm); box-shadow:0 12px 32px rgba(17,17,17,.16);
}
/* `hidden` tem de ganhar ao `display:flex` — senão o menu nascia à vista. */
.tar-lote-menu[hidden], .tar-lote-menu .tar-lote-f[hidden], .tar-lote-bloco[hidden]{ display:none; }
.tar-lote-cab{ margin:0; padding:6px 10px 4px; font-size:12px; color:var(--cinza-medio); }
.tar-lote-f{ display:flex; flex-wrap:wrap; align-items:center; gap:4px; margin:0; }
.tar-lote-bloco{
  display:flex; flex-direction:column; gap:5px;
  margin-top:4px; padding:8px 10px; border-top:1px solid var(--cinza-borda);
}
.tar-lote-rot{ font-size:11.5px; letter-spacing:.04em; text-transform:uppercase; color:var(--cinza-medio); }
.tar-lote-bloco select,
.tar-lote-bloco input[type="date"],
.tar-lote-bloco input[type="text"]{ flex:1 1 auto; min-width:0; padding:5px 8px; font-size:12.5px; }
.tar-lote-sair{ margin-top:4px; border-top:1px solid var(--cinza-borda); color:var(--cinza-medio); }
@media (max-width: 760px){
  .tar-coluna{ flex-basis:86%; max-width:86%; }
}
/* Rótulo que existe para quem lê com leitor de ecrã, e não ocupa espaço. */
.visualmente-oculto{
  position:absolute; width:1px; height:1px; overflow:hidden;
  clip:rect(0 0 0 0); clip-path:inset(50%); white-space:nowrap;
}
/* ⭐ Os filtros salvos, no topo do painel. */
.tar-pn-filtros{ margin-bottom:10px; }
.tar-pn-rot{ display:block; font-size:.68rem; text-transform:uppercase; letter-spacing:.5px;
  color:var(--cinza-medio); margin:6px 4px 4px; font-weight:700; }
.tar-pn-filtro{ display:flex; align-items:center; gap:2px; }
.tar-pn-filtro .tar-pn-item{ flex:1 1 auto; min-width:0; }
/* O × de apagar só aparece ao passar por cima: numa barra lateral de dez linhas,
   dez cruzes vermelhas são ruído. No telemóvel fica sempre visível (não há
   hover para revelar nada). */
.tar-pn-filtro .ic-btn{ opacity:0; transition:opacity .12s; }
.tar-pn-filtro:hover .ic-btn, .tar-pn-filtro:focus-within .ic-btn{ opacity:1; }
@media (hover: none){ .tar-pn-filtro .ic-btn{ opacity:.7; } }
.tar-pn-guardar{ margin:0 0 12px; gap:4px; }
.tar-pn-guardar input[type=text]{ flex:1 1 auto; min-width:0; padding:5px 8px; font-size:12.5px; }

/* ⭐ Seletor do ícone do sistema: escolhe-se a olhar, e o escolhido tem de se
   ver de longe (a moldura, não só um ponto). */
/* ⚠️ `flex-start` e não o `stretch` de omissão: na Conta, a opção "Seguir a
   casa" leva um rótulo por baixo e é mais alta, e sem isto as outras seis
   esticavam-se para a acompanhar (medido no navegador: 85px contra 72px). */
.cfg-icones{ display:flex; flex-wrap:wrap; gap:12px; align-items:flex-start; }
.cfg-icone{ display:inline-flex; padding:6px; border:2px solid transparent; border-radius:var(--raio);
  cursor:pointer; line-height:0; background:var(--fundo); }
.cfg-icone input{ position:absolute; opacity:0; width:0; height:0; }
.cfg-icone img{ border-radius:var(--raio); display:block; }
.cfg-icone:hover{ border-color:var(--cinza-borda); }
.cfg-icone-ativo, .cfg-icone:has(input:checked){ border-color:var(--vermelho); }
/* ⭐ "Seguir a casa", na Conta: é o mesmo botão de ícone, mas precisa de dizer
   o que é — as outras seis explicam-se sozinhas pela cor, esta não. */
.cfg-icone:has(.cfg-icone-rot){ flex-direction:column; align-items:center; gap:5px; }
.cfg-icone-rot{ font-size:11px; line-height:1.2; color:var(--cinza-medio); text-align:center; max-width:60px; }


/* ============================================================
   PAGAMENTO MISTO — a conferência do total contra as partes
   ⭐ Pedido dele, 21/08/2026: *"se o valor total que coloquei não bater com a
   soma de pequenos lançamentos internos, fica vermelho, senão, passa"*.
   ⚠️ O vermelho vai no CAMPO e no selo, e o selo diz DE QUANTO é a diferença —
   "não bate" manda procurar; "não bate, falta €12,40" manda corrigir.
   ============================================================ */
.lanc-confere{ display:flex; gap:10px; flex-wrap:wrap; align-items:baseline;
  margin:6px 0 0; font-size:13px; color:var(--cinza-texto); }
.lanc-confere-selo{ font-weight:600; }
.lanc-confere-selo.e-ok{ color:var(--verde, #1a7f37); }
.lanc-confere-selo.e-erro{ color:var(--vermelho, #b3261e); }
/* ⚠️ A borda muda, não o fundo: fundo vermelho num campo com número dentro
   torna o número mais difícil de ler, que é o oposto do que se quer. */
input.campo-erro{ border-color:var(--vermelho, #b3261e) !important;
  box-shadow:0 0 0 2px color-mix(in srgb, var(--vermelho, #b3261e) 18%, transparent); }
input.campo-ok{ border-color:var(--verde, #1a7f37) !important; }


/* ⚠️ 21/08/2026: um link de AÇÃO PERIGOSA ao lado de um normal. Nasceu com o
   "excluir projeto", que fica ao lado do "arquivar" — dois links iguais em cima
   um do outro, e um deles não tem volta. A cor é o único aviso antes do clique. */
.btn-link-perigo{ color:var(--vermelho) !important; }
.btn-link-perigo:hover{ color:var(--vermelho-hover) !important; }

/* ⭐ ALERGÉNIOS (23/08/2026) — os 14 do Regulamento (UE) 1169/2011.
   ⚠️ Grade que se adapta: são catorze pares nome+seletor, e numa coluna vertical
   empurravam o resto da ficha para muito longe. `auto-fill` com mínimo de 190px
   dá quatro colunas no computador e uma no telemóvel, sem media query. */
.alg-grade{ display:grid; grid-template-columns:repeat(auto-fill, minmax(190px, 1fr)); gap:8px 14px; margin-bottom:18px; }
.alg-item{ display:flex; align-items:center; justify-content:space-between; gap:8px;
  padding:6px 10px; border:1px solid var(--linha); border-radius:var(--raio-sm); background:var(--branco); }
.alg-nome{ font-size:13px; color:var(--texto); }
.alg-item select{ max-width:118px; font-size:12px; padding:3px 6px; }
/* A leitura, na tela de ver: uma etiqueta por alergénio, com a origem no title. */
.alg-lista{ display:flex; flex-wrap:wrap; gap:8px; margin:6px 0 4px; }
/* 🚨 A SÉTIMA PÍLULA, migrada a 26/08/2026. `.alg-selo` era o `.selo` outra
   vez — cápsula, texto pequeno, negrito — com nome próprio e medidas próprias
   (12px/600 contra 11,5px/700), e com a sua paleta particular de dois tons.
   ⭐ E os dois tons já existiam na paleta da casa, com o mesmo significado:
   **contém** é `selo-perigo` (é a coisa que pode magoar alguém) e **traços** é
   `selo-alerta` (pede atenção, não é erro). Escrever `#fff6e5` à mão aqui era
   inventar um âmbar ao lado do âmbar que a casa já tinha.
   ⚠️ O `.alg-origem` fica: é o texto MAIS FINO dentro do selo, e não a forma. */
.alg-origem{ font-weight:400; opacity:.75; }

/* ⭐ ENGENHARIA DE CARDÁPIO (23/08/2026) — os quatro quadrantes de Kasavana-Smith.
   ⚠️ A cor diz a AÇÃO, não o nome: verde é "não mexa", âmbar é "mexa no preço",
   azul é "mostre mais", cinza é "pense em tirar". */
.card-quad{ display:inline-block; padding:3px 10px; border-radius:999px; font-size:12px; font-weight:600; white-space:nowrap; }
.card-estrela{ background:#e8f6ed; color:#1c6b3d; }
.card-cavalo{ background:#fff6e5; color:#8a5a00; }
.card-enigma{ background:#e9f0fb; color:#1f4f96; }
.card-cao{ background:var(--cinza-claro, #f1f1f2); color:var(--cinza-medio, #6b6b70); }
.card-acoes{ margin:10px 0 26px; display:flex; flex-direction:column; gap:6px; }
.card-acoes .card-quad{ margin-right:6px; }

/* ═══════════════════ AVALIAÇÕES (24/08/2026) ═══════════════════
   Ele: *"depois da reserva do cliente, ele recebe um email automático
   perguntando como foi a experiência"* — e, no fim, o convite ao Google com o
   texto pronto para colar.
   ⚠️ A tela do cliente reaproveita o cartão público das reservas (`.pub-wrap`,
   `.pub-cartao`): é a mesma casa, o mesmo logo, a mesma moldura. Aqui só entram
   as peças que não existiam — as estrelas e o bloco de copiar. */

/* ── as estrelas ──
   🚨 Cada uma é um `<button type=submit>`: sem JavaScript, tocar numa envia a
   avaliação. Por isso se despem de aparência de botão, e não o contrário. */
/* ⚠️ O cartão da avaliação é mais estreito que o das reservas: aqui há uma
   pergunta e cinco estrelas, e uma coluna larga fazia o gesto parecer maior do
   que é. */
.aval-cartao{ max-width:440px; }
.aval-estrelas{ display:flex; justify-content:center; gap:6px; margin:18px 0 6px; }
.aval-estrela{ background:none; border:none; cursor:pointer; padding:4px;
  font-size:38px; line-height:1; color:var(--cinza-borda);
  transition:color .12s, transform .12s; }
.aval-estrela:hover, .aval-estrela:focus-visible{ transform:scale(1.08); }
.aval-estrela.acesa{ color:#e8b53d; }
.aval-estrela:focus-visible{ outline:2px solid var(--vermelho); outline-offset:3px; border-radius:var(--raio-xs); }
/* ⚠️ 44px de alvo com o dedo, como o resto da casa — a régua é `pointer:coarse`,
   não largura de tela (auditoria de 23/08). */
@media (pointer:coarse){
  .aval-estrela{ min-width:44px; min-height:44px; }
}
/* Na tela de agradecimento as estrelas são leitura, não gesto. */
.aval-estrelas-lidas{ font-size:26px; gap:3px; margin:4px 0 10px; }
.aval-estrelas-lidas .aval-estrela{ font-size:26px; padding:0; cursor:default; }

.aval-titulo{ font-family:var(--fonte-titulo); font-size:21px; margin:2px 0 6px; text-align:center; }
.aval-sub{ color:var(--cinza-medio); font-size:14px; text-align:center; margin:0 0 4px; }
.aval-legenda{ text-align:center; font-size:13px; font-weight:600; color:var(--cinza-medio);
  min-height:20px; margin:0 0 14px; }
.aval-comentario{ margin-top:6px; }
.aval-quem{ margin-top:4px; }
.aval-opcional{ margin-top:-6px; }

/* ── o convite ao Google ──
   🚨 Sai para TODA A GENTE, seja qual for a nota: mandar só quem gostou é
   *review gating*, o Google proíbe, e custa a ficha da casa. O que se oferece é
   o texto pronto — conveniência, nunca filtro. */
.aval-google{ margin-top:22px; padding-top:18px; border-top:1px solid var(--cinza-borda); }
.aval-google-tit{ font-weight:700; font-size:14.5px; margin:0 0 10px; text-align:center; }
.aval-copiar{ display:flex; align-items:flex-start; gap:10px; background:var(--cinza-fundo);
  border-radius:var(--raio-sm); padding:12px 14px; margin-bottom:10px; }
.aval-copiar-txt{ flex:1; margin:0; font-size:13.5px; line-height:1.5; color:var(--texto); }
/* ⚠️ `text-decoration:none` explícito: dentro do cartão público há uma regra
   que sublinha todo `a`, e o botão do Google saía com um risco por baixo —
   parecia um link partido, não o gesto principal da tela. */
.btn-google{ display:block; text-align:center; margin-top:10px; text-decoration:none; }

/* ── a tela de gestão ── */
.aval-resumo{ margin-bottom:18px; }
/* A distribuição por nota, e cada barra é um FILTRO: ver "as três de 2
   estrelas" é o gesto seguinte a reparar que existem três. */
.aval-barras{ display:flex; flex-direction:column; gap:6px; margin:0 0 22px; max-width:420px; }
.aval-barra{ display:flex; align-items:center; gap:10px; text-decoration:none; color:inherit;
  padding:3px 6px; border-radius:var(--raio-sm); transition:background .12s; }
.aval-barra:hover{ background:var(--cinza-fundo); }
.aval-barra.ativa{ background:var(--cinza-fundo); font-weight:700; }
.aval-barra-rot{ font-size:12.5px; font-weight:600; min-width:26px; color:var(--cinza-medio); }
.aval-barra-trilho{ flex:1; height:8px; background:var(--cinza-fundo); border-radius:999px; overflow:hidden; }
.aval-barra-cheia{ display:block; height:100%; background:#e8b53d; border-radius:999px; }
.aval-barra-n{ font-size:12.5px; min-width:24px; text-align:right; font-variant-numeric:tabular-nums; }

.aval-lista{ display:flex; flex-direction:column; gap:12px; }
.aval-item{ background:var(--branco); border:1px solid var(--cinza-borda);
  border-radius:var(--raio); padding:14px 16px; }
/* ⚠️ A nota baixa tem barra à esquerda, e não fundo vermelho: é para saltar à
   vista numa lista, não para gritar. Mesma decisão da `.linha-marca`. */
.aval-item-baixa{ border-left:3px solid var(--vermelho); }
.aval-item-topo{ display:flex; align-items:center; gap:8px; flex-wrap:wrap; margin-bottom:6px; }
.aval-item-nota{ color:#e8b53d; font-size:15px; letter-spacing:1px; }
.aval-item-quem{ font-weight:700; font-size:14px; }
.aval-item-data{ font-size:12.5px; color:var(--cinza-medio); font-variant-numeric:tabular-nums; }
.aval-item-txt{ margin:0; font-size:14px; line-height:1.55; color:var(--texto); }
.aval-item-mail{ margin:8px 0 0; font-size:12.5px; }

/* ⭐ A TRAVA DAS COMPRAS: número, medida e botão numa linha só (25/08/2026).
   ⚠️ `justify-content:flex-end` porque a célula da ação alinha à direita como
   as outras da tabela; no cartão do telemóvel a `.tabela-cards td` já a põe
   depois do rótulo, e o `flex-wrap` do `.cfg-linha` trata do resto. */
/* 🐞 O BOTÃO CAÍA PARA A SEGUNDA LINHA em todas as linhas da tabela, mesmo com
   1500px de ecrã (auditoria de 25/08). Duas causas somadas:
   · `min-width:90px` do `.cfg-linha input` GANHA ao `max-width:74px` — em CSS o
     mínimo manda sobre o máximo, e o campo do número ficava com 90px;
   · `.cfg-linha` quebra linha, e a coluna nunca chegava a pedir a largura de
     que precisava.
   ⭐ Agora o controlo NÃO quebra, e é a coluna que cresce para o servir — que é
   o que o `white-space:nowrap` do `.td-acoes` já queria. */
/* ⚠️ O CUSTO NÃO SE PARTE do seu "/L" (25/08/2026). É a mesma regra do
   `.dash-num`: um número e a sua unidade são uma coisa só, e quebrá-los ao meio
   dá "€4,00" numa linha e "/L" na seguinte — que se lê como duas colunas. */
.conf-custo{ white-space:nowrap; }

/* ⭐ A linha do "como se compra", por baixo do nome do fornecedor. Discreta de
   propósito: é contexto para quem está a decidir, não um aviso. */
.lc-forn-como{ margin:-6px 0 10px; display:flex; align-items:center; gap:4px; flex-wrap:wrap; }
.lc-forn-como .selo{ margin-right:2px; }

.sug-por{ justify-content:flex-end; flex-wrap:nowrap; }
.sug-por input[type=text]{ flex:0 0 64px; min-width:0; max-width:64px; text-align:right; }
.sug-por select{ max-width:96px; }
