:root{
  --bg:#FBFAF7; --surface:#F1EEE7; --card:#FFFFFF;
  --brand:#0B5C49; --brand-ink:#073F33; --brand-soft:#D6EBE2;
  --ink:#14201B; --muted:#51605A; --faint:#6B776F; --line:#E3DFD5;
  --amber:#7A4A10; --amber-soft:#FBF1DD; --amber-line:#ECD9B6;
  --danger:#9A2C2C; --danger-soft:#FBE9E7;
  --radius:14px; --radius-sm:10px; --btn-radius:10px;
  --shadow:0 1px 2px rgba(20,32,27,.06), 0 10px 26px rgba(20,32,27,.07);
  --sidebar-w:240px; --content-max:1440px;
}
*{box-sizing:border-box}
html,body{margin:0}
body{
  background:var(--bg); color:var(--ink);
  font-family:Inter,system-ui,-apple-system,Segoe UI,Roboto,sans-serif;
  font-size:15px; line-height:1.5; -webkit-font-smoothing:antialiased;
}
h1,h2,h3{font-family:"Space Grotesk",Inter,sans-serif; line-height:1.12; margin:0; color:var(--ink)}
h1{font-size:32px; font-weight:700; letter-spacing:-.02em}
@media(min-width:1280px){h1{font-size:34px}}
h2{font-size:22px; font-weight:600; letter-spacing:-.012em}
h3{font-size:17px; font-weight:600}
a{color:var(--brand-ink); text-decoration:none}
.num{font-variant-numeric:tabular-nums slashed-zero}
.muted{color:var(--muted)} .faint{color:var(--faint)}
.small{font-size:13px}
.brand{font-family:"Space Grotesk",sans-serif; font-weight:700; color:var(--brand-ink)}

