/* ============================================================
   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;
  /* ⚠️ ESCURECIDO DE #8a8a8a PARA #6e6e6e EM 28/08/2026, e não foi gosto: foi
     a primeira medição de CONTRASTE da casa. O #8a8a8a dava **3,45** sobre
     branco e **3,14** sobre o `--cinza-fundo` — o mínimo legível para texto
     pequeno é 4,5. Ou seja: toda a ajuda, todo o subtítulo e o `.selo-neutro`
     (a etiqueta mais usada do sistema) estavam abaixo do mínimo.
     ⭐ O #6e6e6e é o valor MAIS CLARO que passa nos dois fundos (5,10 e 4,64) —
     escolhido para mudar o menos possível, não para ficar bonito.
     ⭐ E um token conserta 274 usos de uma vez: é para isto que eles servem. */
  --cinza-medio:#6e6e6e;
  --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 lugar, 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 tela, 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 lugares — `.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 pegou no `.alg-selo`. */
  /* ⚠️ E o âmbar desceu de #b26a00 para #a05f00 pela mesma medição: sobre o
     `--ambar-fundo` dava **3,86**. O #a05f00 é o mais claro que passa (4,63). */
  --ambar:#a05f00;
  --ambar-fundo:#fff3e0;
  /* ⭐ O ÂMBAR VIVO é outro trabalho, e por isso tem outro nome (28/08/2026):
     o `--ambar` acima é COR DE TEXTO (escuro, para ler); este é a BASE DE
     MISTURA dos fundos suaves (`color-mix(... 16%, transparent)`) e do pino da
     mesa reservada. Dobrar os dois num só dava fundos cor de barro.
     ⚠️ Estava escrito à mão em cinco lugares. */
  --ambar-vivo:#f59e0b;
  /* ⭐⭐ O AZUL era a única família de sinal SEM NOME (28/08/2026) — e é usada
     pela auditoria, pela lista de espera e pelos estados da reserva. Eram
     cinco hexadecimais escritos à mão a dizer a mesma coisa: «está a
     acontecer, e não é bom nem mau». Sinal sem nome é sinal que se duplica. */
  --azul:#1d4ed8;
  --azul-fundo:#e8f0fe;
  /* ⭐ 04/09/2026 · O roxo do FREELANCER. Sai da paleta da casa (`ameixa`,
     `Config::PALETA`) e entra aqui porque é a primeira vez que a interface
     precisa dele.
     🚨 A cor escolheu-se por ELIMINAÇÃO, e é essa a razão que interessa: verde
     já quer dizer «está bem», vermelho «está mal», âmbar «atenção» e azul
     «informação». Um freelancer não é nada disso — não é um estado, é uma
     NATUREZA. Reaproveitar uma cor de estado ensinava a lê-lo como um aviso. */
  --roxo:#7e22ce;
  --roxo-fundo:#f6ecff;

  /* 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 arquivo, 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%). */
  /* Largura da barra lateral, lida pelas faixas fixas e pelo recado (.flash-*).
     Muda para 70px na barra recolhida (ver BARRA RECOLHIDA). */
  --sb-larg:230px;
  --raio:14px;
  --raio-sm:10px;
  --raio-xs:6px;
  --sombra:0 12px 40px rgba(17,17,17,.10);

  /* ⭐⭐ A ESCALA DAS CÁPSULAS (28/08/2026) — o mesmo remédio dos cantos, e pela
     mesma razão. Ele: *"desenvolver um padrão de design coerente e elegante,
     pra seguir em todos os módulos e páginas"*.
     🚨 Medido antes de mexer: **23 cápsulas, NOVE tamanhos de letra e CATORZE
     paddings** — uma delas em `rem` no meio de vinte e duas em `px`. A forma
     estava unificada desde a fase 1 (todas são 999px, e nenhuma é o selo com
     outro nome); a MEDIDA nunca tinha sido olhada. É por isso que o sistema não
     se lia como um só: as peças eram as mesmas e mediam todas diferente.
     ⚠️ Três degraus chegam, e cada um tem um trabalho:
       `etiqueta`  o que CLASSIFICA e não se clica — o selo e a sua família
       `controle`  o que se CLICA — navegação, filtros, chips, `summary`
       `contador`  o NÚMERO dentro de um círculo — os badges
     ⚠️ Fora da escala ficam três, cada uma com o seu porquê escrito onde vive:
     a seta do painel (é um glifo dimensionado para o alvo de 44px), o pulso do
     relógio (é um pulso, não texto) e a `.etiqueta-base` (é a nota de rodapé de
     um número, e o seu trabalho é ser mais discreta do que ele). */
  --cap-etiqueta-fonte:11.5px;  --cap-etiqueta-peso:700;  --cap-etiqueta-pad:3px 10px;
  --cap-controle-fonte:13px;    --cap-controle-peso:600;  --cap-controle-pad:7px 14px;
  --cap-contador-fonte:11px;    --cap-contador-peso:700;  --cap-contador-pad:1px 7px;
}

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

/* 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; }
/* 🐞 29/09/2026 (auditoria no celular): um seletor cresce até à opção mais longa,
   e o campo de arquivo tem largura fixa do navegador — nenhum dos dois respeitava
   a caixa. Em Processos (atribuir pessoa) e na Minha conta (a foto), a página
   rolava para o lado. Regra geral: nenhum passa da largura de quem o contém. */
select, input[type=file]{ max-width:100%; }
.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:not(:focus-visible), .campo textarea:focus:not(:focus-visible){ 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. */
/* 🚨🚨 04/09/2026 · NO IPHONE ELES SAÍAM DA CAIXA. Ele, com um print do
   formulário de reserva: *"o campo data e horário estão pra fora e fora do
   padrão, deixa do mesmo tamanho que as outras."*
   ⚠️ **Não reproduz no Chromium** — medi a 375px na cópia e os cinco campos do
   formulário davam exactamente 277px, todos iguais. É do **Safari do iOS**, que
   trata `date` e `time` como controlo nativo com tamanho próprio e ignora a
   largura que lhe damos. Por isso o `width:100%` que já lá estava não chegava.
   ⭐ `appearance:none` é o que o faz aceitar a nossa medida — passa a ser uma
   caixa como as outras. O desenho não se perde: a borda, o raio, o padding e a
   cor vêm todos da regra de cima, e é ISSO que ele pediu («do mesmo tamanho que
   as outras»).
   ⚠️ `max-width:100%` é o cinto: mesmo que um dia um motor volte a inventar uma
   largura mínima, ela não passa da célula. */
.campo input[type=date], .campo input[type=time]{
  min-width:0; max-width:100%;
  appearance:none; -webkit-appearance:none;
}
.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 tela 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 tela:
     · `: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, pego 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 tela. É exactamente o defeito que a
   v0.31.1 tinha resolvido para as telas, e que os diálogos nunca chegaram a
   pegar. `dialog` entra na MESMA lista `:where()`, portanto a base continua a
   valer 0,0,1 e a perder de toda a gente. */
/* ⚠️ `.tlin-solto` pela mesma razão do `dialog`: o balão da linha rápida muda-se
   para o `<body>` quando abre (23/09/2026). */
:where(.conteudo, dialog, .tlin-solto) input:where(:not([type=checkbox],[type=radio],[type=hidden],[type=color],[type=range])),
:where(.conteudo, dialog, .tlin-solto) select,
:where(.conteudo, dialog, .tlin-solto) 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, .tlin-solto) input:where(:not([type=checkbox],[type=radio],[type=hidden])):focus,
:where(.conteudo, dialog, .tlin-solto) select:focus:not(:focus-visible), :where(.conteudo, dialog, .tlin-solto) textarea:focus:not(:focus-visible){
  outline:none; border-color:var(--preto);
}

/* ══════════════════════════════════════════════════════════════════════
   ⭐⭐⭐ OS BOTÕES DA CASA — UM SISTEMA SÓ (27/09/2026, pedido dele).
   *"Quero que seja mais padronizado, mesmo que tenha mais opções. Não dá pra
   uma página ter um tipo de botão, um visual, um estilo, e na outra outro."*

   Antes: o principal grande era da cor da marca e o pequeno era PRETO; bordas
   de 1px aqui e 1,5px ali; cinco alturas, quatro tamanhos de letra; o
   `.btn-ghost` e o `.btn-sec` quase iguais mas não; o `.btn-export` era um
   secundário com outro nome e outra medida; e oito telas mudavam o tamanho do
   botão só para si.

   AGORA, duas escolhas e nada mais:
     TAMANHO  .btn (normal) · .btn-mini (pequeno) · .btn-grande
              + .btn-bloco quando tem de ocupar a largura (portas: login, PIN)
     TOM      principal (sem classe: a cor do botão da marca)
              .btn-sec     secundário — branco, contorno
              .btn-ghost   discreto — sem fundo, texto cinza
              .btn-perigo  destrutivo — contorno vermelho, enche ao passar
              .btn-ok      concluir — verde
              .btn-link    só texto (e .btn-cancelar, o link neutro)
   Qualquer tom em qualquer tamanho: `btn-mini btn-perigo`, `btn btn-sec`.
   Nomes antigos que continuam a valer (sinónimos, mesmo desenho):
   `.btn-inline` (hoje todo botão já tem a largura do texto), `.btn-mini-ghost`
   = fantasma, `.btn-mini-perigo` = perigo, `.btn-export` = secundário.
   ⚠️ Uma tela NÃO muda o tamanho de um botão só para si: se precisar de outro,
   é outro tamanho do sistema. A cerca `test-botoes-um-sistema` mede isto.
   ══════════════════════════════════════════════════════════════════════ */
.btn, .btn-mini, .btn-perigo, .btn-export{
  --bt-fundo:var(--botao); --bt-texto:var(--botao-fg); --bt-borda:var(--botao);
  --bt-fundo-h:var(--botao-hover); --bt-texto-h:var(--botao-fg); --bt-borda-h:var(--botao-hover);
  display:inline-flex; align-items:center; justify-content:center; gap:6px;
  width:auto; max-width:100%; box-sizing:border-box;
  font-family:var(--fonte-texto); font-weight:600; line-height:1.3; text-align:center;
  text-decoration:none; white-space:nowrap; cursor:pointer;
  border:1.5px solid var(--bt-borda); border-radius:var(--raio-sm);
  background:var(--bt-fundo); color:var(--bt-texto);
  transition:background .15s, color .15s, border-color .15s;
  padding:9px 18px; font-size:14px; min-height:42px;
}
.btn:hover, .btn-mini:hover, .btn-perigo:hover, .btn-export:hover{
  background:var(--bt-fundo-h); color:var(--bt-texto-h); border-color:var(--bt-borda-h); text-decoration:none; }
.btn:disabled, .btn-mini:disabled, .btn-perigo:disabled, .btn-export:disabled{ opacity:.5; cursor:not-allowed; }
/* tamanhos */
.btn-mini{ padding:5px 12px; font-size:13px; min-height:32px; }
.btn-grande{ padding:13px 30px; font-size:16px; min-height:50px; }
.btn-bloco{ display:flex; width:100%; }
.btn-inline{ width:auto; display:inline-flex; text-decoration:none; }
/* tons */
.btn-sec, .btn-export{ --bt-fundo:var(--branco); --bt-texto:var(--texto); --bt-borda:var(--cinza-borda);
  --bt-fundo-h:var(--branco); --bt-texto-h:var(--texto); --bt-borda-h:var(--preto); }
.btn-ghost{ background:transparent; color:var(--cinza-medio);
  --bt-fundo:transparent; --bt-texto:var(--cinza-medio); --bt-borda:var(--cinza-borda);
  --bt-fundo-h:transparent; --bt-texto-h:var(--preto); --bt-borda-h:var(--cinza-medio); }
.btn-mini-ghost{ --bt-fundo:transparent; --bt-texto:var(--cinza-medio); --bt-borda:var(--cinza-borda);
  --bt-fundo-h:transparent; --bt-texto-h:var(--preto); --bt-borda-h:var(--cinza-medio); }
.btn-ghost .ajuda{ color:inherit; opacity:.65; }
.btn-perigo, .btn-mini-perigo{ --bt-fundo:transparent; --bt-texto:var(--vermelho);
  --bt-borda:color-mix(in srgb, var(--vermelho) 45%, transparent);
  --bt-fundo-h:var(--vermelho); --bt-texto-h:#fff; --bt-borda-h:var(--vermelho); }
.btn-ok{ --bt-fundo:var(--verde); --bt-texto:#fff; --bt-borda:var(--verde);
  --bt-fundo-h:color-mix(in srgb, var(--verde) 82%, #000); --bt-texto-h:#fff; --bt-borda-h:color-mix(in srgb, var(--verde) 82%, #000); }
/* só texto */
.btn-link, .btn-cancelar{ appearance:none; -webkit-appearance:none; background:none; border:0;
  font-family:inherit; font-weight:600; font-size:14px; cursor:pointer; padding:4px 0; text-decoration:none; }
.btn-link{ color:var(--vermelho); }
.btn-link:hover{ text-decoration:underline; }
.btn-cancelar{ color:var(--cinza-medio); }
.btn-cancelar:hover{ color:var(--preto); }
/* 🐞🐞 `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`. */

/* 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:not(:focus-visible){ outline:none; border-color:var(--preto); }
.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:var(--verde); }
.leg-reservada::before{ background:var(--ambar-vivo); }
.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, var(--verde) 45%, transparent); }
.mesa-reservada{ border-color:var(--ambar-vivo); background:color-mix(in srgb, var(--ambar-vivo) 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:var(--verde); 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, var(--ambar-vivo) 16%, transparent); color:var(--ambar); }
.st-esp-chamado{ background:color-mix(in srgb, var(--azul) 14%, transparent); color:var(--azul); }
.st-esp-sentado{ background:color-mix(in srgb, var(--verde) 14%, transparent); color:var(--verde); }
.st-esp-desistiu{ background:var(--cinza-fundo); 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:var(--cap-contador-fonte); font-weight:var(--cap-contador-peso);
  border-radius:999px; padding:var(--cap-contador-pad); 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(--cinza-borda); 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 lugar 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 celular 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 tela** — visto no
   celular dele a 20/08. `anywhere` porque um token não tem lugar 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 tela 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 celular — 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:var(--verde); }
.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 fato precisa de ação. */
.tar-e-nota{ background:var(--cinza-fundo); 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 tela largo e passam para baixo no
   celular: `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(--cinza-borda); }

/* ═══ 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:var(--cap-controle-fonte); font-weight:var(--cap-controle-peso);
  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 celular 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:var(--cap-controle-fonte); font-weight:var(--cap-controle-peso); 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 lugar para um alvo pequeno é ao lado de um nome
     que se parece com o do vizinho.
     ⚠️ 🔍 E fica um fato 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
     telas 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; }

  /* ══════════════════════════════════════════════════════════════════════
     ⭐⭐ OS 255 ALVOS DE 31px — pagos em 28/08/2026, e sem mexer no desenho.

     O `.btn-mini` media **31px** com o dedo, contra a régua de 44 da casa, em
     **255 usos espalhados por 48 telas**. Ficou anotado como "medido e não
     tocado" desde 25/08 por um motivo bom: crescer o botão de verdade empurra
     a linha da tabela, e isso mexe em dezenas de telas de uma vez.

     ⭐ A saída é esticar a ÁREA DE TOQUE sem esticar o botão: um pseudo-
     elemento invisível, centrado, com os 44px de altura. O dedo acerta em 44;
     o olho continua a ver 31; e **nenhuma linha se move**.

     🚨 MEDIDO ANTES, porque isto só é seguro se os botões não estiverem
     empilhados: a área invisível cresce ~6,5px para cada lado, e dois botões
     verticalmente próximos passariam a roubar o toque um do outro. Medido em
     quatro telas com o dedo (375px):
        Tarefas   30 botões · menor distância vertical **167px**
        Produtos   3 botões · menor distância vertical  **55px**
        Estoque / Conta — sem pares
     Zero pares abaixo de 44. Com folga.

     ⚠️ Se um dia aparecer uma tela com dois `.btn-mini` empilhados a menos de
     44px, esta regra passa a roubar toques em silêncio — e o silêncio é o
     problema. Por isso a medição está escrita aqui, e não só no commit.
     ⚠️ `pointer-events` fica como está: o pseudo-elemento é filho do botão, e
     por isso o toque nele já é toque no botão.
     ══════════════════════════════════════════════════════════════════════ */
  .btn-mini{ position:relative; }
  .btn-mini::after{
    content:''; position:absolute; left:0; right:0; top:50%;
    transform:translateY(-50%); height:44px;
  }

  /* ══════════════════════════════════════════════════════════════════════
     🚨🚨 O BOTÃO DO MENU MEDIA 38px — auditoria de 01/09/2026.

     E não era uma peça qualquer: é a **porta da navegação em ~100 telas**, a
     que mais se toca no telemóvel. `padding:6px` à volta de um ícone de 26px
     dá 38, e faltavam 6.

     🚨 **A cerca estava VERDE**, e a razão é a mesma que mordeu o `.voltar` a
     30/08: o `test-alvo-do-dedo.php` procura classes que DECLAREM
     `height:<44px`, e a altura destas três vem do `padding`. Duas vezes o mesmo
     ponto cego. O que a cerca não vê só aparece varrendo o navegador — e é por
     isso que a varredura ficou escrita na fila do PENDENCIAS.

     🚨 MEDIDO ANTES, como manda a regra desta secção (375px):
        vão entre a logo e o sanduíche  **20px** → sobra 17 depois de crescer
        `.voltar`, o clicável mais perto  **17px** abaixo → sobra ~11 entre áreas
        altura da barra  **72px**
     Zero pares a colidir.

     🐞 E A PRIMEIRA TENTATIVA ESTAVA ERRADA, o que vale mais do que a correção:
     pus `min-height:44px` nos dois e cresci a caixa de verdade. Funcionou — e
     **empurrou a barra de 72 para 76px**. Medido no navegador logo a seguir.
     ⚠️ Os 72 estão escritos à mão em DOIS sítios do CSS (o recuo do `.conteudo`
     e o do recado), e há cerca a exigir que sejam iguais — mas ela compara os
     dois NÚMEROS ESCRITOS, não a barra desenhada: ficou verde com a barra já a
     medir 76, e 4px de conteúdo por baixo dela.
     ⭐ Por isso a ALTURA vai por área invisível (a barra não sente) e só a
     LARGURA cresce de verdade (não há nada a empurrar na horizontal). O olho vê
     o mesmo cabeçalho de sempre; o dedo passa a acertar em 44×44.
     ══════════════════════════════════════════════════════════════════════ */
  .sb-hamburguer{ min-width:44px; position:relative; }
  .sb-hamburguer::after{
    content:''; position:absolute; left:0; right:0; top:50%;
    transform:translateY(-50%); height:44px;
  }
  /* A logo é também um LINK (leva ao Início) — 110px de largo, faltava-lhe só a
     altura, e pela mesma razão ela vai por área invisível. */
  .sb-dext{ position:relative; }
  .sb-dext::after{
    content:''; position:absolute; left:0; right:0; top:50%;
    transform:translateY(-50%); height:44px;
  }
  /* ⚠️ O «Agora não» do convite a instalar: 36px, e é o botão que faz a faixa
     desaparecer. Um dedo que falha nele deixa a faixa a tapar a tela.
     ⭐ Este cresce de verdade: vive numa faixa que se mede pelo conteúdo, e não
     há barra nenhuma dependente da altura dele. */
  .inst-nao{ min-height:44px; display:inline-flex; align-items:center; }
  /* ⭐ O mesmo para o `+` da coluna: 24px no olho, 44 no dedo. As colunas são
     vizinhas na HORIZONTAL, por isso aqui a área cresce nos dois eixos — e a
     coluna tem 300px de largura, folga de sobra. */
  .tar-coluna-mais::after{
    content:''; position:absolute; left:50%; top:50%;
    transform:translate(-50%, -50%); width:44px; height:44px;
  }

  /* ══════════════════════════════════════════════════════════════════════
     ⭐ MAIS QUATRO PEÇAS PEQUENAS (28/08/2026) — as que a medição libertou.

     A cerca do `test-alvo-do-dedo.php` nomeou onze peças abaixo dos 44px.
     Estas quatro foram MEDIDAS no navegador e não têm vizinho vertical perto:
       `.dica-btn`     15px · vizinho V: nenhum
       `.txt-btn`      26px · vizinho V: nenhum
       `.ic-btn`       26px · vizinho V: 67px
       `.ret-remover`  34px · vizinho V: nenhum

     ⚠️ **A área cresce só em ALTURA**, e é isso que as torna seguras: estas
     peças vivem em FILA HORIZONTAL e os vizinhos de lado estão perto — o `?`
     da ajuda tem outro a 21px, a barra do texto rico tem 31px entre botões,
     o `.ic-btn` tem 38px. Crescer para os lados roubava-lhes o toque.
     ⭐ `left:0; right:0` = a largura é a do próprio elemento. Só a altura sobe.

     🚨 E O `.cel-add` FICA DE FORA, medido: o `+` da grelha da escala tem
     vizinho vertical a **39px** — abaixo dos 44. Ali a área invisível roubava
     o toque da linha de baixo, e um `+` que acrescenta turno à pessoa errada é
     pior do que um alvo pequeno. O mesmo vale para o `.chip-x` (30px).
     ⏭ E seis não consegui pôr à vista para medir (`.lanc-ico`,
     `.lanc-conferir`, `.lanc-receber-btn`, `.flash-x`, `.tar-sub-tique`,
     `.tar-dia span`). O que não se mede, não se toca.
     ══════════════════════════════════════════════════════════════════════ */
  /* ══════════════════════════════════════════════════════════════════
     🚨🚨 O «VOLTAR» — 36px em **86 TELAS**, e nenhuma cerca o via.

     Achado na auditoria de 30/08/2026, e achado NO NAVEGADOR: o cronômetro do
     `test-alvo-do-dedo.php` procura classes que DECLAREM `height:<44px`, e a
     altura desta vem do `padding: 7px 14px`. Uma cerca que lê declarações não
     vê o que é desenhado — e este é o alvo mais repetido da casa inteira, o
     primeiro de quase todas as telas.

     📏 MEDIDO a 375px com o dedo: **119×36px**, vão vertical até ao clicável
     seguinte **173px**, vão horizontal **10px** (o irmão do `atalho-par`).
     ⭐ 4px para cada lado em ALTURA cabem com folga de sobra; para os lados
     não havia 10px para dar — daí o `left:0; right:0`, que é a receita que já
     serve o `.btn-mini` e as quatro peças de 28/08.
     ══════════════════════════════════════════════════════════════════════ */
  .voltar{ position:relative; }
  .voltar::after{
    content:''; position:absolute; left:0; right:0; top:50%;
    transform:translateY(-50%); height:44px;
  }

  .dica-btn, .txt-btn, .ic-btn, .ret-remover{ position:relative; }
  .dica-btn::after, .txt-btn::after, .ic-btn::after, .ret-remover::after{
    content:''; position:absolute; left:0; right:0; top:50%;
    transform:translateY(-50%); height:44px;
  }

  /* ══════════════════════════════════════════════════════════════════════
     ⭐⭐ AS SEIS QUE FALTAVAM — POSTAS À VISTA E MEDIDAS (30/08/2026).

     O bloco acima fechou com *"seis não consegui pôr à vista para medir"*, e
     a casa tem regra para isso: **o que não se mede, não se toca**. Ficaram
     seis meses de cerca amarela por falta de medição, não por falta de
     decisão. Hoje mediram-se — e o difícil não era medir, era **fazê-las
     nascer**:
       `.lanc-ico` e irmãs  o Diário abre no MÊS CORRENTE, e o mês corrente
                            estava vazio. A tela certa, sem uma linha dentro.
       `.tar-dia`           só nasce com a recorrência posta em *Semanal* —
                            está atrás de uma escolha num `select`.
       `.tar-sub-tique`     precisa de uma tarefa com FILHAS (`mae_id`), e não
                            havia nenhuma.
       `.flash-x`           o `x` é feito em JS, e só sobre um `.flash-erro`.

     🚨🚨 E A MEDIÇÃO DEU UMA COISA QUE NINGUÉM TINHA PERCEBIDO: até aos 600px
     o Diário **não mostra a coluna dos ícones** (`.lanc-tabela tbody tr >
     td.td-acoes{display:none}`, mais acima) — a linha inteira é o alvo, e
     toca-se para abrir a ficha. Ou seja, no telemóvel estas peças não existem
     para o dedo. Existem **do iPad para cima**: `pointer:coarse` verdadeiro e
     a coluna à vista. É exatamente onde ele trabalha, e é lá que estavam
     1.332 botões de 26px — um deles o de APAGAR.

     📏 MEDIDO NO NAVEGADOR, a 760px e com o dedo, sobre os 1.332 (não uma
     amostra): altura **26px** em todos, vão vertical mínimo **39px**, vão
     horizontal **4px** (a grelha é `repeat(6, 30px)` com `gap:2px`).
     ⭐ Por isso a área cresce **só em altura**: 9px para cada lado comem 18
     dos 39, e sobram 21 livres. Para os lados não havia 4px para dar.

     ⭐ PROVADO NA PÁGINA, e não só na conta — `elementFromPoint` sobre um par
     vizinho de verdade, depois de a regra entrar:
        dentro do botão .......... acerta nele
        5px abaixo dele .......... acerta nele   ← a área nova a funcionar
        8px abaixo dele .......... acerta nele   ← a beira da área
        19px (meio do vão) ....... acerta na CÉLULA, em ninguém
        8px acima do de baixo .... acerta no de baixo
     Nenhum dos dois rouba o toque do outro. E 0 de 1.332 mudaram de lugar.

     ⭐ O `.flash-x` cresce nos DOIS eixos, e é o único que pode: mede 38x38 e
     o clicável mais perto está a **115px** por baixo e **501px** à esquerda.
     Está sozinho no cimo da página — é um aviso, não uma fila de botões.

     🚨 E DUAS FICAM DE FORA, medidas e escritas, para ninguém as "arrumar"
     por engano mais tarde:
       `.tar-sub-tique`  22x22 · vizinho vertical a **18px** (um campo de
                         texto). Crescer 11px para cada lado punha a área a
                         7px de um campo — e o engano aqui DÁ A SUBTAREFA POR
                         FEITA. Alvo pequeno é pior do que nada; alvo que
                         mente é pior do que alvo pequeno.
       `.tar-dia`        34px de alto, mas com **7px** por cima e **11px** por
                         baixo (as sete pílulas dobram para duas linhas). Não
                         há folga nenhuma para dar.
     ⏭ Estas duas só se arranjam mudando o DESENHO — dando-lhes altura a
     sério, com a fila a crescer — e isso vê-se, por isso pede-se antes.
     ══════════════════════════════════════════════════════════════════════ */
  .td-acoes-icones .lanc-ico{ position:relative; }
  .td-acoes-icones .lanc-ico::after{
    content:''; position:absolute; left:0; right:0; top:50%;
    transform:translateY(-50%); height:44px;
  }
  .flash-x{ position:relative; }
  .flash-x::after{
    content:''; position:absolute; left:50%; top:50%;
    transform:translate(-50%, -50%); width:44px; height:44px;
  }
  /* ⭐ Os ícones da LINHA QUE ENTENDE (23/09/2026): 28px com o rato, 44 com o
     dedo — é no telemóvel que se escolhe a data com o polegar. E o × de cada
     etiqueta estica a área sem crescer o desenho, como o `.btn-mini`. */
  .tlin-ic{ width:44px; height:44px; }
  .tlin-x{ position:relative; }
  .tlin-x::after{ content:''; position:absolute; inset:-14px -10px; }
}

/* ⚠️ 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 tela 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 tela 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 celular 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 tela de 375. */
  .dash-tile:has(.dash-num) .dash-num{ font-size:clamp(16px, 16cqi, 28px); }
  /* 🐞 A BARRA TRANSBORDAVA NO TELEMÓVEL (pego 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 tela, 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 arquivo 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
     celular, 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:not(:focus-visible){ 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-fundo); 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:var(--verde); }
.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:not(:focus-visible){ outline:none; border-color:var(--preto); }
.form-filtros .campo-acao{ display:flex; flex-direction:row; gap:10px; align-items:center; height:44px; }
.selo-aud{ background:var(--cinza-fundo); 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, var(--verde) 14%, transparent); color:var(--verde); }
.selo-aud.aud-editar, .selo-aud.aud-status{ background:color-mix(in srgb, var(--azul) 12%, transparent); color:var(--azul); }
.selo-aud.aud-aprovar{ background:color-mix(in srgb, var(--verde) 14%, transparent); color:var(--verde); }
.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:not(:focus-visible){ 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 var(--vermelho-sinal); 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:var(--vermelho-sinal-fundo); border:1px solid #f6c9d3; color:var(--vermelho-sinal); 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 tela 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 tela 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 tela 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 celular. `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 var(--verde); }
.op-mesa-livre .op-mesa-estado{ color:var(--verde); font-weight:700; }
.op-mesa-ocupada{ border-left:3px solid var(--vermelho-sinal); background:var(--cinza-fundo); }
.op-mesa-ocupada .op-mesa-estado{ color:var(--vermelho-sinal); 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); }

.alerta{
  background:var(--vermelho-sinal-fundo); border:1px solid #f6c9d3; color:var(--vermelho-sinal);
  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__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 */
  }
}

/* Logotipo, endereço e mapa das Configurações. (A barra superior antiga que
   vivia aqui saiu a 27/09/2026: o menu lateral substituiu-a.) */
.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; }

.conteudo{ max-width:1000px; margin:0 auto; padding:40px 22px; }
/* ══════════════════════════════════════════════════════════════════════
   🚨🚨 A FAIXA DE INSTALAR TAPAVA O QUE ESTÁ POR BAIXO DELA (03/09/2026).
   Ele: *"não consegui selecionar e nem alterar a data de reserva pelo
   celular. Clico na data e nada acontece."*

   A `.inst-faixa` é `position:fixed` no fundo do ecrã — e **nada abria espaço
   para ela**. Medido a 375px na tela de nova reserva: 162px de altura mais
   16 de margem, **22% do ecrã**, e por baixo dela estavam três controlos
   vivos: o botão de ajuda, o campo «pessoas» e o **campo da data**. Tocar
   neles acertava na faixa. Nada acontecia, e nada explicava porquê.

   ⚠️ **Não era da data**, e é isso que torna o defeito caro: era de tudo o que
   calhasse ali. A data foi só onde ele reparou.
   ⚠️ A altura é MEDIDA em JS e não escrita aqui: a faixa muda de altura com o
   idioma, com o aparelho (o texto do iPhone é mais longo — ensina o gesto em
   vez de oferecer um botão) e com a rotação. Um número fixo aqui acertava num
   caso e falhava nos outros. Ver `partials/instalar-app.php`.
   ⚠️ E some com ela: a classe sai quando a faixa é dispensada, senão ficava um
   buraco de 200px no fundo de todas as telas para sempre. */
body.com-faixa-instalar .conteudo{
  padding-bottom: calc(var(--h-faixa-instalar, 200px) + 40px);
}
/* 🚨 E O BOTÃO DE AJUDA SOBE COM ELA. Este não se resolve com espaço no fim da
   página: é `fixed` como a faixa, no MESMO canto, com o MESMO `z-index:60` — e
   a faixa ganha por vir depois no documento. Medido: um toque no meio do botão
   acertava no «Agora não» da faixa. Ou seja, enquanto a faixa estivesse de pé
   **a ajuda estava inalcançável em todas as telas**, e ninguém o ligaria à
   faixa de instalar. */
body.com-faixa-instalar .ajuda-fab{
  bottom: calc(var(--h-faixa-instalar, 200px) + 32px);
}

/* ⭐ 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 tela à 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 tela 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 seçõ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 celular 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:var(--vermelho-sinal-fundo)` 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 lugar.
   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:var(--cap-controle-fonte); font-weight:var(--cap-controle-peso); 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; }
/* ⭐ A AÇÃO PRINCIPAL NO CABEÇALHO (27/09/2026, do FH Finanças): o título
   encolhe e as ações (período + botão) ficam juntas à direita, na mesma linha.
   Sem isto o subtítulo comprido empurrava o botão para baixo do mês. */
.pagina-cabecalho > div:first-child{ flex:1 1 240px; min-width:0; }
.pagina-cabecalho > .cab-acoes{ flex:0 0 auto; flex-wrap:nowrap; justify-content:flex-end; }
.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; }


/* min-width:0 é o que faz o overflow-x funcionar de fato: 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 celular. */
.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-fundo); }
/* ⭐⭐ 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 tela 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:var(--vermelho-sinal); 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:var(--vermelho-sinal); 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, var(--vermelho-sinal) 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:var(--cap-etiqueta-fonte); font-weight:var(--cap-etiqueta-peso); line-height:1.45;
  padding:var(--cap-etiqueta-pad); 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-freela { background:var(--roxo-fundo); color:var(--roxo); }
.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
   lugares 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 seçõ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 seção curta não esticar até
   à altura da vizinha. */
.cfg-blocos{ display:grid; gap:14px 28px; align-items:start; grid-template-columns:minmax(0,1fr); }
/* 🐞 29/09/2026 (auditoria no celular): sem coluna declarada abaixo dos 900px, a
   coluna automática crescia até ao conteúdo mais largo — o código do widget (um
   `<pre>`, que não quebra) — e as Configurações de Clientes rolavam para o lado
   (542px num telemóvel de 375). `minmax(0,1fr)` deixa-a encolher; o código rola
   dentro da própria caixa, que já tem `overflow-x:auto`. */
@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 celular (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 seçã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 lugares 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; }
/* 🚨 O `min-width:0` que falta na CÉLULA, e não no campo — 29/08/2026.
   Ele mandou um print do iPad com os campos por cima uns dos outros. Numa
   grelha, uma célula `1fr` recusa-se a encolher abaixo do seu conteúdo mínimo
   (`min-width` vale `auto`, não zero), e o widget de data do Safari é bem mais
   largo que o do Chrome — a célula do Dia estica e passa por cima da vizinha.

   ⚠️ Já se tinha tentado consertar isto na linha do `input[type=date]` (a regra
   `min-width:0` mais acima), mas quem transborda numa grelha é a CÉLULA — o
   filho direto —, e a célula é o `.campo`.

   ⭐ MEDIDO ANTES DE ESCREVER, porque esta regra toca 35 telas e nesta casa já
   se mediu mal uma vez: Lançamentos, Configurações, Config do Operacional e
   Novo colaborador — **28 células, zero mudaram de posição ou de largura**.
   A regra é inerte onde nada transborda; só age onde já estava errado.

   🚨 E é o único conserto desta leva que NÃO consegui provar a falhar: sem um
   iPad, não reproduzo o defeito. O Chromium redistribui as colunas em vez de
   as sobrepor. Fica escrito: **isto é um conserto por diagnóstico, e espera
   confirmação dele na tela.** */
.form-linha > *{ min-width:0; }
/* 🚨 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);
}
/* ⚠️ UM `<select multiple>` NÃO É UM CAMPO DE UMA LINHA (08/09/2026).
   Ele: *"Veja se o botão não está desalinhado."* Medi os botões e estão certos —
   «Abrir mesa» bate ao pixel com o campo ao lado (base 454 nos dois) e o
   «Concluir» está dentro do cartão a 375, 768 e no computador. O que partia a
   fila era este campo: o `padding:13px 15px` da casa aplica-se à CAIXA inteira,
   empurra todas as opções para dentro e deixa-o com ar de lista do sistema
   operativo no meio de campos desenhados.
   ⭐ O padding passa para as OPÇÕES, que é onde ele serve. O `multiple` fica: uma
   mesa de 8 pode ocupar duas de 4, e é para isso que ele existe. */
.campo select[multiple]{ padding:4px; }
/* ⚠️ 6px e não 9: com 9 a caixa passava dos 157px e desequilibrava ainda mais a
   fila dos campos de uma linha (48px). O que se quer é que PAREÇA um campo da
   casa, não que fique maior do que já era. */
.campo select[multiple] option{ padding:6px 11px; border-radius:var(--raio-sm); }
.campo select:focus:not(:focus-visible), .campo input:focus:not(:focus-visible){ outline:none; border-color:var(--preto); }
.ajuda{ display:block; font-size:12px; color:var(--cinza-medio); margin-top:6px; }
/* ⭐ Ajuda que abre um BLOCO (10/09/2026): fica colada ao título em cima e
   respira antes do que vem a seguir. Nasceu porque o mesmo espaçamento estava a
   ser escrito à mão em `style=` nas Configurações, e a cerca do espaçamento
   conta-os — com razão: um `style` é um lugar onde a regra da casa não chega. */
.ajuda-bloco{ margin:0 0 14px; }
.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. */

@media (max-width:600px){
  .form-linha{ grid-template-columns:1fr; }
  .pagina-cabecalho{ flex-direction:column; align-items:stretch; }
  /* no celular as ações do cabeçalho podem quebrar linha (três botões num
     idioma de textos compridos não cabem em 343px) */
  .pagina-cabecalho > .cab-acoes{ flex-wrap:wrap; justify-content:flex-start; }
  /* ⚠️ em coluna, o `flex-basis` de 240px do título vira ALTURA: abria um buraco
     entre o subtítulo e as ações (apanhado a 375px nos Lançamentos) */
  .pagina-cabecalho > div:first-child{ flex:none; }
  /* 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 celular. 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. */
  /* no celular um rótulo comprido quebra dentro do botão, em vez de o esticar
     para fora da tela (vale para o sistema todo, não só o antigo `.btn-inline`) */
  .btn, .btn-mini, .btn-perigo, .btn-export{ white-space:normal; max-width:100%; }
  /* Navegação de período: as setas e o seletor de data já enchem a largura de um
     celular, 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 tela, 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 arquivo, 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 arquivo. */
  .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
     celular é onde ele mais o usa. */
  /* ══════════════════════════════════════════════════════════════════
     🚨🚨 A CAIXA DE SELEÇÃO ESTAVA INTOCÁVEL NO TELEMÓVEL (30/08/2026).

     Achado na auditoria, e achado com `elementFromPoint` — não a olho: nas
     Fichas, a 375px, o toque no CENTRO da caixa devolvia o `nome-link`. Não
     era a caixa pequena: era a linha inteira a ser um link por cima dela.
     A regra `.nome-link::after{ position:absolute; inset:0 }`, aqui em baixo,
     faz do cartão todo um alvo — de propósito, e é bom. Só que `inset:0` é
     relativo à LINHA, e a linha inclui a célula da caixa.

     ⚠️ E a consequência não é estética: as caixas existem para a AÇÃO EM
     LOTE. Sem as poder marcar, a ação em lote não existe no telemóvel — e
     ninguém reporta o que julga que é assim mesmo.
     ⭐ `z-index:1` na célula chega: a caixa sobe acima da sobreposição, e o
     resto do cartão continua a abrir a ficha ao toque, como antes.
     🚨 Vale para as CINCO telas que juntam as duas coisas (fichas, produtos,
     lançamentos e as duas linhas do Diário) — por isso a regra mora aqui, na
     `.col-sel`, e não numa delas. */
  .tabela-cards.tabela-compacta tbody td.col-sel{ display:block; flex:none; width:auto; padding:0;
    position:relative; z-index:1; }
  /* ⚠️ 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 celular, 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 celular: 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 tela
     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 tela 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.) */
/* 🚨🚨 ERA `min-width:981px`, E ISSO DEIXAVA UMA FAIXA CEGA (30/08/2026).
   A coluna de 230px existe a partir dos **821px** — é aos 820 que ela vira
   barra de topo. Entre 821 e 980 o recado nascia em `left:16px`, ou seja, com
   o COMEÇO DA FRASE por baixo da coluna. Medido no navegador a 900px: o toque
   em `x=46` caía na `.sb-dext`, não no recado.
   ⭐ O número certo é o mesmo do outro lado do corte, e agora são o mesmo. */
@media (min-width:821px){
  .flash-ok, .flash-erro{ left:calc(var(--sb-larg) + 16px); right:auto; max-width:620px; }
}
/* ══════════════════════════════════════════════════════════════════════
   🚨🚨 E ATÉ AOS 820px O RECADO NASCIA DEBAIXO DA BARRA DE TOPO.

   A barra mede 72px e é `fixed`; o recado nascia em `top:14px`. Resultado
   medido no navegador, a 375px e a 760px: o `×` do erro ficava INTEIRO por
   baixo dela, e `elementFromPoint` no meio do `×` devolvia `.sb-marca`.
   ⭐ E isto é pior do que parece por causa de uma decisão boa, logo abaixo:
   **o erro não sai sozinho — fecha-se com o `×`**. Um `×` que não se pode
   tocar é um erro preso na tela para sempre, e meio tapado por cima.

   ⚠️ Porque é que o `z-index:70` não chegou: a `.flash-erro` vive dentro da
   `.conteudo`, e a `.conteudo` tem `position:relative; z-index:1` (lá em
   baixo, só para ficar acima da marca d'água do fundo). Isso ABRE UM CONTEXTO
   DE EMPILHAMENTO: o 70 passa a valer só lá dentro, e o que a barra lateral
   (z:51) vê é o `1` da `.conteudo`. 51 ganha a 1, sempre.
   ⏭ Tirar o `z-index:1` da `.conteudo` conserta isto pela raiz — e solta, de
   uma vez, o `.tar-lote-menu` (60), a `.editor-barra` (61) e o `.rec-overlay`
   (1000), que hoje estão presos ao mesmo contexto. São dezenas de telas de
   uma vez, como o `.btn-mini` foi; quer-se medido e visto, não enfiado ao lado
   deste conserto. Está anotado no PENDENCIAS.

   🚨 O `72px` é o MESMO NÚMERO do `padding-top` da `.conteudo` no bloco dos
   820 — a altura da barra. Os dois têm de andar juntos, e há uma cerca no
   `test-alvo-do-dedo.php` que falha se alguém mudar um e esquecer o outro.
   ══════════════════════════════════════════════════════════════════════ */
@media (max-width:820px){
  .flash-ok, .flash-erro{ top:calc(72px + 14px + env(safe-area-inset-top, 0px)); }
}
.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:var(--vermelho-sinal-fundo); border:1px solid #f6c9d3; color:var(--vermelho-sinal);
}

/* ⭐ 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;
}
/* ⚠️ `margin:0` porque estes passaram a ser `<h1>` a 08/09/2026: sem isto o
   navegador punha a margem dele e a tela mexia-se. O aspeto tem de ficar igual. */
.pin-nome, .bater-nome{ font-family:var(--fonte-titulo); font-weight:700; font-size:24px; letter-spacing:-.4px; margin:0; }
.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:not(:focus-visible){ outline:none; border-color:var(--preto); }

/* Tela de bater */
.bater-estado{
  display:inline-block; margin-top:10px; padding:var(--cap-controle-pad); border-radius:999px;
  font-size:var(--cap-controle-fonte); font-weight:var(--cap-controle-peso);
}
.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 `var(--vermelho-sinal-fundo)` à 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;
}
/* ⭐ A navegação por DIA do relatório operacional (30/08/2026). Mesmo desenho
   da do mês — o olho não tem de aprender duas barras —, mas nome próprio: a
   `.mes-nav` marca as telas que o acelerador tem de cobrir, e a do relatório
   fica fora de propósito (é um formulário, ver a nota na vista). */
.dia-nav{ display:flex; align-items:center; gap:6px; }
/* ⭐ 04/09/2026 · O dia da semana ao lado da data, no Relatório do dia. Em tom
   mais leve porque é CONTEXTO e não o dado — quem procura o dia 01 procura o
   «01», e a terça-feira é o que lhe diz que tipo de dia foi. */
.dia-nav-dow{ margin-left:6px; color:var(--cinza-medio); font-weight:600; font-size:13px; }
/* ⚠️ O `•` vem do CSS e não da marcação: é pontuação de desenho, não texto —
   não se traduz, não se copia com o texto da página, e não obriga cada tela que
   use isto a lembrar-se dele. Foi o separador que ele escreveu no exemplo
   («01/09 • Terça-feira»). */
/* 🐞 Nasceu em `--cinza-borda` (#e6e6e8) e era invisível no ecrã — vi-o na
   captura, não no código: o pseudo-elemento existia e ninguém o lia. Um
   separador que não se vê não separa nada. Fica no tom do próprio texto. */
.dia-nav-dow::before{ content:"•"; margin-right:6px; color:inherit; opacity:.55; }
.dia-nav a, .dia-nav .cinza-vazio{
  display:inline-flex; align-items:center; justify-content:center;
  min-width:32px; min-height:32px; border-radius:var(--raio-xs);
  text-decoration:none; color:var(--texto);
}
/* ⚠️ A seta desligada continua a OCUPAR O LUGAR: sem isto, a barra encolhia ao
   chegar a hoje e o rótulo do dia saltava de sítio a cada navegação. */
.dia-nav .cinza-vazio{ color:var(--cinza-borda); cursor:default; }
.dia-nav a:hover{ background:var(--cinza-fundo); }

/* ⭐ Os relatórios do período, um por dia. */
.reldia-texto{ white-space:pre-wrap; line-height:1.55; }
/* Quem responde · quem gravou · a nota — tudo na mesma linha, e a embrulhar
   quando o telemóvel não a couber inteira. */
.reldia-meta{ display:flex; flex-wrap:wrap; align-items:center; gap:8px; margin:0 0 8px; }
.reldia-meta .lanc-sub{ font-size:12.5px; }
/* ⚠️ `.form-acoes` não embrulha, e o aviso de «gravar vazio apaga» ficava
   espremido ao lado do botão. O `wrap` fica PRESO a esta tela: mexer no
   `.form-acoes` de todos mudava o rodapé de formulários que já estão em uso. */
.reldia-acoes{ flex-wrap:wrap; }
.reldia-acoes .ajuda{ margin-top:0; }
/* O rótulo e o `?` da nota ocupam a largura que precisam; só a caixa é curta —
   um `<select>` de 0 a 10 não tem que ter a largura de um nome. */
.campo-nota select{ max-width:110px; }
.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 tela — para uma ação secundária. Aqui vale o tamanho do texto. */

.export-toolbar{ display:flex; gap:10px; margin-bottom:14px; flex-wrap:wrap; }
/* ⭐ A saída de uma lista fica SOBRE ela, encostada à direita — junto da barra
   de rolagem por onde a tabela se lê, e não no cabeçalho da página, que nestas
   telas já leva os botões de CRIAR. Sair não é criar, e misturar os dois faz
   com que se clique num a pensar no outro.
   ⚠️ Uma classe só para as cinco telas (03/09/2026): cinco margens escritas à
   mão acabam sempre com uma diferente das outras quatro. */
.lista-exportar{ margin:0 0 10px; text-align:right; }
/* com o alternador cartões|lista ao lado (produtos, 26/09/2026) */
.lista-exportar:has(.ver-alterna){ display:flex; justify-content:flex-end; align-items:center; gap:10px; flex-wrap:wrap; }
/* ⚠️ A caixa de seleção da agenda vive dentro do `.reserva-topo`, que é um
   flex: sem `flex:none` ela encolhe ou estica com o nome ao lado, e sem a
   margem cola-se ao nome. Vem antes de tudo na linha, que é onde o polegar a
   procura. */
/* ⭐ 04/09/2026 · A fila de espera usa o MESMO cartão (`.reserva-topo`), e por
   isso a mesma regra — e não uma cópia com outro nome, que divergia à primeira
   alteração. */
.sel-res,
.sel-esp{ flex:none; margin:0 6px 0 0; }
/* ⚠️ 02/09/2026 · O `.btn-export` media **41px** com o dedo — 3 a menos que a
   régua da casa, em **7 usos por 6 telas**. Foi visto ao provar a 375px o botão
   novo do Diário, e não é dele: a classe sempre foi assim.
   ⚠️ E nem todos são exports: em Receber, Estoque e Inventário a classe é só o
   DESENHO de uma ligação («ver o extrato →»). Crescer-lhes o alvo é ganho na
   mesma, mas quem procurar por «export» não os encontra — fica dito aqui.
   ⭐ O remédio é o mesmo do `.btn-mini`, já provado a 28/08: estica-se a ÁREA DE
   TOQUE e não o botão. O dedo acerta em 44, o olho continua a ver 41, e nenhuma
   linha se mexe — crescer o botão a sério empurrava o cabeçalho da secção.
   ⚠️ Cresce ~1,5px para cada lado; não há dois `.btn-export` empilhados em
   nenhuma das três telas (nas Horas são lado a lado), logo não roubam toque. */
@media (pointer:coarse){
  .btn-export{ position:relative; }
  .btn-export::after{ content:""; position:absolute; left:0; right:0; top:50%;
    transform:translateY(-50%); height:44px; }
}

/* ============================================================
   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; }
/* 🐞 O `<strong>` VIRAVA UMA PEÇA SOLTA (medido a 375px, 08/09/2026).
   Isto é `inline-flex` com `gap`, e num flex TODO o filho é um item: o
   `<strong>` do meio da frase separava-se do resto e a pontuação a seguir
   nascia com um espaço à frente — «para arrastar .». No computador via-se na
   dica do rato («para copiar .»); no telemóvel a frase parte em três linhas e
   fica óbvio. O `<span>` à volta do texto devolve-lhe a natureza de frase: os
   itens do flex passam a ser dois — o ícone e a frase inteira. */
.escala-dica{ color:var(--cinza-medio); font-size:13px; margin:0 0 12px; display:inline-flex; align-items:center; gap:7px; flex-wrap:wrap; }
.escala-dica > span{ min-width:0; }
/* 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 celular 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:var(--cinza-fundo); 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:var(--cap-etiqueta-peso); font-size:var(--cap-etiqueta-fonte); 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; }

/* ⭐⭐ FÉRIAS E FOLGA NA GRELHA (01/09/2026) — pedido dele.
   ⭐ Herda a FORMA do turno (mesma pílula, mesmo ponto, mesmo tamanho): quem lê
   a escala lê uma linha de dias, e trocar de desenho a meio da linha obrigava a
   aprender duas peças para a mesma pergunta — *"o que faz esta pessoa neste
   dia?"*. O que muda é só a cor, porque a resposta é de outra natureza.
   ⚠️ E a cor NÃO é a do dinheiro nem a do alerta: uma folga não é um problema.
   Férias leva o azul da casa (a família da espera e da auditoria), folga leva o
   cinza — a mesma escada de «isto é informação, não é sinal». */