/* App-shell: sidebar fixa + conteúdo fluido ancorado à esquerda */
.app{display:grid; grid-template-columns:var(--sidebar-w) minmax(0,1fr); min-height:100vh}
.sidebar{
  position:sticky; top:0; height:100vh; overflow-y:auto;
  background:var(--card); border-right:1px solid var(--line);
  padding:18px 14px; display:flex; flex-direction:column; gap:3px;
}
.sidebar .brand{
  font-family:"Space Grotesk",sans-serif; font-weight:700; font-size:19px;
  color:var(--brand-ink); padding:4px 10px 14px; display:block;
}
.side-link{
  display:flex; align-items:center; gap:10px; padding:9px 12px; border-radius:10px;
  color:var(--ink); font-weight:500; font-size:14px; position:relative;
}
.side-link.active{background:var(--brand-soft); color:var(--brand-ink)}
.side-link.active::before{content:""; position:absolute; left:0; top:7px; bottom:7px; width:3px; border-radius:0 3px 3px 0; background:var(--brand)}
.side-cta{margin-top:8px; background:var(--brand); color:#fff; justify-content:center}
.side-group{margin:14px 12px 3px; font-size:11px; font-weight:600; letter-spacing:.05em; color:var(--muted)}
.side-foot{margin-top:auto; border-top:1px solid var(--line); padding:12px 12px 2px; font-size:13px; color:var(--muted)}
.side-head{display:flex; align-items:center; justify-content:space-between}
.nav-burger{display:none}
.side-links{display:flex; flex-direction:column; gap:3px; flex:1; min-height:0}
.content{min-width:0; padding:30px 32px 64px}
.inner{max-width:var(--content-max)}
.inner.narrow{max-width:720px}
.inner.mid{max-width:1040px}

@media(max-width:1024px){
  .app{grid-template-columns:1fr}
  .sidebar{position:sticky; top:0; z-index:50; height:auto; overflow:visible; flex-direction:column; gap:0; border-right:none; border-bottom:1px solid var(--line); padding:10px 16px}
  .side-head{width:100%}
  .sidebar .brand{padding:0}
  .nav-burger{display:inline-flex; align-items:center; font-size:22px; line-height:1; cursor:pointer; padding:6px 10px; border-radius:8px; color:var(--ink)}
  /* @media aninhada: precisa de continuar preso a esta largura (o burger só existe aqui)
     E de só valer com rato — ver o bloco de estados de rato no fim do ficheiro. */
  @media(hover:hover){ .nav-burger:hover{background:var(--surface)} }
  .side-links{display:none; width:100%; padding-top:10px}
  .nav-cb:checked ~ .side-links{display:flex}
  .side-link{padding:10px 12px}
  .side-link.active::before{display:none}
  .side-cta{margin-top:0; margin-bottom:4px}
  .side-group{display:none}
  .side-foot{margin:6px 0 0; border-top:1px solid var(--line); padding:10px 12px 2px}
  .content{padding:22px 16px 48px}
}
/* Tabelas largas (ex.: Obras = 8 colunas) rolam na horizontal no telemóvel, em vez de
   empurrar o body inteiro. display:block + nowrap = padrão responsivo CSS-only.
   Quem tem `.cartoes` NÃO entra aqui — vira cartão (a seguir). */
@media(max-width:720px){
  .lista:not(.cartoes){display:block; overflow-x:auto; white-space:nowrap; -webkit-overflow-scrolling:touch}
}
/* Modo CARTÃO. As Compras têm 10 colunas = 1590px numa viewport de 375: via-se 19% da
   tabela e chegar à coluna "Ações" exigia arrastar 1284px, mais de 4 ecrãs. Pior, o menu
   ⋮ da última linha abria 186px FORA do contentor — e um contentor com overflow-x:auto
   computa overflow-y:auto, por isso o menu ficava cortado e fora de alcance.
   Sem scroll horizontal esse problema desaparece por construção.
   O posicionamento usa as classes c-* do template (NÃO nth-child, que se desalinharia mal
   alguém acrescentasse uma coluna) e `order` para o cartão ler pela ordem que interessa:
   quem vendeu + quanto, depois a obra, depois o resto. Só as células NÃO-focáveis são
   reordenadas — o que se pode clicar (pagar, observações, ⋮) fica no fim, no DOM e no
   ecrã, por isso a ordem do teclado continua a bater certo com a visual.
   O corte está em 1279px, medido e não escolhido a olho. A tabela precisa de 1026px de
   largura mínima e o espaço útil é (viewport − 240 da sidebar − 64 de padding − o card),
   por isso só cabe a partir de ~1350px; sem a coluna "Origem" precisa de 938px e cabe a
   partir de ~1245. Daí os três regimes, sem nenhum vão entre eles:
     ≤1279px .......... CARTÃO (telemóvel, tablet e portátil estreito)
     1280–1365px ...... tabela SEM a coluna Origem (a menos acionável; fica no detalhe)
     ≥1366px .......... tabela completa
   Antes o corte estava em 720 e entre 721 e 1024 a tabela transbordava 340px. */
@media(max-width:1279px){
  .lista.cartoes, .lista.cartoes tbody{display:block; white-space:normal}
  .lista.cartoes thead{display:none}
  .lista.cartoes tr{display:flex; flex-wrap:wrap; align-items:baseline; gap:2px 8px;
    padding:14px; background:var(--surface); border-radius:var(--radius-sm)}
  .lista.cartoes tr+tr{margin-top:10px}
  /* Anula o .lista tbody tr:hover — o realce de linha não diz nada num cartão. Só faz
     falta onde há rato (num tablet ≤1279px com rato), daí a @media aninhada. */
  @media(hover:hover){ .lista.cartoes tbody tr:hover{background:var(--surface)} }
  .lista.cartoes td{display:block; border:none; padding:0; font-size:14px}
  /* 1.ª linha: fornecedor + valor — é o que se procura de relance */
  .lista.cartoes .c-fornecedor{order:1; flex:1 1 55%; font-weight:600; font-size:15px; color:var(--ink)}
  .lista.cartoes .c-valor{order:2; flex:0 0 auto; margin-left:auto; text-align:right;
    font-size:17px; font-weight:600; white-space:nowrap}
  /* 2.ª: a obra, sozinha */
  .lista.cartoes .c-obra{order:3; flex:1 1 100%; color:var(--muted)}
  /* 3.ª: metadados, que fluem e quebram sozinhos */
  .lista.cartoes .c-data, .lista.cartoes .c-categoria,
  .lista.cartoes .c-comprador, .lista.cartoes .c-origem{flex:0 1 auto; font-size:13px; color:var(--faint)}
  .lista.cartoes .c-data{order:4}
  .lista.cartoes .c-categoria{order:5}
  .lista.cartoes .c-comprador{order:6}
  .lista.cartoes .c-origem{order:7}
  .lista.cartoes .c-data>.small{display:none}  /* "recebida X" é ruído aqui; fica no detalhe */
  .lista.cartoes .c-categoria::before, .lista.cartoes .c-comprador::before,
  .lista.cartoes .c-origem::before{content:"· "}
  /* Um ::before/::after do flex container É um flex item: com flex-basis:100% obriga o
     rodapé a começar numa linha nova, sem precisar de um <div> extra no template. */
  .lista.cartoes tr::after{content:""; order:8; flex:0 0 100%; height:0}
  .lista.cartoes .c-estado{order:9; flex:0 0 auto; margin-top:8px}
  .lista.cartoes .c-pago{order:10; flex:0 0 auto; margin-top:8px}
  .lista.cartoes .c-acoes{order:11; flex:0 0 auto; margin-top:8px; margin-left:auto}
}
/* Portátil estreito: já é tabela, mas ainda faltam ~50px para as 10 colunas caberem.
   Esconde-se a coluna com menos valor de decisão — "Origem" (whatsapp / painel manual),
   que continua visível no detalhe da compra — em vez de deixar a página abanar para os
   lados. Regra por CLASSE (o <th> também a leva), para não depender da posição. */
@media(min-width:1280px) and (max-width:1365px){
  .lista.cartoes .c-origem{display:none}
}

/* Auth (sem sidebar) */
.auth-wrap{max-width:420px; margin:7vh auto 0; padding:0 20px}

/* Helpers de layout */
.row{display:flex; align-items:baseline; gap:12px; flex-wrap:wrap}
.between{display:flex; align-items:center; justify-content:space-between; gap:16px; flex-wrap:wrap}
.stack>*+*{margin-top:14px}
.eyebrow{display:inline-block; background:var(--brand-soft); color:var(--brand-ink); font-size:13px; padding:3px 12px; border-radius:999px; margin-bottom:10px}
.cap{font-size:14px; font-weight:600; color:var(--brand-ink)}

/* Cards */
.card{background:var(--card); border:1px solid var(--line); border-radius:var(--radius); padding:18px; box-shadow:var(--shadow)}
.card+.card{margin-top:16px}
.grid{display:grid; gap:14px; grid-template-columns:repeat(auto-fill,minmax(250px,1fr))}
/* minmax(0,…) e NÃO 1fr: uma coluna `1fr` tem mínimo = min-content, por isso um conteúdo
   indivisível (ex.: a linha "Fornecedor · Cimpor Betões e Agregados, S.A." no detalhe da
   compra) esticava a coluna para além do ecrã — o Detalhe sangrava 137px no telemóvel e os
   Relatórios 15px. Com minmax(0,…) a coluna pode encolher e o conteúdo é que se ajusta. */
.cols-2{display:grid; gap:18px; grid-template-columns:minmax(0,1fr)}
@media(min-width:1100px){.cols-2{grid-template-columns:minmax(0,1fr) minmax(0,1fr)} .cols-2 .span-2{grid-column:1/-1}}

/* Obra card */
.obra-card{display:flex; flex-direction:column; gap:10px}
.obra-card .nome{font-family:"Space Grotesk",sans-serif; font-weight:600; font-size:16px}
.obra-card .total{font-size:24px; font-weight:600; color:var(--brand)}

/* KPI tiles */
.kpis{display:grid; gap:14px; grid-template-columns:repeat(auto-fit,minmax(190px,1fr))}
.kpi-tile{background:var(--surface); border-radius:12px; padding:16px}
.kpi-tile .lbl{font-size:13px; color:var(--muted)}
.kpi-tile .val{font-family:"Space Grotesk",sans-serif; font-size:32px; font-weight:700; line-height:1.05; margin-top:4px; color:var(--ink)}
.kpi-tile .val.brand{color:var(--brand)} .kpi-tile .val.amber{color:var(--amber)}

/* Barras de progresso e ranking (partilhado painel/relatórios) */
.bar{height:8px; border-radius:999px; background:var(--surface); overflow:hidden; display:flex}
.bar .saldo{background:#CFC9BC} .bar .rastreado{background:linear-gradient(90deg,var(--brand-ink),var(--brand))}
.legend{display:flex; gap:14px; font-size:12px; color:var(--muted)}
.dot{display:inline-block; width:8px; height:8px; border-radius:50%; margin-right:5px; vertical-align:middle}
.dot.saldo{background:#CFC9BC} .dot.rastreado{background:var(--brand)}
.rep-row{display:grid; grid-template-columns:minmax(120px,1.3fr) 3fr minmax(88px,auto); gap:12px; align-items:center; padding:7px 0; color:var(--ink)}
.rep-label{font-size:14px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis}
.rep-track{height:10px; border-radius:999px; background:var(--surface); overflow:hidden}
.rep-fill{display:block; height:100%; background:linear-gradient(90deg,var(--brand-ink),var(--brand)); border-radius:999px; min-width:4px; box-shadow:inset 0 1px 0 rgba(255,255,255,.15)}
.rep-val{text-align:right; font-size:14px; font-weight:600; color:var(--ink)}
.rep-cols{display:flex; gap:12px; align-items:flex-end; height:180px; overflow-x:auto; padding-top:6px}
.rep-col{display:flex; flex-direction:column; align-items:center; justify-content:flex-end; gap:6px; min-width:46px}
.rep-colbar{width:38px; background:var(--brand); border-radius:6px 6px 0 0; min-height:2px}
.rep-colx{white-space:nowrap}

/* Chips / flash */
.chip{display:inline-flex; align-items:center; gap:6px; padding:4px 10px; border-radius:999px; font-size:12.5px; font-weight:500; background:#E9E5DC; color:var(--ink)}
.chip.amber{background:var(--amber-soft); color:var(--amber); border:1px solid var(--amber-line)}
.chip.green{background:var(--brand-soft); color:var(--brand-ink)}
.chip.neutral{background:#E9E5DC; color:var(--ink)}
/* Selo da conta em cortesia perpétua (/assinatura) — substitui a lista de preços. */
.selo-cortesia{background:linear-gradient(180deg,var(--brand-soft) 0%,var(--card) 62%); border-color:#BFDFD2}
.banner{display:flex; align-items:center; gap:10px; padding:12px 18px; border-radius:var(--radius-sm); font-size:14px; margin-bottom:18px}
.banner.amber{background:var(--amber-soft); color:var(--amber); border:1px solid var(--amber-line)}
.flash{padding:12px 16px; border-radius:var(--radius-sm); margin-bottom:18px; font-size:14px}
.flash.ok{background:var(--brand-soft); color:var(--brand-ink)}
.flash.erro{background:var(--danger-soft); color:var(--danger)}

/* Forms */
label{display:block; font-size:13px; font-weight:500; color:var(--ink); margin-bottom:4px}
input,select,textarea{
  width:100%; padding:8px 11px; font:inherit; color:var(--ink);
  background:var(--card); border:1px solid var(--line); border-radius:var(--radius-sm);
}
input:focus,select:focus,textarea:focus{outline:none; border-color:var(--brand); box-shadow:0 0 0 3px var(--brand-soft)}
/* 16px é o limiar do Safari no iOS: ABAIXO disto o browser dá zoom sozinho ao focar o campo
   e a pessoa fica com o ecrã descalibrado, a ter de fazer pinch para voltar. Acontecia em
   TODOS os formulários (criar conta, entrar, lançamento, validação) porque `font:inherit`
   herdava os 15px do body. Só no telemóvel — no rato não há zoom e os 15px mantêm-se. */
@media(max-width:720px){input,select,textarea{font-size:16px}}
/* Campo compacto de orçamento, embutido na célula da lista de Obras. Vinha com o tamanho
   inline (12px), que a media query acima não alcança — e era o pior sítio para o iOS dar
   zoom, porque a tabela à volta já rola na horizontal. */
.orc-inline{width:78px; font-size:12px}
@media(max-width:720px){.orc-inline{width:92px; font-size:16px}}
/* Foco de teclado visível e consistente em controlos não-form (a11y). */
a:focus-visible,button:focus-visible,summary:focus-visible,.icon-act:focus-visible,.modal-x:focus-visible,[tabindex]:focus-visible{outline:2px solid var(--brand); outline-offset:2px; border-radius:4px}
input[type=checkbox],input[type=radio]{width:18px; height:18px; accent-color:var(--brand); flex:none}
.field+.field{margin-top:10px}
.field-row{display:grid; gap:10px; grid-template-columns:1fr 1fr}
@media(max-width:520px){.field-row{grid-template-columns:1fr}}
.hint{font-size:12px; color:var(--muted); margin-top:5px}
.btn{
  display:inline-flex; align-items:center; justify-content:center; gap:8px;
  padding:11px 18px; border:none; border-radius:var(--btn-radius); cursor:pointer;
  background:linear-gradient(180deg,#0E6A55,#0B5C49); color:#fff; font:inherit; font-weight:600; line-height:1.2;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.12), 0 8px 18px -8px rgba(11,92,73,.5);
  transition:background .18s ease, box-shadow .18s ease, transform .06s ease;
}
.btn:active{transform:translateY(0)}
.btn.full{width:100%}
.btn.ghost{background:transparent; color:var(--brand-ink); border:1px solid var(--line); box-shadow:none}

/* Linha de checkbox/radio reutilizável */
.check-row{display:flex; align-items:center; gap:10px; cursor:pointer; font-weight:500; font-size:14px; margin:0}
.check-list{display:flex; flex-direction:column; gap:6px; margin-top:6px}

/* Filtros em linha */
.filters{display:grid; gap:12px; align-items:end; grid-template-columns:2fr 1fr 1fr 1fr auto}
.filters .field{margin:0}
.filters .field+.field{margin-top:0}
@media(max-width:900px){.filters{grid-template-columns:1fr 1fr}}

/* Tabela */
.lista{width:100%; border-collapse:collapse}
.lista th,.lista td{text-align:left; padding:12px 12px; border-bottom:1px solid var(--line); font-size:14px}
.lista th{color:var(--muted); font-weight:500; font-size:12px; text-transform:uppercase; letter-spacing:.03em}
.lista td.num{font-weight:600; color:var(--ink)}
.lista td.num,.lista th.num{text-align:right}

/* Folha de pessoas + toggles */
.pessoas-linha{display:grid; gap:10px; grid-template-columns:1fr 140px auto; align-items:center}
.pessoas-linha+.pessoas-linha{margin-top:8px}
/* Remover a linha. NÃO existia: a 3.ª coluna da grelha era um <span> vazio, reservado e
   nunca preenchido — uma pessoa acrescentada por engano ficava lá para sempre (só
   recarregando o formulário, e perdendo o resto do que já estava escrito). Fica oculto
   enquanto houver uma só linha: a folha nunca pode ficar sem nenhuma. */
.pessoa-remover{display:inline-flex; align-items:center; justify-content:center;
  width:44px; height:44px; padding:0; flex:none; font:inherit; font-size:20px; line-height:1;
  background:var(--card); color:var(--muted); border:1px solid var(--line);
  border-radius:var(--radius-sm); cursor:pointer}
/* `hidden` sozinho não bastava: a regra de autor acima vence o [hidden]{display:none} do browser. */
.pessoa-remover[hidden]{display:none}
/* No telemóvel o nome passa a ocupar a linha inteira. Com as 3 colunas lado a lado ele
   ficava com ~106px depois de o botão entrar na grelha — 10 caracteres, menos que um nome
   próprio. O valor e o remover ficam por baixo, e a moldura agrupa a pessoa. */
@media(max-width:520px){
  .pessoas-linha{grid-template-columns:1fr auto; gap:8px;
    padding:10px; border:1px solid var(--line); border-radius:var(--radius-sm)}
  .pessoas-linha>.pessoa-nome{grid-column:1/-1}
}
.modo-toggle{display:flex; gap:8px; flex-wrap:wrap}
.modo-toggle label{display:flex; align-items:center; gap:8px; flex:1; min-width:160px; margin:0; padding:12px; border:1px solid var(--line); border-radius:var(--radius-sm); cursor:pointer; font-weight:500}
/* Chip de obra no filtro do Painel. Estava como `style="flex:0 0 auto"` INLINE no template
   — e inline nenhuma media query alcança: o chip não encolhia e um nome de obra comprido
   ("Remodelação Av. da Liberdade 214, 3.º Esq.") empurrava o painel inteiro para fora do
   ecrã. Aqui em CSS, no telemóvel cada obra passa a ocupar a sua linha. */
.modo-toggle label.obra-chip{flex:0 1 auto; min-width:0; padding:8px 12px}
@media(max-width:720px){.modo-toggle label.obra-chip{flex:1 1 100%}}
.btn-row{display:flex; gap:8px}

/* Paginação */
.pager{display:flex; gap:10px; justify-content:center; align-items:center; margin-top:20px}
.empty{text-align:center; padding:40px 20px; color:var(--muted)}

/* Ações por linha: ícone, kebab (CSS-only via <details>) e modal (CSS-only via :target) */
.acoes{white-space:nowrap}
.icon-act{display:inline-flex; align-items:center; gap:4px; padding:4px 8px; border-radius:8px; color:var(--ink); font-size:16px; line-height:1; cursor:pointer; border:1px solid transparent; user-select:none}
.kebab{position:relative; display:inline-block}
.kebab>summary{list-style:none; display:inline-flex}
.kebab>summary::-webkit-details-marker{display:none}
.kebab-menu{position:absolute; right:0; top:calc(100% + 4px); z-index:30; min-width:190px; background:var(--card); border:1px solid var(--line); border-radius:10px; box-shadow:var(--shadow); padding:6px; display:flex; flex-direction:column; gap:2px; text-align:left}
.kebab-menu a, .kebab-menu button{display:block; width:100%; text-align:left; padding:9px 10px; border:none; background:none; border-radius:8px; font:inherit; font-size:14px; color:var(--ink); cursor:pointer; line-height:1.3}
.kebab-menu button.danger{color:var(--danger)}
.kebab-menu form{margin:0}
/* A caixa centra-se em --vv (altura REALMENTE visível) e não na viewport inteira. No iOS
   o teclado NÃO encolhe a viewport — tapa o ecrã por cima — por isso o modal continuava
   centrado nos 812px e o botão de guardar ficava 60px POR BAIXO do teclado (medido: caixa
   253→559, teclado a partir dos 476). A --vv vem da VisualViewport API, publicada pelo JS
   do base.html: é a única fonte que sabe quanto do ecrã sobra. Sem essa API o fallback
   100% dá exatamente o comportamento antigo, por isso isto nunca piora nada.
   O backdrop passa a fixed/inset:0 para continuar a escurecer o ecrã TODO, agora que o
   .modal só ocupa a parte visível.
   O max(…,240px) é defesa em profundidade: se a --vv alguma vez trouxer lixo (aconteceu —
   a API devolveu 0 no arranque e o modal colapsou para o padding), o modal continua
   utilizável em vez de desaparecer. Num ecrã a sério a --vv é sempre muito maior. */
.modal{display:none; position:fixed; top:0; left:0; right:0; height:max(var(--vv,100%),240px);
  z-index:100; align-items:center; justify-content:center; padding:20px}
.modal:target{display:flex}
.modal-backdrop{position:fixed; inset:0; background:rgba(20,32,27,.45)}
.modal-box{position:relative; z-index:1; background:var(--card); border-radius:14px; width:min(520px,100%); max-height:100%; overflow:auto; padding:22px; box-shadow:0 16px 48px rgba(20,32,27,.22)}
.modal-x{font-size:24px; line-height:1; color:var(--muted); padding:0 4px}

/* Polimento: gráfico de linhas (cap de altura) + colunas esparsas + estado vazio */
.chart-line{max-height:260px}
.rep-cols.poucos{justify-content:center; height:150px}
.rep-cols.poucos .rep-col{min-width:88px}
.rep-cols.poucos .rep-colbar{width:60px}
.empty p{margin:0}

/* Ativação do WhatsApp (prova de posse) — cartão do painel + bloco da Conta. */
.btn.small{padding:7px 14px; font-size:13px}
.wa-onboard{border:1px solid var(--brand-soft); background:linear-gradient(180deg,var(--brand-soft) 0%,var(--card) 55%)}
.wa-ativar .btn.full{max-width:340px}
.wa-manual{margin-top:12px; padding:10px 12px; border:1px dashed var(--line); border-radius:10px; background:var(--surface)}
.wa-codigo{display:inline-block; font-family:ui-monospace,SFMono-Regular,Menlo,monospace; font-size:15px;
  letter-spacing:1px; background:var(--card); border:1px solid var(--line); border-radius:8px; padding:6px 10px}
.convite-bloco{border:1px dashed var(--line); border-radius:10px; padding:10px 12px; background:var(--surface); max-width:560px}
.convite-texto{width:100%; margin-top:6px; font-size:13px; line-height:1.45; resize:vertical;
  border:1px solid var(--line); border-radius:8px; padding:8px 10px; background:var(--card); color:var(--ink)}
/* Ação secundária com cara de link (ex.: "Não quero usar WhatsApp") — não compete
   visualmente com o botão principal, mas continua a ser um submit real. */
.btn-link{background:none; border:0; padding:0; color:var(--muted); text-decoration:underline;
  cursor:pointer; font:inherit}
/* Par de CTAs no mesmo nível (WhatsApp × manual) — quebram para coluna no telemóvel. */
.cta-par{display:flex;flex-wrap:wrap;gap:10px}
.cta-par .btn{flex:0 1 auto}
@media (max-width:520px){.cta-par .btn{flex:1 1 100%}}

/* ---------------------------------------------------------------------------
   ESTADOS DE RATO. Ficam todos aqui, e não junto de cada regra, por uma razão de
   COMPORTAMENTO: no telemóvel (iOS e Android) o :hover COLA depois do toque — o botão
   fica aceso, e o .btn até sobe 1px, enquanto não se tocar noutro sítio. Parece encravado.
   `hover:hover` só casa em ponteiros que conseguem mesmo pairar, por isso ao dedo estes
   estados deixam de existir e ao rato nada muda.
   A ORDEM ABAIXO É A ORIGINAL e não pode ser trocada: .brand:hover, .sidebar .brand:hover
   e a.rep-row:hover existem para ANULAR o sublinhado que a:hover põe.
   --------------------------------------------------------------------------- */
@media(hover:hover){
  a:hover{text-decoration:underline}
  .brand:hover{text-decoration:none}
  .sidebar .brand:hover{text-decoration:none}
  .side-link:hover{background:var(--surface); text-decoration:none}
  .side-cta:hover{background:var(--brand-ink); color:#fff}
  a.rep-row:hover{text-decoration:none} a.rep-row:hover .rep-label{text-decoration:underline}
  .btn:hover{background:linear-gradient(180deg,#0B5C49,#073F33); box-shadow:inset 0 1px 0 rgba(255,255,255,.12), 0 10px 24px -8px rgba(11,92,73,.6); transform:translateY(-1px); text-decoration:none}
  .btn.ghost:hover{background:var(--surface); border-color:var(--brand-ink); transform:none; box-shadow:none}
  .lista tbody tr:hover{background:var(--surface)}
  .pessoa-remover:hover{background:var(--danger-soft); border-color:var(--danger); color:var(--danger)}
  .icon-act:hover{background:var(--surface); text-decoration:none}
  .kebab-menu a:hover, .kebab-menu button:hover{background:var(--surface); text-decoration:none}
  .modal-x:hover{color:var(--ink); text-decoration:none}
  .btn-link:hover{color:var(--brand-ink)}
}