.aus-chip{ display:inline-flex; align-items:center; gap:5px; border-radius:999px;
  padding:4px 8px 4px 10px; margin:0 auto 5px; white-space:nowrap;
  font-weight:var(--cap-etiqueta-peso); font-size:var(--cap-etiqueta-fonte);
  background:var(--cinza-fundo); color:var(--cinza-medio); }
.aus-chip::before{ content:''; width:7px; height:7px; border-radius:50%;
  background:currentColor; flex:0 0 auto; }
.aus-ferias{ background:var(--azul-fundo, #eaf1fb); color:var(--azul, #1b4f9c); }
.aus-atestado{ background:var(--ambar-fundo); color:var(--ambar); }
.aus-falta{ background:var(--vermelho-sinal-fundo); color:var(--vermelho-sinal); }
/* ⚠️ O PEDIDO POR DECIDIR não pode parecer decidido: fica esvaziado, com o
   traço a dizer que é uma proposta. É a mesma distinção que o e-mail do dia já
   fazia por palavras — *"um pedido por aprovar não é uma ausência, é uma decisão
   à espera de alguém"*. */
.aus-pedido{ background:transparent; box-shadow:inset 0 0 0 1px currentColor;
  opacity:.75; font-style:italic; }
.aus-pedido small{ font-style:normal; font-weight:700; }
/* A linha «ou marcar» dentro do `+`, separada das horas por um traço
   (volta a 28/09/2026: folga e férias marcam-se na escala). */
.add-pop-ou{ display:flex; align-items:center; gap:6px; flex-wrap:wrap;
  margin-top:8px; padding-top:8px; border-top:1px solid var(--cinza-borda); }
.add-pop-ou > span{ font-size:.78rem; color:var(--cinza-medio); }
/* ⭐ 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 pegou 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; }
/* ⭐ 12/09/2026: as batidas NOVAS são várias. A primeira mantém o respiro que
   a separa da lista; as seguintes colam-se a ela, senão pareciam blocos soltos. */
.batida-add + .batida-add{ padding-top:0; margin-top:0; }
.batida-mais-linha{ margin:6px 0 0; }
/* ⚠️ `.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:var(--ambar); }
/* 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 lugar, 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
   pegou: 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:var(--vermelho-sinal-fundo); color:var(--vermelho-sinal); }
.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; }

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

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

/* aviso de sucesso */
.aviso-ok{ background:var(--verde-fundo); border:1px solid #bfe6cb; color:var(--verde); 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. */

/* ⭐⭐ COR NOS BOTÕES DA TAREFA (30/08/2026, a pedido dele). Os três estavam em
   preto-e-branco e liam-se todos iguais — «Feita» e «Recusar» são gestos
   opostos e tinham o mesmo peso na tela.
   ⚠️ Segue a regra da casa: **cor forte só em superfície pequena**, e as duas
   que não são a principal levam a cor no TRAÇO e no texto, não no fundo. Três
   fundos cheios lado a lado num card é um semáforo, não uma barra de ações.
   ⚠️ E as cores são as dos sinais que já existem — nada de hexadecimal à mão,
   que foi o que a fase 3 do selo passou a semana a arrancar. */
.btn-mini-feita{ --bt-fundo:var(--verde); --bt-texto:#fff; --bt-borda:var(--verde);
  --bt-fundo-h:color-mix(in srgb, var(--verde) 82%, #000); --bt-texto-h:#fff; --bt-borda-h:color-mix(in srgb, var(--verde) 82%, #000); }
.btn-mini-comecar{ --bt-texto:var(--azul, var(--preto)); --bt-borda:color-mix(in srgb, var(--azul, var(--preto)) 38%, transparent);
  --bt-texto-h:var(--azul, var(--preto)); --bt-borda-h:var(--azul, var(--preto)); }
/* ⭐ 04/09/2026 · O «Aceitar» das tarefas do sistema. Vive ao lado do Comecei,
   do Feita e do Recusar, e por isso segue-lhes o feitio — o que muda é a cor,
   porque o gesto é outro: aceitar é TRIAR, não trabalhar. Fica no tom neutro
   forte da casa, entre o fantasma do Comecei e o verde do Feita. */
.btn-mini-aceitar{ --bt-texto:var(--preto); --bt-borda:var(--preto);
  --bt-fundo-h:var(--preto); --bt-texto-h:var(--branco); --bt-borda-h:var(--preto); }

/* ══════════ A ENTRADA das tarefas do sistema (04/09/2026) ══════════
   ⚠️ Ela NÃO é um cartão como as outras secções: é uma fila de triagem, e o
   desenho tem de dizer isso — encostada acima da lista, com uma barra própria
   e um traço que a separa do resto. */
.tar-entrada{ margin:0 0 24px; }
.tar-entrada > .pagina-cabecalho{ margin-bottom:2px; }
.tar-entrada > .ajuda{ margin:0 0 12px; }
/* A barra da triagem: os dois seletores e o botão numa linha só, e a quebrar
   por baixo no telemóvel em vez de esmagar os seletores. */
.tar-entrada-barra{
  display:flex; align-items:center; gap:10px; flex-wrap:wrap;
  padding:12px 14px; margin:0 0 12px;
  background:var(--cinza-fundo); border:1px solid var(--cinza-borda);
  border-radius:var(--raio-sm);
}
.tar-entrada-barra select{ flex:1 1 160px; min-width:0; }
.tar-entrada-barra .barra-sel-txt{ margin-left:auto; white-space:nowrap; }
/* A caixa de seleção da linha, à esquerda do cartão. */
.tar-entrada .tar-item{ display:flex; align-items:flex-start; gap:10px; }
.tar-entrada-sel{ flex:none; padding-top:12px; }
.btn-mini-recusar{ --bt-texto:var(--vermelho); --bt-borda:color-mix(in srgb, var(--vermelho) 45%, transparent);
  --bt-fundo-h:var(--vermelho); --bt-texto-h:#fff; --bt-borda-h:var(--vermelho); }

/* ⭐ A pílula do setor no card. Herda a forma da etiqueta — é a mesma peça a
   fazer o mesmo trabalho, e um desenho novo para isto era mais uma cápsula. */
.tar-setor-pil{ font-weight:600; }

/* 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 seçã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 celular 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:var(--cap-controle-fonte); font-weight:var(--cap-controle-peso); color:var(--cinza-medio); text-decoration:none;
  padding:var(--cap-controle-pad); 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 arquivo — 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). */
/* ⭐ 27/09/2026: devolve-se ao botão o que é dele LENDO o sistema de botões —
   qualquer tom, em qualquer tamanho, sem repetir cor nenhuma aqui. */
.sub-nav a:is(.btn, .btn-mini, .btn-export){ background:var(--bt-fundo); color:var(--bt-texto); border-color:var(--bt-borda); }
.sub-nav a:is(.btn, .btn-mini, .btn-export):hover{ background:var(--bt-fundo-h); color:var(--bt-texto-h); border-color:var(--bt-borda-h); }
.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 usuário 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 celular: 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:var(--verde-fundo); color:var(--verde); }
.st-sentada{ background:var(--azul-fundo); color:var(--azul); }
.st-concluida{ background:var(--cinza-fundo); color:#5b6470; }
.st-cancelada{ background:var(--cinza-fundo); 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
   lugar 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 tela 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 celular 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 celular, agora acionado pela LARGURA
   DA COLUNA e não pela da janela. A regra do celular (@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; }

/* ficha do cliente */
/* ⭐ A caixa de estado da ficha (30/08/2026) — desativar e excluir dentro da
   própria ficha, que é o defeito #12 do handover.
   ⚠️ Separada do formulário por uma margem a sério: um botão de apagar colado
   ao de guardar é o par mais fácil de trocar por engano que existe. */
/* ⭐ As portas da receita para a ficha (30/08/2026): ver, editar. A tela
   continua a ser de leitura — o que faltava era o caminho. */
.rec-acoes{ margin:2px 0 16px; gap:8px; }

.ficha-estado{ margin-top:22px; display:flex; flex-direction:column; gap:8px; }
.ficha-estado .inline-f{ gap:10px; }

.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 */
/* 🐞 29/09/2026 (auditoria no tablet): a 768px, 300px de formulário + a tabela
   (680px de mínimo) não cabiam, e a página rolava para o lado (1027px). A coluna
   da lista pode encolher (`minmax(0,1fr)`), e a grade empilha abaixo dos 1100px. */
.mesas-layout{ display:grid; grid-template-columns:300px minmax(0,1fr); gap:24px; align-items:start; }
.mesas-form .secao-titulo{ margin-top:0; }
@media (max-width:1100px){ .mesas-layout{ grid-template-columns:minmax(0,1fr); } }

.campo-check{ font-size:14px; }
.campo-check label{ display:flex; align-items:center; gap:8px; cursor:pointer; font-weight:500; }

/* ══════════════════════════════════════════════════════════════════════════
   🚨🚨 A CAIXA DE MARCAR SÓ RESPONDE ONDE SE VÊ ALGUMA COISA (22/09/2026).

   Ele: *"todo lugar no sistema onde tem a caixinha de tick deve funcionar
   somente clicando na caixinha. Tem alguns que eu clico na frente, totalmente
   fora, e ele ticka."*

   🐞 Medido no navegador a 1280px, no formulário de Lançamentos:
       «Pagamento misto» → etiqueta de 706px, **560px de espaço morto**
       «Pago»            → 706px, **649px mortos**
       «Conciliado»      → 706px, **307px mortos**
   A etiqueta é `block` (ou `flex`) e estica até ao fim do formulário; clicar a
   meio metro do texto continua a ser clicar na etiqueta, e marca.

   ⚠️ **E NÃO SE ENCOLHE PARA TODA A GENTE**, que é onde isto quase correu mal:
   a `.pro-chk` foi esticada DE PROPÓSITO na v0.429.0 para cumprir a régua dos
   44px do dedo (§2.5 da auditoria de 21/09) — a 375px dava 331×20px e não se
   acertava nela. Encolher à bruta desfazia esse trabalho e deixava seis caixas
   outra vez impossíveis no telemóvel.

   ⭐ Por isso a regra pergunta pelo PONTEIRO, como a casa já faz 20 vezes com
   `pointer:coarse`: com RATO, a etiqueta encolhe ao que se vê; com DEDO, fica
   como está. São dois problemas opostos e cada um fica com a sua resposta.
   ══════════════════════════════════════════════════════════════════════════ */
@media (pointer:fine){
  label:has(> input[type=checkbox]){ width:fit-content; max-width:100%; }
}
/* 🐞 E UMA TENTATIVA QUE NÃO SERVIU, escrita para não se repetir: pôr
   `pointer-events:none` no `.ajuda` para o parágrafo de explicação deixar de
   marcar. Medido com `elementFromPoint` + clique a sério: **continua a
   marcar** — tirar o span do teste de colisão faz o clique cair na `<label>`
   que está por baixo, que é justamente quem alterna. Ficava o preço (não se
   selecionar o texto) sem o ganho.
   ⏭️ Para o parágrafo deixar mesmo de marcar é preciso tirá-lo de DENTRO da
   etiqueta — 11 sítios, e é também o certo para quem usa leitor de ecrã (hoje
   o leitor anuncia o parágrafo inteiro como nome do controlo). Fica por
   decidir com ele: clicar no texto de um controlo é o gesto normal em toda a
   parte, e o que ele descreveu foi o espaço VAZIO. */
.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 tela
   inteiro. Com 100vh fixos, um cartão mais alto do que o tela 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:var(--verde-fundo); color:var(--verde);
  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 celular. */
.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 celular
   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; }

/* ⭐⭐ O BOTÃO DE CONTACTO (08/09/2026) — um toque, e a ação acontece.
   Ver `partials/contato-rapido.php` para o porquê do `<details>`. */
.contato{ display:inline-block; position:relative; }
.contato > summary{ list-style:none; cursor:pointer; }
.contato > summary::-webkit-details-marker{ display:none; }
.contato-menu{
  position:absolute; z-index:40; top:calc(100% + 6px); left:0; min-width:170px;
  background:var(--branco); border:1px solid var(--cinza-borda); border-radius:var(--raio-sm);
  box-shadow:var(--sombra); padding:6px; display:flex; flex-direction:column;
}
.contato-op{
  display:block; padding:10px 12px; border-radius:var(--raio-sm); text-decoration:none;
  color:var(--texto); font-size:14px; font-weight:600; white-space:nowrap;
}
.contato-op:hover{ background:var(--cinza-fundo); }
/* 🚨 A LIGAÇÃO SÓ ONDE SE PODE LIGAR. Num computador o `tel:` abre uma caixa a
   perguntar que aplicação usar, e isso é pior do que não oferecer. Quem decide é
   o dedo (`pointer:coarse`), como nos alvos de toque — não o nome do navegador. */
.contato-so-toque{ display:none; }
@media (pointer:coarse){ .contato-so-toque{ display:block; } }

/* ⭐ Alterar uma linha da lista de compras e desfazer o «comprado» (08/09/2026).
   O `<details>` fica fechado: a lista é para ler de relance, não um formulário. */
.lc-editar{ display:inline-block; }
.lc-editar > summary{ list-style:none; cursor:pointer; }
.lc-editar > summary::-webkit-details-marker{ display:none; }
.lc-editar-form{ display:flex; flex-wrap:wrap; gap:8px; align-items:center; margin-top:8px; }
.lc-editar-form input[type=text]{ flex:1 1 160px; min-width:0; }
/* o desfazer dura um desenho: uma linha, não uma seção */
.lc-desfazer{ display:flex; align-items:center; justify-content:space-between; gap:14px; flex-wrap:wrap; }

/* ---- 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 seçã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
   ============================================================ */
/* ══════════════════════════════════════════════════════════════════════
   ⭐⭐ O «SALTAR PARA O CONTEÚDO» — invisível até ao foco (30/08/2026).

   ⚠️ Fora do ecrã, e NÃO `display:none`: o que está escondido assim não é
   focável, e um link de salto que não recebe foco não serve para nada. É o
   erro clássico desta peça.
   ⭐ Ao receber foco, aparece por cima de tudo — inclusive da barra lateral
   (z:51) e da faixa de recado (z:70), senão nasce tapado como a faixa de erro
   nasceu esta manhã.
   ══════════════════════════════════════════════════════════════════════ */
.saltar{
  position:fixed; left:8px; top:-100px; z-index:100;
  padding:12px 18px; border-radius:var(--raio-sm);
  background:var(--preto); color:var(--branco); text-decoration:none;
  font-weight:600; font-size:14px; box-shadow:0 8px 24px rgba(17,17,17,.28);
  transition:top .12s;
}
.saltar:focus{ top:8px; color:var(--branco); }
/* 🚨 E O ALVO FICA COM O ANEL. Escrevi `.conteudo:focus{outline:none}` a
   pensar que um anel à volta da área inteira era ruído — e a cerca do foco
   apanhou-me: aquilo apaga o anel do TECLADO, que é a única pista que a pessoa
   tem. Quem carregou em «Ir para o conteúdo» precisa de ver que funcionou, e o
   contorno da região é exactamente o «estás aqui». A cerca estava certa. */

.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 celular 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); }
/* ⭐ As seções dentro de um módulo (27/09/2026, do FH Finanças): um rótulo
   pequeno, na cor de destaque do menu, a separar os grupos. Não é link. */
/* 27/09/2026 (ele): *"deixar a fonte deles maior pra dar mais destaque, estão
   um pouco apagados"* — 10,5px a 90% passou a 12px cheio, com mais ar em cima. */
.sb-sec{ display:block; padding:14px 10px 4px; font-size:12px; font-weight:800;
  letter-spacing:.05em; text-transform:uppercase; color:var(--destaque-menu); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.sb-subs > .sb-sec:first-child{ padding-top:6px; }
.sb-sub.ativo{ background:var(--menu-hover); color:var(--menu-fg); font-weight:700; }
/* "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:var(--cap-contador-pad);
  border-radius:999px; font-size:var(--cap-contador-fonte); font-weight:var(--cap-contador-peso); 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 celular 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; }
  body:has(.sidebar.sb-min){ --sb-larg: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 lugar 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 pegar 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 celular 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 lugar.
     ⚠️ 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 celular 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 arquivo 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 arquivo. 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; }

/* ============================================================
   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; }
/* ⚠️ `.mot-regra` (as regras do motor, em Operacional → Configurações) entra
   nestes seletores em vez de ganhar desenho próprio: é a MESMA peça a fazer o
   mesmo trabalho — uma gaveta com o resumo no `summary` — e um segundo desenho
   para isso era mais uma cápsula. A forma fica escrita uma vez, com dois nomes
   a usá-la. Ver `operacional/config.php`. */
.ajuda-item, .mot-regra{ border:1px solid var(--cinza-borda); border-radius:var(--raio-sm); margin-bottom:7px; overflow:hidden; }
.ajuda-item summary, .mot-regra summary{ cursor:pointer; padding:11px 14px; font-weight:600; font-size:14px; list-style:none; position:relative; }
.ajuda-item summary::-webkit-details-marker, .mot-regra summary::-webkit-details-marker{ display:none; }
.ajuda-item summary::after, .mot-regra summary::after{ content:'+'; position:absolute; right:14px; color:var(--cinza-medio); font-size:17px; }
.ajuda-item[open] summary::after, .mot-regra[open] summary::after{ content:'–'; }
.ajuda-item[open] summary, .mot-regra[open] summary{ color:var(--vermelho); }
/* ⚠️ O `summary` da regra leva um selo e um contador ao lado do nome, e por
   isso é flex: sem isto o selo caía para a linha de baixo a 375px. O `padding`
   à direita guarda o lugar do `+`, que é absoluto. */
.mot-regra summary{ display:flex; align-items:center; gap:8px; flex-wrap:wrap; padding-right:34px; }
.mot-regra-corpo{ padding:2px 14px 14px; }
/* ⭐ A gaveta que discrimina a diferença Perdas × CMV (item 19, 01/09/2026).
   ⚠️ Nasce FECHADA e mede-se pelo texto: é uma resposta a quem foi conferir, e
   não uma tabela para quem só quer o número. O resumo vive no `summary`. */
.cmv-fora{ margin-top:8px; }
.cmv-fora > summary{ cursor:pointer; font-size:12px; color:var(--cinza-medio);
  font-weight:600; list-style:none; text-decoration:underline; }
.cmv-fora > summary::-webkit-details-marker{ display:none; }
.cmv-fora[open] > summary{ color:var(--vermelho); }
.cmv-fora-corpo{ margin-top:6px; }
.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:var(--verde-fundo); border:1px solid #bfe6cb; color:var(--verde); 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:var(--azul-fundo); color:var(--azul); }
.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; }
/* 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 ===== */
/* 🚨🚨 28/08/2026 — ESTA REGRA EXISTIA E NÃO VALIA para os campos, e a
   auditoria de acessibilidade foi quem a apanhou. Sete regras da casa
   apagavam o contorno no `:focus` — `.campo input:focus{ outline:none }` e
   companhia — e **ganhavam por especificidade**: (0,2,1) contra os (0,1,1)
   daqui de baixo. Resultado: quem anda de Tab pelo sistema não via onde
   estava; ficava só uma borda a mudar de cinza para preto, 1,5px.
   ⭐ A intenção delas estava certa: **o anel não deve aparecer ao clicar com o
   rato**, senão cada clique acende uma moldura. O que faltava era dizer isso
   com precisão — `:focus:not(:focus-visible)` apaga para o rato e deixa o
   teclado em paz. O rato continua exatamente como estava.
   ⚠️ Fica escrito porque é a armadilha: `outline:none` num `:focus` é quase
   sempre um anel de teclado morto, e não dá erro nenhum. */
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: var(--ambar); 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) + 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) + 16px); } }

/* ═══════════ CONVITE DE INSTALAÇÃO (PWA) ═══════════
   Flutua no fim do tela, 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 celular 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) + 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-medio); font-weight: 600; }
.salao-kpi span { font-size: .8rem; color: var(--cinza-medio); }

/* o formulário de abrir mesa: numa linha no computador, empilhado no celular */
/* ⚠️ 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 lugar; 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-medio); }
.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-medio); }
.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. */

/* ═══════════ 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; }
.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-fundo); }
.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; }
/* 🐞 29/09/2026 (print dele): o «Alterar» ABERTO dividia a fila com o texto, e o
   nome do item ficava espremido a uma letra por linha, por baixo do formulário.
   Aberto, desce para uma linha só dele, na largura toda; o texto fica intacto. */
.lc-item { flex-wrap: wrap; position: relative; }
.lc-editar[open] { flex: 1 1 100%; min-width: 0; }
/* ⚠️ Sem `order` (a casa tem teto: muda o que se vê e não por onde se tabula):
   o Excluir, que no HTML vem depois do Alterar, fica preso ao canto de cima
   enquanto o Alterar está aberto — onde sempre esteve. */
.lc-item:has(> .lc-editar[open]) > .lc-apagar { position: absolute; top: 12px; right: 14px; }
.lc-item:has(> .lc-editar[open]) > .lc-texto { padding-right: 80px; }
.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-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 lugar é
   um `op-link`**.
   ⚠️ Alvo de toque generoso (44px de altura efetiva) porque isto usa-se com o
   celular 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. */
/* ⭐ As duas saídas da tela do turno, lado a lado (21/09/2026): o link de
   espreitar e o botão de decidir. Numa coluna a 375px, que é onde esta tela
   se usa, e o `op-link` já traz os 44px de alvo. */
.op-cabecalho-acoes{ display:flex; flex-direction:column; align-items:flex-start; gap:0; }
.op-fixar-form{ margin:0; }
/* ⚠️ O botão de decidir é o discreto: o gesto comum é espreitar, e pintar os
   dois de vermelho fazia a decisão parecer a ação principal. */
.op-link-fixar{ color:var(--cinza-medio); }

.op-link{
  display:inline-flex; align-items:center; gap:6px;
  padding:12px 0; margin-top:8px;   /* 44px de alvo de toque, para o celular 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 lugar 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 { 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-fundo); 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-medio); font-size: .92rem; margin: 0 0 18px; }
.cad-obrig { font-size: .8rem; color: var(--cinza-medio); margin: 0 0 16px; }
.req { color: #b42318; font-weight: 700; }

.cad-sec { border: 0; border-top: 1px solid var(--cinza-borda); 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(--texto);
}
.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%; }
/* 🐞 O TELEFONE PASSAVA POR CIMA DO E-MAIL (ele, 24/09/2026, na Nova reserva).
   O `.campo` é uma grelha, e na grelha um filho não encolhe abaixo da sua
   largura natural: o número (200px) + o país (118px) davam 326px numa coluna
   de 263px, e os 63px a mais iam para cima do e-mail. Aqui o par vive dentro da
   caixa das sugestões (`.ac-wrap`), que era quem empurrava. */
.ac-wrap, .campo-tel { min-width: 0; }
.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(--cinza-borda); }
.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: var(--verde); }
.cad-doc-arq { font-size: .78rem; color: var(--cinza-medio); 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: var(--cinza-fundo); color: #47536b; }
.st-cad-preenchendo { background: #fff8e6; color: var(--ambar); }
.st-cad-enviado     { background: var(--azul-fundo); color: var(--azul); }
.st-cad-aprovado    { background: var(--verde-fundo); color: var(--verde); }
.st-cad-revogado    { background: var(--cinza-fundo); 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(--cinza-borda); }
.cad-ver-linha dt { flex: 0 0 210px; color: var(--cinza-medio); 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(--cinza-borda); }
.cad-anexo-nome { font-size: .9rem; font-weight: 500; }
.cad-anexo-falta .cad-anexo-nome { color: #9aa3af; }
.pub-ok-ic .ic-inline{ width:30px; height:30px; opacity:1; }   /* o ✓ grande da confirmação, agora do sprite (26/09) */
.pub-ok-ic-erro { background: var(--vermelho-sinal-fundo) !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(--cinza-borda); 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(--cinza-borda); 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; } }

/* ⭐ Leis e regras (24/09/2026, sessão 52): uma linha por regra; a fonte vai
   miúda por baixo do valor, porque é para conferir, não para ler. */
.lei-contrato { max-width: 560px; margin: 0 0 18px; }
.lei-tabela td:first-child { width: 38%; }
.lei-antes, .lei-fonte, .lei-conflito { display: block; margin-top: 3px; }
.lei-fonte { font-size: .76rem; color: var(--cinza-medio); }
.lei-conflito .selo { margin-right: 4px; }
/* O ajuste abre numa linha própria, com a largura da tabela: na célula
   apertava a coluna do valor, e por cima era cortado pela caixa (800px). */
.lei-acoes { text-align: right; white-space: nowrap; }
.lei-abrir { font-size: .85rem; }
.lei-linha-ajuste td { background: var(--cinza-fundo); }
.lei-form { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 12px; margin: 0; }
.lei-form .campo { margin: 0; min-width: 140px; }
.lei-form-motivo { flex: 1 1 240px; }
.lei-voltar { margin-top: 10px; }
/* No celular a tabela vira cartões: o nome da regra é o título do cartão (sem
   o rótulo «Regra» ao lado), e a linha do ajuste não é um campo do cartão.
   ⚠️ 600px: é onde a `.tabela-cards` vira cartão; antes disso é tabela. */
@media (max-width: 600px) {
  .lei-tabela td:first-child { width: 100%; font-weight: 600; text-align: left; }
  .lei-tabela td:first-child::before, .lei-linha-ajuste td::before { display: none; }
  .lei-linha-ajuste td { text-align: left; }
  .lei-form .campo { flex: 1 1 100%; }
  .lei-tabela tbody tr.lei-linha-ajuste { border-top: 0; padding-top: 0; }
}

/* ⭐ Os avisos da lei na escala (24/09/2026): um selo por aviso, dentro do dia;
   o texto inteiro vai no title. */
.esc-lei { display: inline-block; margin: 0 0 4px; font-size: .68rem; cursor: help; }
.esc-lei-resumo { align-items: center; }
.esc-custo td, .esc-custo th { font-size: .78rem; color: var(--cinza-medio); border-top: 2px solid var(--cinza-borda); }
.esc-pct { font-weight: 600; color: var(--texto); }

/* ⭐ O contrato na ficha e os prazos na lista (24/09/2026, sessão 52). */
.ctr-aviso { margin: 0 0 10px; }
.ctr-gesto { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--cinza-borda); }
.ctr-historico { margin: 0; padding-left: 18px; font-size: .85rem; color: var(--cinza-medio); }
.ctr-prazos { margin: 0 0 18px; padding: 12px 16px; border: 1px solid #f0dfae; background: #fff8e6; border-radius: var(--raio-sm); }
.ctr-prazos .secao-titulo { margin: 0 0 6px; }
.ctr-prazos ul { margin: 0; padding-left: 18px; font-size: .88rem; }
.ctr-prazos li + li { margin-top: 4px; }
.ficha-validade { display: block; margin-top: 4px; font-size: .8rem; color: var(--cinza-medio); }
.mapa-mes input { padding: 6px 10px; }
.mapa-tabela td { vertical-align: top; }
.msal-nota { margin-top: 14px; }
/* ⭐ O mapa impresso para o contador: só a tabela, sem o menu nem os botões. */
@media print {
  body:has(.mapa-tabela) .sidebar, body:has(.mapa-tabela) .voltar, body:has(.mapa-tabela) .mapa-mes,
  body:has(.mapa-tabela) .lista-exportar, body:has(.mapa-tabela) .sb-hamburguer { display: none !important; }
  body:has(.mapa-tabela) .conteudo { margin: 0 !important; padding: 0 !important; max-width: none !important; }
  .mapa-tabela { font-size: 10px; }
  .mapa-tabela .msal-conf { display: none !important; }   /* o sinal verde é da casa, não do contador */
}
.msal-conf .selo { white-space: nowrap; text-decoration: none; }
.msal-conf .ic-inline { width: 13px; height: 13px; vertical-align: -2px; }
.fmes-bloco { max-width: 720px; margin-bottom: 18px; }
.fmes-lista { margin: 0 0 14px; padding-left: 0; list-style: none; }
.fmes-lista li { padding: 8px 0; border-bottom: 1px solid var(--cinza-borda); }
.fmes-lista li.fmes-atencao a { color: var(--ambar, #9a6700); font-weight: 600; }
.fmes-lista li.fmes-ok a { color: var(--cinza-medio); }
.fmes-pacote { display: flex; gap: 10px; flex-wrap: wrap; margin: 0 0 16px; }
.fmes-fechar { margin-top: 8px; }
.rec-lista { list-style: none; margin: 12px 0 0; padding: 0; }
.rec-lista li { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 10px 0; border-bottom: 1px solid var(--cinza-borda); }
.rec-lista li a { display: flex; gap: 10px; align-items: baseline; text-decoration: none; color: var(--texto); }
.rec-subir { margin-top: 6px; }
.sal-custo-total { margin: 14px 0 4px; font-weight: 600; }
/* ⭐ 25/09/2026: o recibo simulado na ficha, com as colunas do recibo do contador.
   ⚠️ `.tabela.rsim-tab` porque a casa escreve `.tabela thead th` e `.tabela tbody td`:
   com um seletor só de classe, o padding e as maiúsculas da casa vencem. */
.tabela.rsim-tab .num { text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
.tabela.rsim-tab thead th, .tabela.rsim-tab tbody td, .tabela.rsim-tab tfoot th { padding: 7px 10px; }
.tabela.rsim-tab thead th { text-transform: none; letter-spacing: 0; text-align: right; white-space: normal; }
.tabela.rsim-tab tbody .rsim-desc td:first-child { padding-left: 22px; color: var(--cinza-medio); }
.tabela.rsim-tab tfoot th { border-top: 1px solid var(--cinza-borda); text-align: left; }
.tabela.rsim-tab tfoot th.num { text-align: right; }
.tabela.rsim-tab .rsim-liq th { font-size: 16px; border-top: 0; }
.rsim-rot { margin: 14px 0 4px; font-size: 13px; font-weight: 600; }
.rsim-duo { display: block; margin: 4px 0 18px; }
.rsim-par { display: grid; grid-template-columns: minmax(0, 1fr) 110px; gap: 8px; margin-bottom: 8px; }
.pub-ok-email { font-size: 14px; color: var(--cinza-medio); overflow-wrap: anywhere; }
/* ⭐ 25/09/2026: o recibo lido como base do salário, e o que não bate */
.lrec-base { margin: 16px 0 4px; padding: 12px 14px; border: 1px solid var(--cinza-borda); border-radius: var(--raio-sm); background: var(--branco); }
.lrec-base-alerta { border-color: color-mix(in srgb, var(--ambar-vivo) 55%, transparent); }
.lrec-base-tit { margin: 0 0 6px; display: flex; flex-direction: column; gap: 2px; }
.lrec-base-aviso { margin: 6px 0 2px; color: var(--ambar); font-weight: 600; font-size: 14px; }
.lrec-base-ok { margin: 6px 0 0; color: var(--verde); font-size: 14px; }
.lrec-div { margin: 0 0 10px; padding-left: 18px; font-size: 14px; }
.lrec-aviso-linha { display: block; color: var(--ambar); font-size: 13px; font-weight: 600; }
/* ⭐ 25/09/2026: os e-mails ao cliente, na reserva */
.res-emails { margin-top: 22px; }
.res-emails-lista { list-style: none; margin: 4px 0 12px; padding: 0; }
.res-emails-lista li { display: flex; gap: 10px; align-items: flex-start; padding: 8px 0; border-bottom: 1px solid var(--cinza-borda); }
.res-emails-txt { display: flex; flex-direction: column; gap: 2px; min-width: 0; overflow-wrap: anywhere; }
.imp-falta { margin-bottom: 18px; }
.imp-falta-lista { list-style: none; margin: 4px 0 10px; padding: 0; }
.imp-falta-lista li { padding: 8px 0; border-bottom: 1px solid var(--cinza-borda); }
.imp-falta-lista li a { font-weight: 600; font-size: 15px; color: var(--texto); text-decoration: none; }
.imp-falta-lista .ajuda-inline { display: block; }
.imp-falta-atraso { color: var(--vermelho-sinal); }
.imp-hist-o { display: block; font-size: 13px; color: var(--cinza-medio); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* ⭐ 25/09/2026: no telemóvel o histórico é UMA linha (o modo compacto da casa) — e a
   ação fica: o «Desfazer» não pode desaparecer com as outras células. */
@media (max-width: 600px) {
  .tabela-cards.tabela-compacta.imp-hist tbody td.imp-hist-acao { display: block; flex: none; width: auto; padding: 0; border-bottom: none; }
  .tabela-cards.tabela-compacta.imp-hist tr { align-items: center; }
}
@media (max-width: 480px) {
  .tabela.rsim-tab { font-size: 13px; }
  .tabela.rsim-tab thead th, .tabela.rsim-tab tbody td, .tabela.rsim-tab tfoot th { padding: 6px; }
  .tabela.rsim-tab tbody .rsim-desc td:first-child { padding-left: 14px; }
}
.aus-comprov { font-size: .8rem; white-space: nowrap; }
.aus-motivo-lei .campo { min-width: 0; }
.ficha-validade input { margin-left: 6px; padding: 2px 6px; font-size: .8rem; }

/* aviso de atenção: problema real que o cliente ainda não percebeu */
.alerta-atencao { background: #fff8e6; border-color: #f0dfae; color: var(--ambar); }
.smtp-tecnico { border-left: 2px solid var(--cinza-borda); 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(--cinza-borda); }
.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(--cinza-borda); 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-fundo);
  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:var(--verde); }
.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, var(--azul) 12%, transparent); color:var(--azul); }
.pill-motivo-manual{ background:color-mix(in srgb, var(--verde) 14%, transparent); color:var(--verde); }
.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(--cinza-borda); }

/* 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(--cinza-borda); 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-fundo); }
.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; }
/* ⏭ 08/09/2026: era uma caixa de seleção com 17px; passou a ser uma LISTA de
   canal (aviso / email / ambos / nenhum), a pedido dele. O `input{width:17px}`
   esmagava a lista — a regra passa a mirar a caixa, não «tudo o que for campo». */
.notif-item{ display:flex; align-items:center; justify-content:space-between; gap:14px; flex-wrap:wrap;
  padding:10px 0; border-top:1px solid var(--cinza-borda); }
.notif-item > label{ flex:1 1 240px; min-width:0; display:flex; flex-direction:column; gap:2px; cursor:pointer; }
/* ⚠️ `.campo select` da casa vale 100% — e o invólucro leva `campo` de propósito,
   para o seletor ter o aspeto de todos os outros. O que se trava aqui é só a
   largura: com 100% a lista ocupava a linha inteira e empurrava o rótulo. */
.notif-item.campo > select{ flex:0 0 auto; width:auto; min-width:150px; }
.notif-item input[type=checkbox]{ flex:0 0 auto; width:17px; height:17px; }
.notif-item:first-of-type{ border-top:none; }
.notif-item input[type=checkbox]{ 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:var(--ambar);
  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;
}
/* ⭐ O KPI que LEVA A ALGUM LADO (31/08/2026). Ele: *"quando clicar nele, ele
   mostre quais são pra fazer a alteração."* Herda tudo do cartão normal — só
   diz, ao dedo e ao rato, que ali se clica. ⚠️ Sem sublinhado e com a cor do
   texto: um cartão inteiro pintado de link era ruído numa faixa de quatro. */
.fecho-kpi-link{ text-decoration:none; color:inherit; cursor:pointer;
  transition:border-color .15s ease, box-shadow .15s ease; }
.fecho-kpi-link:hover{ border-color:var(--preto); }
.fecho-kpi-link:focus-visible{ outline:2px solid var(--preto); outline-offset:2px; }
.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 SEM BASE DE CÁLCULO (item 13 do handover, 01/09/2026). Ele: *"num
   painel financeiro, ausência de base de cálculo e resultado zero não podem ter
   a mesma aparência"*.
   ⚠️ E por isso NÃO herda o tamanho do número: 26px de «sem base» gritava mais
   do que o valor do cartão ao lado, que é um número de verdade. Fica do tamanho
   da frase que é, em itálico e discreto — o que se lê é o estado, não um
   destaque. */
.fecho-kpi-vazio{ font-family:inherit !important; font-size:15px !important;
  font-style:italic; color:var(--cinza-medio) !important; font-weight:600; }
/* ⭐ 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 usuário 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 celular 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; }
@media (max-width:560px){
  /* 🐞 A RETIRADA PASSAVA DA TELA (27/09/2026): a linha tem ~273px dentro do
     cartão e a grade pedia 110 + 132 + 34 + 34 + folgas = 334px — o `1fr` é
     `minmax(auto,1fr)` e não desce abaixo dos 132px de mínimo do campo do
     valor; o motivo, na linha toda, saía 61px da linha (8px da tela). Agora
     três colunas que encolhem: origem | valor (até ao fim) · motivo inteiro ·
     categoria | dividir | ×. */
  .retirada-linha{ grid-template-columns:minmax(0,1fr) minmax(0,1fr) 34px; }
  .retirada-linha > .campo-moeda{ grid-column:2 / -1; min-width:0; }
  .retirada-linha input[name="ret_motivo[]"]{ grid-column:1 / -1; }
  .retirada-linha select[name="ret_categoria[]"]{ grid-column: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 celular 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:var(--ambar); background:color-mix(in srgb, var(--ambar-vivo) 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 tela 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 tela 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 celular 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; }
/* 🚨 A TABELA DE DENTRO ROLA SOZINHA, e o corpo da página não (30/08/2026).
   Achado a medir a validade herdada: a 375px o `.resumo-card` dos indicadores
   deixava a tabela transbordar e era a PÁGINA INTEIRA que passava a rolar de
   lado — `document.scrollWidth 505 > clientWidth 329`. ⚠️ E já era assim antes
   desta sessão: a linha «Conservação / Validade» cortava do mesmo modo. A
   regra da casa é a mesma do `.tabela-wrap`: o que é largo rola dentro da sua
   própria caixa, e o corpo da página nunca rola na horizontal.
   ⚠️ Só a tabela, e não o cartão: `overflow` no cartão cortaria as sombras e
   os balões de ajuda que vivem lá dentro noutras telas. */
.resumo-card > table{ display:block; overflow-x:auto; max-width:100%; }
.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; }

/* 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,
.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:var(--vermelho-sinal); } .cfg-nat-cab.nat-des .dot{ background:var(--vermelho-sinal); }
.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:var(--ambar); font-size:15px; margin-bottom:3px; }
.cfg-reclass-txt p{ margin:0 0 8px; font-size:13.5px; color:var(--ambar); }
.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:var(--cap-controle-fonte); background:#fff; border:1px solid #f0dfae; border-radius:999px; padding:var(--cap-controle-pad); font-weight:var(--cap-controle-peso)}
.cfg-reclass-txt li span{ color:var(--cinza-medio); }
.cfg-linha{ display:flex; gap:6px; align-items:center; flex-wrap:wrap; margin:0; }
/* ⭐ O seletor de medida ao lado do número (30/08/2026). Era um `style=` à mão
   de `max-width:80px` no parcial; ganhou nome quando a opção passou a poder
   dizer o que vale — `un (700 ml)` não cabe em 80px, e um rótulo cortado no
   meio é pior do que rótulo nenhum. */
.medida-sel{ max-width:150px; flex:0 0 auto; }
.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; }
/* ⭐ As caixas de «quais despesas pedem comprovante» (30/08/2026): nove
   grupos numa grelha que se ajusta sozinha. `auto-fill` com um mínimo, e não
   um número de colunas: a mesma regra serve o telemóvel e o ecrã largo, e
   ninguém tem de manter dois números em dois sítios. */
.cfg-grupos{
  display:grid; grid-template-columns:repeat(auto-fill, minmax(180px, 1fr));
  gap:4px 14px; margin-top:10px;
}
.cfg-grupos .cfg-toggle{ margin-top:0; }

/* 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:var(--ambar); }
.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,
.fatura-linha select, .perda-linha select, .retirada-linha select{ padding-right:28px; }

@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; }
  /* ══════════════════════════════════════════════════════════════════════
     🚨🚨 «OLHA COMO FICOU UN E RESPONSÁVEL» (ele, 31/08/2026, sobre a própria
     captura que eu lhe mandei)

     A UNIDADE e o RESPONSÁVEL apareciam espremidos a **22px**, com os rótulos
     cortados ao meio. Medido a 686px: os outros campos com 532px de largura,
     estes dois com 22.

     🚨 A causa é o POSICIONAMENTO AUTOMÁTICO da grelha, e não uma largura mal
     escolhida. A terceira coluna de 22px existe de propósito — é onde vive o
     `×` de apagar a linha, preso à **fila 1**. Mas nas filas seguintes essa
     coluna fica VAGA, e um campo com `span 1` e sem lugar marcado cai no
     primeiro buraco livre: a fila do «Qtd» ocupava as duas colunas largas e
     deixava a de 22px aberta ao lado — e era lá que a Unidade aterrava. O mesmo
     ao Responsável, uma fila abaixo.

     ⭐ Deixa de haver buracos: cada campo diz em que coluna vive. E de passagem
     arruma-se o que faz sentido ler junto — Qtd ao lado da Unidade, Custo ao
     lado do Total — em vez de cada um numa fila sua.
     ⚠️ `.campo-un` perde o tecto de 92px aqui: numa coluna de meia largura, o
     rótulo «UNIDADE» não cabe em 92px, e era metade do que ele viu.
     ══════════════════════════════════════════════════════════════════════ */
  /* 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(7), .perda-linha .campo:nth-child(8){ grid-column:1 / span 2 !important; }
  /* E os que se leem aos pares, cada um com lugar marcado. */
  .perda-linha .campo:nth-child(3){ grid-column:1 !important; }   /* Qtd     */
  .perda-linha .campo:nth-child(4){ grid-column:2 !important; }   /* Unidade */
  .perda-linha .campo:nth-child(5){ grid-column:1 !important; }   /* Custo   */
  .perda-linha .campo:nth-child(6){ grid-column:2 !important; }   /* Total   */
  .perda-linha .campo-un{ max-width:none; }
  .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); }
/* ⭐ O lápis da linha DIVIDIDA (22/09/2026). Ocupa o lugar do cadeado que lá
   estava e herda tudo do `.lanc-ico`; só precisa de deixar de parecer um
   botão de formulário, porque é um `<button>` e os vizinhos são `<a>`. */
.lanc-abrir-partes{ background:none; border:0; padding:0; font:inherit; cursor:pointer; }
/* 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 (usuários,
   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:var(--vermelho-sinal); border-color:var(--vermelho-sinal); background:color-mix(in srgb, var(--vermelho-sinal) 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:var(--ambar); 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 celular. */
.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 tela 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(--cinza-borda); 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(--cinza-medio); }
.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:var(--ambar); 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
   arquivo — 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(--cinza-medio); 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 tela. */
.lanc-sub{ display:block; font-size:11px; line-height:1.35; color:var(--cinza-medio); 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(--cinza-medio); font-variant-numeric:tabular-nums; }
.lanc-vazio{ color:var(--cinza-borda); }
.td-saldo{ font-variant-numeric:tabular-nums; white-space:nowrap; color:var(--cinza-medio); }
/* 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 lugar 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
   lugar 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:var(--cap-controle-pad); border:1px solid var(--cinza-borda);
  border-radius:999px; background:var(--branco); color:var(--texto); text-decoration:none;
  font-size:var(--cap-controle-fonte); transition:border-color .15s; font-weight:var(--cap-controle-peso)}
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-fundo); 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 pegou 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 tela mas continua a existir para o teclado e o leitor de tela.
   ⚠️ É 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:var(--cap-controle-pad); border:1px solid var(--cinza-borda);
  border-radius:999px; background:var(--branco); color:var(--texto);
  font-size:var(--cap-controle-fonte); transition:border-color .15s, background .15s, color .15s; font-weight:var(--cap-controle-peso)}
.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(--cinza-medio); 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:var(--verde-fundo); color:var(--verde); }
.lanc-liq-atraso{ background:var(--vermelho-sinal-fundo); color:var(--vermelho-sinal); }

/* Aviso de variação no fecho: aparece só quando o contado difere do previsto. */
.var-aviso{ display:block; margin-top:4px; font-weight:600; }
/* ⭐ O TIQUE DA CONCILIAÇÃO (21/09/2026). Só aparece quando o contado não bate
   com o que o sistema calculou, e é uma DECISÃO — não um campo a mais. A caixa
   dá-lhe o peso de quem pede uma resposta, sem gritar: a mesma borda dos
   blocos do fecho e um fundo de um degrau só. */
.campo-conciliar{ margin-top:10px; padding:10px 12px; border:1px solid var(--cinza-borda);
  border-radius:var(--raio-sm); background:color-mix(in srgb, var(--destaque) 5%, transparent); }
.campo-conciliar .ajuda{ display:block; margin-top:4px; }

/* ⚠️ 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 tela: 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 tela 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:var(--ambar); 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. */
/* ══ ⭐ A JANELA «DE ONDE VEM ESTE NÚMERO» (10/09/2026) ═════════════════════
   Ele: *"eu clico em CMV, abre uma janela com todas as transações que aquele
   valor se refere"*.
   ⚠️ A TABELA rola, a janela não: o total fica à vista enquanto se percorrem as
   linhas — senão perde-se o que se veio conferir. */
.dlg-detalhe{ width:min(620px,94vw); }
.det-cab{ display:flex; align-items:flex-start; justify-content:space-between; gap:14px; margin-bottom:2px; }
.det-rot{ display:block; font-family:var(--fonte-titulo); font-size:17px; font-weight:700; }
.det-janela{ display:block; font-size:12px; color:var(--cinza-medio); margin-top:2px; }
.det-total{ font-family:var(--fonte-titulo); font-size:22px; font-weight:700; white-space:nowrap; }
/* ⚠️ Sem margem negativa: ela empurrava o conteúdo 6px para cada lado e a
   tabela passava a rolar 8px de lado a 375px — um arrasto lateral inútil dentro
   de uma janela que já rola para baixo. */
.det-rolo{ max-height:min(52vh,420px); overflow-y:auto; overflow-x:auto; }
/* ⚠️ `table-layout:fixed`: sem ele a tabela não encolhe abaixo do seu tamanho
   natural (297px), e a 375px sobravam 8px — uma barra de rolagem lateral dentro
   de uma janela que já rola para baixo. Com as colunas medidas, a descrição
   quebra e nada sai do sítio. */
.det-tabela{ width:100%; table-layout:fixed; }
.det-tabela th:first-child, .det-tabela td:first-child{ width:58px; }
.det-tabela th:last-child, .det-tabela td:last-child{ width:92px; }
.det-tabela td:nth-child(2){ overflow-wrap:anywhere; }
.det-tabela td{ vertical-align:top; }
.det-data{ white-space:nowrap; color:var(--cinza-medio); font-size:12px; }
.det-sub{ display:block; font-size:11px; color:var(--cinza-medio); margin-top:2px; }
/* ⚠️ A devolução é uma linha negativa no meio de saídas: marca-se, senão lê-se
   como erro de lançamento. */
.det-estorno td{ background:rgba(0,0,0,.02); }
/* ⭐ A tabela do SALDO não tem cabeçalho nem data: são duas colunas, o nome da
   conta e o que lá está. Uma linha de cabeçalho para duas colunas óbvias é
   moldura a mais. */
.det-contas td:first-child{ font-weight:700; }
/* ⭐ «entrou X − saiu Y», quando o total é uma subtração: sem isto, somar as
   linhas de cabeça nunca dava o número de cima. */
.det-conta{ margin:2px 0 10px; font-size:13px; display:flex; gap:8px; align-items:baseline; flex-wrap:wrap; }
.det-menos{ color:var(--cinza-medio); }
.det-pe{ margin-top:14px; }
.det-cartao{ padding:20px 22px; }
/* ⭐ O cartão que ABRE diz que abre — sem isto, dois cartões iguais fazem coisas
   diferentes ao toque e ninguém sabe quais. */
/* ⚠️ `position:relative` AQUI e não no `.dash-tile`: sem ela a setinha
   ancorava no primeiro antepassado posicionado — que é a página — e ia parar ao
   canto do ecrã. E pô-la no cartão base mexia em todos os cartões da casa. */
.dash-tile.dash-abre{ cursor:pointer; position:relative; }
.dash-tile.dash-abre::after{ content:''; position:absolute; right:10px; top:10px;
  width:6px; height:6px; border-right:1.5px solid var(--cinza-medio);
  border-bottom:1.5px solid var(--cinza-medio); transform:rotate(-45deg); opacity:.5; }
.dash-tile.dash-abre:hover::after{ opacity:1; }

.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; }
/* ══════════════════════════════════════════════════════════════════════════
   🚨 A LINHA DO QUE NINGUÉM DECLAROU PODE QUEBRAR (31/08/2026)

   Ele, com o painel numa janela estreita: *"sumiram as coisas daqui"* — e as
   colunas dos valores tinham mesmo desaparecido.

   A causa é o `white-space:nowrap` da regra acima, e ele estava certo para quem
   nasceu: as sub-linhas dos meses são «Julho/2026», curtas por natureza. A minha
   linha nova é uma frase — e com `nowrap` a frase empurra a largura mínima da
   tabela para além do cartão, expulsando as colunas do valor e da percentagem.
   ⚠️ Uma regra herdada por parecença de nome («também é uma sub-linha») e não
   por parecença de conteúdo. A frase não é um rótulo de mês.

   ⭐ Duas correções, e as duas eram devidas: o texto encurtou (ele pede menos
   texto desde sempre) e ESTA linha passa a poder quebrar. As dos meses ficam
   exactamente como estavam. */
.mini-tab tr.sub-suposto td{ align-items:baseline; }
.mini-tab tr.sub-suposto td span:first-child{ white-space:normal; overflow-wrap:anywhere; }

/* ---------- 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:var(--ambar); }
.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 lugar
   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-fg,#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; }
/* ⭐ Com o «+ Novo» no cabeçalho (27/09/2026), o de baixo não pode ser um
   segundo botão igual: fechado, some; aberto, é o título do formulário (e é
   por ele que se fecha). Um «Novo» por tela. */
.com-cab:not([open]) > summary{ display:none; }
.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 tela 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. */
/* ⭐ COMO O CSV FOI LIDO — por cima da prévia da fatura (28/08/2026).
   ⚠️ Fica ANTES da tabela e não num rodapé: quem confere números decide com o
   primeiro número que vê, e o aviso tem de chegar antes dele. */
.cmp-decimal{
  display:flex; flex-wrap:wrap; align-items:center; gap:6px 14px;
  margin:0 0 14px; padding:12px 16px;
  border:1px solid var(--cinza-borda); border-radius:var(--raio-sm);
  background:var(--branco); font-size:14px;
}
.cmp-decimal p{ margin:0; display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
.cmp-decimal-troca{ margin-left:auto; }
/* A dúvida veste o âmbar do `alerta`: pede atenção, e não é erro. */
.cmp-decimal-duvida{ border-color:var(--ambar); background:var(--ambar-fundo); }
/* ⭐ CONTAR NA UNIDADE NATURAL — embalagens fechadas + o resto solto.
   ⚠️ Alinhado à DIREITA como o resto da coluna, e os dois campos estreitos: são
   números curtos (2 garrafas, 200 ml), e um campo largo convida a escrever o
   que não cabe. */
/* ⭐ O VASILHAME RETORNÁVEL, na ficha do produto — atrás de um `<details>`
   porque a esmagadora maioria dos produtos não devolve vasilhame, e dois campos
   sempre à vista eram ruído em 250 fichas para servir cinco. */
.prod-retornavel{ margin-top:16px; padding-top:12px; border-top:1px dashed var(--cinza-borda); }
.prod-retornavel summary{ cursor:pointer; }
.prod-retornavel[open] summary{ margin-bottom:4px; }
/* ⭐ A CONVERSÃO DE MEDIDA CASEIRA, no editor da ficha (30/08/2026) — atrás de
   um `<details>` pela mesma razão do vasilhame acima: quem já sabe o peso não
   tropeça nela, e quem precisa abre uma vez. Segue a forma da irmã, e não
   inventa uma nova: um bloco dobrável a mais com desenho próprio é a maneira
   de o padrão se desfazer sem ninguém decidir nada. */
.bloco-dobra{ margin:0 0 16px; padding-top:12px; border-top:1px dashed var(--cinza-borda); }
.bloco-dobra summary{ cursor:pointer; font-weight:600; }
.bloco-dobra[open] summary{ margin-bottom:8px; }
.bloco-dobra .filtro-linha{ align-items:flex-end; }
/* A lista de resultados da tabela de fatores. Uma linha por alimento, com o
   valor a saltar à vista — é ele que se vai escrever no campo ao lado. */
.fct-lista{ list-style:none; margin:8px 0 0; padding:0; }
.fct-lista li{
  display:flex; align-items:baseline; gap:8px; flex-wrap:wrap;
  padding:6px 0; border-bottom:1px solid var(--cinza-borda);
}
.fct-lista li:last-child{ border-bottom:0; }
.fct-val{ font-variant-numeric:tabular-nums; font-weight:600; }
/* ⚠️ O «usar» empurra-se para a direita e leva alvo de dedo: é um botão numa
   lista densa, e a regra dos 44px vale aqui como em qualquer outro lado. */
.fct-lista .btn-link{ margin-left:auto; min-height:44px; }
/* ⚠️ No celular os três campos empilham-se: um `select` de alimento espremido
   ao lado de outro não se lê, e a regra da casa mede-se a 375px. */
@media (max-width:520px){
  .bloco-dobra .filtro-linha{ flex-direction:column; align-items:stretch; }
  .bloco-dobra .filtro-linha .campo{ width:100%; }
}
.inv-contar{ display:flex; gap:8px; align-items:flex-end; justify-content:flex-end; flex-wrap:wrap; }
.inv-contar-c{ display:flex; flex-direction:column; gap:2px; align-items:flex-end; }
.inv-contar-c span{ font-size:11px; color:var(--cinza-medio); line-height:1.2; }
.inv-contar-c input{ max-width:82px; text-align:right; }
.inv-contar .js-total-conta{ align-self:center; font-variant-numeric:tabular-nums; }
.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-fundo);
}
.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:var(--cap-controle-fonte); font-weight:var(--cap-controle-peso);
  color:var(--cinza-medio); background:var(--branco); border:1px solid var(--cinza-borda);
  padding:var(--cap-controle-pad); 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 CAIXA DE SELEÇÃO COM O DEDO (03/09/2026, medido a 375px na cópia).
   🚨 Uma caixa nativa mede **13×13px**, e são 257 só na tela de Produtos. A
   régua da casa é 44 — e o cronómetro do dedo (`test-alvo-do-dedo.php`) NUNCA
   as viu, pela mesma razão que não via o `.btn-export`: ele procura peças que
   DECLAREM `height:` abaixo de 44, e uma caixa nativa não declara nada. A
   régua lê o que está escrito; o que o navegador decide sozinho só se vê no
   navegador.
   ⚠️ **Aqui NÃO se usa o truque da área invisível de 44px** — o mesmo que
   salvou o `.btn-mini` e o `.btn-export`. Nestas duas listas a caixa tem uma
   LIGAÇÃO a 6px de distância (o nome do produto, o nome da reserva), e um alvo
   invisível de 44px engolia o clique dela: quem quisesse abrir a ficha marcava
   a linha. Cresce-se a caixa DE VERDADE, que ninguém confunde.
   ⚠️ 22px e não 44: é o que cabe na coluna de 26px do Produtos sem lhe mexer no
   desenho. Fica **abaixo da régua**, e isso está dito na fila em vez de ficar
   por dizer — meio caminho anotado vale mais do que um teto fingido. */
/* 🐞 E ISTO VIVE **AQUI**, logo a seguir à regra dos 17px, e não lá em cima
   ao pé do `.btn-export` — foi preciso o navegador para o descobrir, duas
   vezes seguidas:
     1. a primeira versão dizia `.sel-prod` e perdia por ESPECIFICIDADE para
        `.col-sel input[type=checkbox]` (uma classe + um tipo + um atributo);
     2. a segunda igualou a especificidade e continuou a perder — por ORDEM.
        Com o mesmo peso ganha a última, e a dos 17px estava 3.000 linhas
        abaixo. No código as duas pareciam ambas verdade; só a régua do
        navegador disse qual mandava.
   ⭐ De caminho o remédio passou a valer para a coluna de seleção de QUALQUER
   lista (o Diário usa a mesma `.col-sel`), que é onde o problema é o mesmo. */
@media (pointer:coarse){
  .sel-res,
  .sel-esp,
  .sel-entrada,
  /* ⭐ A caixa «Bate» do inventário (07/09/2026): 📏 13×13px medidos a 375px,
     256 delas, na tela que se usa com o DEDO dentro da câmara fria. É a caixa
     mais pequena da casa na tela onde o dedo mais importa. */
  .js-bate,
  .col-sel input[type=checkbox]{ width:22px; height:22px; }
}
/* ⭐⭐⭐ E O ALVO DO DEDO CHEGA AOS 44 (03/09/2026, decisão dele).
   Os 22px eram o meio caminho de ontem, e ficou dito que não eram 44.

   🐞 **A razão que eu dei para não dar era falsa, e ele mandou explicar melhor.**
   Eu disse que o alvo invisível engolia a ligação a 6px de distância. Fui medir:
   são **10px** nos Produtos em cartão, **15** na agenda, **25** até ao link na
   tabela — e, sobretudo, eu tinha assumido que o alvo teria de ser CENTRADO,
   como o do `.btn-mini`. Não tem. **À esquerda da caixa não há nada clicável**
   (a hora da reserva, o corpo do cartão, a margem da célula), e é para lá que
   ele cresce.

   ⚠️ **Por isso `right:-8px` e não `left:50%`**: o alvo estende-se 14px para a
   ESQUERDA e 8 para a direita, e o número saiu da régua e não do palpite.
   🐞 A primeira tentativa foi `-2px` — quase tudo para a esquerda — e mediu
   **39 de 44**: o `overflow-x:auto` da `.tabela-wrap` corta o que passa da
   borda da linha, e nos Produtos em cartão só há **16px** livres desse lado.
   Com 14+22+8 = 44 cabe dos dois lados, e os 8 da direita ficam a **2px** do
   nome do produto (que está a 10) e a 7 do nome da reserva (que está a 15).
   ⚠️ **E vive numa `<label>`, não no `<input>`.** Um `<input>` é elemento
   SUBSTITUÍDO: a norma não garante que desenhe `::after`. O Chromium desenha
   (medi 44×45), o Safari do iPhone historicamente não — e um alvo que funciona
   no Android e falha no iPhone é pior do que 22px que funcionam nos dois. Uma
   `<label>` é elemento normal, desenha em qualquer lado, e clicar nela já marca
   a caixa por comportamento nativo.
   ⚠️ O alvo é INVISÍVEL: nenhuma cor, nenhuma borda. O olho continua a ver a
   caixa de 22px e nenhuma linha se mexe. */
.sel-alvo{ position:relative; display:inline-flex; align-items:center; justify-content:center; flex:none; }
@media (pointer:coarse){
  .sel-alvo::after{
    content:""; position:absolute; top:50%; transform:translateY(-50%);
    right:-8px; width:44px; height:44px;
  }
}
/* ⭐ 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 (celular) 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 tela 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 celular — 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 controle: 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: a 04/09/2026 `.barra-sel` existe em SETE
   telas — fichas, produtos, lançamentos, agenda, fila de espera, mesas e
   clientes — e o balão vem do parcial global `ajuda.php`.
   🐞 Este comentário dizia «três telas» e ficou a dizê-lo enquanto quatro
   nasciam: um número escrito à mão num comentário envelhece calado. */
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 lugares.
   🚨 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); }
/* ⚠️ 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); }
/* ⭐ 04/09/2026 · O campo de texto da barra (a etiqueta dos Clientes).
   ⚠️ Largura FIXA e pequena: a barra é uma pílula que já quebra em duas linhas
   a 375px, e um campo elástico empurrava os botões para uma terceira. 40
   caracteres é o que o motor aceita, e «Natal 2026» leva dez. */
.barra-sel-campo{
  width:150px; max-width:38vw; padding:8px 12px; font-size:14px;
  background:var(--branco); color:var(--texto);
  border:1px solid var(--cinza-borda); border-radius:var(--raio-sm);
}

/* 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 tela à 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:var(--cap-controle-fonte); font-weight:var(--cap-controle-peso); color:var(--cinza-medio);
  background:var(--branco); border:1px solid var(--cinza-borda);
  padding:var(--cap-controle-pad); 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:var(--cap-contador-fonte); font-weight:var(--cap-contador-peso);
}
.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 tela 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 tela 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 tela 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 (tela) ═══════════
   ⚠️ As classes são as MESMAS da folha A4 (app/Views/relatorios/imprimir.php),
   porque o corpo do relatório é um arquivo só, servido aos dois. Mexer numa
   sem olhar à outra é como o papel começa a sair diferente do tela. */
.rel-periodo { display: flex; gap: 12px; align-items: flex-end; flex-wrap: wrap; margin-bottom: 20px; }
.rel-periodo .campo { margin: 0; }
/* 🚨🚨 O RELATÓRIO EMPURRAVA A PÁGINA PARA O LADO NO TELEMÓVEL (auditoria de
   30/08/2026). Medido a 375px: **324px** de página a rolar de lado, por causa
   de uma `.rel-tab` de 664px lá dentro. A página inteira andava — o menu, o
   título, tudo — e é o pior tipo de mexida, porque a pessoa julga que a tela é
   que está torta.
   ⭐ A casa já tinha a resposta escrita no `.tabela-wrap`: *"min-width:0 é o
   que faz o overflow-x funcionar de fato: sem ele a caixa herda a largura
   mínima da tabela e, em vez de rolar por dentro, empurra a página inteira"*.
   É a mesma receita, e agora a tabela rola DENTRO da caixa.
   ⚠️ E isto é só de TELA: a folha A4 tem as regras dela dentro do
   `folha-a4.php` e não passa por aqui — o papel não muda. */
.rel-corpo { background: var(--branco, #fff); border: 1px solid var(--cinza-borda, #e4e4e7);
             border-radius: var(--raio-sm); padding: 22px 24px;
             overflow-x: auto; min-width: 0; }
.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 celular, 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; }
/* ⭐ O ALVO DO DEDO NA CAIXA DE MARCAR (21/09/2026, medido na auditoria).
   📏 A 375px, com dedo, a `.pro-chk` dava um alvo de **331×20px**: larga e
   BAIXA — e o que falha é sempre a dimensão pequena. A régua da casa é 44px e
   a `.sel-alvo` já a cumpre desde 24/08; estas seis ficaram de fora.
   ⚠️ Cresce a ALTURA DA LINHA e não o desenho da caixa, como no resto da casa.
   ⚠️ E só com dedo (`pointer:coarse`): quem tem rato acerta os 20px, e esticar
   a linha no computador afastava os campos sem motivo. */
@media (pointer: coarse) {
  .pro-chk { min-height: 44px; }
}
.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 celular 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 tela largo dá três ou quatro colunas,
   no celular 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-fundo); }
.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; }

/* ── 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-fundo); 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 celular, 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-fundo); 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; }

/* ══════════ ⭐⭐⭐ OS MARCADORES E OS NÍVEIS (10/09/2026) ══════════
   Ele: *"não é a bolinha, eu quero escolher qual (bolinha, tracinho, etc). E
   quero níveis de subbullet points, diferentes."*

   ⭐ **O marcador é o CARACTERE que ele escreveu**, e chega aqui como classe do
   `<li>` — nunca do `<ul>`. É essa escolha que aguenta uma lista com marcadores
   MISTURADOS no mesmo nível, coisa que uma classe na lista inteira não aguenta.
   ⚠️ O `list-style-type` com uma string (`'– '`) é o que desenha o traço sem um
   `::before` à mão: com `::before` perdia-se o recuo automático da segunda linha
   de um item comprido, e um parágrafo desalinhado por baixo do marcador é o
   defeito clássico das listas feitas à mão. */
.texto-rico li.tr-m-traco{ list-style-type:'–  '; }
.texto-rico li.tr-m-bolinha{ list-style-type:disc; }
.texto-rico li.tr-m-circulo{ list-style-type:circle; }
.texto-rico li.tr-m-quadrado{ list-style-type:square; }
/* O degrau que segura uma sub-lista quando se saltam dois níveis de uma vez:
   existe para o HTML ser válido, e não tem nada para mostrar. */
.texto-rico li.tr-degrau{ list-style:none; }
/* ⚠️ O recuo de CADA nível vem do `padding-left` da sub-lista — sem isto o HTML
   estava aninhado e a tela mostrava tudo encostado à mesma margem, que é o mesmo
   que não haver níveis. 18px é o degrau que a lista de primeiro nível já usa. */
.texto-rico li > ul, .texto-rico li > ol{ padding-left:18px; }
/* ⚠️ Sub-lista NÃO leva a margem de cima do bloco: colada ao pai é que se lê
   como filha dele. E o recuo é o do `padding-left` de cada nível, não uma
   margem — assim a segunda linha de um item comprido alinha com a primeira. */
.texto-rico li > ul, .texto-rico li > ol{ margin:2px 0 0; }
.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);
}

/* ⭐⭐ A ETIQUETA É PÍLULA (01/09/2026). Ele: *"colocar pílulas coloridas nas
   etiquetas das tarefas."*

   🚨 A cor já existia no catálogo desde 14/08 e **a etiqueta não era pílula
   nenhuma**: era texto na cor com um ponto de 6px à frente, e no detalhe da
   tarefa era um `.selo-neutro` cinzento — a mesma etiqueta a dizer duas coisas
   diferentes conforme o lugar. Agora é a MESMA forma nos dois, e é a forma que
   já estava aprovada nesta linha: a do responsável, aqui em cima.
   ⚠️ Por isso a fórmula é copiada dela e não inventada — fundo a 12%, texto na
   cor cheia, anel a 24%. Um segundo desenho para o mesmo trabalho é a cápsula a
   mais que esta tela passou o mês a arrancar.
   ⚠️ E `text-decoration:none` porque a etiqueta é um LINK (leva ao filtro): sem
   isto o `.selo` do detalhe saía sublinhado, que era como estava. */
.selo-tag{ background:var(--cinza-fundo); color:var(--cinza-medio); text-decoration:none; }
.selo-tag-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 seçõ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 tela.
   ⚠️ 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); }
/* ⭐ A ETIQUETA DA TAREFA NO DEDO (08/09/2026, rastreio das telas): 📏 18px de
   altura medidos a 375px, e são dez por tela. Como o `?` das dicas e a caixa do
   inventário, cresce a ÁREA e não o desenho — uma etiqueta de 44px de altura
   empurrava o cartão inteiro para baixo. */
@media (pointer:coarse){
  .tar-tag{ position:relative; }
  .tar-tag::after{
    content:''; position:absolute; left:50%; top:50%; transform:translate(-50%, -50%);
    width:100%; min-width:44px; height:44px;
  }
}
.tar-recusa{ font-style:italic; }
.tar-tag-motor{ background:var(--cinza-fundo); 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; }
/* ══════════════════════════════════════════════════════════════════════════
   🚨 ENQUANTO A RECUSA ESTÁ ABERTA, AS AÇÕES OCUPAM UMA LINHA INTEIRA.

   O `.tar-item` da lista é uma linha flex de duas colunas — corpo à esquerda,
   ações à direita — e o `.tar-acoes` mede-se pelo conteúdo (`flex:0 0 auto`).
   Ao receber o painel da recusa (949px medidos), crescia até lá e deixava o
   corpo com 61px: o título vinha espremido para baixo dos botões, que é o que
   ele viu.

   ⭐ A marca é posta e tirada pelo JavaScript no CARD (`tar-recusando`), porque
   quem muda de forma é a linha inteira, e volta ao normal quando o painel sai.
   ⚠️ E não se usa `:has()`: seria mais curto, mas isto é uma tela que se abre no
   telemóvel do turno, e uma classe explícita não depende de versão de motor. */
.tar-item.tar-recusando{ flex-wrap:wrap; }
.tar-item.tar-recusando > .tar-acoes{ flex:1 1 100%; min-width:0; }
/* ⭐ 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; }
/* ══════════════════════════════════════════════════════════════════════════
   🚨🚨 A LINHA DO FORMULÁRIO É UMA GRADE, E NÃO UM FLEX QUE QUEBRA (28/08/2026)

   Ele, com a foto do iPad, pela SEGUNDA vez: *"os campos data, hora, projeto
   estão em desequilíbrio, alinha eles, tira um de cima do outro."*

   ⚠️ A correção de 26/08 (o `min-width:0` logo abaixo) tratou o TRANSBORDO e
   estava certa — mas não tratou o ALINHAMENTO, porque **`flex-wrap` não faz
   grade**. Quando seis campos quebram em duas linhas visuais, cada linha
   reparte o espaço por si: as colunas da segunda não caem debaixo das colunas
   da primeira, e a página fica com aquele ar de coisa mal encaixada.

   ⭐ Uma grade resolve as duas coisas de uma vez:
     · `auto-fill` (e NÃO `auto-fit`) — o `auto-fit` colapsa as colunas vazias,
       e aí uma linha com dois campos esticava os dois de ponta a ponta. Com
       `auto-fill` as colunas vazias ficam lá, e o *Avisar antes* de uma linha
       cai exatamente debaixo da *Data* da outra;
     · `align-items:end` — o CONTROLE assenta no fundo da célula. É isto que
       endireita a linha quando um rótulo tem duas linhas ("Hora (opcional)")
       e o vizinho tem uma: os rótulos ficam onde couberem, as caixas alinham.

   ⚠️ O teto de 320px por campo deixou de ser preciso: numa grade, uma tela
   larga ganha mais COLUNAS em vez de campos gigantes — que era o defeito que
   o teto tapava.
   ══════════════════════════════════════════════════════════════════════════ */
.tar-linha{
  display:grid;
  grid-template-columns:repeat(auto-fill, minmax(190px, 1fr));
  gap:14px;
  align-items:end;
}
/* 🚨 `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 controle 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 controle do sistema com tamanho próprio a escapar do contentor.
   Vale a pena guardar a lição: *num flex, quem tem controle 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. */
/* ⚠️ `margin-bottom:0` — o `.campo` traz 18px de margem de fora desta tela, e
   dentro de uma grade com `gap` isso dava duas distâncias somadas: a linha de
   baixo ficava mais afastada do que as colunas entre si, e o bloco perdia o
   ritmo. Quem espaça a grade é o `gap`. */
.tar-linha .campo{ min-width:0; margin-bottom:0; }
/* ⭐ E o controle mede o mesmo, seja ele qual for. No iPad o `input[type=date]`
   e o `input[type=time]` são controles NATIVOS e nascem mais altos do que um
   `<select>` — era essa a diferença que fazia a Data e a Hora parecerem
   desencaixadas do Projeto, mesmo com tudo alinhado. */
/* ⭐ ALTURA IGUAL, e não só mínima. Medido no navegador depois de alinhar a
   grade: o `<select>` dava 50px e o `<input type=text>` 48 — dois pixels que
   ninguém sabe nomear mas que se veem numa fila de seis caixas. Com
   `align-items:end` os fundos já batiam certo; isto endireita também os topos.
   ⚠️ 48px também resolve o dedo: fica acima da régua dos 44. */
.tar-linha .campo input,
.tar-linha .campo select{ height:48px; box-sizing:border-box; }
/* ⚠️ Menos o que não é uma caixa de uma linha: as caixas de marcar dos dias da
   semana medem-se sozinhas, e forçá-las a 48px dava sete botões deformados. */
.tar-linha .campo .tar-dias input{ height:auto; }
/* ⚠️ 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 celular 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 seções. A fila dos projetos é OUTRA fila, separada dos estados:
   juntá-las dava uma barra de vinte fichas onde nada se acha. */
.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-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-fundo); border-radius:999px; font-size:var(--cap-etiqueta-fonte); color:var(--cinza-medio); font-weight:var(--cap-etiqueta-peso)}

/* 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 celular. */
.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); }
/* 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 lugares: *"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
   arquivo 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-fundo); color:var(--cinza-medio); }

/* Anexos: a lista é para reconhecer o arquivo, 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 arquivo 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 arquivo 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-fundo); 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; }
.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 celular: o texto
   "Nenhum arquivo 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, pegava 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`, e o `>` prende a
   regra a ele. */
.exec-evidencia form, .tar-bloco > form.inline-f{ flex:1 1 100%; display:flex; gap:8px; flex-wrap:wrap; align-items:center; }
/* 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(--cinza-medio);
  /* ⚠️ 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 lugar.
   ⚠️ 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 lugares 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 celular */
  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 seçã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; }
.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:var(--cap-controle-fonte); font-weight:var(--cap-controle-peso);
  color:var(--cinza-medio); background:var(--branco); border:1px solid var(--cinza-borda);
  padding:var(--cap-controle-pad); 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; }

/* 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:var(--verde); 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; }

/* ⭐ O QUE PRECISA ANTES (21/09/2026, pedido dele). *"Deve ficar evidenciado
   separado dos outros itens que vão entrar pra lista semanal."*
   ⚠️ Âmbar e não vermelho: o vermelho da casa é de ERRO, e um item urgente não
   é um erro. E a marca é a FAIXA da esquerda — não o fundo inteiro, que num
   bloco de vinte linhas cansa a vista e deixa de se notar. */
.lc-urgente{ border-left:3px solid var(--ambar-vivo); background:var(--ambar-fundo);
  border-radius:0 var(--raio) var(--raio) 0; padding:10px 14px 4px; margin-bottom:18px; }
.lc-urgente .lc-grupo{ color:var(--ambar); }
.lc-bloco-titulo{ font-size:14px; font-weight:700; margin:0 0 6px; }
.lc-urgente .lc-bloco-titulo{ color:var(--ambar); }
/* A caixa do «precisa antes» no formulário: uma linha inteira, porque é uma
   decisão e não um detalhe do campo ao lado. */
.lc-campo-antes{ flex:1 1 100%; }
/* ⭐ As duas observações do item (22/09/2026). Linha inteira, como o «precisa
   antes»: são campos de FRASE, e espremê-los ao lado do número dava uma caixa
   onde não cabe o que se quer escrever. */
.lc-campo-obs{ flex:1 1 100%; }
.lc-campo-antes .ajuda{ margin:2px 0 0 26px; display:block; }
/* ⭐ E a marca na própria linha, para quem lê a lista fora do bloco (uma
   exportação, um pedido) continuar a ver qual era qual. */
.lc-item-antes{ font-size:11.5px; font-weight:700; text-transform:uppercase;
/* ⭐ As notas do item na lista (22/09/2026). A do fornecedor leva a seta e a cor
   da marca: quem lê a lista tem de ver, de relance, o que vai sair de casa. */
.lc-obs{ display:block; font-size:13px; color:var(--cinza-medio); font-style:italic; }
.lc-obs-forn{ color:var(--destaque); font-style:normal; }
  letter-spacing:.04em; color:var(--ambar); margin-left: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 seçã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 (celular) 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 celular 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 celular 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); }
/* ⚠️ `position:absolute` é o ponto de partida — sem JavaScript o painel abre
   assim, como sempre abriu, e continua a funcionar. Com JavaScript passa a
   `fixed` ao abrir, para escapar ao recorte do `.tar-quadro-kanban`
   (`overflow-x:auto`), que o cortava a meio das palavras. Ver `porMenuNoSitio`
   no `tarefas.php`.
   🚨 O `z-index` sobe de 30 para 61: em `fixed` o painel deixa de competir só
   dentro da coluna e passa a competir com a barra do topo do telemóvel (z:51).
   Um menu por baixo da barra é o mesmo defeito com outra roupa. */
.tar-menu-lista{ position:absolute; right:0; top:calc(100% + 4px); z-index:61; 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); }
/* ⭐ A pílula de «Em andamento» que ele pediu: sinal de que a tarefa foi
   começada, para ela poder continuar no setor em vez de sumir. Discreta — é um
   estado, não um alarme; o vermelho está reservado ao que corre mal. */
.tar-tag-andamento{ background:var(--azul-fundo, #eaf1fb); color:var(--azul, #1b4f9c);
  border:1px solid transparent; }
/* ⭐ E o desfazer, ao lado do recado que fica no lugar da linha que saiu. */
.tique-desfazer{ font-weight:600; text-decoration:underline; padding:0 2px; }
.tar-menu-perigo:hover{ color:var(--vermelho); background:var(--vermelho-sinal-fundo); }
/* 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 celular 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-fundo); }
.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:var(--vermelho-sinal-fundo); }
/* 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:var(--vermelho-sinal-fundo); }

/* 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]`. */
/* ⭐ O tipo de ficha que veio de fábrica: mostra-se ao lado dos da casa, para o
   que se vê aqui ser o que a ficha oferece — mas sem campo e sem `×`, porque é
   ele que liberta os campos técnicos da panificação. */
.cfg-fixo{ flex:1 1 auto; color:var(--texto); padding:7px 0; }
/* ══════════════════════════════════════════════════════════════════════════
   ⭐ O QUE VEIO DO CÓDIGO POSTAL FICA MARCADO ATÉ ALGUÉM LHE TOCAR.

   Ele: *"tem que ser muito preciso, porque ninguém vai checar."* Um campo
   preenchido sozinho tem o ar de conferido — e é isso que o torna perigoso.
   A marca é discreta de propósito: não é um erro, é uma origem. Quem escreve
   por cima, apaga-a; quem não escreve, ao menos vê que aquilo não foi digitado
   por uma pessoa. */
.cp-auto{ background:var(--ambar-fundo); border-color:var(--ambar-vivo); }
/* ⭐ O «Reabrir» de uma tarefa já concluída: é o caminho de volta que ele pediu
   (*"se eu precisar reativar, tem que dar"*). Discreto como o «Recusar» — não é
   o gesto principal de quem está a olhar para a lista das concluídas. */
.btn-mini-reabrir{ --bt-texto:var(--cinza-medio); --bt-texto-h:var(--preto); --bt-borda-h:var(--preto); }
.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 seções não pode empurrar a tela inteira para o lado. No celular cada
   coluna ocupa quase o tela, 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 controle 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;
}
/* ══════════════════════════════════════════════════════════════════════════
   ⚠️ AQUI ESTEVE, ENTRE A MANHÃ E A NOITE DE 31/08/2026, UMA REGRA QUE PUNHA O
   MENU DOS 3 PONTINHOS A ABRIR **EM FLUXO** DENTRO DO CARD.

   Era a saída para o `contain:paint` deste quadro ancorar e recortar qualquer
   `position:fixed` lá dentro. Funcionava — e ele apanhou o preço na mesma noite:
   *"quero que a janela abra separado do campo da tarefa, está expandindo o campo
   da tarefa pra frente."* Um menu não é conteúdo do card; é uma coisa por cima.

   ⭐ A saída certa era a que eu tinha evitado por dar mais trabalho: **tirar o
   painel do quadro**. Enquanto for descendente daqui, nada o salva. Hoje ele
   muda-se para o `<body>` ao abrir e volta ao fechar — ver `porMenuNoSitio` em
   `Views/operacional/tarefas.php`.

   ⚠️ **NÃO REPOR UMA REGRA `.tar-quadro-kanban .tar-menu-lista` AQUI.** Seja o
   que for que ela declare, o painel já não é filho deste quadro quando está
   aberto: a regra não pega, e quem a escrever vai passar uma tarde a perceber
   porquê. Fica esta nota no lugar dela.
   ══════════════════════════════════════════════════════════════════════════ */
.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; }

/* ══════════════════════════════════════════════════════════════════════════
   ⭐⭐⭐ OS TRÊS GESTOS DA SEÇÃO, NO PRÓPRIO QUADRO (30/08/2026)
   ══════════════════════════════════════════════════════════════════════════ */

/* ⭐ RENOMEAR CLICANDO EM CIMA DO NOME. O nome É o `<summary>` — não há botão
   novo, não há ícone novo, e não há uma linha de JavaScript: o quadro vive
   dentro da região que o acelerador troca, e um ouvinte preso a um elemento
   morre com ele em silêncio. */
.tar-sec-edita{ min-width:0; flex:1 1 auto; }
.tar-sec-edita > summary{
  cursor:pointer; list-style:none; border-radius:var(--raio-sm);
  padding:2px 4px; margin:-2px -4px;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
.tar-sec-edita > summary::-webkit-details-marker{ display:none; }
.tar-sec-edita > summary:hover{ background:var(--branco); }
.tar-sec-form{ display:flex; gap:6px; align-items:center; margin:8px 0 4px; }
.tar-sec-form input[type=text]{ flex:1 1 auto; min-width:0; }

/* ⭐⭐ A DESCRIÇÃO DA SEÇÃO. Ele: *"deve ser um campo grande de texto, mas que
   expande quando necessário, mas quando retraído fica no tamanho de uma
   simples tarefa"* — é literalmente o que o `max-height` abaixo faz.
   ⚠️ Fechada: uma linha, com reticências. Aberta: cresce até onde precisar,
   com um teto e rolagem própria, para uma descrição longa não empurrar as
   tarefas todas para fora da vista. */
.tar-sec-desc{ margin:0 4px 10px; font-size:.78rem; }
.tar-sec-desc > summary{
  cursor:pointer; list-style:none; color:var(--cinza-medio);
  background:var(--branco); border:1px solid var(--cinza-borda);
  border-radius:var(--raio-sm); padding:8px 10px;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
.tar-sec-desc > summary::-webkit-details-marker{ display:none; }
.tar-sec-desc > summary:hover{ border-color:var(--cinza-medio); }
.tar-sec-desc[open] > summary{ margin-bottom:6px; }
.tar-sec-desc-corpo{
  background:var(--branco); border:1px solid var(--cinza-borda);
  border-radius:var(--raio-sm); padding:10px 12px;
  max-height:340px; overflow-y:auto;
}

/* ⭐ O LÁPIS NO CANTO DA DESCRIÇÃO (30/08/2026). Abrir a descrição é LER; o
   lápis é que abre para escrever. Discreto de propósito: é o gesto raro. */
.tar-sec-editar{ margin-top:2px; }
.tar-sec-editar > summary{
  list-style:none; cursor:pointer; display:inline-grid; place-items:center;
  min-width:26px; height:24px; border-radius:var(--raio-xs);
  color:var(--cinza-medio); font-size:13px;
}
.tar-sec-editar > summary::-webkit-details-marker{ display:none; }
.tar-sec-editar > summary:hover{ color:var(--preto); background:var(--cinza-fundo); }
/* ⚠️ Aberto, o lápis fica marcado: sem isto não há como saber que aquele campo
   de texto pertence àquele botão, e fechar volta a ser adivinhação. */
.tar-sec-editar[open] > summary{ color:var(--preto); background:var(--cinza-fundo); }
.tar-sec-form-desc{ display:block; margin-top:8px; }
.tar-sec-form-desc textarea{ width:100%; min-height:96px; resize:vertical; }
.tar-sec-form-desc .btn-mini{ margin-top:6px; }

/* ⭐⭐ ARRASTAR PARA REORDENAR. Só existe no modo de reordenar — fora dele a
   coluna não é arrastável, e por isso não muda de aspeto.
   ⚠️ O `cursor:grab` é a única pista de que aquilo se arrasta; sem ele o modo
   liga-se e nada na tela diz que mudou alguma coisa. */
.tar-coluna-arrasta{ cursor:grab; outline:2px dashed var(--cinza-borda); outline-offset:-2px; }
.tar-coluna-arrasta:active{ cursor:grabbing; }
.tar-coluna-arrasta.tar-arrastando{ opacity:.45; }
/* A barra do modo de reordenar, por cima do quadro. */
.tar-reordenar-barra{
  display:flex; align-items:center; gap:10px; flex-wrap:wrap;
  background:var(--branco); border:1px solid var(--preto);
  border-radius:var(--raio); padding:10px 14px; margin:0 0 12px;
}
.tar-reordenar-barra p{ margin:0; flex:1 1 240px; font-size:.85rem; }
/* ⭐ DE QUE PROJETO É A COLUNA — só no quadro de um SETOR, onde as seçõ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
   seçã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 `+` DA COLUNA e a COLUNA QUE CRIA COLUNA (28/08/2026), o modelo do
   TickTick que ele descreveu: *"clicando no + de cada coluna eu crio uma
   tarefa, clicando no mais no fim de todas as seções eu crio uma seção nova"*.
   ⚠️ O `+` é discreto até se passar por cima: no cabeçalho de seis colunas,
   seis sinais fortes competiam com os nomes das seções — e o nome é o que se
   lê primeiro. Cor forte só em selo pequeno, regra da casa. */
.tar-coluna-mais{
  flex:0 0 auto; display:inline-flex; align-items:center; justify-content:center;
  width:24px; height:24px; border-radius:var(--raio-xs);
  color:var(--cinza-medio); text-decoration:none; font-size:17px; font-weight:600;
  line-height:1; transition:background .15s, color .15s;
}

/* ⭐ O ACRÉSCIMO RÁPIDO NA COLUNA (30/08/2026). O `+` deixa de ser um link para
   a janela grande e passa a abrir um campo — um só. Ver a nota na vista.
   ⚠️ O painel é `absolute` e não empurra a coluna: um `+` que faz a coluna
   crescer 60px empurra os cards para baixo e perde-se o sítio onde se estava. */
.tar-coluna-add{ position:relative; }
.tar-coluna-add > summary{ list-style:none; }
.tar-coluna-add > summary::-webkit-details-marker{ display:none; }
/* ⭐ A LINHA QUE ENTENDE, na coluna (23/09/2026): o mesmo balão do campo
   antigo — por cima, sem empurrar os cards — e a mesma largura: medido a
   375px, com 300 saía 7px pela esquerda. A letra é a normal, que o cabeçalho
   da coluna é negrito. */
.tar-coluna-add > .tlin, .tlin.tlin-solto{
  position:absolute; right:0; top:calc(100% + 6px); z-index:29;
  width:min(280px, 76vw); padding:10px; 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);
  font-size:14px; font-weight:400; text-transform:none;
}
.tar-coluna-mais:hover{ background:var(--branco); color:var(--vermelho); text-decoration:none; }
/* ⚠️ E cumpre a régua do dedo sem crescer, como o `.btn-mini`: a área de toque
   estica por baixo, o desenho fica em 24px. Ver o bloco `pointer:coarse`. */
.tar-coluna-mais{ position:relative; }
/* A coluna que cria coluna é a única sem fundo: ela não guarda cards, é um
   convite. Traço tracejado diz "aqui pode nascer uma", que é o que ela é. */
.tar-coluna-nova{
  background:transparent; border:1px dashed var(--cinza-borda);
  display:flex; align-items:flex-start;
}
.tar-coluna-nova .inline-f{ flex-wrap:wrap; gap:8px; width:100%; }
.tar-coluna-nova label{ width:100%; color:var(--cinza-medio); }
.tar-coluna-nova input{ flex:1 1 140px; min-width:0; }

/* ⭐ O `+` DOS GRUPOS DA BARRA (28/08/2026) — SETORES e PROJETOS. Mesma peça do
   `+` da coluna e pelo mesmo motivo: discreto ao lado do nome do grupo, forte
   quando o rato passa. Um `+` gritado em cada cabeçalho competia com os nomes,
   que é o que ali se lê. */
.tar-pn-mais{
  flex:0 0 auto; display:inline-flex; align-items:center; justify-content:center;
  width:22px; height:22px; margin-left:2px; border-radius:var(--raio-xs);
  color:var(--cinza-medio); text-decoration:none; font-size:16px; font-weight:600; line-height:1;
}
.tar-pn-mais:hover{ background:var(--branco); color:var(--vermelho); text-decoration:none; }
/* ⚠️ O cabeçalho PROJETOS lê-se como o `<summary>` dos setores, sem ser um:
   não abre nada — as pastas lá em baixo é que abrem. */
.tar-pn-grupo{
  display:flex; align-items:center; gap:6px;
  padding:8px 10px 2px; margin-top:6px;
}
.tar-pn-grupo .tar-pn-nome{
  flex:1; min-width:0; font-size:.72rem; font-weight:700; letter-spacing:.04em;
  color:var(--cinza-medio);
}
/* 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; }
/* ⭐⭐⭐ A LINHA QUE ENTENDE (23/09/2026) — `partials/tarefa-linha.php`.
   Os ícones são pequenos e ficam por baixo: a frase é o gesto principal. */
.tlin{ display:flex; flex-direction:column; gap:6px; }
.tlin-linha{ display:flex; gap:6px; align-items:center; }
.tlin-linha input[name="linha"]{ flex:1 1 auto; min-width:0; }
.tlin-entendi{ display:flex; flex-wrap:wrap; gap:4px; }
.tlin-entendi:empty{ display:none; }
/* ⚠️ As etiquetas são o `.selo selo-neutro` da casa (a cerca do selo único
   apanhou uma cápsula nova aqui): o JavaScript só lhes junta o ×. */
.tlin-x{ border:none; background:none; cursor:pointer; font-size:14px; line-height:1; padding:0 3px; color:var(--cinza-medio); }
.tlin-icones{ display:flex; flex-wrap:wrap; align-items:center; gap:4px 10px; font-size:13px; }
.tlin-ic{ position:relative; display:inline-flex; align-items:center; justify-content:center;
  width:28px; height:28px; border-radius:var(--raio-xs); cursor:pointer; color:var(--cinza-medio); }
.tlin-ic:hover, .tlin-ic:focus-within{ background:var(--cinza-fundo); }
/* O controlo nativo fica POR CIMA do ícone, invisível: é ele que abre o
   calendário, o relógio ou a lista — no telemóvel isso vale ouro. */
.tlin-in{ position:absolute; inset:0; opacity:0; cursor:pointer; width:100%; height:100%; }
.tlin-mais summary{ cursor:pointer; list-style:none; color:var(--cinza-medio); }
.tlin-mais summary::-webkit-details-marker{ display:none; }
/* ⚠️ `min-width:0`: um item de flex não encolhe abaixo do seu conteúdo sem isto. */
.tlin-mais[open]{ flex-basis:100%; min-width:0; }
/* 🚨 A CAIXA NÃO SAI DO BALÃO (ele, 23/09, com print). Medido: o campo nascia
   com `resize:both` — o canto arrastava-o para fora do balão, por cima da
   coluna do lado — e ficava nas 3 linhas por mais que se escrevesse.
   Agora a largura é a do balão, sem pega, e a altura segue o texto: o
   `field-sizing` onde existe, o `data-tlin-cresce` em `tarefas.php` onde não.
   O teto é meia tela: daí para baixo rola por dentro. */
.tlin-mais textarea{ display:block; width:100%; max-width:100%; margin-top:4px;
  resize:none; field-sizing:content; min-height:3.2em; max-height:50vh;
  overflow-wrap:anywhere; }
.tlin-svg{ width:18px; height:18px; flex:none; }
.tlin-mais summary{ display:inline-flex; align-items:center; gap:4px; }
.tlin-mais summary .tlin-svg{ width:15px; height:15px; }
.tlin-x svg{ width:12px; height:12px; vertical-align:-1px; }
/* ⭐ O `+` da coluna vira SETA PARA CIMA quando o balão está aberto. */
.tar-coluna-mais svg{ width:17px; height:17px; }
.tar-coluna-mais .tcm-fecha{ display:none; transform:rotate(-90deg); }
.tar-coluna-add[open] > .tar-coluna-mais .tcm-abre{ display:none; }
.tar-coluna-add[open] > .tar-coluna-mais .tcm-fecha{ display:block; }
.tar-coluna-add[open] > .tar-coluna-mais{ background:var(--branco); color:var(--preto); }
/* 🚨 Aberto, o balão vive no `<body>` e é `fixed`, colado ao `+`: o quadro tem
   `contain:paint` e cortava-o (ver «O BALÃO SAI DO QUADRO» em `tarefas.php`).
   z-index 61, como o menu dos pontinhos: acima da barra do telemóvel (51). */
.tlin.tlin-solto{ position:fixed; right:auto; z-index:61; overflow-y:auto; overscroll-behavior:contain; }
.tlin-completo{ margin-left:auto; }
.tar-linha-topo{ margin:0 0 12px; }
.tar-dia-nova-t{ margin:0 0 6px; font-weight:600; }

/* ⭐ ARRASTAR O CARTÃO ENTRE SEÇÕES (23/09/2026) — a mecânica da escala.
   Com o arrastar ligado, o seletor de mover sai do cartão: ele pediu o gesto
   EM VEZ do seletor. Sem JavaScript a classe não existe e o seletor fica.
   🚨 `touch-action:none` SÓ enquanto se arrasta: antes disso o dedo tem de
   poder rolar o quadro de lado. */
html.tar-arrasta .tar-quadro-kanban .tar-mover{ display:none; }
.tar-quadro-kanban .tar-card{ -webkit-touch-callout:none; }
/* 🐞 E SEM ENCAIXE enquanto se arrasta: medido a 375px, o `scroll-snap`
   puxava cada passo de 14px de volta ao início da coluna, e o quadro não
   andava sozinho — só se largava na coluna que já estava à vista. */
.tar-quadro-kanban.tar-quadro-arrastando{ touch-action:none; overscroll-behavior:contain; scroll-snap-type:none; }
.tar-quadro-kanban.tar-quadro-arrastando *{ user-select:none; -webkit-user-select:none; }
.tar-card.tar-card-arrastando{ opacity:.4; }
/* A «sem seção» VAZIA: uma faixa, e não uma coluna inteira — continua a ser
   onde se larga, sem tapar o primeiro ecrã do celular (a decisão de 26/08). */
.tar-coluna.tar-coluna-estreita{ flex:0 0 110px; max-width:110px; align-self:stretch; min-height:160px; }
.tar-coluna.tar-coluna-estreita .tar-coluna-vazia{ display:none; }
.tar-card-fantasma{
  position:fixed; z-index:60; pointer-events:none; opacity:.94; margin:0;
  box-shadow:0 6px 18px rgba(17,17,17,.28); transform:rotate(1.5deg);
}
.tar-coluna.tar-coluna-alvo{
  background:color-mix(in srgb, var(--destaque) 12%, var(--cinza-fundo));
  outline:2px dashed color-mix(in srgb, var(--destaque) 55%, transparent); outline-offset:-2px;
}
.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 tela.

   ⚠️ 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 pegar 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 celular. */
.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 tela, 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 celular 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-medio); }
.lanc-confere-selo{ font-weight:600; }
.lanc-confere-selo.e-ok{ color:var(--verde, var(--verde)); }
.lanc-confere-selo.e-erro{ color:var(--vermelho, var(--vermelho-sinal)); }
/* ⚠️ O selo do total AUTOMÁTICO é cinzento de propósito (22/09/2026): não é um
   veredicto, é uma informação. Verde e vermelho estão gastos a dizer «confere»
   e «não bate» — pintar isto de verde era prometer um exame que, enquanto o
   total segue a soma, nunca pode chumbar. */
.lanc-confere-selo.e-auto{ color:var(--cinza-medio); font-weight:500; }
/* ⚠️ 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, var(--vermelho-sinal)) !important;
  box-shadow:0 0 0 2px color-mix(in srgb, var(--vermelho, var(--vermelho-sinal)) 18%, transparent); }
input.campo-ok{ border-color:var(--verde, var(--verde)) !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 celular, 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(--cinza-borda); 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:var(--cap-etiqueta-pad); border-radius:999px; font-size:var(--cap-etiqueta-fonte); font-weight:var(--cap-etiqueta-peso); 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-fundo); color:var(--cinza-medio); }
.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 celular 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 tela (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 controle 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; }

/* ⭐ O RECEITUÁRIO — o texto do modo de preparo (29/08/2026).
   ⚠️ `pre-line` e não `pre`: as linhas do caderno dele já vêm quebradas onde
   devem, mas algumas são longas e têm de dobrar. O `pre` puro obrigava a
   rolagem lateral num passo de duas linhas, e ninguém lê uma receita assim. */
.rec-preparo{
  white-space:pre-line; line-height:1.7; font-size:15px;
  background:var(--branco); border:1px solid var(--cinza-borda);
  border-radius:var(--raio-sm); padding:16px 18px; margin-bottom:18px;
}
/* A nota do chef é o que a receita não diz — fica à parte, e mais discreta. */
.rec-nota{
  white-space:pre-line; line-height:1.7; font-size:14px; color:var(--cinza-medio);
  border-left:3px solid var(--destaque); padding:4px 0 4px 14px; margin-bottom:18px;
}

/* ══════════════════════════════════════════════════════════════════════════
   ⭐⭐ O SELETOR DE PRODUTO DA LISTA DE COMPRAS (31/08/2026)

   Ele: *"tentei buscar «saco de» pra encontrar «Saco de lixo» não trouxe
   nada"*. O `<datalist>` do navegador filtra à maneira dele — no telemóvel,
   quase sempre só pelo COMEÇO do nome. Esta lista filtra pela regra da casa
   (palavras em qualquer ordem, sem acento) e desenha-se aqui.

   ⚠️ `position:relative` no campo e a lista ABSOLUTA por cima: a lista de
   compras é uma coluna estreita, e empurrar o formulário para baixo a cada
   tecla fazia o botão «Acrescentar» fugir de debaixo do dedo.
   ══════════════════════════════════════════════════════════════════════════ */
.lc-campo-texto{ position:relative; }
.lc-achados{
  position:absolute; z-index:62; left:0; right:0; top:100%; margin:4px 0 0; padding:4px;
  list-style:none; max-height:min(46vh, 320px); overflow:auto;
  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);
}
.lc-achados[hidden]{ display:none; }
/* ⚠️ 44px de altura mínima: é um alvo de dedo no meio do serviço, e a casa
   inteira mede-se por esse número (ver test-alvo-do-dedo). */
.lc-achado{
  display:flex; flex-direction:column; gap:1px; width:100%; min-height:44px;
  padding:7px 10px; border:0; border-radius:var(--raio-sm);
  background:transparent; text-align:left; cursor:pointer; font:inherit; color:var(--preto);
}
.lc-achado:hover, .lc-achado:focus-visible{ background:var(--cinza-fundo); }
.lc-achado-nome{ font-weight:600; font-size:14px; line-height:1.25; }
.lc-achado-sub{ font-size:12px; color:var(--cinza-medio); }
.lc-nao-achou{ display:block; margin-top:6px; }
.lc-nao-achou[hidden]{ display:none; }

/* ══════════════════════════════════════════════════════════════════════════
   ⭐⭐ A JANELA DO PRODUTO, ABERTA DA LISTA DE COMPRAS (31/08/2026)

   Ele: *"quando clica nele, abre uma janela flutuante com mais informações do
   produto, expansível (…) e opção de editar. Assim, se houver algo errado com
   o produto, não preciso ir até produtos e voltar."*

   ⚠️ Desenha-se de BAIXO PARA CIMA no telemóvel e centrada no computador: esta
   lista usa-se com o telemóvel numa mão, no meio do serviço, e uma caixa ao
   centro fica longe do polegar.
   ══════════════════════════════════════════════════════════════════════════ */
.lc-abrir{ color:inherit; text-decoration:none; }
.lc-abrir:hover strong, .lc-abrir:focus-visible strong{ text-decoration:underline; }

.lc-jan{ position:fixed; inset:0; z-index:1000; display:flex; align-items:flex-end; justify-content:center; }
.lc-jan[hidden]{ display:none; }
.lc-jan-fundo{ position:absolute; inset:0; background:rgba(0,0,0,.45); }
.lc-jan-caixa{
  position:relative; width:min(520px, 100%); max-height:86vh; overflow:auto;
  padding:16px 16px 20px; background:var(--branco);
  border-radius:var(--raio-sm) var(--raio-sm) 0 0;
  box-shadow:0 -8px 40px rgba(17,17,17,.24);
}
@media (min-width:640px){
  .lc-jan{ align-items:center; }
  .lc-jan-caixa{ border-radius:var(--raio-sm); box-shadow:0 12px 40px rgba(17,17,17,.24); }
}
.lc-jan-topo{ display:flex; align-items:flex-start; gap:8px; margin-bottom:10px; }
.lc-jan-nome{ flex:1; margin:0; font-size:17px; line-height:1.3; }
/* ⚠️ O lápis é um `<a>`: sem isto ficava inline e sublinhado, como a cerca do
   `test-link-que-parece-botao` ensinou noutro sítio desta mesma sessão. */
.lc-jan-editar{ display:inline-flex; text-decoration:none; }
.lc-jan-dados{ display:grid; grid-template-columns:auto 1fr; gap:4px 12px; margin:0; }
.lc-jan-dados dt{ font-size:12px; color:var(--cinza-medio); }
.lc-jan-dados dd{ margin:0; font-size:14px; font-weight:600; }
.lc-jan-mais{ margin-top:12px; }
.lc-jan-mais summary{ cursor:pointer; min-height:44px; display:flex; align-items:center;
                      font-size:13px; font-weight:600; color:var(--cinza-medio); }
/* ⚠️ O corpo não rola por trás da janela aberta: no telemóvel, arrastar dentro
   da caixa levava a página inteira atrás. */
body.lc-jan-aberta{ overflow:hidden; }

/* ⚠️ A barra de proporção do painel não tem rótulo (ele, 31/08/2026: *"deixa
   sem rótulo, já é autoexplicativo"*). Sem isto o `::before` do cartão ficava
   lá, vazio, a ocupar o `gap` da linha e a empurrar a barra para a direita. */
@media (max-width:768px){
  .tabela-cards td.td-dash-barra:not([data-label])::before{ display:none; }
}


/* ══════════ ⭐⭐ O FREELANCER NA ESCALA (04/09/2026) ══════════
   Ele: *"deve ter uma cor diferente dos outros, destacado."*
   ⚠️ **Uma faixa à esquerda e um fundo levíssimo**, e não a linha inteira
   pintada: a grelha da escala já usa a cor das células para dizer coisas
   (férias, folga, hoje), e um fundo forte por baixo disso apagava-as. A faixa
   fica na coluna do nome, que é onde o olho entra na linha.
   ⚠️ O fundo é `--roxo-fundo` a 55% para não competir com o `dia-hoje`. */
.escala-grade tr.linha-freela .col-nome{
  border-left:3px solid var(--roxo);
  background:color-mix(in srgb, var(--roxo-fundo) 55%, transparent);
}
.escala-grade tr.linha-freela .col-nome .nome-link{ color:var(--roxo); }

/* ⭐ E O HORÁRIO DELE TAMBÉM (08/09/2026, ele: *"a cor do horário do freelancer,
   pode ser diferente também"*).
   ⚠️ Faltava o essencial: a faixa de 04/09 pinta a coluna do NOME, que no
   telemóvel é a primeira a sair do ecrã quando se rola para ver a sexta e o
   sábado. Ficavam turnos roxos… vermelhos, iguais aos de toda a gente, e a
   informação «este é freelancer» desaparecia exactamente onde ele estava a
   montar a escala. Agora a cor viaja com o turno.
   ⚠️ Pinta-se o CHIP e o que herda cor dele — o ponto, a pausa e o foco —, e
   não a célula: as células continuam a ser das férias, da folga e do dia de
   hoje, que é o que o bloco de 04/09 já protegia. */
.escala-grade tr.linha-freela .turno-chip{
  background:color-mix(in srgb, var(--roxo) 10%, transparent);
  color:var(--roxo);
}
.escala-grade tr.linha-freela .turno-chip::before{ background:var(--roxo); }
.escala-grade tr.linha-freela .turno-chip .chip-p{ color:var(--roxo); }
.escala-grade tr.linha-freela .turno-chip .chip-x{ color:var(--roxo); }
.escala-grade tr.linha-freela .chip-h-btn:focus-visible{ outline-color:var(--roxo); }

/* ══════════ ⭐⭐⭐ A ESCALA NO TELEMÓVEL (08/09/2026) ══════════
   Ele: *"Tava tentando fazer a escala pelo celular, e tem algumas coisas pra
   melhorar."* Três peças: a coluna do nome encolhe, há um interruptor
   mover/copiar (porque no dedo não há tecla `Alt`) e o arraste tem um fantasma
   a seguir o dedo. */

/* ── 1 · a coluna do nome encolhe ──
   ⚠️ Os dois nomes vivem no HTML e é o CSS que escolhe: trocar texto por
   JavaScript perdia-se na próxima troca de semana, que substitui a grelha
   inteira. O estado vive numa classe da tabela, que a troca respeita. */
.col-nome-btn{
  display:inline-flex; align-items:center; gap:6px;
  background:none; border:none; padding:0; margin:0; cursor:pointer;
  font:inherit; color:inherit; text-transform:inherit; letter-spacing:inherit;
}
.col-nome-btn:focus-visible{ outline:2px solid var(--vermelho); outline-offset:3px; border-radius:var(--raio-xs); }
.col-nome-seta{
  width:0; height:0; flex:0 0 auto;
  border-top:4px solid transparent; border-bottom:4px solid transparent;
  border-right:5px solid var(--cinza-medio);
}
.escala-grade.nomes-curtos .col-nome-seta{ border-right:none; border-left:5px solid var(--cinza-medio); }
.escala-grade .nome-curto{ display:none; }
.escala-grade.nomes-curtos .nome-cheio{ display:none; }
.escala-grade.nomes-curtos .nome-curto{ display:inline; }
/* ⚠️ Encolhida, a coluna deixa de ter espaço para o selo «Freelancer» — e não
   faz falta: a faixa roxa e os turnos roxos já dizem quem é. */
.escala-grade.nomes-curtos .selo-freela{ display:none; }
/* ⭐ A semana anterior de cada um (27/09/2026): discreta — letra pequena e
   cinza, numa linha por baixo do nome, como a dica de um campo. Com a coluna
   encolhida some, e fica no `title`. */
.escala-grade .esc-ant{ display:block; font-size:11px; font-weight:400; color:var(--cinza-medio);
  line-height:1.3; margin-top:2px; white-space:normal; max-width:190px; }
.escala-grade.nomes-curtos .esc-ant{ display:none; }
/* ⭐ O × que tira o freelancer da escala (22/09/2026). Discreto: é uma ação
   rara e de consequência, não um botão de todos os dias — e fica ao lado do
   selo, que é onde o olho já está quando pergunta «quem é este?».
   ⚠️ E some com o selo quando a coluna encolhe (a seta do COLABORADOR): numa
   coluna de 90px um × ao lado do nome é um toque errado à espera de acontecer. */
.escala-grade tr.linha-freela .freela-tirar{ margin-left:6px; color:var(--cinza-medio);
  text-decoration:none; font-size:15px; line-height:1; padding:0 4px; border-radius:var(--raio-xs); }
.escala-grade tr.linha-freela .freela-tirar:hover{ color:var(--vermelho); background:var(--fundo); }
.escala-grade.nomes-curtos .freela-tirar{ display:none; }
/* a ficha do freelancer abre-se da escala (26/09/2026): já não está em Colaboradores */
.escala-grade tr.linha-freela .freela-ficha{ margin-left:6px; color:var(--cinza-medio); display:inline-flex; vertical-align:middle;
  padding:2px; border-radius:var(--raio-xs); }
.escala-grade tr.linha-freela .freela-ficha .ic-inline{ width:14px; height:14px; }
.escala-grade tr.linha-freela .freela-ficha:hover{ color:var(--texto); background:var(--fundo); }
.escala-grade.nomes-curtos .freela-ficha{ display:none; }
.escala-grade.nomes-curtos th.col-nome,
.escala-grade.nomes-curtos td.col-nome{ min-width:0; max-width:96px; }
.escala-grade.nomes-curtos .col-nome-rot{
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap; max-width:64px;
}

/* ── 2 · o interruptor mover/copiar ──
   Só no toque: no rato o `Alt` continua a ser a forma da casa, e um segundo
   caminho para a mesma coisa é um caminho para esquecer de manter. */
/* ⚠️ O canto é do GRUPO, com `overflow:hidden`, e os botões ficam a `0`. A
   régua da casa não deixa escrever cantos à mão (`--raio-sm 0 0 --raio-sm`) e
   tem razão: dois cantos escritos são dois sítios que um dia discordam do
   degrau. E `min-height:44px`, que é o alvo do dedo da casa — a primeira versão
   saiu a 36 e o varredor apanhou-a. */
.escala-modo{
  display:none; margin:0 0 12px;
  border:1px solid var(--cinza-borda); border-radius:var(--raio-sm); overflow:hidden;
}
.escala-modo-btn{
  min-height:44px; padding:8px 18px; cursor:pointer;
  font-size:13px; font-weight:600; font-family:inherit;
  background:var(--branco); color:var(--cinza-medio);
  border:none; border-radius:0;
}
.escala-modo-btn + .escala-modo-btn{ border-left:1px solid var(--cinza-borda); }
.escala-modo-btn.on{
  background:color-mix(in srgb, var(--vermelho) 10%, transparent);
  color:var(--vermelho);
}
.escala-modo-btn:focus-visible{ outline:2px solid var(--vermelho); outline-offset:-3px; }
@media (hover:none){ .escala-modo{ display:inline-flex; } }

/* ── 3 · o arraste com o dedo ──
   🚨 `touch-action:none` SÓ enquanto se arrasta, e não sempre: a grelha mede
   760px num ecrã de 375 e tem de continuar a rolar-se com o dedo enquanto o
   arraste ainda não começou. É a classe que o JavaScript põe ao fim dos 400ms.
   ⚠️ `pointer-events:none` no fantasma: sem isso o `elementFromPoint` achava
   sempre o próprio fantasma e nunca encontrava a célula por baixo. */
.escala-wrap.escala-arrastando{ touch-action:none; overscroll-behavior:contain; }
.escala-wrap.escala-arrastando *{ user-select:none; -webkit-user-select:none; }
.chip-fantasma{
  position:fixed; z-index:60; pointer-events:none; opacity:.92;
  box-shadow:0 6px 18px rgba(17,17,17,.28); transform:scale(1.06);
}
.chip-fantasma .chip-x, .chip-fantasma .add-pop{ display:none; }

/* O cadastro de um toque, ao pé da grelha. */
.escala-freela{
  display:flex; flex-wrap:wrap; align-items:center; gap:8px;
  margin:0 0 12px; padding:10px 14px;
  background:var(--roxo-fundo); border:1px solid color-mix(in srgb, var(--roxo) 22%, transparent);
  border-radius:var(--raio-sm);
}
.escala-freela-rot{ font-size:13.5px; font-weight:600; color:var(--roxo); }
/* ⚠️ `email` na mesma lista que `text` (08/09/2026): o campo novo do
   e-mail é `type=email` e ficava de fora — sem o `flex`, sem a borda da casa e,
   pior, sem os 44px de alto da régua do dedo no telemóvel. */
.escala-freela input[type=text],
.escala-freela input[type=email]{
  flex:1 1 150px; min-width:0; max-width:100%;
  padding:8px 12px; font-size:14px;
  background:var(--branco); color:var(--texto);
  border:1px solid var(--cinza-borda); border-radius:var(--raio-sm);
}
/* 🚨 MEDIDO NO NAVEGADOR a 375px, e as duas coisas eram verdade:
   · o campo de texto media **35px** de alto — a régua da casa são 44;
   · e o botão, no canto direito, ficava por baixo do balão da ajuda
     (`.ajuda-fab`, `position:fixed` naquele canto). O centro dele continuava a
     receber o toque — medido com `elementFromPoint` — mas ~33px do lado
     direito não. Um botão que responde em parte é pior do que um que não
     responde: quem falha o toque acha que a página está lenta.
   ⭐ No dedo, o botão passa a ter **linha própria e largura toda**: sai do canto
   do balão e ganha um alvo que se acerta sem olhar. */
@media (pointer:coarse){
  .escala-freela input[type=text],
  .escala-freela input[type=email]{ min-height:44px; }
  .escala-freela button{ flex:1 0 100%; min-height:44px; }
}


/* ══════════ ⭐⭐ O RELÓGIO DE PONTO — o tablet do balcão (04/09/2026) ══════════
   ⚠️ A foto e o número entram no cartão que já existia: quem está ao balcão com
   as mãos ocupadas acerta numa cara de longe e lê um nome de perto. O número
   serve para quem tem homónimo, e por isso é discreto — é desempate, não
   identidade. */
.kiosk-foto{
  width:56px; height:56px; border-radius:50%; object-fit:cover;
  display:block; margin:0 auto 6px;
}
.kiosk-num{
  display:block; margin-top:2px;
  font-size:12px; font-weight:600; color:var(--cinza-medio);
  font-variant-numeric:tabular-nums;
}
/* ⚠️ O freelancer no relógio leva a MESMA cor da escala — se aqui fosse outra,
   eram duas linguagens para a mesma coisa na mesma casa. */
.kiosk-freela{ border-color:color-mix(in srgb, var(--roxo) 35%, transparent); }
.kiosk-freela .nm{ color:var(--roxo); }


/* ══════════ ⭐⭐⭐ O APARELHO DE BALCÃO (06/09/2026) ══════════
   Ele: *"abre uma tela com os cards de todos os usuários"*. Esta é a tela onde
   o tablet descansa entre pessoas, e por isso desenha-se para o BRAÇO ESTICADO,
   não para o olho a 40 cm: nome grande, cara grande, e o dedo acerta sem mirar. */
.apar-escolha{ display:grid; gap:16px; grid-template-columns:repeat(auto-fit,minmax(260px,1fr)); margin:8px 0 18px; }
.apar-card{
  padding:20px; border:1px solid var(--cinza-borda); border-radius:var(--raio);
  background:var(--branco); display:flex; flex-direction:column; gap:8px; align-items:flex-start;
}
.apar-card h2{ margin:0; font-size:18px; }
.apar-card .ajuda{ margin:0; flex:1; }
/* ⚠️ O modo de balcão leva a cor do freelancer NÃO — leva a da marca: é o modo
   que a casa escolhe, e não uma natureza de pessoa. */
.apar-card-op{ border-color:color-mix(in srgb, var(--vermelho) 30%, transparent); }
.apar-nota{ margin-top:4px; }
/* Largar o turno é um POST (muda estado), mas veste-se de «voltar»: para quem
   está ao balcão é o mesmo gesto de sair da tela. */
button.voltar{ font-family:inherit; cursor:pointer; }

.apar-grade{ display:grid; gap:14px; grid-template-columns:repeat(auto-fill,minmax(150px,1fr)); }
.apar-pessoa{
  display:flex; flex-direction:column; align-items:center; gap:6px;
  padding:20px 12px; min-height:150px; justify-content:center;
  background:var(--branco); border:1px solid var(--cinza-borda); border-radius:var(--raio);
  text-decoration:none; color:var(--texto); text-align:center;
}
.apar-pessoa:hover{ border-color:var(--vermelho); text-decoration:none; }
.apar-foto{ width:64px; height:64px; border-radius:50%; object-fit:cover; }
.apar-ini{
  width:64px; height:64px; border-radius:50%; display:grid; place-items:center;
  background:var(--preto); color:var(--branco); font-size:22px; font-weight:600;
}
.apar-nome{ font-size:15px; font-weight:600; line-height:1.2; }
.apar-num{ font-size:12px; font-weight:600; color:var(--cinza-medio); font-variant-numeric:tabular-nums; }
/* ⚠️ Quem não tem PIN aparece, mas apagado e sem link: esconder a pessoa fazia
   parecer que ela não existe na casa; um card que não responde ao toque, sem
   dizer porquê, é pior ainda. */
.apar-pessoa-sem{ opacity:.5; cursor:default; }
.apar-sem-pin{ font-size:11.5px; color:var(--cinza-medio); }
.apar-pessoa-freela{ border-left:3px solid var(--roxo); }

.apar-pin-caixa{ max-width:340px; margin:10vh auto 0; text-align:center; }
/* ⚠️ Grande e espaçado: é um PIN digitado de pé, com uma mão. */
.apar-pin{
  display:block; width:100%; margin:14px 0; padding:16px;
  font-size:28px; text-align:center; letter-spacing:.4em;
  border:1px solid var(--cinza-borda); border-radius:var(--raio-sm);
  background:var(--branco); color:var(--texto);
}
.apar-pin-caixa .btn{ width:100%; }
@media (pointer:coarse){
  .apar-pessoa{ min-height:170px; }
  .apar-pin{ min-height:64px; }
}
.apar-min{ display:flex; flex-direction:column; gap:4px; width:100%; }
/* ⭐ «Não sair sozinho» (10/09/2026): vive debaixo do número de minutos, porque
   é a mesma pergunta — quanto tempo até o turno acabar, e se acaba. */
.apar-fixo{ width:100%; margin-top:4px; }
.apar-min input{ width:96px; padding:9px 10px; border:1px solid var(--cinza-borda);
  border-radius:var(--raio-sm); background:var(--branco); color:var(--texto); font-size:15px; }
/* O aparelho em descanso: sem barra lateral, sem rodapé, e o conteúdo ocupa
   tudo. Ver o porquê em `app/Views/layout.php`. */
.apar-descansa .sidebar,
.apar-descansa .rodape-dext{ display:none; }
.apar-descansa .conteudo{ margin-left:0; max-width:none; padding-top:18px; }
.apar-erro{
  margin:12px 0 0; padding:11px 14px; border-radius:var(--raio-sm);
  background:color-mix(in srgb, var(--vermelho) 10%, var(--branco));
  border:1px solid color-mix(in srgb, var(--vermelho) 35%, transparent);
  color:var(--vermelho); font-weight:600; font-size:14.5px;
}
.apar-rodape{ margin:26px 0 0; text-align:center; font-size:13px; }
.apar-rodape a{ color:var(--cinza-medio); }

/* ⭐ O inventário por prateleira (06/09/2026): a linha de grupo e a fila dos setores. */
.inv-grupo th{ text-align:left; background:var(--fundo); color:var(--texto); font-weight:600;
  padding:16px 10px 6px; border-bottom:1px solid var(--cinza-borda); font-size:13.5px; }
.inv-setores{ margin-top:-6px; }
@media (max-width:640px){
  /* nos cards, a linha de grupo é um título entre cartões, e não um cartão */
  .tabela-cards .inv-grupo{ display:block; background:none; border:0; box-shadow:none; padding:0; }
  .tabela-cards .inv-grupo th{ display:block; background:none; border:0; padding:14px 2px 4px; }
}

/* O saldo que diz o que é, e a equivalência por baixo (07/09/2026). */
.inv-saldo-n{ display:block; font-variant-numeric:tabular-nums; }
.inv-saldo-eq{ display:block; }
/* O setor de quem está a contar, destacado entre os outros. */
.inv-setores .inv-meu{ border-color:var(--vermelho); font-weight:600; }
.inv-rascunho{ margin:10px 0 0; }
/* Os dois botões de cada relatório do dia (07/09/2026). */
.reldia-acoes{ display:inline-flex; gap:8px; margin-left:auto; }
/* O relatório do dia em leitura: o texto formatado, e o «editar» ao lado. */
.reldia-lido .reldia-texto{ margin-bottom:14px; }

/* ⭐ A pré-visualização do editor de texto (07/09/2026): o mesmo desenho do
   campo, para o olho não ter de se reajustar ao alternar. */
.txt-previa{
  border:1px solid var(--cinza-borda); border-radius:var(--raio-sm);
  background:var(--branco); padding:10px 12px; min-height:64px;
}
.txt-previa > *:first-child{ margin-top:0; }
.txt-previa > *:last-child{ margin-bottom:0; }
.txt-previa-vazia{ color:var(--cinza-medio); }
/* ⭐⭐⭐ A CAIXA QUE JÁ MOSTRA (23/09/2026) — ver `texto-rico.js`. Tem a cara
   de um campo (a mesma borda, o mesmo foco), e por dentro é o `.texto-rico`
   da tela final: o que se vê a escrever é o que se lê depois. */
.txt-visual{
  border:1.5px solid var(--cinza-borda); border-radius:var(--raio-sm);
  background:var(--branco); color:var(--preto); padding:11px 14px; min-height:84px;
  font-family:var(--fonte-texto); font-size:15px; line-height:1.45;
  overflow-wrap:anywhere; cursor:text; transition:border-color .15s;
}
.txt-visual:focus{ border-color:var(--preto); }
.txt-visual:focus:not(:focus-visible){ outline:none; }
.txt-visual:focus-visible{ outline:2px solid var(--vermelho); outline-offset:1px; }
.txt-visual > *:first-child{ margin-top:0; }
.txt-visual > *:last-child{ margin-bottom:0; }
.txt-visual.txt-visual-vazio::before{
  content:attr(data-placeholder); color:var(--cinza-medio); position:absolute; pointer-events:none;
}
.txt-visual{ position:relative; }
.txt-visual.txt-visual-falta{ border-color:var(--vermelho-sinal); }
/* ⭐ OS BLOCOS DA CAIXA — uma linha, um bloco, desenhado como a tela final
   desenha as marcas. O nível é o recuo; o marcador é o que ele escreveu
   (`data-marca`), como no `.texto-rico` (tr-m-*). */
.txt-visual .bl{ min-height:1.45em; margin:0 0 .35em; position:relative; }
.txt-visual .bl[data-tipo="h1"]{ font-size:1.12em; font-weight:700; margin:.6em 0 .3em; }
.txt-visual .bl[data-tipo="h2"]{ font-size:1em; font-weight:700; margin:.5em 0 .25em; }
.txt-visual .bl[data-tipo="quote"]{ border-left:3px solid var(--cinza-borda); padding-left:10px; color:var(--cinza-medio); }
.txt-visual .bl[data-tipo="ul"], .txt-visual .bl[data-tipo="ol"], .txt-visual .bl[data-tipo="check"]{
  padding-left:calc(1.4em * var(--nv, 1)); margin-bottom:.15em;
}
.txt-visual .bl[data-nivel="2"]{ --nv:2; } .txt-visual .bl[data-nivel="3"]{ --nv:3; }
.txt-visual .bl[data-nivel="4"]{ --nv:4; } .txt-visual .bl[data-nivel="5"]{ --nv:5; }
.txt-visual .bl[data-tipo="ul"]::before, .txt-visual .bl[data-tipo="ol"]::before{
  position:absolute; left:calc(1.4em * var(--nv, 1) - 1.2em); color:var(--cinza-medio);
}
.txt-visual .bl[data-tipo="ul"]::before{ content:attr(data-marca); }
.txt-visual .bl[data-tipo="ol"]::before{ content:attr(data-num) "."; }
.txt-visual .bl[data-tipo="check"]{ padding-left:calc(1.4em * var(--nv, 1) - 1.4em); }
.txt-visual .bl[data-feito="1"]{ color:var(--cinza-medio); text-decoration:line-through; }
.txt-visual .bl-cx{ cursor:pointer; user-select:none; margin-right:.35em; text-decoration:none; display:inline-block; }
.txt-visual .bl[data-tipo="hr"] hr{ margin:.6em 0; }
/* O comentário da janela da tarefa é curto: a caixa também. */
textarea[rows="2"] + .txt-visual{ min-height:52px; }
/* A lista de alterações antes da senha (07/09/2026). */
.pdia-mudancas{ list-style:none; margin:0 0 16px; padding:0; display:grid; gap:8px; }
.pdia-mudancas li{ display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
.pdia-de{ color:var(--cinza-medio); text-decoration:line-through; }

/* ⭐⭐ OS CAMPOS DE UMA LINHA ALINHAM PELO CAMPO, NÃO PELO TOPO (07/09/2026).
   🐞 Ele, com um print: *"o Categoria do Inventário tá desalinhado."* Medido:
   o rótulo «Categoria de inventário» ocupa 39px contra os 20px de «Setor» —
   quebra em duas linhas e empurra o `<select>` 20px para baixo do vizinho.
   ⚠️ A cura NÃO é encurtar o rótulo: o nome longo existe porque há um segundo
   «Categoria» na mesma ficha (a de cocção, que é dele) e encurtá-lo trazia de
   volta os dois campos com o mesmo nome. É o ALINHAMENTO que estava errado —
   uma linha de campos deve emparelhar as CAIXAS, que é o que o olho segue, e
   não os topos dos rótulos, que têm alturas diferentes por natureza.
   ⭐ Vale para todas as `.form-linha` da casa, e por isso arruma de uma vez
   qualquer par em que um rótulo caiba numa linha e o outro não. */
.form-linha > .campo{ display:flex; flex-direction:column; }
.form-linha > .campo > label{ margin-top:auto; }
.form-linha > .campo > input,
.form-linha > .campo > select,
.form-linha > .campo > textarea{ margin-top:auto; }

/* ══════ ⭐⭐ E O RÓTULO TAMBÉM ALINHA — a mesma regra, melhor cumprida (09/09/2026)
   🐞 Ele, com um print do cadastro de produto: *"alinha isso. Preço tá
   desalinhado com o do lado."*

   O remédio de 07/09 (acima) empurra o conteúdo para a BASE da célula, e com
   isso emparelha o que está em baixo. Funciona enquanto as duas caixas medirem
   o mesmo — e no cadastro do produto não medem: o «Embalagem» é um número MAIS
   um seletor (`.cfg-linha`, 48px, e **82px quando o seletor desce para outra
   linha**), o «Preço total» é uma caixa de moeda de 43px. Alinhados por baixo,
   a caixa mais curta desce — e o rótulo dela desce com ela.
   📏 Medido no navegador a 820px: o rótulo «Preço total» nascia **5px** abaixo
   do «Embalagem»; com o seletor quebrado para a linha de baixo, a diferença
   passava dos 30px e o rótulo aparecia a meio da célula do lado. É isso que a
   captura dele mostra.

   ⭐ **O `subgrid` faz o que o `margin-top:auto` tentava fazer, mas pelos dois
   lados:** os rótulos partilham uma linha da grelha e as caixas partilham a
   seguinte. Um rótulo de duas linhas cresce a linha DOS DOIS (que era o pedido
   de 07/09) e uma caixa mais alta cresce a linha das duas caixas — sem nunca
   deslocar o rótulo do vizinho.

   ⚠️ **O `row-gap:0` é obrigatório**, e não é cosmética: com seis linhas na
   grelha, o `gap:16px` passava a somar 80px de ar DENTRO de cada campo. O
   espaço entre rótulo e caixa continua a vir das margens, como sempre veio.
   ⚠️ **Seis linhas** porque um `.campo` tem rótulo, caixa e ajuda — e um deles
   já tem quatro filhos. Sobra folga; linha vazia não ocupa altura nenhuma.
   ⚠️ **Só a duas colunas.** Empilhado (≤720px) cada campo é uma célula sozinha,
   não há vizinho com que alinhar, e o `gap:16px` é o que separa um campo do
   outro — apagá-lo colava-os.
   ⚠️ E fica dentro de `@supports`: sem subgrid, vale o remédio de 07/09 acima,
   que continua a ser melhor do que nada. */
@supports (grid-template-rows: subgrid){
  @media (min-width:721px){
    .form-linha{ grid-template-rows:repeat(6, auto); row-gap:0; column-gap:16px; }
    .form-linha > .campo{ display:grid; grid-template-rows:subgrid; grid-row:span 6; align-content:start; }
    .form-linha > .campo > label{ margin-top:0; }
    .form-linha > .campo > input,
    .form-linha > .campo > select,
    .form-linha > .campo > textarea{ margin-top:0; }
    /* 🐞 A CAIXA NÃO ESTICA À ALTURA DA VIZINHA (ele, 24/09/2026, na Nova
       reserva). Na grelha a caixa estica por omissão: o «Origem» ao lado da
       lista das mesas (quatro linhas) ficava com 150px. Cada caixa fica com a
       sua altura, encostada em cima, e o rótulo continua na linha do vizinho. */
    .form-linha > .campo > input,
    .form-linha > .campo > select,
    .form-linha > .campo > textarea{ align-self:start; }

    /* 🐞 E A LINHA DE TRÊS CAMPOS VOLTA AO REMÉDIO ANTIGO — apanhado na
       auditoria de 09/09, medido no Diário e nas Configurações de Pessoas.
       A grelha tem DUAS colunas: com três campos, o terceiro desce para uma
       segunda fila — e o `row-gap:0` que os seis degraus obrigam deixava-o
       colado ao de cima, sem os 16px de respiro. Duas linhas de campos não são
       um par: aqui o `margin-top:auto` de 07/09 continua a ser o certo. */
    .form-linha:has(> .campo:nth-child(3):not([hidden])){ grid-template-rows:none; row-gap:16px; }
    .form-linha:has(> .campo:nth-child(3):not([hidden])) > .campo{ display:flex; grid-row:auto; }
    .form-linha:has(> .campo:nth-child(3):not([hidden])) > .campo > label,
    .form-linha:has(> .campo:nth-child(3):not([hidden])) > .campo > input,
    .form-linha:has(> .campo:nth-child(3):not([hidden])) > .campo > select,
    .form-linha:has(> .campo:nth-child(3):not([hidden])) > .campo > textarea{ margin-top:auto; }
  }
}

/* ⭐ Os módulos contratados no painel da Dext (23/09/2026): uma caixa por
   módulo, em linha, e o «Gravar» discreto ao lado. */
.dext-mods{ display:flex; flex-wrap:wrap; align-items:center; gap:4px 12px; margin:0; }
.dext-mod{ display:inline-flex; align-items:center; gap:4px; font-size:13px; white-space:nowrap; }

/* ⭐ O aviso do número ambíguo (23/09/2026): discreto, por baixo do campo, só
   para quem escreve numa régua diferente da do país. Ver `topo.php`. */
.num-lido{ display:block; margin-top:3px; font-size:12px; color:var(--cinza-medio); }

/* ⭐ O MEU PONTO POR PERÍODO (24/09/2026) — a tela pessoal ganhou a lente do
   relatório. Três números em linha, que no telemóvel caem uns por baixo dos
   outros; e as batidas de cada dia como pequenas cápsulas. */
.meu-periodo{ margin-top:28px; }
.meu-totais{ display:flex; flex-wrap:wrap; gap:10px; margin:12px 0; }
.meu-total{ flex:1 1 120px; background:var(--branco); border:1px solid var(--cinza-borda); border-radius:var(--raio-sm); padding:10px 12px; }
.meu-total-rot{ display:block; font-size:12px; color:var(--cinza-medio); }
.meu-total strong{ font-size:18px; }
.meu-turno{ display:inline-block; margin:0 6px 2px 0; font-variant-numeric:tabular-nums; }

/* ⭐ O alternador «cartões | lista» (25/09/2026): dois botões colados, o ativo cheio. */
.ver-alterna{ display:inline-flex; border:1px solid var(--cinza-borda); border-radius:var(--raio-sm); overflow:hidden; background:var(--branco); }
.ver-alterna a{ display:inline-flex; align-items:center; gap:6px; padding:8px 12px; min-height:40px; font-size:13.5px; font-weight:600;
  color:var(--cinza-medio); text-decoration:none; }
.ver-alterna a + a{ border-left:1px solid var(--cinza-borda); }
.ver-alterna a.ativo{ background:var(--texto); color:var(--branco); }
.ver-alterna .ic-inline{ width:17px; height:17px; }
@media (max-width:520px){ .ver-alterna .ver-rot{ display:none; } .ver-alterna a{ padding:8px 11px; } }

/* ═══ ⭐⭐⭐ OS CARTÕES DA CASA — nasceram nos relatórios do dia (24/09/2026) ═══
   25/09/2026: ele gostou tanto que pediu o mesmo desenho nas outras áreas
   (*"fichas técnicas, receituários, etc. (…) no mesmo design e estrutura"*).
   Por isso os nomes deixaram de ser `reldia-*`: a faixa de números
   (`.cartoes-faixa` + `.cartoes-kpi`), a grade (`.cartoes-grade`) e o cartão
   (`.cartao`, com o bloco à esquerda `.cartao-bloco`, o `.cartao-titulo`, o
   `.cartao-txt` e os `.cartao-selos`) servem qualquer tela. Uma cópia por tela
   divergia no primeiro retoque. O que é só dos relatórios continua `reldia-*`.
   ---- a nota original: ----
   Ele: *"coloca uns cards com o dia e quando clicar, abre o relatório
   completo"*. Um card por dia que abriu a casa; o que ficou sem relato é
   tracejado, no lugar dele. A janela (`.dlg-reldia`) mostra o relato inteiro. */
.reldia-cab{ align-items:center; gap:12px; flex-wrap:wrap; }
.reldia-cab .sub-nav{ margin:0; }
.cartoes-faixa{ display:flex; flex-wrap:wrap; align-items:stretch; gap:10px; margin:6px 0 18px; }
.cartoes-kpi{ display:flex; flex-direction:column; gap:2px; min-width:92px; padding:10px 14px;
  background:var(--branco); border:1px solid var(--cinza-borda); border-radius:var(--raio-sm); }
.cartoes-kpi span{ font-size:12px; color:var(--cinza-medio); }
.cartoes-kpi strong{ font-size:20px; font-weight:600; font-variant-numeric:tabular-nums; }
.cartoes-kpi-alerta{ border-color:color-mix(in srgb, var(--ambar-vivo) 55%, transparent); }
.cartoes-kpi-alerta strong{ color:var(--ambar); }
.cartoes-kpi-vazio{ color:var(--cinza-medio); }
.reldia-imprimir{ margin-left:auto; align-self:center; }
.nota-ok{ color:var(--verde); }
.nota-meio{ color:var(--ambar); }
.nota-ruim{ color:var(--vermelho-sinal); }

.cartoes-grade{ display:grid; grid-template-columns:repeat(auto-fill, minmax(260px, 1fr)); gap:14px; }
/* ⚠️ 28/09/2026 — só DENTRO da grade. `.cartao` já era, desde antes, o painel
   branco da linha 1518 (Anexos, Customizar o painel, Tarefas, POP): esta regra
   pô-los em linha e sem quebra, e no celular a página alargava (Anexos a 477px,
   Customizar a 538px). `:where` para não subir o peso — o tracejado e o inativo,
   que vêm depois, continuam a ganhar. */
:where(.cartoes-grade) > .cartao{ display:flex; gap:14px; align-items:flex-start; padding:16px; min-width:0;
  background:var(--branco); border:1px solid var(--cinza-borda); border-radius:var(--raio);
  color:var(--texto); text-decoration:none; box-shadow:0 1px 2px rgba(17,17,17,.04);
  transition:border-color .15s, box-shadow .15s, transform .15s; }
:where(.cartoes-grade) > .cartao:hover{ border-color:var(--cinza-medio); box-shadow:var(--sombra); transform:translateY(-1px); }
.cartao:focus-visible{ outline:2px solid var(--vermelho); outline-offset:2px; }
.cartao-bloco{ display:flex; flex-direction:column; align-items:center; flex:0 0 52px; padding:6px 0;
  border-radius:var(--raio-sm); background:var(--cinza-fundo); line-height:1.1; }
.cartao-bloco span{ font-size:11.5px; text-transform:uppercase; letter-spacing:.04em; color:var(--cinza-medio); }
.cartao-bloco strong{ font-family:var(--fonte-titulo); font-size:24px; font-weight:700; margin:2px 0; }
.cartao-corpo{ display:flex; flex-direction:column; gap:6px; min-width:0; flex:1; }
.cartao-titulo{ font-weight:600; font-size:14px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.cartao-txt{ font-size:13.5px; line-height:1.45; color:var(--cinza-medio);
  display:-webkit-box; -webkit-line-clamp:3; -webkit-box-orient:vertical; overflow:hidden; overflow-wrap:anywhere; }
.cartao-selos{ display:flex; flex-wrap:wrap; gap:6px; min-width:0; }
/* ⚠️ 28/09/2026 — o selo não quebra linha (`nowrap`), e «Justino Alexandre
   Sardinha Lda» saía pela borda do cartão (print dele). Dentro do cartão o selo
   para na largura e corta com «…»; o nome inteiro fica no `title`. É
   `inline-block` porque o texto solto de um `inline-flex` não corta. */
.cartao-selos .selo{ display:inline-block; max-width:100%; overflow:hidden; text-overflow:ellipsis; vertical-align:middle; }
.cartao-tracejado{ border-style:dashed; background:transparent; box-shadow:none; align-items:center; }
.cartao-tracejado .cartao-bloco{ background:transparent; }
.cartao-falta-rot{ font-weight:600; color:var(--ambar); font-size:14px; }
.cartao-ir{ font-size:13px; color:var(--vermelho); font-weight:600; }

/* ⭐ 25/09/2026 — o cartão que é BLOCO (div) e não link: o título estica-se por
   cima dele, e a caixa de marcar fica acima dessa camada. */
:where(.cartoes-grade) > div.cartao{ position:relative; }
:where(.cartoes-grade) > div.cartao:hover{ border-color:var(--cinza-medio); box-shadow:var(--sombra); transform:translateY(-1px); }
.cartao-link{ color:inherit; text-decoration:none; }
.cartao-link::after{ content:''; position:absolute; inset:0; border-radius:var(--raio); }
.cartao-link:focus-visible{ outline:none; }
.cartao-link:focus-visible::after{ outline:2px solid var(--vermelho); outline-offset:2px; }
.cartao-sel{ position:absolute; top:6px; right:6px; z-index:1; }
/* no celular o alvo-toque tem 44px com margem −13px: encostado ao canto DE DENTRO,
   senão saía 6px do cartão (medido a 375px nos 55 cartões de venda) */
@media (pointer:coarse), (max-width:600px){ .cartao-sel{ top:0; right:0; margin:0; } div.cartao .cartao-titulo.cartao-link{ padding-right:36px; } }
/* ⚠️ `div.cartao` à frente: a regra de base (26px) vem depois no arquivo e, com o
   mesmo peso, ganhava — o nome passava por baixo da caixa (auditoria de 25/09). */
.cartao-marca{ border-left:3px solid var(--linha-cor, var(--cinza-borda)); }
.cartao-inativo{ opacity:.55; }
.cartao-titulo.cartao-link{ padding-right:26px; }
.cartoes-faixa-fim{ margin-left:auto; display:flex; align-items:center; gap:10px; flex-wrap:wrap; }
.cartoes-sel-todos{ margin:0 0 8px; font-size:13.5px; }
.cartoes-legenda{ margin-top:10px; }
/* o «marcar todos» é um rótulo com texto: o alvo-toque do celular (margem −13px,
   feito para a caixa sozinha) empurrava-o para fora da borda */
.cartoes-sel-todos .alvo-toque{ margin:0; gap:8px; justify-content:flex-start; }
/* ⚠️ O bloco cresce com o número: «26%» a 24px não cabe em 52px (medido: 55 blocos
   a transbordar a 375px). A data dos relatórios continua a caber nos 52. */
.cartao-bloco{ flex:0 0 auto; min-width:52px; padding-left:8px; padding-right:8px; }
/* a CARA no bloco (colaboradores, 26/09/2026): a foto ou as iniciais, o molde
   do relógio de ponto, e o código de 4 dígitos por baixo */
.cartao-bloco-cara{ gap:4px; background:transparent; padding:0; }
/* o produto aberto no painel ao lado (produtos) */
.cartao-aberto{ border-color:var(--cartao-cor, var(--vermelho)); }
.cartao-foto{ width:44px; height:44px; border-radius:50%; object-fit:cover; display:block; }
.cartao-bloco .cartao-ini{ display:flex; align-items:center; justify-content:center; width:44px; height:44px; margin:0;
  border-radius:50%; background:var(--cinza-fundo); font-size:17px; }
.cartao-bloco-cara > span{ font-variant-numeric:tabular-nums; text-transform:none; letter-spacing:0; }
@media (max-width:520px){ .cartoes-faixa-fim{ margin-left:0; flex:1 1 100%; justify-content:space-between; } }
/* ═══ ⭐⭐ A COR DOS CARTÕES (26/09/2026) — uma das cores da marca, escolhida em
   Configurações › Aparência (`--cartao-cor`, e `--cartao-cor-texto`, a mesma cor
   ajustada para ler sobre branco). Ele: *"pegar uma cor das que estão
   configuradas, pra deixar mais visualmente destacado e customizado"*.
   Tinge o bloco do número, pinta o número e a borda ao passar; a faixa ganha
   um fio da cor. ⚠️ Os números que já têm cor própria (o semáforo do CMV, o
   «sem preço» vermelho) mantêm-na: a regra só pinta o `strong` SEM classe. */
.cartao-bloco{ background:color-mix(in srgb, var(--cartao-cor, var(--cinza-borda)) 9%, var(--branco)); }
.cartao-bloco > strong:not([class]), .cartao-bloco > strong[class=""]{ color:var(--cartao-cor-texto, var(--texto)); }
:where(.cartoes-grade) > .cartao:hover{ border-color:var(--cartao-cor, var(--cinza-medio)); }
.cartoes-kpi{ border-top:3px solid var(--cartao-cor, var(--cinza-borda)); }
.cartoes-kpi-alerta{ border-top-color:var(--ambar-vivo); }
.cartao-bloco .cartao-ini{ background:color-mix(in srgb, var(--cartao-cor, var(--cinza-borda)) 16%, var(--branco)); color:var(--cartao-cor-texto, var(--texto)); }
.cartao-bloco-cara{ background:transparent; }
.cartao-tracejado .cartao-bloco{ background:transparent; }
/* a escolha na Aparência: três amostras, uma por cor da marca */
.cor-cartoes-opcoes{ display:flex; flex-wrap:wrap; gap:10px; }
.cor-cartoes-op{ display:inline-flex; align-items:center; gap:8px; padding:8px 12px; border:1px solid var(--cinza-borda);
  border-radius:var(--raio-sm); background:var(--branco); cursor:pointer; font-weight:500; min-height:44px; }
.cor-cartoes-op:has(input:checked){ border-color:var(--texto); box-shadow:inset 0 0 0 1px var(--texto); }
.cor-cartoes-amostra{ display:inline-block; flex:0 0 auto; width:22px; height:22px; border-radius:var(--raio-xs); background:var(--amostra); border:1px solid rgba(0,0,0,.12); }
.dlg-reldia{ width:min(680px,94vw); max-height:88vh; }
.reldia-janela-dow{ font-size:12px; text-transform:uppercase; letter-spacing:.05em; color:var(--cinza-medio); margin:0; }
.reldia-janela h3{ font-size:20px; margin:0 0 8px; }
.reldia-notas-janela{ margin:4px 0 14px; }
.reldia-janela .reldia-texto{ max-height:52vh; overflow:auto; padding-right:4px; }
.reldia-janela-acoes{ display:flex; flex-wrap:wrap; align-items:center; gap:10px; margin-top:18px; }
.reldia-fechar{ margin-left:auto; color:var(--cinza-medio); }
@media (max-width:520px){
  .cartoes-grade{ grid-template-columns:1fr; }
  /* ⚠️ No telemóvel a faixa não pode empurrar os cards para fora do ecrã:
     três por linha, mais baixos, e o Imprimir numa linha sua. */
  .cartoes-faixa{ gap:8px; }
  .cartoes-kpi{ flex:1 1 calc(33.33% - 6px); min-width:0; padding:8px 10px; }
  .cartoes-kpi strong{ font-size:17px; }
  .reldia-imprimir{ margin-left:0; flex:1 1 100%; }
  /* com QUATRO números, dois por linha: três e um esticado sozinho lia-se como
     destaque. Classe explícita na tela (`nth-of-type` conta divs, e a caixa do
     fim da faixa também é um div). */
  .cartoes-faixa-2x2 > .cartoes-kpi{ flex-basis:calc(50% - 4px); }
}

/* ═══ ⭐ OS E-MAILS POR SETOR (24/09/2026) — um campo por setor e, por baixo,
   os tipos de aviso que vão para lá. */
.cfgn-setor{ padding:12px 0; }
.cfgn-setor + .cfgn-setor{ border-top:1px solid var(--cinza-borda); }
.cfgn-setor .campo{ margin-bottom:8px; }
.cfgn-setor-tipos{ display:flex; flex-wrap:wrap; gap:6px 18px; }
.cfgn-setor-tipos .campo-check{ font-size:13.5px; font-weight:500; }

/* A aba-porta do Funcionamento (24/09/2026): um link com a cara das abas. */
a.cfg-aba{ text-decoration:none; display:inline-flex; align-items:center; }

/* ⭐ 24/09/2026: o dia em que a casa fecha, vindo do Funcionamento. */
.escala-grade th.dia-fechado{ color:var(--cinza-medio); }
.dia-fechado-rot{ display:block; font-size:10.5px; font-weight:600; text-transform:uppercase; letter-spacing:.04em; color:var(--cinza-medio); }
.escala-grade td.cel-fechada{ background:repeating-linear-gradient(135deg, var(--cinza-fundo) 0 6px, transparent 6px 12px); }

/* ═══ ⭐⭐ O CONTROLE DE FÉRIAS & FOLGAS (24/09/2026) ═══ */
.aus-atribuir{ margin:0 0 18px; }
.aus-atribuir > summary{ list-style:none; display:inline-flex; cursor:pointer; }
.aus-atribuir > summary::-webkit-details-marker{ display:none; }
.aus-atribuir-form{ margin-top:12px; max-width:640px; }
.aus-cab{ align-items:center; gap:12px; flex-wrap:wrap; margin-top:6px; }
.aus-cab .sub-nav{ margin:0; }
.aus-bloco{ margin-bottom:22px; }
.aus-saldo td strong{ font-weight:600; }

/* ═══ ⭐ O CALENDÁRIO DA EQUIPE (24/09/2026) — uma linha por pessoa, um dia
   por coluna. As cores são as dos sinais da casa; o pedido é tracejado. */
.aus-cal-wrap{ overflow-x:auto; background:var(--branco); border:1px solid var(--cinza-borda); border-radius:var(--raio); }
.aus-cal{ border-collapse:collapse; font-size:12px; min-width:100%; }
.aus-cal th, .aus-cal td{ border-bottom:1px solid var(--cinza-borda); text-align:center; padding:0; min-width:24px; height:28px; }
.aus-cal thead th{ font-weight:600; color:var(--cinza-medio); padding:4px 0; line-height:1.1; }
.aus-cal thead th span{ display:block; font-size:10px; font-weight:500; }
.aus-cal .aus-cal-nome{ text-align:left; padding:0 10px; white-space:nowrap; position:sticky; left:0; background:var(--branco); font-weight:600; font-size:12.5px; z-index:1; }
.aus-cal .cal-hoje{ color:var(--vermelho); }
.aus-cal td{ font-weight:700; font-size:11px; }
.cal-fechado{ background:repeating-linear-gradient(135deg, var(--cinza-fundo) 0 5px, transparent 5px 10px); }
.cal-ferias{ background:var(--azul-fundo); color:var(--azul); }
.cal-folga{ background:var(--verde-fundo); color:var(--verde); }
.cal-falta{ background:var(--vermelho-sinal-fundo); color:var(--vermelho-sinal); }
.cal-atestado{ background:var(--ambar-fundo); color:var(--ambar); }
/* ⭐ 25/09/2026: o dia normal de trabalho (turno na escala) e o resumo à frente do nome */
.cal-trabalho{ color:var(--cinza-medio); font-weight:700; }
.aus-cal-resumo{ display:block; font-weight:500; font-size:10.5px; color:var(--cinza-medio); margin-top:2px; }
.aus-cal-resumo .cal-leg{ margin-right:2px; }
.aus-cal td.cal-pedido{ background-image:repeating-linear-gradient(45deg, rgba(255,255,255,.75) 0 3px, transparent 3px 6px); outline:1px dashed currentColor; outline-offset:-3px; }
.aus-cal-leg{ margin:-12px 0 20px; }
.cal-leg{ display:inline-grid; place-items:center; width:18px; height:16px; border-radius:var(--raio-xs); font-size:10px; font-weight:700; vertical-align:middle; }
.cal-leg.cal-pedido{ outline:1px dashed var(--cinza-medio); outline-offset:-2px; }

/* O botão do mapa de férias, no topo do controle (24/09/2026). */
.aus-acoes-topo{ margin:0 0 10px; display:flex; gap:10px; flex-wrap:wrap; }

/* ═══ EMPRÉSTIMOS (27/09/2026) — a barra do que já se pagou, o formulário em
   pares (valor + unidade) e as duas caixas de abater. Só variáveis da casa. */
.empr-barra{ display:block; height:6px; border-radius:var(--raio-xs); background:var(--cinza-borda); overflow:hidden; margin:8px 0 6px; }
.empr-barra > span{ display:block; height:100%; background:var(--cartao-cor, var(--destaque)); border-radius:var(--raio-xs); }
.empr-barra-grande{ height:10px; margin:14px 0 8px; }
.empr-direcao{ display:flex; gap:18px; flex-wrap:wrap; }
.empr-direcao label{ display:flex; gap:8px; align-items:center; font-weight:500; }
.empr-par{ display:flex; gap:8px; }
.empr-par > input{ flex:1; min-width:0; }
.empr-par > select{ flex:0 0 auto; width:auto; }
.empr-previa{ margin:4px 0 14px; font-weight:600; color:var(--cartao-cor-texto, var(--preto)); }
.empr-novo{ margin:0 0 22px; }
.empr-novo > summary{ cursor:pointer; margin-bottom:14px; list-style:none; }
.empr-novo > summary::-webkit-details-marker{ display:none; }
.empr-novo[open] > summary{ display:none; }
.empr-portas{ margin:26px 0; align-items:start; }
.empr-caixa{ border:1px solid var(--cinza-borda); border-radius:var(--raio); padding:18px; background:var(--branco); }
.empr-caixa h3{ margin:0 0 6px; font-size:16px; }
.empr-rotulo{ display:block; font-weight:600; margin-bottom:8px; }
.empr-ligado{ margin:0; }

/* ══════════ ⭐⭐ A ESCALA ACEITA PELO FUNCIONÁRIO (27/09/2026) ══════════
   A caixa de responder (página do link e «Minha escala»), o pedido que a gestão
   decide, e o selo na grade. Os botões são os do sistema. */
.escr-caixa{ margin:18px 0 8px; display:flex; flex-direction:column; gap:12px; }
.escr-aceitar{ display:flex; align-items:center; gap:12px; flex-wrap:wrap; margin:0; }
.escr-destaque{ box-shadow:0 0 0 3px color-mix(in srgb, var(--verde) 25%, transparent); }
.escr-pedir > summary{ list-style:none; cursor:pointer; }
.escr-pedir > summary::-webkit-details-marker{ display:none; }
.escr-pedir[open] > summary{ margin-bottom:12px; }
.escr-form{ margin:0; }
.escr-estado{ font-weight:600; margin:0; display:flex; align-items:center; gap:6px; }
.escr-ok{ color:var(--verde); }
.escr-titulo{ font-family:var(--fonte-titulo); font-size:20px; margin:10px 0 2px; }
.escr-semana{ width:100%; border-collapse:collapse; margin:14px 0 4px; font-size:14px; }
.escr-semana td{ padding:8px 0; border-top:1px solid var(--cinza-borda); }
.escr-semana .escr-horas{ text-align:right; white-space:nowrap; }
.escr-motivo{ font-size:16px; line-height:1.5; margin:10px 0; }
.escala-grade .esc-resp{ display:inline-block; margin-top:4px; font-size:11px; text-decoration:none; }
.escala-grade.nomes-curtos .esc-resp{ display:none; }
