/* ============================================================
   Painel de Presença · Ala Agita Tom
   Identidade da marca (vermelho/amarelo/preto) + tema claro/escuro
   ============================================================ */
:root {
  color-scheme: light;
  /* Marca */
  --marca-vermelho: #7a0f12;
  --marca-vermelho-claro: #b3161b;
  --marca-amarelo: #f5b301;
  /* A MARCA DA MAD, que não é a da escola. As três acima são da Tom
     Maior; estas duas são de quem assina o rodapé. Separar evita o que
     acontecia até 28/08: o nome do fornecedor pintado com a cor do
     cliente. O tom claro é o marinho clareado, para o tema escuro. */
  --mad-marinho: #0d2542;
  --mad-marinho-claro: #9fb4d0;
  --marca-preto: #171614;

  /* Superficies / tinta (paleta dataviz - modo claro) */
  --plane: #f4f3ef;
  --surface: #ffffff;
  --surface-2: #faf9f6;
  --ink: #171614;
  --ink-2: #52514e;
  --muted: #898781;
  --grid: #e6e4dd;
  --border: rgba(11,11,11,0.10);

  /* Status (presença) */
  --p: #0ca30c;   /* Presente */
  --f: #d03b3b;   /* Falta    */
  --j: #f0a500;   /* Justificada */

  --radius: 14px;
  --shadow: 0 1px 3px rgba(0,0,0,.06), 0 6px 18px rgba(0,0,0,.05);
  --tap: 44px;
}
:root[data-theme="dark"] {
  color-scheme: dark;
  --plane: #0d0d0d;
  --surface: #1a1a19;
  --surface-2: #201f1d;
  --ink: #ffffff;
  --ink-2: #c3c2b7;
  --muted: #9a988f;
  --grid: #2c2c2a;
  --border: rgba(255,255,255,0.12);
  --p: #14b814;
  --f: #e05a5a;
  --j: #f0b52a;
  --shadow: 0 1px 3px rgba(0,0,0,.4), 0 6px 18px rgba(0,0,0,.35);
}

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  background: var(--plane);
  color: var(--ink);
  -webkit-text-size-adjust: 100%;
  padding-bottom: env(safe-area-inset-bottom);
}
h1,h2,h3 { margin: 0; }
code { background: var(--surface-2); padding: 1px 5px; border-radius: 5px; font-size: .9em; }
.hidden { display: none !important; }

/* ---------- Cabeçalho ---------- */
.app-header {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 14px; padding-top: calc(10px + env(safe-area-inset-top));
  background: linear-gradient(120deg, var(--marca-vermelho), var(--marca-vermelho-claro));
  color: #fff;
  box-shadow: var(--shadow);
  position: sticky; top: 0; z-index: 20;
  border-bottom: 3px solid var(--marca-amarelo);
}
.app-header .logo {
  width: 46px; height: 46px; border-radius: 50%; background: #fff;
  object-fit: cover; box-shadow: 0 0 0 2px var(--marca-amarelo);
  flex: 0 0 auto;
}
.titles h1 { font-size: 1.05rem; line-height: 1.1; letter-spacing: .3px; }
.titles p { margin: 2px 0 0; font-size: .72rem; opacity: .9; }
.header-right { margin-left: auto; display: flex; align-items: center; gap: 8px; }
.icon-btn {
  background: rgba(255,255,255,.15); color: #fff; border: 0; cursor: pointer;
  width: 38px; height: 38px; border-radius: 10px; font-size: 1.1rem;
}
.conn { font-size: 1.4rem; line-height: 1; }
.conn--on { color: #7CFC00; }
.conn--off { color: #ffd2d2; }
.login-btn { width: auto; padding: 0 14px; font-size: .82rem; font-weight: 600; }
.user-chip { display: inline-flex; align-items: center; gap: 6px; background: rgba(255,255,255,.15); color: #fff; border-radius: 10px; padding: 4px 6px 4px 12px; font-size: .82rem; font-weight: 600; max-width: 140px; }
.user-chip #usuarioNome { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.user-chip #btnLogout { background: rgba(0,0,0,.18); color: #fff; border: 0; width: 28px; height: 28px; border-radius: 8px; cursor: pointer; font-size: .9rem; flex: 0 0 auto; }

/* Etiqueta de posição no mapa */
.pos { display: inline-block; background: var(--marca-preto); color: #fff; font-size: .68rem; font-weight: 700; border-radius: 6px; padding: 1px 6px; margin-right: 6px; vertical-align: middle; font-variant-numeric: tabular-nums; }
:root[data-theme="dark"] .pos { background: var(--marca-amarelo); color: var(--marca-preto); }
.grade .td-nome .pos { margin-right: 4px; }
.inp-pos { max-width: 130px; }
.inp-cidade { max-width: 160px; }

/* "Componentes + Liderança" no cadastro de ala. Era "Mín.", e o David
   reparou que ninguém adivinha o que informar ali; depois ele próprio
   escolheu o texto. Cortá-lo em reticências devolveria o problema, e
   por isso a largura acompanha a frase, e não o contrário.

   DUAS ARMADILHAS, as duas pagas em build:

   1. 'max-width' não bastou. '.form-inline input' nasce com
      'flex: 1 1 140px' e o campo só cresce até onde sobra na linha —
      parou em 220px e cortou em "Lideranç". Quem manda no tamanho
      MÍNIMO é a base do flex, não o teto. Com base 240px o campo
      prefere quebrar para a linha de baixo a encolher.

   2. Escrever só '.inp-minimo { flex: ... }' não pegou: vale (0,1,0)
      contra o (0,1,1) de '.form-inline input' — classe mais elemento
      ganha de classe sozinha, e a declaração era descartada em
      silêncio. Daí o '.form-inline' na frente, que vale (0,2,0).

   E MORA AQUI EM CIMA, e não no fim do arquivo, de propósito: a regra
   que empilha o formulário no celular está no '@media (max-width:
   560px)', e media query NÃO soma especificidade. Empatados em
   (0,2,0), vence quem vem DEPOIS — com esta regra no fim do arquivo,
   ela venceria também no celular e o campo nunca empilharia. Era
   exatamente o que acontecia com o 'max-width' antes desta correção:
   no print do David, no celular, todos os campos ocupavam a linha
   inteira menos este. É a segunda vez que especificidade morde este
   arquivo; a primeira foi a corrente de ':not()' que achatava os
   campos dos componentes. */
.form-inline .inp-minimo { flex: 1 1 240px; max-width: 260px; }
/* "Ordem no desfile", ao lado do mínimo — mesma armadilha, mesma cura:
   o peso precisa ser (0,2,0) para vencer '.form-inline input'. */
.form-inline .inp-ordem { flex: 1 1 190px; max-width: 210px; }

/* ALMOXARIFADO — largura por IMPORTÂNCIA, nao por ordem de chegada.
   O padrao do '.form-inline' e 'flex: 1 1 140px' para todo input, e
   com isso a unidade ("un", tres letras) ficava do mesmo tamanho do
   nome do produto, e a quantidade maior que o seletor de produto. O
   olho procura o NOME; o resto e detalhe.

   Mora aqui em cima pelo mesmo motivo da '.inp-minimo': empatadas em
   (0,2,0), vence a ultima — e no fim do arquivo estas venceriam
   tambem o '@media' que empilha tudo no celular. */
.form-inline .inp-largo  { flex: 3 1 240px; }
.form-inline .inp-medio  { flex: 1 1 170px; }
.form-inline .inp-curto  { flex: 0 1 110px; max-width: 130px; }
.form-inline select.inp-largo { flex: 3 1 240px; min-width: 0; }
.form-inline select.inp-medio { flex: 1 1 160px; min-width: 0; }
/* Seletor de ordenação nas listas de ala. Não cresce: ele acompanha a
   busca, que é quem deve tomar a linha. */
.inp-ordenar { flex: 0 0 auto; max-width: 230px; }
/* Canto de ações do cabeçalho do cartão (filtro + botões).
   ANTES ERA UM <div> SEM LAYOUT NENHUM (achado no celular do David,
   11/08): com só botões dentro, o fluxo em linha resolvia sozinho; a
   Ajuda pôs um <select> junto, ele vira 100% de largura no celular e o
   botão caía na linha seguinte colado nele — encostando no anel de foco
   do select, que sangra 3px. Com flex e gap, os dois ficam lado a lado
   e o espaço é garantido, não acidental. */
.card-acoes { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
/* Número da ala na ordem do desfile. Só aparece quando é ele que manda
   na lista; por isso pode ser forte sem poluir o resto do tempo. */
.ord-desfile { display: inline-block; min-width: 26px; text-align: center;
  background: var(--marca-preto); color: #fff; font-size: .7rem; font-weight: 800;
  border-radius: 6px; padding: 1px 5px; vertical-align: middle;
  font-variant-numeric: tabular-nums; }
:root[data-theme="dark"] .ord-desfile { background: var(--marca-amarelo); color: var(--marca-preto); }
.cidade { color: var(--marca-vermelho); font-weight: 600; }
:root[data-theme="dark"] .cidade { color: var(--marca-amarelo); }
.local-sub { color: var(--muted); font-weight: 600; }
.tam { color: var(--muted); font-weight: 600; white-space: nowrap; }

/* ---------- Mapa da ala ---------- */
.resumo-mapa { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; margin-left: auto; }
.resumo-mapa .pill { font-size: .76rem; font-weight: 700; border-radius: 20px; padding: 5px 10px; color: #fff; }
.resumo-mapa .pill.p { background: var(--p); } .resumo-mapa .pill.j { background: var(--j); }
.resumo-mapa .pill.f { background: var(--f); } .resumo-mapa .pill.v { background: var(--grid); color: var(--ink-2); }

.mapa-formacao { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 16px; box-shadow: var(--shadow); }
.frente-label { text-align: center; font-size: .7rem; letter-spacing: .16em; text-transform: uppercase; color: var(--muted); margin-bottom: 10px; }
.linha-lider { display: flex; gap: 8px; justify-content: center; flex-wrap: wrap; margin: 8px 0; }
.campo-mapa { display: grid; grid-template-columns: auto 1fr auto; gap: 6px; align-items: start; margin: 10px 0; }
/* Com bloco que flanqueia, o campo tem CINCO colunas: os apoios
   por fora e a fila de guardiao colada na grade. */
/* (as filas que flanqueiam passaram a entrar DENTRO da grade) */
.lado-mapa { display: flex; flex-direction: column; gap: 6px; align-items: center; }
.lado-mapa > div { display: flex; flex-direction: column; gap: 6px; align-items: center; }
.lado-rot { writing-mode: vertical-rl; font-size: .54rem; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); }

.mlider { border-radius: 9px; padding: 5px 8px; text-align: center; color: #fff; font-size: .7rem; box-shadow: var(--shadow); cursor: pointer; min-width: 68px; }
.mlider b { display: block; font-size: .76rem; }
.mlider small { opacity: .9; font-size: .6rem; }
.mlider.st-P { background: var(--p); } .mlider.st-J { background: var(--j); } .mlider.st-F { background: var(--f); }
.mlider.vazio { background: var(--surface-2); color: var(--muted); cursor: default; box-shadow: none; border: 1px dashed var(--border); }
/* Laterais: nomes na vertical, ocupando pouca largura (cabe as 7 colunas no retrato) */
.lado-mapa .mlider { writing-mode: vertical-rl; text-orientation: mixed; min-width: 0; width: 30px; padding: 10px 5px; display: flex; align-items: center; justify-content: center; }
.lado-mapa .mlider b { font-size: .74rem; text-align: center; margin: 0; }
.lado-mapa .mlider small { display: none; }
.lado-mapa .mlider.vazio { writing-mode: horizontal-tb; width: 30px; padding: 8px 4px; }

.grade-mapa { overflow-x: auto; }
/* margin-inline auto centraliza a grade quando ela tem largura máxima
   (mapa por blocos, onde a coluna é limitada a 130px). No mapa antigo,
   que ocupa a largura inteira, não muda nada. */
.mapa-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 5px; min-width: 0; margin-inline: auto; }
.mpos { aspect-ratio: 1; border-radius: 50%; display: flex; flex-direction: column; align-items: center; justify-content: center;
  position: relative; gap: 1px; padding: 4px; box-sizing: border-box;
  font-weight: 700; font-size: .72rem; color: #fff; cursor: pointer; box-shadow: inset 0 0 0 2px rgba(255,255,255,.3); user-select: none; }
/* O NOME NA BOLINHA (28/09/2026). O número continua sendo o texto
   principal — é ele que casa com a chamada e com a folha impressa —, e
   o nome curto entra embaixo, menor. A reticência resolve o nome longo
   sem empurrar a bolinha: o nome completo está no 'title'. */
.mpos .mnum { line-height: 1; }
.mpos .mnome { max-width: 100%; font-size: .52rem; font-weight: 600; line-height: 1.05;
  letter-spacing: -.01em; opacity: .95; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mpos.vaga .mnome { display: none; }
.mpos.st-P { background: var(--p); } .mpos.st-J { background: var(--j); } .mpos.st-F { background: var(--f); }
.mpos.vaga { background: var(--grid); color: var(--muted); cursor: default; box-shadow: inset 0 0 0 1px var(--border); }
.mpos .mk { position: absolute; top: -3px; right: -3px; width: 14px; height: 14px; border-radius: 50%; background: var(--surface);
  color: var(--ink); font-size: .56rem; font-weight: 800; display: flex; align-items: center; justify-content: center; box-shadow: var(--shadow); }

/* ---------- Mapa por blocos ----------
   Cada bloco da ala é um cartão. Reaproveita .mapa-grid, .campo-mapa,
   .linha-lider e .lado-mapa de propósito: o desenho por blocos tinha
   que sair IDÊNTICO ao mapa que a coordenação já conhece — o que muda
   é de onde vêm as medidas, não a aparência. */
.mapa-blocos { display: flex; flex-direction: column; gap: 14px; }
.bloco-mapa {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 16px; box-shadow: var(--shadow);
}
.bloco-head { display: flex; align-items: center; gap: 7px; margin-bottom: 10px; flex-wrap: wrap; }
.bloco-head b { font-size: .95rem; }
.bloco-head small { color: var(--muted); font-size: .72rem; }
.bloco-head + .bloco-head { margin-top: -6px; }
.perim-lado { display: flex; align-items: center; gap: 10px; margin: 6px 0; }
.perim-lado .lado-rot { writing-mode: horizontal-tb; min-width: 96px; text-align: right; }
.perim-lado .linha-lider { flex: 1; justify-content: flex-start; margin: 0; }
/* Colorido por atributo: a cor do atributo entra por baixo e a marca
   de presença (✓ ! ✕) continua no canto — as duas leituras ao mesmo
   tempo, que é o ponto de colorir por naipe sem perder a chamada. */
.mpos.tem-cor { box-shadow: inset 0 0 0 2px rgba(255,255,255,.45); }
/* Fila lateral na tela: as bolinhas do bloco de guardiões empilhadas
   ao lado da grade, e não numa grade própria. */
/* Buraco na grade: lugar que nao existe naquela fileira (a fila que
   flanqueia e mais curta que a grade, ou vice-versa). Ocupa a celula
   para o alinhamento nao escorregar, e nao desenha nada. */
.mpos.fora { background: none; box-shadow: none; cursor: default; }
.legenda-atributo {
  display: flex; gap: 12px; flex-wrap: wrap; margin: 0 0 12px;
  font-size: .78rem; color: var(--ink-2);
}
.legenda-atributo span { display: flex; align-items: center; gap: 6px; }
.legenda-atributo i { width: 13px; height: 13px; border-radius: 50%; display: inline-block; }

.legenda-mapa { display: flex; gap: 14px; flex-wrap: wrap; justify-content: center; margin-top: 14px; font-size: .78rem; color: var(--ink-2); }
.legenda-mapa span { display: flex; align-items: center; gap: 6px; }
.legenda-mapa i { width: 13px; height: 13px; border-radius: 50%; display: inline-block; }
.legenda-mapa .bg-p { background: var(--p); } .legenda-mapa .bg-j { background: var(--j); }
.legenda-mapa .bg-f { background: var(--f); } .legenda-mapa .bg-v { background: var(--grid); }

/* ---------- Área de testes (admin) ---------- */
.card--teste { border: 1px solid var(--f); }
.acoes-teste { display: flex; gap: 8px; flex-wrap: wrap; }
.pos-local { background: var(--marca-vermelho); color: #fff; font-weight: 600; text-transform: none; letter-spacing: 0; }
:root[data-theme="dark"] .pos-local { background: var(--marca-vermelho-claro); color: #fff; }

/* ---------- Portão de acesso (login obrigatório) ---------- */
.gate { min-height: 62vh; display: flex; align-items: center; justify-content: center; padding: 30px 20px; }
.gate-box { text-align: center; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 30px 26px; box-shadow: var(--shadow); max-width: 360px; }
.gate-logo { width: 88px; height: 88px; border-radius: 50%; object-fit: cover; box-shadow: 0 0 0 3px var(--marca-amarelo); }
.gate-box h2 { margin: 16px 0 8px; font-size: 1.15rem; color: var(--marca-vermelho); }
:root[data-theme="dark"] .gate-box h2 { color: var(--marca-amarelo); }
.gate-box p { color: var(--ink-2); font-size: .9rem; margin-bottom: 18px; }
.gate-box .btn { width: 100%; }
/* Assinatura da marca no rodapé do gate: nome grande, descritor
   no mesmo compasso. Discreta, para não competir com o logo da
   escola, mas presente — é o "lar" do produto na tela de acesso. */
.gate-marca {
  margin: 22px 0 0; padding-top: 16px;
  border-top: 1px solid var(--border);
  font-size: .72rem; font-weight: 700;
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--marca-vermelho);
}
:root[data-theme="dark"] .gate-marca { color: var(--marca-amarelo); }
.form-login { display: flex; flex-direction: column; gap: 10px; }
.form-login input { width: 100%; text-align: center; font-size: 1rem; }
.form-login .pin-erro { margin: 0; }

/* Sugestão de nome no login: aparece só ao digitar, e só por início do nome.
   Substitui o <datalist>, que casava no meio da palavra e abria a lista
   inteira de usuários ao clicar na seta. */
.campo-sugestao { position: relative; }
.sugestoes {
  list-style: none; margin: 4px 0 0; padding: 4px; position: absolute; z-index: 30;
  left: 0; right: 0; text-align: left; background: var(--surface);
  border: 1px solid var(--border); border-radius: 10px; box-shadow: var(--shadow);
  max-height: 190px; overflow-y: auto;
}
.sugestoes li {
  padding: 9px 12px; border-radius: 7px; cursor: pointer; font-size: .95rem;
  display: flex; justify-content: space-between; align-items: center; gap: 10px;
}
.sugestoes li:hover, .sugestoes li.ativo { background: var(--surface-2); }
.sugestoes li b { font-weight: 600; }
.sugestoes li small { color: var(--muted); font-size: .75rem; white-space: nowrap; }
/* Quando ninguém está logado, esconde abas e conteúdo */
body.deslogado .barra-contexto, body.deslogado main { display: none; }
body:not(.deslogado) .gate { display: none; }

/* ---------- Abas ---------- */
.tabs {
  display: flex; gap: 2px; background: var(--surface); position: sticky; top: 66px;
  z-index: 15; box-shadow: var(--shadow); overflow-x: auto;
}
.tab {
  flex: 1 1 auto; min-width: 90px; border: 0; background: transparent; cursor: pointer;
  padding: 12px 8px; font-size: .82rem; color: var(--ink-2); white-space: nowrap;
  border-bottom: 3px solid transparent; font-weight: 600;
}
.tab.is-active { color: var(--marca-vermelho); border-bottom-color: var(--marca-amarelo); }
:root[data-theme="dark"] .tab.is-active { color: var(--marca-amarelo); }

/* ---------- Layout geral ---------- */
main { max-width: 1000px; margin: 0 auto; padding: 14px; }
.view { animation: fade .18s ease; }
@keyframes fade { from { opacity: 0; transform: translateY(4px);} to { opacity: 1; } }

.toolbar {
  display: flex; flex-wrap: wrap; gap: 10px; align-items: flex-end; margin-bottom: 14px;
}
.field { display: flex; flex-direction: column; gap: 4px; }
.field.grow { flex: 1 1 180px; }
.field--ensaio { flex: 1 1 210px; }
.field--ensaio select { width: 100%; }
/* FILTRO QUE NAO ENCOLHE. '.field' e flex-item sem base: a largura
   sai do CONTEUDO, e um <select> cujo texto mais longo e "Todas as
   areas" vira uma caixa de 60px quando a lista esta vazia — foi o que
   o David achou no almoxarifado novo, com zero produto cadastrado.
   Dar base e o mesmo remedio do '.field--ensaio', pela mesma razao. */
.field--filtro { flex: 1 1 180px; min-width: 0; }
.field--filtro select, .field--filtro input { width: 100%; min-width: 0; }
/* O filtro PRINCIPAL da barra — o que a pessoa usa primeiro e cujo
   conteudo e o mais longo. No almoxarifado e o produto: "Fita de cetim
   vermelha 50mm" nao cabe na mesma largura de "Todas as areas". */
.field--filtro.field--largo { flex: 2 1 260px; }
/* QUEBRA DE LINHA NO FLEX. Um item de base 100% empurra o resto para a
   linha seguinte — e o par De/Ate se le junto, nao separado pela
   dobra. Altura zero: ele nao ocupa espaco, so quebra. */
.quebra-linha { flex: 1 1 100%; height: 0; margin: 0; padding: 0; }
.field label { font-size: .7rem; color: var(--muted); font-weight: 600; text-transform: uppercase; letter-spacing: .4px; }
/* ============================================================
   TODO CAMPO TEM A MESMA ALTURA E A MESMA FONTE — corrigido 08/08/2026

   O SELETOR ANTIGO listava tipos: input[type="text"], "search", "date",
   "password". Parece completo e não é — **um <input> SEM atributo type
   não casa com [type="text"]**, embora se comporte como texto.

   Resultado medido a 390px, antes desta correção: o app tinha CINCO
   alturas de campo. 27 selects a 45px, 15 inputs a 44px e TREZE inputs
   a 21px com fonte de 13,3px — os que ficavam no padrão do navegador.
   Entre eles "Nome completo", "Posição" e "Cidade", no cadastro de
   integrantes, ao lado de "Nascimento" que estava certo. Foi assim que
   o David notou: dois campos vizinhos com alturas diferentes.

   Ficavam de fora: os ~20 inputs sem 'type', os 18 de 'number', os de
   'url' e 'email', e todos os textarea.

   A CORREÇÃO É EXPLÍCITA, e a primeira tentativa foi por exclusão:
   'input:not([type=checkbox]):not([type=radio])...'. Funcionou e criou
   um problema pior — **cada :not() SOMA especificidade**. Aquele
   seletor virava (0,7,1) e passava por cima de estilos legítimos de
   componente, como o do campo "Quem está retirando" no balcão, que
   encolheu de 15px para 12px sem ninguém pedir.

   Listar os tipos deixa todos os seletores em (0,1,1) — a mesma
   especificidade que um '.classe input' —, e aí quem manda é a ordem,
   que é o que se espera. Vale a lição que este projeto já registrou na
   migração 31: em regra que atravessa o sistema inteiro, EXPLÍCITO
   GANHA DE CURTO.

   'input:not([type])' é o pedaço que faltava no seletor antigo: pega o
   input SEM atributo type, que era a maioria dos quebrados.

   E A FONTE PRECISA SER 16px NO CELULAR: abaixo disso o Safari do
   iPhone DÁ ZOOM sozinho ao focar o campo, e a tela salta. 'font:
   inherit' herda os 16px do corpo — por isso vem antes de tudo.
   ============================================================ */
input:not([type]),
input[type="text"], input[type="search"], input[type="date"], input[type="password"],
input[type="number"], input[type="email"], input[type="url"], input[type="tel"],
select, textarea, .form-inline input, .form-inline select {
  font: inherit; padding: 10px 12px; border-radius: 10px; border: 1px solid var(--border);
  background: var(--surface); color: var(--ink); min-height: var(--tap);
  /* 'line-height' explícito: sem ele o <select> fica 1px mais alto que
     o <input>, porque a caixa de linha dele acomoda a seta. Um pixel
     não se vê sozinho — mas neste app select e input ficam LADO A LADO
     (Função ao lado de Bloco, Posição ao lado de Cidade), e aí a linha
     de baixo desencontra. */
  line-height: 1.25;
}
/* O textarea cresce pelas linhas ('rows'); o min-height acima é só o
   piso, e a barra de redimensionar fica só na vertical — na horizontal
   ela estoura o cartão no celular. */
textarea { resize: vertical; }
/* Textarea dentro de '.field' ocupa a largura do campo. Sem isto ela
   fica com a largura PADRÃO do elemento — cerca de 20 colunas —, e o
   'align-items: stretch' do flex não a alcança quando há um <label>
   acima definindo a linha. Estava resolvido por regra própria em
   '.form-recado' e em '.form-acervo'; era a terceira cópia esperando
   para nascer. */
.field textarea { width: 100%; }

/* O <select> é sempre de UMA linha, então pode ter altura fixa. Sem
   isto ele fica 1px mais alto que o <input> ao lado, porque o navegador
   reserva espaço para a seta dentro da caixa de linha. */
select { height: var(--tap); }
input:focus, select:focus { outline: 2px solid var(--marca-amarelo); outline-offset: 1px; }

.btn {
  font: inherit; font-weight: 600; cursor: pointer; border: 0; border-radius: 10px;
  padding: 10px 16px; min-height: var(--tap);
  background: var(--marca-vermelho); color: #fff;
}
.btn:active { transform: translateY(1px); }
.btn--ghost { background: var(--surface); color: var(--ink); border: 1px solid var(--border); }
.btn--danger { background: var(--f); color: #fff; border: none; }
.btn--danger:hover { filter: brightness(.94); }

.aviso {
  background: #fff3cd; color: #664d03; border: 1px solid #ffe69c;
  padding: 12px 14px; border-radius: var(--radius); margin-bottom: 14px; font-size: .9rem;
  display: flex; flex-direction: column; gap: 3px;
}

.card {
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
  padding: 16px; box-shadow: var(--shadow); margin-bottom: 14px;
  min-width: 0; /* permite encolher em grids (evita overflow horizontal da página) */
}
/* Contêineres que devem poder encolher (o conteúdo rola dentro deles) */
.kpi, .chart, .tabela-wrap { min-width: 0; }
.card h3 { font-size: .98rem; margin-bottom: 12px; }
.card h3 small { font-weight: 400; color: var(--muted); font-size: .78rem; }
.dica { font-size: .82rem; color: var(--ink-2); margin: 4px 0 12px; }
.lg { display: inline-block; min-width: 20px; text-align: center; border-radius: 5px; padding: 0 5px; color: #fff; font-weight: 700; }
.lg--p { background: var(--p); } .lg--j { background: var(--j); } .lg--f { background: var(--muted); }

/* ---------- Chamada ---------- */
.resumo-chamada { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; margin-bottom: 12px; }
.chip {
  background: var(--surface); border: 1px solid var(--border); border-radius: 12px;
  padding: 10px 6px; text-align: center; box-shadow: var(--shadow);
}
.chip b { display: block; font-size: 1.3rem; line-height: 1; }
.chip span { font-size: .66rem; color: var(--muted); text-transform: uppercase; letter-spacing: .3px; }
.chip--p b { color: var(--p); } .chip--j b { color: var(--j); } .chip--f b { color: var(--f); }
.chip--total b { color: var(--marca-vermelho); }
:root[data-theme="dark"] .chip--total b { color: var(--marca-amarelo); }

.acoes-rapidas { display: flex; gap: 8px; margin-bottom: 12px; flex-wrap: wrap; }
.acoes-rapidas .btn { flex: 1 1 auto; font-size: .85rem; }

.lista-chamada { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.item {
  display: flex; align-items: center; gap: 10px; background: var(--surface);
  border: 1px solid var(--border); border-radius: 12px; padding: 8px 10px; box-shadow: var(--shadow);
}
.item .nome { flex: 1 1 auto; min-width: 0; }
.item .nome b { display: block; font-size: .95rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.item .nome small { color: var(--muted); font-size: .72rem; }
.item.st-P { border-left: 5px solid var(--p); }
.item.st-J { border-left: 5px solid var(--j); }
.item.st-F { border-left: 5px solid transparent; }
.seg { display: flex; gap: 4px; flex: 0 0 auto; }
.seg button {
  min-width: 46px; min-height: 40px; border-radius: 9px; border: 1px solid var(--border);
  background: var(--surface-2); color: var(--ink-2); font-weight: 700; cursor: pointer; font-size: .9rem;
}
.seg button.on-P { background: var(--p); color: #fff; border-color: var(--p); }
.seg button.on-J { background: var(--j); color: #fff; border-color: var(--j); }
.seg button.on-F { background: var(--f); color: #fff; border-color: var(--f); }

/* ---------- KPIs ---------- */
.kpis { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 10px; margin-bottom: 14px; }
.kpi { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 14px; box-shadow: var(--shadow); }
.kpi .valor { font-size: 1.9rem; font-weight: 700; line-height: 1; }
.kpi .rotulo { font-size: .74rem; color: var(--muted); margin-top: 6px; text-transform: uppercase; letter-spacing: .3px; }
.kpi .sub { font-size: .75rem; color: var(--ink-2); margin-top: 4px; }

.cards-relatorio { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; }
.card--wide { grid-column: 1 / -1; }
.chart { width: 100%; overflow-x: auto; }

/* ---------- Barras (charts) ---------- */
.bar-row { display: grid; grid-template-columns: 130px 1fr auto; align-items: center; gap: 10px; margin: 7px 0; }
.bar-row .lbl { font-size: .82rem; color: var(--ink-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bar-track { background: var(--grid); border-radius: 6px; height: 22px; position: relative; overflow: hidden; }
.bar-fill { height: 100%; border-radius: 6px; min-width: 2px; transition: width .3s ease; }
.bar-row .val { font-size: .82rem; font-weight: 700; font-variant-numeric: tabular-nums; min-width: 46px; text-align: right; }

/* Mini colunas por ensaio */
.cols { display: flex; align-items: flex-end; gap: 6px; height: 180px; padding-top: 10px; min-width: max-content; }
.col { display: flex; flex-direction: column; align-items: center; gap: 4px; width: 34px; }
.col .colbar { width: 26px; background: var(--marca-vermelho); border-radius: 5px 5px 0 0; min-height: 2px; position: relative; }
:root[data-theme="dark"] .col .colbar { background: var(--marca-vermelho-claro); }
.col .colbar.tipo-Rua { background: #1baf7a; }
.col .colbar.tipo-Tecnico { background: #eda100; }
.col .colbar.tipo-Desfile { background: #4a3aa7; }
.col .colnum { font-size: .68rem; color: var(--ink-2); font-variant-numeric: tabular-nums; }
.col .coldata { font-size: .6rem; color: var(--muted); text-align: center; line-height: 1.1; }
.legenda { display: flex; gap: 14px; flex-wrap: wrap; font-size: .74rem; color: var(--ink-2); margin-top: 10px; }
.legenda i { display: inline-block; width: 11px; height: 11px; border-radius: 3px; margin-right: 4px; vertical-align: middle; }

/* ---------- Tabelas ---------- */
.tabela-wrap { overflow-x: auto; }
table { border-collapse: collapse; width: 100%; font-size: .85rem; }
th, td { padding: 8px 10px; text-align: left; border-bottom: 1px solid var(--grid); white-space: nowrap; }
th { color: var(--muted); font-size: .72rem; text-transform: uppercase; letter-spacing: .3px; position: sticky; top: 0; background: var(--surface); }
td.num, th.num { text-align: right; font-variant-numeric: tabular-nums; }
.pct-badge { display: inline-block; padding: 2px 8px; border-radius: 20px; font-weight: 700; font-size: .8rem; color: #fff; }
/* CHAMADA DE UM DIA (28/09). A pastilha é a mesma do Ranking — só as
   três cores de situação são novas, e vêm das variáveis que a chamada
   já usa, para a folha do dia e a tela falarem a mesma língua. */
.cd-P { background: var(--p); }
.cd-J { background: var(--j); }
.cd-F { background: var(--f); }
.cd-ala { margin: 18px 0 6px; font-size: .95rem; color: var(--marca-vermelho); }
/* FAIXA DO SETOR no catálogo de fantasias (03/10/2026) — a mesma
   hierarquia visual do seletor de ala e da relação de acessos: setor,
   depois ala. */
.cd-setor {
  margin: 22px 0 8px; padding: 5px 10px; border-radius: 6px;
  background: var(--marca-vermelho); color: #fff;
  font-size: .78rem; font-weight: 800; text-transform: uppercase; letter-spacing: .6px;
}
.cd-setor:first-child { margin-top: 0; }
.cd-ala:first-child { margin-top: 0; }
.cd-ala small { color: var(--muted); font-weight: 500; margin-left: 6px; }
tr:hover td { background: var(--surface-2); }
.rank-controls { display: flex; gap: 12px; flex-wrap: wrap; align-items: center; margin-bottom: 10px; }
.switch-inline { font-size: .8rem; color: var(--ink-2); display: flex; align-items: center; gap: 6px; }
/* O PCD divide a linha do cadastro com campos de 44px; sem altura
   mínima ele cola na borda de baixo (a barra alinha por 'flex-end') e
   parece deslocado do resto da linha. */
#novoPcdCampo { min-height: var(--tap); white-space: nowrap; padding-inline: 2px; }
.mini-btn { border: 1px solid var(--border); background: var(--surface-2); color: var(--ink-2); border-radius: 8px; padding: 5px 9px; cursor: pointer; font-size: .78rem; }
.mini-btn.danger { color: var(--f); }

/* ---------- Grade ---------- */
.grade-wrap { overflow: auto; max-height: 72vh; border: 1px solid var(--border); border-radius: var(--radius); }
.grade { border-collapse: separate; border-spacing: 0; font-size: .78rem; }
.grade th, .grade td { border-bottom: 1px solid var(--grid); border-right: 1px solid var(--grid); padding: 6px 8px; text-align: center; }
.grade thead th { position: sticky; top: 0; z-index: 3; background: var(--surface); font-size: .66rem; }
.grade .th-nome, .grade .td-nome { position: sticky; left: 0; z-index: 2; background: var(--surface); text-align: left; min-width: 150px; max-width: 180px; overflow: hidden; text-overflow: ellipsis; }
.grade thead .th-nome { z-index: 4; }
.grade .cell { cursor: pointer; font-weight: 700; user-select: none; }
.grade .cell.st-P { background: rgba(12,163,12,.18); color: var(--p); }
.grade .cell.st-J { background: rgba(240,165,0,.20); color: var(--j); }
.grade .cell.st-F { color: var(--muted); }
.grade .th-data small { display: block; font-weight: 400; color: var(--muted); }

/* ---------- Gerenciar ---------- */
.grid-2 { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 14px; }
.form-inline { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 12px; }
.form-inline input { flex: 1 1 140px; }
.mapa { width: 100%; border-radius: 10px; border: 1px solid var(--border); }

/* ---------- Modal ---------- */
.modal { position: fixed; inset: 0; background: rgba(0,0,0,.5); display: flex; align-items: center; justify-content: center; z-index: 100; padding: 20px; }
.modal-box { background: var(--surface); border-radius: var(--radius); padding: 22px; max-width: 340px; width: 100%; text-align: center; box-shadow: var(--shadow); }
.modal-logo { width: 60px; height: 60px; border-radius: 50%; box-shadow: 0 0 0 2px var(--marca-amarelo); margin-bottom: 8px; }
.modal-box h3 { margin-bottom: 6px; }
.modal-box p { font-size: .85rem; color: var(--ink-2); margin: 6px 0 12px; }
.modal-box input { width: 100%; text-align: center; font-size: 1.1rem; letter-spacing: 3px; margin-bottom: 10px; }
/* "O que falta" no relatório impresso de menores: nomes de documento
   são longos e são vários, então esta coluna quebra em linha e vai
   menor. Sem isso, uma pessoa faltando cinco papéis empurraria a
   tabela para fora da folha. */
.pt-falta { font-size: .82em; line-height: 1.25; }

/* Aviso do recorte na convocação: diz o que a lista está mostrando e
   oferece a troca. Discreto de propósito — é orientação, não alerta. */
.conv-recorte {
  margin: 6px 0 8px; font-size: .82rem; color: var(--ink-2);
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
}

/* Tarja da chamada encerrada. Fica ACIMA do resumo, no caminho do
   olho: quem abre a Chamada de um evento antigo precisa entender a
   trava antes de tocar num nome, não depois do erro. */
.trava-chamada {
  display: flex; align-items: center; gap: 6px 14px; flex-wrap: wrap;
  margin: 10px 0; padding: 10px 14px; border-radius: var(--radius);
  background: color-mix(in srgb, var(--f) 10%, var(--surface));
  border: 1px solid color-mix(in srgb, var(--f) 35%, transparent);
}
.trava-chamada b { font-size: .92rem; }
.trava-chamada span { font-size: .82rem; color: var(--ink-2); flex: 1 1 240px; }
.trava-chamada .btn { flex: 0 0 auto; }
/* Liberada: mesma tarja, outro recado. Some sozinha quando os 30
   minutos acabam e a tela é repintada. */
.trava-chamada.liberada {
  background: color-mix(in srgb, var(--p) 10%, var(--surface));
  border-color: color-mix(in srgb, var(--p) 35%, transparent);
}

.modal-acoes { display: flex; gap: 8px; }
.modal-acoes .btn { flex: 1; }
/* Caixa de "tem certeza?". Um pouco mais larga que o padrão porque
   alguns avisos têm duas frases — e frase de aviso cortada em quatro
   linhas estreitas é frase que ninguém lê. */
.modal-confirma { max-width: 400px; }
.modal-confirma h3 { margin-bottom: 2px; }
#cfTexto { font-size: .92rem; color: var(--ink); margin: 8px 0 4px; }
/* O detalhe é a segunda parte do aviso — o que se perde, quem fica sem
   lugar, quantas fotos somem. Alinhado à esquerda e com quebra de linha
   preservada: a entrega em lote lista nome por nome, e a lista rola em
   vez de empurrar os botões para fora da tela. */
.cf-detalhe { white-space: pre-line; text-align: left; margin: 0 0 12px;
  max-height: 38vh; overflow-y: auto; }

/* Modal-formulário (edição de integrante): campos à esquerda, largura maior */
.modal-form { max-width: 420px; text-align: left; }
.modal-form h3 { text-align: center; margin-bottom: 14px; }
.ed-label { display: block; font-size: .78rem; font-weight: 600; color: var(--ink-2); margin-bottom: 10px; }
/* 1rem e não .95rem: abaixo de 16px o Safari do iPhone dá zoom sozinho
   ao focar o campo e a tela salta. O rótulo continua menor — quem
   precisa de 16px é a CAIXA DE DIGITAR, não a etiqueta dela. */
.ed-label input, .ed-label select { width: 100%; text-align: left; letter-spacing: normal; font-size: 1rem; margin-top: 4px; }
.modal-form .switch-inline { display: flex; align-items: center; gap: 8px; font-size: .85rem; margin: 4px 0 8px; }
.modal-form .switch-inline small { color: var(--muted); }
.modal-form .dica { margin: 0 0 8px; font-size: .78rem; }
tr.lider-inativo td { opacity: .55; }
.ed-dois { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.modal-form .pin-erro { margin: 2px 0 10px; }

/* Tabela de integrantes: posição abaixo do nome + colunas cidade/fantasia */
.tab-integrantes td { vertical-align: middle; }
.cel-nome b { font-weight: 600; display: block; line-height: 1.2; }
.sub-pos { display: block; font-size: .68rem; color: var(--muted); margin-top: 2px; font-weight: 500; }
.sub-pos.vazio { color: var(--j); font-style: italic; }
.tab-integrantes .na { color: var(--muted); }
.tab-integrantes .na.pend { color: var(--j); font-style: italic; }
.pin-erro { color: var(--f); font-weight: 600; }

/* ---------- Toast ---------- */
.toast {
  position: fixed; left: 50%; bottom: 76px; transform: translateX(-50%);
  background: var(--marca-preto); color: #fff; padding: 12px 18px; border-radius: 30px;
  font-size: .88rem; box-shadow: var(--shadow); z-index: 90; max-width: 90%;
}

/* ---------- Rodapé ---------- */
.app-footer { text-align: center; padding: 18px; color: var(--muted); font-size: .74rem; display: flex; flex-direction: column; gap: 4px; }
/* O crédito da MAD leva o monograma desde 28/08/2026. É uma linha só,
   centrada: 'inline-flex' com gap, para o ícone e o texto andarem
   juntos em vez de o ícone virar um bloco por cima. */
.app-footer .credito { font-size: .72rem; display: inline-flex; align-items: center; justify-content: center; gap: 6px; }
/* A cor é a da MAD, e não a da escola — ver as variáveis lá em cima.
   No escuro vai o marinho CLAREADO, e não branco: branco deixaria o
   crédito mais forte que a linha do cliente logo acima, que é a que
   importa no dia a dia. Aqui a marca assina, não anuncia. */
.app-footer .credito b { color: var(--mad-marinho); }
:root[data-theme="dark"] .app-footer .credito b { color: var(--mad-marinho-claro); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .app-footer .credito b { color: var(--mad-marinho-claro); }
}

/* 16px, e não os 20px do papel: na tela isto fica acima da dobra do
   PWA no celular, e o texto ao lado já diz o nome por extenso — a
   marca aqui é assinatura, não identificação. */
.app-footer .cred-marca { height: 16px; width: auto; flex: none; }

/* Tema escuro: a versão negativa. 'brightness(0)' leva tudo que é
   opaco a preto e 'invert(1)' o devolve branco, preservando o alfa das
   bordas — o mesmo arquivo serve aos dois temas. */
:root[data-theme="dark"] .app-footer .cred-marca { filter: brightness(0) invert(1); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .app-footer .cred-marca { filter: brightness(0) invert(1); }
}

/* ---------- Responsivo ---------- */
@media (max-width: 720px) {
  .cards-relatorio { grid-template-columns: minmax(0, 1fr); }
  .grid-2 { grid-template-columns: minmax(0, 1fr); }
  .bar-row { grid-template-columns: 96px 1fr auto; }
  .titles p { display: none; }
}

/* Otimização para celular: evita quebras, filtros e formulários se ajustam */
@media (max-width: 560px) {
  main { padding: 12px 10px; }
  .app-header { gap: 10px; padding-left: 12px; padding-right: 12px; }
  .app-header .logo { width: 40px; height: 40px; }
  .titles h1 { font-size: .98rem; }
  .icon-btn { width: 34px; height: 34px; }
  .login-btn { padding: 0 12px; }

  /* Abas: cabem melhor e continuam roláveis */
  .tab { min-width: auto; flex: 0 0 auto; padding: 11px 12px; font-size: .8rem; }

  /* Barras de filtros: grid de 2 colunas que encolhem (sem overflow) */
  .toolbar { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 8px; align-items: end; }
  .toolbar .field { min-width: 0; }
  .toolbar .field.grow, .toolbar .field--ensaio { grid-column: 1 / -1; }
  .toolbar > .btn { grid-column: 1 / -1; width: 100%; }
  .toolbar .field select, .toolbar .field input { width: 100%; min-width: 0; }

  /* FORMULÁRIO DE ESCREVER NÃO É BARRA DE FILTRO.
     A grade de duas colunas serve a filtro, onde os campos são curtos e
     se leem em par. No chamado de ajuda o usuário ESTÁ ESCREVENDO, e o
     "Tipo" caía sozinho em meia coluna: o rótulo da opção saía cortado
     em "Erro — algo não funci" (celular do David, 11/08), com a outra
     metade da linha vazia. Uma coluna só, e cada campo inteiro.
     Mesmo peso de '.toolbar .field' (0,2,0) — precisa vir DEPOIS. */
  .form-chamado .field { grid-column: 1 / -1; }

  /* No celular o filtro e o botão dividem a linha em vez de empilhar. */
  .card-acoes { width: 100%; }
  .card-acoes .inp-ordenar { flex: 1 1 150px; max-width: none; width: auto; }
  .card-acoes .btn { flex: 0 0 auto; }

  /* Formulários de cadastro empilham limpo */
  .form-inline { gap: 8px; }
  .form-inline input, .form-inline select, .form-inline .btn { flex: 1 1 100%; width: 100%; }
  /* Precisa repetir '.form-inline' e o 'max-width': o campo do mínimo
     é (0,2,0) lá em cima, e a linha de baixo, com (0,1,0), perderia
     por especificidade mesmo vindo depois. */
  .form-inline .inp-minimo { flex: 1 1 100%; max-width: none; }
  .form-inline .inp-ordem { flex: 1 1 100%; max-width: none; }
  .inp-ordenar { flex: 1 1 100%; max-width: none; width: 100%; }
  .inp-pos, .inp-cidade { max-width: none; }
  .switch-inline { flex: 1 1 100%; }

  .card { padding: 14px 12px; }
  .kpi .valor { font-size: 1.6rem; }
  .acoes-teste .btn { flex: 1 1 100%; }
}
@media (max-width: 380px) {
  .resumo-chamada { grid-template-columns: repeat(2, 1fr); }
  .kpis { grid-template-columns: 1fr 1fr; }
}

/* ============================================================
   MAPA DE FORMAÇÃO PARA IMPRESSÃO (marca MAD) — só na impressão
   ============================================================ */
.btn-print { background: var(--marca-preto); color: #fff; border: none; white-space: nowrap; }
:root[data-theme="dark"] .btn-print { background: var(--marca-amarelo); color: var(--marca-preto); }
#mapaPrint { display: none; }

#mapaPrint { color: #1a1a1a; font-family: inherit; background: #fff; padding: 4mm 2mm; }
#mapaPrint .pf-head { display: flex; align-items: center; gap: 12px; border-bottom: 3px solid #7a0f12; padding-bottom: 7px; }
#mapaPrint .pf-logo { width: 54px; height: 54px; border-radius: 50%; object-fit: cover; flex: 0 0 auto; }
#mapaPrint .pf-tit h1 { color: #7a0f12; font-size: 21px; margin: 0; letter-spacing: .5px; line-height: 1.1; }
#mapaPrint .pf-tit p { margin: 3px 0 0; color: #666; font-size: 11px; }
#mapaPrint .pf-frente { text-align: center; font-weight: 800; color: #1a1a1a; background: #f5b301; border-radius: 6px; padding: 3px 0; margin: 8px auto 6px; width: 55%; font-size: 11px; letter-spacing: 3px; }
#mapaPrint .pf-coord, #mapaPrint .pf-fundos { display: flex; justify-content: center; align-items: center; gap: 8px; margin: 3px 0; }
#mapaPrint .pf-pos-rot { font-size: 9px; font-weight: 800; color: #7a0f12; text-transform: uppercase; letter-spacing: .5px; }
#mapaPrint .pf-corpo { display: grid; grid-template-columns: 96px 1fr 96px; gap: 8px; align-items: start; margin: 4px 0; }
/* Com bloco que flanqueia sao CINCO colunas: apoios, fila de guardiao,
   grade, fila de guardiao, apoios. A fila em coluna propria e o que
   impede o mapa de virar a pagina. */
/* As colunas de guardiao entram DENTRO da grade, e TODAS as colunas
   tem a mesma largura (David, 20/08). Por isso o corpo voltou a ter
   tres colunas e nao ha mais estilo proprio de flanco. */
#mapaPrint .pf-lado { display: flex; flex-direction: column; gap: 7px; align-items: center; padding-top: 26px; }

#mapaPrint .pf-lado-rot { font-weight: 800; color: #7a0f12; font-size: 10px; text-transform: uppercase; letter-spacing: .5px; text-align: center; }
#mapaPrint .pf-lider { border: 1.5px solid #7a0f12; border-radius: 7px; padding: 4px 8px; text-align: center; min-width: 84px; background: #fff; }
#mapaPrint .pf-lider b { display: block; font-size: 12px; color: #1a1a1a; }
#mapaPrint .pf-lider small { color: #777; font-size: 9px; }
/* Os titulos dos blocos ficam na MESMA linha, separados por barra.
   Eram tres divs empilhados e custavam altura numa folha que fecha
   no limite. Nunca tiveram estilo proprio: como <div> herdavam o
   bloco por acidente. */
#mapaPrint .pf-bloco-tit { font-size: 11px; color: #555; }
#mapaPrint .pf-bloco-tit + .pf-bloco-tit::before { content: ' | '; color: #bbb; }
#mapaPrint .pf-grade { display: flex; flex-direction: column; gap: 4px; }
/* As colunas vêm INLINE, do bloco (ver desenharGrade). O 'repeat(7)'
   aqui é só o padrão de quem não recebeu estilo — cravá-lo quebrava a
   fileira de 8 dos estandartes da Dá o Tom em 7 + 1. */
#mapaPrint .pf-linha { display: grid; grid-template-columns: 22px repeat(7, minmax(0, 1fr)); gap: 4px; }
#mapaPrint .pf-rot { font-size: 9px; color: #999; font-weight: 700; align-self: center; text-align: right; }
/* A altura da célula acompanha o tamanho da formação: o JS escreve
   --pf-cel-h no container (21, 25 ou 32px) para o mapa caber em UMA
   página, que é como a escola usa a folha. */
#mapaPrint .pf-cel { border-radius: 6px; padding: 2px 2px; min-height: var(--pf-cel-h, 32px); display: flex; flex-direction: column; align-items: center; justify-content: center; border: 1px solid rgba(0,0,0,.1); overflow: hidden; }
#mapaPrint .pf-num { font-weight: 800; font-size: 11px; font-variant-numeric: tabular-nums; line-height: 1; }
#mapaPrint .pf-nome { font-size: 8.5px; line-height: 1.1; margin-top: 1px; text-align: center; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* O box-shadow interno repete a cor de fundo: navegadores mobile costumam
   imprimir com "gráficos de plano de fundo" desligado, e nesse modo o
   background some mas a sombra continua sendo desenhada. */
#mapaPrint .cor-r { background: #7a0f12; box-shadow: inset 0 0 0 100px #7a0f12; color: #fff; border-color: #5e0b0e; }
#mapaPrint .cor-r .pf-nome { color: #ffe6c2; }
#mapaPrint .cor-a { background: #f5b301; box-shadow: inset 0 0 0 100px #f5b301; color: #3a2a00; border-color: #d69a00; }
#mapaPrint .cor-a .pf-nome { color: #4a3600; }
#mapaPrint .cor-b { background: #fff; color: #1a1a1a; border-color: #b9b9b9; }
/* Guardião e estandarte: DOURADO (David, 20/08/2026), e ganha da
   moldura vermelha. O tom é o #c79a2e da cor do bloco, e NÃO o #f5b301
   do miolo — os dois são amarelos e ficam vizinhos na folha. O que os
   separa não é só o tom: o guardião leva texto BRANCO e borda escura de
   2px; o miolo leva texto escuro sobre amarelo vivo. Com o fundo
   desligado na impressão, a borda continua distinguindo. Nas Baianas ele ocupa
   as colunas das pontas, que a moldura pintaria igual a uma baiana de
   ponta; na Dá o Tom são os estandartes da 1ª fileira. */
#mapaPrint .cor-g { background: #c79a2e; box-shadow: inset 0 0 0 100px #c79a2e; color: #fff; border-color: #7a5c10; border-width: 2px; }
#mapaPrint .cor-g .pf-num { color: #fff; }
#mapaPrint .cor-g .pf-nome { color: #fff4d8; }
/* Vagas mantêm a cor do padrão; só uma borda tracejada + "livre" discreto */
#mapaPrint .pf-cel.vaga { border-style: dashed; }
#mapaPrint .pf-cel.vaga .pf-nome { opacity: .72; font-style: italic; }
/* RODAPÉ CENTRALIZADO, como o da tela (David, 28/08/2026).

   Era 'space-between': o crédito colava na margem esquerda e a data na
   direita. Numa folha larga os dois ficavam tão longe um do outro que
   não se liam como um rodapé só.

   CENTRALIZA A LINHA INTEIRA, e não empilha. Empilhar somaria altura a
   uma folha que já fecha no limite — o mapa da Dá o Tom tem 14 fileiras
   e o das Baianas 12, e foi preciso trabalho para caberem em uma
   página. O 'gap' é o que separa o crédito da data. */
#mapaPrint .pf-foot { display: flex; justify-content: center; align-items: center; gap: 18px; text-align: center; border-top: 2px solid #7a0f12; margin-top: 9px; padding-top: 6px; font-size: 9px; color: #555; }
#mapaPrint .pf-mad { display: flex; align-items: center; gap: 6px; }
#mapaPrint .pf-mad img { height: 20px; width: auto; border-radius: 3px; }

/* Cabeçalho do card com botão de impressão à direita */
.card-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; margin-bottom: 8px; }
.card-head h3 { margin: 0; }

/* ===== Modo Desenvolvedor (MAD) ===== */
.tab[data-view="dev"] { color: var(--marca-amarelo); }
.dev-hero { border-left: 4px solid var(--marca-amarelo); }
.dev-hero h3 span { color: var(--marca-vermelho); }
.dev-info { margin-top: 6px; }
.di-row { display: flex; justify-content: space-between; gap: 12px; align-items: baseline; padding: 6px 0; border-bottom: 1px dashed var(--border); font-size: .9rem; }
.di-row:last-child { border-bottom: none; }
.di-row > span { color: var(--muted); }
.di-row > b { text-align: right; word-break: break-word; }
.card-danger { border: 1px solid var(--f); }
.card-danger h3 { color: var(--f); }

/* ============================================================
   Sistema de impressão de DOCUMENTOS (mesmo padrão do mapa):
   cabeçalho com logo da ala + rodapé assinado pela MAD.
   ============================================================ */
.print-doc { display: none; color: #1a1a1a; background: #fff; font-family: inherit; }
.print-doc .ph-head { display: flex; align-items: center; gap: 12px; border-bottom: 3px solid #7a0f12; padding-bottom: 7px; }
.print-doc .ph-logo { width: 54px; height: 54px; border-radius: 50%; object-fit: cover; flex: 0 0 auto; }
.print-doc .ph-tit h1 { color: #7a0f12; font-size: 19px; margin: 0; letter-spacing: .4px; line-height: 1.1; }
.print-doc .ph-tit p { margin: 3px 0 0; color: #666; font-size: 11px; }
.print-doc .ph-foot { display: flex; justify-content: center; align-items: center; gap: 18px; text-align: center; border-top: 2px solid #7a0f12; margin-top: 10px; padding-top: 6px; font-size: 9px; color: #555; }
.print-doc .ph-mad { display: flex; align-items: center; gap: 6px; }
.print-doc .ph-mad img { height: 20px; width: auto; border-radius: 3px; }
.print-doc .pt-tabela { width: 100%; border-collapse: collapse; margin-top: 12px; font-size: 10.5px; }
.print-doc .pt-tabela thead { display: table-header-group; }
.print-doc .pt-tabela thead th { background: #7a0f12; color: #fff; text-align: left; padding: 5px 8px; font-size: 9.5px; text-transform: uppercase; letter-spacing: .4px; }
.print-doc .pt-tabela td { padding: 4px 8px; border-bottom: 1px solid #e9e3da; }
/* LINHA DE ALTURA IGUAL (28/09/2026). Três coisas faziam a folha da
   lista sair com espaçamento irregular: a idade em segunda linha (agora
   é inline, ver 'celNascImpressao'), o selo MENOR/PCD empurrando o nome
   para baixo, e o nome comprido quebrando em duas linhas. O 'nowrap' na
   coluna do nome e o selo alinhado resolvem as duas últimas — nome que
   não cabe passa a ser cortado com reticência, em vez de dobrar a
   altura da linha inteira. */
.print-doc .pt-tabela td { white-space: nowrap; }
.print-doc .pt-tabela td:nth-child(2) { max-width: 260px; overflow: hidden; text-overflow: ellipsis; }
.print-doc .pt-tabela .pt-idade { color: #7b7167; margin-left: 4px; }
.print-doc .pt-tabela .pm-selo { line-height: 1.2; }
.print-doc .pt-tabela tbody tr { break-inside: avoid; }
.print-doc .pt-tabela tbody tr:nth-child(even) td { background: #faf6f0; }
.print-doc .pt-num { text-align: center; font-variant-numeric: tabular-nums; color: #7a0f12; font-weight: 700; white-space: nowrap; }
.print-doc .pt-mid { text-align: center; }
.print-doc .pt-tabela thead th.pt-mid,
.print-doc .pt-tabela thead th.pt-num { text-align: center; }
.print-doc .pt-check { width: 26px; text-align: center; }
.print-doc .cbox { display: inline-block; width: 11px; height: 11px; border: 1.2px solid #7a0f12; border-radius: 2px; }
.print-doc .pt-sec td { background: #f0e4d6 !important; font-weight: 700; color: #7a0f12; text-transform: uppercase; font-size: 9px; letter-spacing: .6px; padding: 4px 8px; }
/* MENOR FORA DO PRAZO no papel (16/08/2026). O relatório dos menores
   circula impresso na quadra e vai ao Juizado: um selo pequeno se perde
   numa folha com 60 linhas, uma faixa não. Fundo claro de propósito —
   precisa sobreviver a impressora preto e branco, onde vermelho vira
   cinza; a barra à esquerda é o que continua legível. */
.print-doc .pt-atraso td { background: #fbe9e7 !important; }
.print-doc .pt-atraso td:first-child { box-shadow: inset 3px 0 0 #b3241a; }
/* Faixa da ALA, um nível ACIMA das seções de função (08/08/2026).
   Mais escura e maior, porque é ela que diz onde uma ala termina e a
   outra começa — e é por essa linha que a coordenação vai separar as
   folhas. 'break-before: auto' de propósito: forçar página nova por ala
   desperdiçaria papel numa ala de seis pessoas. */
.print-doc .pt-ala td {
  background: #7a0f12 !important; color: #fff !important;
  font-weight: 800; text-transform: uppercase; font-size: 10px;
  letter-spacing: .8px; padding: 6px 8px;
}

/* Relatório: KPIs, filtro e mini-tabelas */
.print-doc .pr-filtro { margin: 8px 0 0; font-size: 10px; color: #666; font-style: italic; }
.print-doc .pk-row { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; margin: 12px 0; }
.print-doc .pk { border: 1px solid #e4ddd3; border-left: 4px solid #7a0f12; border-radius: 6px; padding: 8px 12px; background: #faf6f0; }
.print-doc .pk-v { font-size: 20px; font-weight: 800; color: #7a0f12; line-height: 1; }
.print-doc .pk-r { font-size: 9px; color: #666; margin-top: 3px; }
.print-doc .pr-h2 { color: #7a0f12; font-size: 12px; text-transform: uppercase; letter-spacing: .5px; margin: 14px 0 4px; border-bottom: 1.5px solid #e4ddd3; padding-bottom: 3px; }
.print-doc .pr-dois { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.print-doc .pt-mini { font-size: 10px; }
.print-doc .pt-mini td { padding: 3px 8px; }

/* Grade: muitas colunas, fonte compacta + cores por status */
.print-doc .pg-tabela { font-size: 8.5px; table-layout: fixed; }
.print-doc .pg-tabela th, .print-doc .pg-tabela td { padding: 2px; text-align: center; }
.print-doc .pg-nome { text-align: left !important; width: 120px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.print-doc .pg-data { font-size: 7.5px; line-height: 1.05; }
.print-doc .pg-data small { display: block; color: #f2d9b8; font-size: 7px; font-weight: 400; }
.print-doc .pg-cell { font-weight: 700; }
.print-doc .pg-cell.g-P { background: #dff3df; color: #0c7a24; }
.print-doc .pg-cell.g-J { background: #fdf1d6; color: #9a6b00; }
.print-doc .pg-cell.g-F { background: #fbe4e4; color: #b02a2a; }
.print-doc .pg-leg { display: flex; gap: 16px; margin-top: 8px; font-size: 9px; color: #555; }
.print-doc .pg-leg i { display: inline-block; width: 9px; height: 9px; border-radius: 2px; margin-right: 4px; vertical-align: middle; }
.print-doc .pg-leg .lg-p { background: #0c7a24; } .print-doc .pg-leg .lg-j { background: #e0a000; } .print-doc .pg-leg .lg-f { background: #b02a2a; }

/* Os quatro documentos são impressos por imprimir.html, uma página que contém
   só o documento. Não existe mais interface para esconder aqui — a antiga
   abordagem de classe no body (printing-mapa etc.) foi removida porque no
   Android a classe era perdida antes da renderização e saía a tela do app. */
@media print {
  @page { size: A4 landscape; margin: 7mm; }
  html, body { background: #fff !important; margin: 0 !important; padding: 0 !important; height: auto !important; }
  /* print-color-adjust sozinho não basta no mobile: as cores de fundo das
     células do mapa vêm de box-shadow inset, que sobrevive quando o navegador
     imprime com "gráficos de segundo plano" desligado.

     ISTO ERA UMA LISTA DE ids ESCRITA À MÃO, e cobria quatro dos onze
     documentos. Quem chegasse depois perdia as cores de fundo na
     impressão — e foi o que aconteceu com a CARTEIRINHA: o cabeçalho
     vinho virou branco, e o David pegou em 15/08/2026 imprimindo as
     da Agita Tom e da Tom do Futuro.

     É a mesma família de defeito do CASCA no sw.js e das capacidades
     da migração 34: lista que não acompanha a realidade. A cura é a
     mesma — parar de manter lista. Todo documento de impressão nasce
     com a classe '.print-doc' (o imprimir.js a aplica sozinho); o
     único sem ela é o mapa, que tem grade própria. */
  #mapaPrint, #mapaPrint *,
  .print-doc, .print-doc * { -webkit-print-color-adjust: exact !important; print-color-adjust: exact !important; }
}

/* NOTA sobre orientação: Chrome Android e Safari iOS ignoram o @page size, e a
   folha sai em retrato se o usuário não escolher Paisagem no próprio diálogo de
   impressão. Chegou a existir aqui uma regra que girava o documento 90° nesse
   caso; foi removida por nunca ter sido validada em aparelho real. Se voltar a
   incomodar, o caminho é esse — mas só depois de testar num celular. */

/* ============================================================
   Liberar acesso (convite) e link discreto no login — v2 (BATUTA)
   ============================================================ */
.link-btn {
  background: none; border: 0; padding: 6px 2px;
  color: var(--muted); font-size: .85rem; cursor: pointer;
  text-decoration: underline; align-self: center;
}
.link-btn:hover { color: var(--marca-vermelho, #b3121a); }

.form-convite { display: flex; flex-direction: column; gap: 8px; margin: 8px 0 4px; }
.cv-linha { display: flex; gap: 8px; flex-wrap: wrap; }
.cv-linha > input,
.cv-linha > select { flex: 1 1 180px; min-width: 0; }
.cv-linha > .btn { flex: 0 0 auto; }
/* ============================================================
   BALCÃO INVERTIDO — a aba Entrega e devolução (30/08)
   ============================================================ */

/* A peça achada na devolução: mostra DE QUEM era antes de confirmar.
   É o que o código individual comprou — sem ele, 40 peças iguais
   voltando são indistinguíveis. */
.dev-achada {
  border: 1px solid rgba(200,137,11,.35); background: rgba(200,137,11,.10);
  border-radius: 10px; padding: 12px; margin: 10px 0;
}
.dev-achada .dev-quem { font-size: 1.05rem; margin-bottom: 8px; }
.dev-acoes { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }

/* Linha da lista de componentes: a linha inteira é o alvo, não só o
   botão. No balcão se toca com a mão apressada, e um alvo de 44px de
   altura erra menos que um botão de 24. */
.lin-clic { cursor: pointer; }
.lin-clic:hover { background: var(--surface-2); }

/* O código da peça é para CONFERIR contra o impresso na etiqueta, e
   por isso vai em monoespaçada: o alfabeto já não tem 0/O/1/I/L, e a
   fonte de largura fixa desfaz o resto da dúvida. */
.cod-peca {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: .85rem; letter-spacing: .06em;
  background: var(--surface-2); border-radius: 6px; padding: 2px 6px;
}

/* Quem está recebendo fica visível o tempo todo: no balcão invertido a
   pessoa é escolhida UMA vez e as peças vêm em sequência — se o nome
   sair da tela, bipa-se a peça seguinte para a pessoa errada. */
.ent-quem {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  background: rgba(200,137,11,.10); border: 1px solid rgba(200,137,11,.35);
  border-radius: 10px; padding: 8px 12px; margin: 0 0 10px;
}
.ent-quem small { color: var(--muted); }

/* Campo COM RÓTULO dentro de uma '.cv-linha' (30/08). As duas datas da
   saída precisam dizer qual é qual: "sai em" e "devolver até" não se
   adivinham pela posição, e trocá-las inverte o prazo inteiro.
   Os rótulos seguem o mesmo desenho de '.field label'. */
.cv-campo { display: flex; flex-direction: column; gap: 4px; flex: 1 1 160px; min-width: 0; }
/* Quem veio no lugar do componente. Fora da '.cv-linha', então precisa
   da própria margem — e de largura contida: é um nome, não um texto. */
.cv-portador { margin: 10px 0; max-width: 380px; }
/* O que NÃO passou numa operação em lote. Erro silencioso em lote vira
   fantasia perdida — a lista aparece inteira, com o código de cada. */
.lista-erros { margin: 4px 0 0 18px; font-size: .88rem; color: var(--muted); }
.lista-erros code { font-family: ui-monospace, Consolas, monospace; }
.cv-campo > span {
  font-size: .7rem; color: var(--muted); font-weight: 600;
  text-transform: uppercase; letter-spacing: .4px;
}
#cvGerar { padding-inline: 12px; }
#cvOk { background: rgba(200,137,11,.14); border-radius: 8px; padding: 8px 10px; line-height: 1.5; }
.lider-inativo { opacity: .55; }

/* ============================================================
   MÓDULO FANTASIA — BATUTA
   ============================================================ */
.subtabs { display: flex; gap: 4px; flex-wrap: wrap; margin: 10px 0 14px; }
.subtab {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 999px; padding: 7px 14px; cursor: pointer;
  font-size: .9rem; color: var(--muted); white-space: nowrap;
}
.subtab.is-active {
  background: var(--marca-vermelho, #7a0f12); border-color: var(--marca-vermelho, #7a0f12);
  color: #fff; font-weight: 600;
}
/* ============================================================
   PÁGINA INICIAL — temas
   Blocos grandes porque o app é usado em pé, no celular, na quadra:
   alvo pequeno com o dedo suado erra. Cada tema mostra o caminho
   inteiro ("Cadastros ▸ Alas") em vez de exigir que a pessoa lembre
   em que aba a coisa mora.
   ============================================================ */
.inicio-cabeca { margin-bottom: 16px; }
.inicio-cabeca h2 { font-size: 1.35rem; margin-bottom: 2px; }
.inicio-grid {
  display: grid; gap: 14px;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
}
.tema {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); box-shadow: var(--shadow); overflow: hidden;
  display: flex; flex-direction: column;
}
.tema-topo {
  display: flex; align-items: center; gap: 12px; width: 100%;
  padding: 16px 16px; border: 0; cursor: pointer; text-align: left;
  background: transparent; color: inherit; font: inherit;
  border-bottom: 1px solid transparent;
}
.tema-topo:hover { background: rgba(200,137,11,.10); }
.tema-icone { font-size: 1.7rem; line-height: 1; flex: 0 0 auto; }
.tema-txt { display: flex; flex-direction: column; min-width: 0; }
.tema-txt b { font-size: 1.05rem; }
/* A descrição virou a LISTA do que há dentro (08/08/2026), no lugar
   dos atalhos que saíram do cartão — ver o comentário em renderInicio.
   Por isso ela pode ocupar duas linhas: cortar em uma esconderia
   justamente a informação que substituiu os atalhos. */
.tema-txt small {
  color: var(--muted); font-size: .78rem; line-height: 1.35;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}

/* SUB-MENU EM CARTÕES (08/08/2026) — Cadastros, Fantasia e Acervo.

   Reusa '.tema' e '.tema-topo' do Início de propósito: o pedido do
   David foi "iguais a da tela inicial", e a consistência é o ganho —
   quem aprendeu a navegar numa tela sabe navegar em todas. Se um dia o
   cartão do Início mudar de forma, estes mudam junto, sem ninguém
   precisar lembrar. */
.sub-menu { display: flex; flex-direction: column; gap: 10px; margin-bottom: 14px; }

/* '.tema-subs' FOI REMOVIDO em 08/08/2026 — não recriar.

   Era a lista de atalhos dentro dos cartões de Relatórios, Fantasia,
   Acervo e Cadastros. No celular cada item media 35px de altura,
   contra os 44px que este mesmo arquivo define em '--tap' como alvo
   mínimo de toque: 20% abaixo do padrão da casa, e 14 alvos ruins numa
   tela só. Agora o alvo é o cartão inteiro — 71px, largura cheia.

   O conteúdo não sumiu: virou a linha de descrição do cartão, e as
   telas de destino continuam tendo tudo. */

/* Versão no rodapé */
.versao {
  display: inline-block; margin-right: 10px; padding: 1px 8px;
  border-radius: 999px; background: var(--surface-2); color: var(--muted);
  font-size: .74rem; font-weight: 600;
}


/* Peça combinada para o dia do desfile — na entrega, some do lote e
   aparece avisada na ficha individual. */
.peca-desfile { opacity: .78; }
.peca-desfile .item-obs { color: var(--marca-amarelo, #c8890b); font-weight: 600; }
.fx-portador-box { display: block; margin: 10px 0; }
.fx-portador-box input { width: 100%; }
.fx-portador-box small { font-weight: 400; text-transform: none; letter-spacing: 0; opacity: .75; }

/* ---------- Entrega em lote (Balcão) ---------- */
#fzLoteBox summary { cursor: pointer; padding: 4px 0; }
#fzLoteBox summary b { font-size: 1rem; }
.lote-corpo { margin-top: 12px; display: flex; flex-direction: column; gap: 10px; }
.lote-rodape { display: flex; gap: 10px; align-items: flex-end; flex-wrap: wrap; }
.lote-portador { flex: 1 1 260px; margin: 0; }
.lote-portador input { width: 100%; }

/* ---------- Convocação ---------- */
.modal-largo { max-width: 720px; text-align: left; }
.conv-atalhos { display: flex; gap: 6px; flex-wrap: wrap; margin: 10px 0; }
.conv-atalhos .btn { padding: 7px 12px; font-size: .85rem; min-height: 34px; }
.conv-copiar {
  display: flex; gap: 8px; align-items: flex-end; flex-wrap: wrap;
  background: var(--surface-2); border-radius: 10px; padding: 10px 12px; margin-bottom: 10px;
}
.conv-copiar .ed-label { flex: 1 1 240px; margin: 0; }
.tab-conv { width: 100%; border-collapse: collapse; }
.tab-conv td { padding: 6px 8px; border-bottom: 1px solid var(--border); vertical-align: middle; }
.tab-conv .pt-check { width: 36px; }
.tab-conv input[type="checkbox"] { width: 20px; height: 20px; }
/* cabeçalho de ala dentro da lista: com a escola inteira na tela, uma
   lista chapada de mil nomes não é utilizável */
.conv-grupo td {
  background: var(--surface-2); font-size: .88rem; position: sticky; top: 0;
}
.conv-grupo small { color: var(--muted); margin-left: 6px; }
.conv-lista { color: var(--marca-vermelho, #7a0f12); font-weight: 700; }
:root[data-theme="dark"] .conv-lista { color: var(--marca-amarelo, #c8890b); }

.fz-painel { display: flex; flex-direction: column; gap: 14px; }

/* ============================================================
   CADASTROS — mesmo padrão de sub-abas do módulo Fantasia.
   Reaproveita .subtabs/.subtab de propósito: são as duas telas
   com várias seções dentro de uma aba, e aprender o padrão uma
   vez tem que valer para as duas.
   ============================================================ */
.cd-painel { display: flex; flex-direction: column; gap: 14px; }
/* bolinha da cor do bloco na lista da formação */
.bloco-cor {
  display: inline-block; width: 11px; height: 11px; border-radius: 50%;
  vertical-align: -1px; margin-right: 4px; box-shadow: inset 0 0 0 1px rgba(0,0,0,.18);
}
/* O seletor de cor precisa de flex-basis própria: .form-inline dá
   'flex: 1 1 140px' a todo input, e o color esticava numa barra vinho
   do tamanho do formulário — parecia um campo obrigatório sem rótulo. */
.inp-cor {
  flex: 0 0 52px; width: 52px; min-width: 52px; max-width: 52px;
  padding: 3px; cursor: pointer;
}
/* Formulário de blocos: usa .toolbar (campos com rótulo em cima) e não
   .form-inline, mas os botões precisam alinhar pela base dos campos. */
.form-bloco { align-items: flex-end; }
.form-bloco .field label small { text-transform: none; letter-spacing: 0; opacity: .75; }
.fz-peca-titulo { margin: 16px 0 6px; font-size: 1rem; }
.fz-peca-titulo:first-child { margin-top: 0; }
.fz-peca-titulo small { font-weight: 400; opacity: .7; }

/* RECEBER O LOTE: a peça que ainda não tem nada não ganha tabela de
   sete colunas para informar sete zeros — ganha uma caixinha por
   tamanho. Mesma largura mínima da grade de fotos, pelo mesmo motivo:
   célula de tamanho fixo se varre com o olho. */
/* ALMOXARIFADO DO BARRACAO
   O motivo do cancelamento e um campo NA PROPRIA LINHA — 'prompt()'
   saiu do projeto em 08/08. O wrap do campo+botao e o mesmo da entrada
   de lote; aqui ele vale em qualquer tabela, e nao so na do estoque. */
td .est-add-wrap { display: inline-flex; align-items: center; gap: 4px; }
.ax-motivo { padding: 4px 6px; font-size: .85rem; }
/* O codigo do produto na lista: monoespacado porque e para ser
   LIDO caractere a caractere quando alguem for digita-lo. */
.cod-produto { font-family: ui-monospace, "Cascadia Mono", Consolas, monospace; letter-spacing: .04em; }
.ax-bip { flex: 1 1 220px; font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
  font-size: 1.05rem; letter-spacing: .06em; text-transform: uppercase; }

/* ALAS ESCOLHIDAS, no formulario de evento. Reusa a grade de
   caixinhas do recebimento de lote (.fz-receber): mesma largura
   minima, mesma leitura de relance. */
.alas-escolhidas { margin: 4px 0 10px; }
.alas-escolhidas .fz-receber-cel { cursor: pointer; }
/* A CAIXA DE MARCAR NAO E UM CAMPO DE QUANTIDADE. Reusar a celula do
   recebimento de lote trouxe junto o 'flex: 1 1 auto; width: 100%' do
   input, e o checkbox esticava pela celula inteira empurrando o nome
   da ala para a direita — cada linha com um recuo diferente. */
.alas-escolhidas .fz-receber-cel input[type="checkbox"] {
  flex: 0 0 auto; width: auto; min-width: 0; margin: 0; padding: 0;
}
.alas-escolhidas .fz-receber-cel span {
  flex: 1 1 auto; min-width: 0; white-space: normal; text-align: left;
  font-weight: 500;
}

.fz-receber {
  display: grid; gap: 8px; margin-bottom: 4px;
  grid-template-columns: repeat(auto-fill, minmax(112px, 1fr));
}
.fz-receber-cel {
  display: flex; align-items: center; gap: 6px; flex-wrap: nowrap;
  border: 1px solid var(--border); border-radius: 9px; padding: 5px 7px;
  background: var(--surface-2);
}
.fz-receber-cel span {
  flex: 0 0 auto; min-width: 38px; font-size: .78rem; font-weight: 600;
  color: var(--ink-2); font-variant-numeric: tabular-nums;
}
/* O campo fica com TODA a largura que sobra: numa celula destas, a
   setinha de incremento do 'number' e o botao ao lado roubavam o
   espaco do proprio numero digitado, que era o unico conteudo que
   importava. */
.fz-receber-cel input {
  flex: 1 1 auto; min-width: 0; width: 100%;
  padding: 5px 6px; text-align: center; font-size: .95rem;
  font-variant-numeric: tabular-nums;
  appearance: textfield; -moz-appearance: textfield;
}
.fz-receber-cel input::-webkit-outer-spin-button,
.fz-receber-cel input::-webkit-inner-spin-button { appearance: none; margin: 0; }

/* O campo de ENTRADA DE LOTE dentro da tabela cheia. Ele divide a
   celula com o numero ja recebido, entao precisa de largura fixa e
   pequena — e sem a setinha do 'number', que sozinha comia um terco
   do campo e deixava o numero digitado invisivel. */
.tab-estoque td { white-space: nowrap; }
.tab-estoque .est-add-wrap { display: inline-flex; align-items: center; gap: 4px; }
/* A coluna de digitar: separada do numero por uma borda leve, para a
   tabela dizer sozinha que 'Recebido' se le e 'Receber' se escreve. */
.tab-estoque .col-receber { border-left: 1px dashed var(--border); }
.tab-estoque .est-add {
  width: 58px; padding: 4px 6px; text-align: center;
  font-variant-numeric: tabular-nums;
  appearance: textfield; -moz-appearance: textfield;
}
.tab-estoque .est-add::-webkit-outer-spin-button,
.tab-estoque .est-add::-webkit-inner-spin-button { appearance: none; margin: 0; }
.tab-estoque .est-add-ok { padding: 4px 8px; }

/* Balcão */
.balcao-linha { display: flex; gap: 8px; flex-wrap: wrap; margin: 10px 0; }
#fzCodigo {
  flex: 1 1 220px; font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
  font-size: 1.3rem; letter-spacing: .12em; text-transform: uppercase; text-align: center;
}
/* O TEXTO DE AJUDA NÃO PODE USAR A FONTE DO CÓDIGO (08/08/2026).

   O campo é grande de propósito: quem digita o código da etiqueta está
   no balcão, lendo caracteres soltos de uma etiqueta amassada, e
   confundir O com 0 custa a ficha errada. Para os 10 caracteres do
   código, 1,3rem com espaçamento entre letras é o certo.

   Só que o TEXTO DE AJUDA tem 36 caracteres. Com a mesma fonte ele
   virava "CÓDIGO DA ETIQUETA OU D" cortado na borda — o David mandou a
   foto. A dica ficava ilegível justamente para quem nunca usou a tela.

   O ::placeholder volta ao normal; o que a pessoa digita continua
   grande. */
#fzCodigo::placeholder {
  font-family: inherit; font-size: .82rem; letter-spacing: normal;
  text-transform: none; opacity: .75;
}
.scanner { margin-top: 10px; display: flex; flex-direction: column; gap: 8px; align-items: center; }
.scanner video {
  width: 100%; max-width: 420px; border-radius: 12px; background: #000;
  aspect-ratio: 4/3; object-fit: cover;
}

/* Ficha do balcão */
.ficha-cab { display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; }
.ficha-cab h3 { margin: 0; }
.ficha-tag { border-radius: 999px; padding: 4px 12px; font-size: .8rem; font-weight: 700; white-space: nowrap; }
.tag-ent { background: rgba(200,137,11,.18); color: #8a5d06; }
.tag-dev { background: rgba(200,137,11,.18); color: #96660a; }
.tab-ficha { width: 100%; }
.tab-ficha td { padding: 9px 6px; border-bottom: 1px solid var(--border); vertical-align: middle; }
.linha-apagada { opacity: .5; }
.radio-inline { display: inline-flex; align-items: center; gap: 4px; margin-right: 14px; font-size: .9rem; }
.ficha-acoes { display: flex; gap: 8px; margin-top: 12px; }
#fxObs { width: 100%; margin-top: 10px; }

/* Tabelas do módulo */
.tab-tamanhos select { min-width: 76px; padding: 4px; }
.tab-tamanhos td, .tab-estoque td { padding: 6px; }

/* PEÇAS DA FANTASIA: o nome vira campo editável na própria tabela
   (03/10/2026). Sem borda em repouso, para a lista continuar parecendo
   uma lista; a borda aparece ao focar, dizendo que ali se digita. Os
   <select> de grade, retirada, tipo e devolve já vinham sem estilo
   próprio e seguem o padrão do projeto. */
#fzListaPecas input.nome-peca {
  width: 100%; min-width: 120px; font: inherit; font-weight: 700;
  color: var(--ink); background: transparent; border: 1px solid transparent;
  border-radius: 6px; padding: 4px 6px;
}
#fzListaPecas input.nome-peca:hover { border-color: var(--border); }
#fzListaPecas input.nome-peca:focus {
  border-color: var(--marca-vermelho); background: var(--surface); outline: none;
}
.linha-falta { background: rgba(200,60,40,.09); }
.linha-total { font-weight: 700; border-top: 2px solid var(--border); }
.est-inp { width: 76px; text-align: right; }

/* ---- ETIQUETAS ---- */
/* ============================================================
   ETIQUETA DA PEÇA — 25 × 25 mm (30/08)

   As medidas são em MILÍMETROS de propósito: a etiqueta existe no
   mundo físico, e pensar em pixels aqui é como o QR sai pequeno demais
   para bipar.

   A CONTA VERTICAL, dentro dos 25mm:
     0,8 margem + 14,0 QR + 0,5 + 5,3 tamanho + 0,3 + 2,3 código
     + 0,8 margem  =  24,0 mm — sobra 1mm para o corte não comer nada.

   EMPILHADO, não lado a lado: 'XGG' a 20pt ocupa ~13mm e o código a
   6,5pt ocupa ~14mm; juntos dariam 27mm, mais do que a etiqueta tem.
   Empilhados, cada um recebe a largura inteira e o leiaute deixa de se
   importar com o comprimento do tamanho.

   ⚠️ Isto é a impressão do NAVEGADOR, para conferir e para uso interno.
   O arquivo definitivo espera a gráfica dizer extensão, dpi e ganho de
   ponto — ver 🔵 P3 no handoff. O que NÃO espera é a geometria: o
   módulo de 0,50mm é inteiro a 203 e a 300 dpi. */
.folha25 { display: flex; flex-wrap: wrap; gap: 2mm; margin-top: 12px; }
.etiq25 {
  width: 25mm; height: 25mm; box-sizing: border-box;
  padding: 0.8mm; background: #fff; color: #000;
  display: flex; flex-direction: column; align-items: center;
  overflow: hidden; border: 1px dashed #bbb;
}
/* ALA E PEÇA NO ALTO (13/09, opção A — a medida aprovada é 25 x 25 mm).
   Para caber, o QR desceu de 14 para 10,5 mm — o mínimo que mantém o
   módulo em 0,50 mm (21 módulos), inteiro a 203 e a 300 dpi — e o
   tamanho, de 20 para 15 pt. Ala e peça são leitura de perto, na mesa
   de triagem do Depto.; o tamanho continua sendo o maior texto.
   Os degraus --m / --p / --pp vêm de 'porComprimento' no fantasia.js. */
.e25-ala, .e25-peca {
  width: 100%; text-align: center; line-height: 1.05;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.e25-ala  { font-size: 6pt; font-weight: 800; letter-spacing: -.01em; }
.e25-ala.e25--m  { font-size: 5.4pt; }
.e25-ala.e25--p  { font-size: 4.9pt; }
.e25-ala.e25--pp { font-size: 4.5pt; }
.e25-peca { font-size: 5.5pt; margin-bottom: 0.5mm; }
.e25-peca.e25--m { font-size: 5pt; }
.e25-peca.e25--p { font-size: 4.6pt; }
.e25-qr { width: 10.5mm; height: 10.5mm; flex: none; }
.e25-qr svg { width: 100%; height: 100%; display: block; }
.e25-tam {
  font-size: 15pt; font-weight: 800; line-height: .78;
  margin-top: 0.7mm; letter-spacing: -.01em;
}
/* TAMANHO LONGO: cinco letras largas a 15 pt passam dos 25 mm, e o
   'overflow: hidden' da etiqueta cortaria as pontas (o MOMO1 já saía
   cortado a 20 pt). */
.e25-tam.e25--m { font-size: 13pt; }
.e25-tam.e25--p { font-size: 10.5pt; margin-top: 1mm; }
.e25-cod {
  font-family: ui-monospace, Consolas, monospace;
  font-size: 5.5pt; line-height: 1; letter-spacing: .04em; margin-top: 0.4mm;
}
@media print {
  /* O tracejado é guia de corte na prova; na etiqueta adesiva de
     verdade a borda vem picotada de fábrica. */
  .etiq25 { border: 1px dashed #999; }
  .folha25 { gap: 1mm; }
}

.etiq-previa { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 12px; }
.etiq {
  display: flex; gap: 10px; align-items: center;
  border: 1px solid #999; border-radius: 6px; padding: 8px 10px;
  width: 62mm; min-height: 26mm; background: #fff; color: #000;
  break-inside: avoid; page-break-inside: avoid;
}
.etiq-qr { flex: 0 0 auto; width: 22mm; height: 22mm; }
.etiq-qr svg { width: 100%; height: 100%; display: block; }
.etiq-txt { flex: 1 1 auto; min-width: 0; line-height: 1.25; }
.etiq-ala  { font-size: 7.5pt; text-transform: uppercase; letter-spacing: .04em; color: #444; }
.etiq-nome { font-size: 10pt; font-weight: 700; margin: 1px 0 2px;
             overflow-wrap: anywhere; }
.etiq-tam  { font-size: 7.5pt; color: #222; }
/* o código legível: existe para ser digitado quando o QR falhar */
.etiq-cod  { font-family: ui-monospace, Consolas, monospace; font-size: 9pt;
             letter-spacing: .1em; margin-top: 3px; }

/* Folha de etiquetas: 3 colunas em A4 retrato */
.folha-etiq { display: flex; flex-wrap: wrap; gap: 4mm; }

@media print {
  .folha-etiq { gap: 3mm; }
  .etiq { border: 1px dashed #666; }
  .subtabs, .balcao-linha, .scanner { display: none !important; }
}
.fz-funcao { color: var(--muted); font-weight: 400; }
.fz-grade { display: block; font-weight: 400; color: var(--muted); font-size: .72rem; }
/* sobra = reserva de emergência; verde discreto, não é alerta */
/* Sobra em AMARELO, não verde: verde com vermelho na mesma tela são
   as cores da atual campeã — vermelho e amarelo são as da Tom Maior. */
.linha-sobra { background: rgba(200,137,11,.10); }

/* Trilha das 4 etapas de custódia da fantasia */
.trilha { list-style: none; display: flex; flex-wrap: wrap; gap: 6px; margin: 12px 0; padding: 0; }
.trilha li {
  flex: 1 1 130px; border: 1px solid var(--border); border-radius: 8px;
  padding: 6px 9px; display: flex; flex-direction: column; gap: 1px;
  font-size: .78rem; color: var(--muted); opacity: .55;
}
.trilha li.feito { opacity: 1; border-color: rgba(200,137,11,.55); background: rgba(200,137,11,.10); }
.trilha li b { font-size: .82rem; color: var(--txt, #222); }
.trilha li i { font-style: normal; }

.ficha-tag.cor-cinza   { background: rgba(120,120,120,.15); color: #555; }
.ficha-tag.cor-azul    { background: rgba(40,90,180,.15);  color: #24508f; }
.ficha-tag.cor-amarelo { background: rgba(200,137,11,.18); color: #96660a; }
.ficha-tag.cor-ouro    { background: rgba(200,137,11,.20); color: #7a5205; }
.pend { color: #b3241a; }
/* Histórico de movimentos da etiqueta */
.hist-mov { margin-top: 12px; }
.hist-mov table { font-size: .85rem; }
.hist-mov td, .hist-mov th { padding: 5px 8px; }
.mov-estorno { background: rgba(200,60,40,.08); }
.mov-estorno td:nth-child(2) { font-weight: 600; }

/* Tamanhos, medidas e números centralizados — coluna de valor curto
   lida melhor centrada que alinhada à esquerda com sobra de campo. */
.tab-tamanhos select.tam-sel { text-align: center; text-align-last: center; }
.tab-tamanhos th, .tab-tamanhos td { text-align: center; }
.tab-tamanhos th:first-child, .tab-tamanhos td:first-child { text-align: left; }
.tab-estoque th, .tab-estoque td { text-align: center; }
.tab-estoque th:first-child, .tab-estoque td:first-child { text-align: left; }
.est-inp { text-align: center; }
/* dígitos com a mesma largura: as colunas não dançam ao mudar valor */
.tab-estoque { font-variant-numeric: tabular-nums; }

/* A LINHA DE TOTAL DO ESTOQUE, no papel (pedido do David, 08/08/2026).

   No PDF ela ficava do mesmo tamanho das linhas de tamanho, e era só
   um pouco mais escura. Mas é a linha que o Depto. de Fantasia lê
   PRIMEIRO — "quantas calças eu preciso ao todo e quantas chegaram" —,
   e ela estava competindo em pé de igualdade com 'MOMO1: 1'.

   O RECEBIDO ganha caixa aqui pelo mesmo motivo que tem caixa na tela:
   é o ÚNICO número que o departamento digita. Na tela isso é evidente
   (é um campo); no papel a informação se perdia, e quem confere não
   sabia qual coluna é a que ele controla. */
.print-doc .tab-estoque .linha-total td {
  font-size: 11.5px; font-weight: 800;
  border-top: 1.5px solid #7a0f12;
  padding-top: 7px; padding-bottom: 7px;
}
.print-doc .tab-estoque .linha-total td:nth-child(3) {
  border: 1.2px solid #7a0f12; border-radius: 6px;
  background: #f7f1e8 !important;
}
/* Mesma caixa nas linhas de cima, mais discreta: assim a coluna inteira
   se lê como "o que o ateliê entregou", e não só o total dela. */
.print-doc .tab-estoque tbody td:nth-child(3) {
  border: 1px solid #d8cfc2; border-radius: 6px; background: #fcfaf7 !important;
}
/* observação por peça, na devolução e na leitura */
.fx-obs { display: block; width: 100%; margin-top: 6px; font-size: .85rem; }
.item-obs { font-size: .85rem; color: var(--muted); margin-top: 2px; font-style: italic; }
.fx-cnf-obs { display: block; width: 100%; margin-top: 6px; font-size: .85rem; }
/* ---------- Barra de contexto ----------
   Onde estou + como volto + em qual ala estou. Uma faixa só: as duas
   anteriores (abas e seletor de ala) somavam quase um terço da tela
   do celular antes de o conteúdo começar. */
.barra-contexto {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding: 8px 16px; border-bottom: 1px solid var(--border);
  background: var(--surface);
}
.voltar-inicio {
  display: inline-flex; align-items: center; gap: 6px;
  background: transparent; border: 1px solid var(--border); border-radius: 999px;
  padding: 6px 14px; cursor: pointer; font: inherit; font-size: .88rem;
  /* 44px é o alvo mínimo de toque definido em '--tap' no topo deste
     arquivo. Este botão estava em 36px — e é o botão de SAIR de uma
     tela, ou seja, o que alguém procura quando entrou no lugar errado.
     Errar o toque nele é ficar preso onde não queria estar. */
  font-weight: 600; color: var(--ink-2); min-height: var(--tap, 44px);
}
.voltar-inicio:hover { background: var(--surface-2); color: var(--ink); }
.titulo-view { font-weight: 700; font-size: .98rem; }
/* empurra o seletor de ala para a direita da faixa */
.barra-contexto 
/* ---------- Seletor de alas (barra de contexto) ----------
   Vários em vez de um: a Harmonia responde por um conjunto de alas e
   precisa do quadro somado. O que ela ALCANÇA continua sendo decidido
   pela RLS — aqui só se escolhe o recorte de leitura. */
.ala-botao {
  display: inline-flex; align-items: center; gap: 8px; cursor: pointer;
  background: rgba(200,137,11,.12); border: 1px solid rgba(200,137,11,.40);
  border-radius: 999px; padding: 7px 14px; font: inherit; color: inherit;
  min-height: var(--tap);
}
.ala-botao:hover { background: rgba(200,137,11,.20); }
.ala-rot { font-size: .62rem; font-weight: 700; letter-spacing: .1em;
  text-transform: uppercase; color: var(--muted); }
.ala-valor { font-weight: 600; }
.ala-seta { color: var(--muted); font-size: .8rem; }
.ala-painel {
  position: absolute; right: 0; top: calc(100% + 6px); z-index: 40;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 12px; box-shadow: 0 10px 30px rgba(0,0,0,.18);
  padding: 6px; min-width: 240px; max-height: 60vh; overflow-y: auto;
}
.ala-opt {
  display: flex; align-items: center; gap: 8px; width: 100%;
  padding: 9px 10px; border: 0; background: transparent; color: inherit;
  font: inherit; text-align: left; border-radius: 8px; cursor: pointer;
}
.ala-opt:hover { background: var(--surface-2); }
.ala-opt small { color: var(--muted); }
.ala-todas { font-weight: 600; border-bottom: 1px solid var(--border); border-radius: 8px 8px 0 0; }
.ala-lista { margin-top: 4px; }
.ala-lista input[type="checkbox"] { width: 18px; height: 18px; }

/* "Em quais alas", no cadastro de Documento (30/08).

   PARECE UM <select> E ABRE UM PAINEL — o mesmo desenho do seletor de
   ala do topo. As medidas abaixo são as MESMAS do bloco "TODO CAMPO TEM
   A MESMA ALTURA E A MESMA FONTE": padding, raio, borda, altura e
   line-height. Copiadas de propósito, para o botão ficar
   indistinguível do <select> ao lado — que era a queixa. */
.campo-alas { position: relative; }
.campo-alas-btn {
  font: inherit; padding: 10px 12px; border-radius: 10px;
  border: 1px solid var(--border); background: var(--surface); color: var(--ink);
  height: var(--tap); line-height: 1.25; cursor: pointer;
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  width: 100%; min-width: 190px; text-align: left;
}
.campo-alas-btn:focus { outline: 2px solid var(--marca-amarelo); outline-offset: 1px; }
.campo-alas-btn > span:first-child {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* O painel do topo é ancorado à direita porque vive no canto da barra.
   Aqui ele nasce sob o campo, então ancora à esquerda. */
.campo-alas .ala-painel { right: auto; left: 0; min-width: 250px; max-height: 46vh; }
/* '.field label' põe MAIÚSCULA, tamanho .7rem e cor de rótulo em todo
   <label> dentro do campo — e as opções do painel SÃO <label>. Sem esta
   regra os nomes saíam "1° CASAL DE MSPB". Nome de ala não é rótulo. */
.campo-alas .ala-opt {
  text-transform: none; letter-spacing: normal;
  font-size: .95rem; font-weight: 400; color: var(--ink);
}
.campo-alas .ala-opt input[type="checkbox"] { width: 17px; height: 17px; flex: none; }
.campo-alas .doc-alas-vazio { color: var(--muted); font-size: .85rem; padding: 8px; display: block; }

.seletor-ala { position: relative; margin-left: auto; }

/* Seletor de ala de trabalho (só para quem alcança mais de uma).
   Global desde 28/07: a mesma escolha manda na Chamada, no Mapa e nos
   Cadastros. Enxugado em 03/08 — era um painel dourado de largura
   inteira para um único campo. */

/* ---------- Seletor de alas (barra de contexto) ----------
   Vários em vez de um: a Harmonia responde por um conjunto de alas e
   precisa do quadro somado. O que ela ALCANÇA continua sendo decidido
   pela RLS — aqui só se escolhe o recorte de leitura. */
.ala-botao {
  display: inline-flex; align-items: center; gap: 8px; cursor: pointer;
  background: rgba(200,137,11,.12); border: 1px solid rgba(200,137,11,.40);
  border-radius: 999px; padding: 7px 14px; font: inherit; color: inherit;
  min-height: var(--tap);
}
.ala-botao:hover { background: rgba(200,137,11,.20); }
.ala-rot { font-size: .62rem; font-weight: 700; letter-spacing: .1em;
  text-transform: uppercase; color: var(--muted); }
.ala-valor { font-weight: 600; }
.ala-seta { color: var(--muted); font-size: .8rem; }
.ala-painel {
  position: absolute; right: 0; top: calc(100% + 6px); z-index: 40;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 12px; box-shadow: 0 10px 30px rgba(0,0,0,.18);
  padding: 6px; min-width: 240px; max-height: 60vh; overflow-y: auto;
}
.ala-opt {
  display: flex; align-items: center; gap: 8px; width: 100%;
  padding: 9px 10px; border: 0; background: transparent; color: inherit;
  font: inherit; text-align: left; border-radius: 8px; cursor: pointer;
}
.ala-opt:hover { background: var(--surface-2); }
.ala-opt small { color: var(--muted); }
.ala-todas { font-weight: 600; border-bottom: 1px solid var(--border); border-radius: 8px 8px 0 0; }
.ala-lista { margin-top: 4px; }
.ala-lista input[type="checkbox"] { width: 18px; height: 18px; }
/* Faixa do setor dentro do seletor de alas — mesma leitura do relatório
   de mínimo (David, 09/08, com 21 alas na lista). Recuo alinhado ao
   TEXTO das opções e não ao checkbox: a faixa nomeia o grupo, não é
   mais uma opção para marcar.

   Vai depois da SEGUNDA cópia do bloco '.ala-opt' — este arquivo tem as
   linhas 1068-1077 repetidas em 1107-1116, idênticas. Como são iguais,
   nada quebra; mas quem editar só a primeira não vê efeito nenhum. */
.ala-grupo { padding: 8px 10px 3px; font-size: .68rem; font-weight: 800;
  letter-spacing: .08em; text-transform: uppercase; color: var(--muted); }
.ala-lista .ala-grupo:not(:first-child) { border-top: 1px solid var(--border); margin-top: 5px; }

.seletor-ala {
  display: flex; align-items: center; gap: 8px; flex-wrap: nowrap;
  background: rgba(200,137,11,.12); border: 1px solid rgba(200,137,11,.35);
  border-radius: 999px; padding: 3px 6px 3px 12px;
}
.seletor-ala label {
  font-size: .7rem; color: var(--muted); font-weight: 700;
  text-transform: uppercase; letter-spacing: .4px; white-space: nowrap;
}
.seletor-ala select {
  min-width: 0; max-width: 190px; border: 0; background: transparent;
  padding: 4px 6px; min-height: 30px; font-weight: 600;
}
.so-lider { color: var(--muted); font-style: italic; }

/* ============================================================
   Coluna Ações sempre visível
   A tabela de integrantes é mais larga que o painel e rola na
   horizontal — editar e excluir ficavam fora da tela, que é o
   mesmo que não existirem. Fixadas à direita, acompanham a rolagem.
   ============================================================ */
.tab-integrantes { position: relative; }
.tab-integrantes th:last-child,
.tab-integrantes td:last-child {
  position: sticky; right: 0; z-index: 2;
  background: var(--surface);
  box-shadow: -6px 0 6px -6px rgba(0,0,0,.25);
  white-space: nowrap; padding-inline: 10px;
}
/* linhas alternadas: o fundo fixo precisa acompanhar, senão a
   coluna presa "flutua" com cor diferente do resto da linha */
.tab-integrantes tbody tr:nth-child(even) td:last-child {
  background: var(--card-alt, var(--surface));
}

/* ============================================================
   Gerenciar — eventos em cima, integrantes embaixo
   ============================================================ */
.conta-itens {
  font-size: .82rem; font-weight: 400; color: var(--muted);
  background: rgba(200,137,11,.12); border-radius: 999px; padding: 2px 10px;
  white-space: nowrap;
}
/* VAZIA, ELA NÃO EXISTE. O fundo e o padding faziam a contagem sem
   texto virar uma bolinha ao lado do título — apareceu na Prestação de
   Contas, mas o defeito é de TODAS: são 8 no index (Menores, PCD,
   Mínimo por ala, Recados, Documentos, Samba-enredo...), e todas ficam
   vazias enquanto a lista não carrega ou está sem itens.
   Uma regra resolve as oito; 'hidden' em cada módulo resolveria uma e
   deixaria as próximas para o próximo a reparar. */
.conta-itens:empty { display: none; }
/* O calendário cresce a cada evento marcado. Sem teto, ele empurraria
   a lista de integrantes para fora da tela — e integrantes é a parte
   mais usada desta aba. */
.lista-rolavel { max-height: 260px; overflow-y: auto; }

/* Meta de frequência da liderança */
.meta-controls { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.meta-controls label { font-size: .85rem; color: var(--muted); }
.meta-controls input[type="number"] { width: 74px; text-align: center; }
.meta-resumo { margin: 0 0 10px; font-size: .95rem; }
.sit { display: inline-block; padding: 3px 10px; border-radius: 999px; font-size: .78rem; font-weight: 700; white-space: nowrap; }
/* Sem verde: "Atingiu" em dourado, "Não atingiu" em vermelho (paleta da própria Tom Maior) */
.sit--ok { background: var(--marca-amarelo); color: #3a2600; }
.sit--nao { color: var(--marca-vermelho); border: 1px solid var(--marca-vermelho); }
.sit--neutro { color: var(--muted); }
/* Centraliza Conv./P/J/F/Freq./Situação na tela — só na tabela da meta,
   deixando a coluna Pessoa à esquerda. Escopo por #id para não afetar
   o ranking nem as outras tabelas. */
#tabelaMeta th, #tabelaMeta td { text-align: center; }
#tabelaMeta th:first-child, #tabelaMeta td:first-child { text-align: left; }

/* Vínculos de acesso (lista de acessos) e modo "adicionar vínculo" */
.vinc { display: inline-block; border: 1px solid var(--border); border-radius: 999px; padding: 2px 9px; font-size: .8rem; margin: 2px 3px 2px 0; white-space: nowrap; }

/* LISTA DE LÍDERES E ACESSO: as pastilhas QUEBRAM LINHA (02/10/2026).
   Toda célula do projeto é 'nowrap' — bom para data e tamanho, péssimo
   aqui: quem tem seis vínculos esticava a linha para fora da tela, e
   para rolar de lado era preciso descer até a barra no fim de sessenta
   linhas. Pior, ao rolar, o NOME saía de vista e já não dava para saber
   de quem era o vínculo que se ia remover (David, 02/10).

   Com a quebra, a tabela cabe na largura e a barra horizontal
   desaparece. A coluna do nome fica GRUDADA à esquerda para o caso de
   ainda sobrar rolagem no celular. */
#listaLideres td:nth-child(2) { white-space: normal; }
#listaLideres td:first-child,
#listaLideres th:first-child {
  position: sticky; left: 0; z-index: 1; background: var(--surface);
  min-width: 190px; max-width: 280px; white-space: normal;
}
#listaLideres tr:hover td:first-child { background: var(--surface-2); }
#listaLideres td:last-child { white-space: nowrap; }
.vinc-x { border: none; background: transparent; color: var(--marca-vermelho); cursor: pointer; font-weight: 700; font-size: 1rem; line-height: 1; padding: 0 0 0 4px; }
.cv-banner { background: rgba(200,137,11,.12); border: 1px solid var(--marca-amarelo); border-radius: 8px; padding: 9px 12px; font-size: .9rem; margin-bottom: 10px; }

/* Cadastro de papéis: centraliza as marcações (menos a coluna Papel) e
   deixa cabeçalhos longos (ex.: "Corrigir Fantasia") quebrarem em 2 linhas. */
#tabelaPapeis th, #tabelaPapeis td { text-align: center; }
#tabelaPapeis th:first-child, #tabelaPapeis td:first-child { text-align: left; }
#tabelaPapeis th { white-space: normal; vertical-align: bottom; }

/* Menor de 18 + documentação */
.selo-menor { display: inline-block; background: #3a5a99; color: #fff; font-size: .62rem; font-weight: 800;
  letter-spacing: .08em; text-transform: uppercase; padding: 2px 6px; border-radius: 5px; vertical-align: middle; }

/* ---------- Selos MENOR e PCD ----------
   PCD em roxo-azulado, fora do verde/vermelho (cores da rival) e
   distinto do azul do MENOR, para não se confundirem de relance. */
.selo-pcd { display: inline-block; background: #6a3d9a; color: #fff; font-size: .62rem; font-weight: 800;
  letter-spacing: .08em; text-transform: uppercase; padding: 2px 6px; border-radius: 5px; vertical-align: middle; }
/* Mesma família dos selos MENOR e PCD (06/09/2026): pequeno, colado ao
   nome, e de uma cor que não é usada por nenhum dos dois. Diz que a ala
   está habilitada a lançar gasto — e é a única pista visual disso na
   lista de alas. */
.selo-presta { display: inline-block; background: #1f6f5c; color: #fff; font-size: .62rem;
  font-weight: 800; letter-spacing: .08em; text-transform: uppercase; padding: 2px 6px;
  border-radius: 5px; vertical-align: middle; }

/* Versão ponto, para Grade e Mapa: não cabe texto, mas o title explica. */
.pt-selo { display: inline-block; width: 8px; height: 8px; border-radius: 50%;
  margin-left: 4px; vertical-align: middle; }
.pt-menor { background: #3a5a99; }
.pt-pcd   { background: #6a3d9a; }
/* No mapa os pontos vão no canto do lugar, sem empurrar o número. */
/* MENOR e PCD dentro da bolinha, ABAIXO do número — mesma leitura do
   mapa impresso (pedido do David, 04/08). Antes ficavam colados ao
   número ("20PCD") porque eram inline. */
.mpos { flex-direction: column; gap: 1px; }
.mpos-tags { display: flex; gap: 2px; flex-wrap: wrap; justify-content: center; line-height: 1; }
.mpos-tags .tg {
  font-size: .46rem; font-weight: 800; letter-spacing: .04em;
  padding: 1px 3px; border-radius: 3px; background: rgba(255,255,255,.92);
}
.tg-menor { color: #24406e; }
.tg-pcd   { color: #52277a; }
/* Nas caixas do perímetro (liderança) o espaço é vertical: entra
   embaixo da função. */
.mlider .mpos-tags { margin-top: 2px; }
.lado-mapa .mlider .mpos-tags { display: none; }  /* caixa deitada não comporta */
/* Célula de quem não foi convocado: nem falta, nem presença. */
.grade .cell.st-NA { background: var(--surface-2); color: var(--muted); cursor: default; opacity: .55; }
.ed-switch { display: flex; align-items: center; gap: 8px; margin: 10px 0; }

.doc-menor { margin-top: 4px; font-size: .82rem; }
.doc-menor label { display: inline-flex; align-items: center; gap: 6px; color: var(--muted); cursor: pointer; }
.menores-bar { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin: 4px 0 10px; }
.menores-data { display: inline-flex; align-items: center; gap: 6px; font-size: .85rem; color: var(--muted); }
.menores-data input { font-size: .9rem; }
.inp-nasc { max-width: 150px; }

/* O QUE ESTE ACESSO VAI DAR — o resumo mostrado antes de conceder um
   vínculo. Ver 'explicarVinculo()' no app.js: existe porque abrangência
   e permissão são eixos independentes, e a tela mostrava os dois como
   se fossem um. */
.cv-explica {
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 10px 12px;
  margin: 4px 0 8px;
  font-size: 0.9rem;
  line-height: 1.45;
  background: var(--surface-2);
}
.cv-explica p { margin: 2px 0; }
.cv-explica .cve-tit {
  font-weight: 700;
  margin-bottom: 6px;
  text-transform: uppercase;
  font-size: 0.75rem;
  letter-spacing: 0.04em;
  opacity: 0.7;
}
/* O alerta só aparece na abrangência "escola". Aviso que aparece
   sempre vira paisagem e deixa de ser lido no dia em que importava. */
.cv-explica .cve-alerta {
  margin-top: 8px;
  padding: 8px 10px;
  border-radius: 6px;
  border-left: 3px solid var(--f);
  background: color-mix(in srgb, var(--f) 10%, transparent);
}

/* Campo com valor inválido. Usado hoje na data de nascimento, que
   passou a ser DIGITADA (ver o bloco "DATA DE NASCIMENTO" no app.js):
   ao abrir o campo para digitação, errar virou possível — e a mensagem
   de erro sozinha não diz ONDE errou quando o formulário é longo. */
.campo-invalido {
  border-color: var(--f) !important;
  background: color-mix(in srgb, var(--f) 8%, transparent);
}
.doc-ok { color: var(--marca-amarelo); font-weight: 800; }
.doc-pend { color: var(--marca-vermelho); font-weight: 800; }
.linha-busca {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  margin: 10px 0 6px;
}
.linha-busca input[type="search"] { flex: 1 1 260px; }
.linha-busca .dica { margin: 0; }

/* Histórico unificado + integrante inativo */
.ent-tag { font-size: .72rem; padding: 2px 8px; border-radius: 999px; white-space: nowrap; }
.ent-presenca   { background: rgba(122,15,18,.12);  color: #7a0f12; }
.ent-integrante { background: rgba(40,90,180,.12);  color: #24508f; }
.ent-evento     { background: rgba(200,137,11,.16); color: #8a5d06; }
.ent-fantasia   { background: rgba(110,60,150,.12); color: #5d3080; }
/* Acesso (migração 38) em VERMELHO forte, e não numa cor a mais da
   paleta: mudança de permissão é a linha que se procura quando algo
   deu errado, e ela tem de saltar no meio de trezentas linhas de
   chamada. É a única entidade que altera QUEM PODE FAZER o resto. */
.ent-acesso     { background: rgba(176,0,32,.14);   color: #8c0018; font-weight: 700; }
/* O módulo escreve na auditoria desde a `75` e a tarja saía sem cor
   nenhuma — '.ent-' + entidade, e '.ent-prestacao' nunca existiu.
   Verde-escuro, o mesmo do '.selo-presta': as duas coisas falam do
   mesmo módulo. */
.ent-prestacao  { background: rgba(31,111,92,.14);  color: #1f6f5c; font-weight: 700; }
.int-inativo { opacity: .5; }
.tag-saiu { color: #b3241a; font-weight: 600; }
/* Pendência do mínimo, ao lado do nome da ala em Cadastros ▸ Alas.
   Mais discreta que '.sit--nao': aqui ela divide a linha com o nome e
   com o selo de ala inativa, e não pode competir com eles. */
.tag-falta { display: inline-block; color: var(--marca-vermelho);
  border: 1px solid var(--marca-vermelho); border-radius: 999px;
  padding: 1px 8px; font-size: .72rem; font-weight: 700; white-space: nowrap;
  vertical-align: middle; }
.tipos-box { margin-top: 14px; border-top: 1px solid var(--border); padding-top: 10px; }
.tipos-box summary { cursor: pointer; font-weight: 600; color: var(--muted); padding: 4px 0; }

/* ---------- MENOR e PCD nos documentos impressos ----------
   Na folha não existe hover: a marca precisa estar escrita. Fundo
   claro com borda para sobreviver à impressão em preto e branco, que
   é como a maior parte sai no barracão. */
.pm-selo { display: inline-block; font-size: .52rem; font-weight: 800;
  letter-spacing: .06em; padding: 0 3px; border-radius: 3px;
  border: 1px solid currentColor; vertical-align: middle; line-height: 1.5; }
.pm-menor { color: #24406e; }
.pm-pcd   { color: #52277a; }
#mapaPrint .pf-cel .pm-selo { display: block; margin-top: 1px; font-size: .46rem; }
#gradePrint .pg-cell.g-NA { color: #aaa; }

/* Checklist de documentos na lista de pessoas: um por linha, para a
   coordenação bater o olho e ver QUAL papel falta. */
.doc-menor label { display: flex; }
.doc-menor label + label { margin-top: 2px; }
.doc-cont { color: var(--muted); font-weight: 700; font-size: .7rem; }
.form-doc { align-items: flex-end; }

/* O que falta, por nome, na lista de menores. Vermelho porque é
   cobrança com prazo de regulamento, não informação neutra. */
.doc-falta { color: var(--f); font-weight: 600; }
/* FORA DO PRAZO (16/08/2026). Um degrau acima de '.doc-falta': falta é
   estado, atraso é cobrança. Vem em negrito e com fundo, porque no
   relatório dos menores as duas linhas aparecem juntas na mesma célula
   — "falta: X" e "fora do prazo: Y" — e sem contraste a segunda some
   dentro da primeira. */
.doc-atraso {
  display: inline-block; margin-top: 2px; padding: 1px 5px; border-radius: 4px;
  background: rgba(179,36,26,.12); color: var(--f); font-weight: 700;
}
/* A LINHA INTEIRA marcada, e não só o selo: este relatório é lido de
   cima a baixo procurando quem cobrar. A faixa à esquerda dá a varredura
   que um selo de 8px no meio da linha não dá. */
.linha-atraso > td { background: rgba(179,36,26,.055); }
.linha-atraso > td:first-child { box-shadow: inset 3px 0 0 var(--f); }
.sit--atraso {
  background: var(--f); color: #fff; font-weight: 700;
}

/* Realce de 1,6s no cartão para onde o atalho levou: numa tela com
   seis cartões, rolar até o certo não basta — a pessoa precisa ver
   qual deles é a resposta ao clique dela. */
.realce { animation: realce-pulso 1.6s ease-out; }
@keyframes realce-pulso {
  0%   { box-shadow: 0 0 0 0 rgba(200,137,11,.65); }
  100% { box-shadow: 0 0 0 14px rgba(200,137,11,0); }
}

/* ============================================================
   CARTEIRINHA DO COMPONENTE

   Um cartão só, em dois lugares: a folha impressa (2 colunas em A4
   retrato) e a prévia. A imagem enviada pelo WhatsApp NÃO usa este
   CSS — ela é desenhada em canvas, no app.js, porque não existe
   jeito de rasterizar HTML sem biblioteca externa.
   ============================================================ */
.folha-cart { display: flex; flex-wrap: wrap; gap: 6mm; }
.cart {
  background: #fff; color: #1a1a1a;
  border: 1px solid #999; border-radius: 3mm; overflow: hidden;
  display: flex; flex-direction: column;
  break-inside: avoid; page-break-inside: avoid;
}
/* MEDIDA EXATA, e 'height' e não 'min-height': o cartão vertical é
   impresso em papel adesivo e colado num cartão RFID de 85,5 × 54 mm
   usado em pé. Com min-height, um nome de três linhas esticava o
   cartão para 89 mm e o adesivo passava a sobrar na borda — e o erro
   só apareceria depois de imprimir a folha inteira. Altura travada,
   conteúdo dimensionado para caber. */
.cart--h { width: 85.5mm; height: 54mm; }
.cart--v { width: 54mm;   height: 85.5mm; }
.cart--h, .cart--v { overflow: hidden; }

/* No vertical o QR ganha 36 mm contra os 24 do horizontal — mais que
   o dobro da área. É o que decide a leitura em quadra escura. */
.cart--v .cart-corpo {
  flex-direction: column; align-items: center; text-align: center;
  gap: 1mm; padding: 2mm; flex: 1 1 auto; justify-content: center;
}
.cart--v .cart-qr { width: 36mm; flex: 0 0 auto; }
.cart--v .cart-qr svg { width: 36mm; height: 36mm; }
.cart--v .cart-cod { font-size: 8pt; margin-top: .8mm; }
.cart--v .cart-dados { width: 100%; }
/* Nome em no máximo 2 linhas: com a altura travada, a terceira linha
   empurraria o rodapé para fora do cartão. */
.cart--v .cart-nome {
  font-size: 9.5pt; line-height: 1.15;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}
.cart--v .cart-funcao { font-size: 6.5pt; }
.cart--v .cart-ala { font-size: 7.5pt; margin-top: .8mm; }
.cart--v .cart-topo { padding: 1.5mm 2mm; }
.cart--v .cart-topo b { font-size: 6.5pt; }
.cart--v .cart-topo span { font-size: 5pt; }
.cart--v .cart-logo { width: 7mm; height: 7mm; }
.cart--v .cart-rodape { font-size: 5.5pt; padding: 1mm 2mm; }

/* O aviso de escala NÃO sai no papel: ele é instrução para a tela de
   impressão, e impresso viraria lixo no meio dos cartões. */
.cart-aviso {
  margin: 0 0 4mm; padding: 6px 10px; border-radius: 6px;
  background: rgba(200,137,11,.18); color: #7a5205; font-size: 10px;
}
@media print { .cart-aviso { display: none !important; } }

.sel-formato { font-size: .8rem; padding: 4px 6px; border-radius: 6px; }
.cart-topo {
  display: flex; align-items: center; gap: 3mm;
  background: #7a0f12; color: #fff; padding: 2mm 3mm;
  border-bottom: 1.2mm solid #c8890b;
}
.cart-logo { width: 9mm; height: 9mm; border-radius: 50%; object-fit: cover; flex: 0 0 auto; }
.cart-topo b { display: block; font-size: 8pt; letter-spacing: .03em; }
.cart-topo span { display: block; font-size: 6.5pt; opacity: .85; }
.cart-corpo { display: flex; gap: 3mm; padding: 3mm; flex: 1 1 auto; align-items: center; }
.cart-dados { flex: 1 1 auto; min-width: 0; }
.cart-nome { font-size: 11pt; font-weight: 700; line-height: 1.15; overflow-wrap: anywhere; }
.cart-funcao { font-size: 7pt; color: #666; margin-top: .5mm; }
.cart-ala { font-size: 8pt; font-weight: 700; color: #7a0f12; margin-top: 1.5mm; }
.cart-qr { flex: 0 0 auto; width: 24mm; text-align: center; }
.cart-qr svg { width: 24mm; height: 24mm; display: block; }
/* O código legível existe para ser DIGITADO quando o QR não lê —
   quadra escura, tela riscada, papel amassado. */
.cart-cod {
  font-family: ui-monospace, Consolas, monospace; font-size: 7.5pt;
  font-weight: 700; letter-spacing: .08em; margin-top: 1mm;
}
.cart-rodape {
  background: #f2f2f2; border-top: 1px solid #e0e0e0;
  padding: 1.5mm 3mm; font-size: 6.5pt; color: #555; text-align: center;
}
@media print {
  .folha-cart { gap: 4mm; }
  /* Tracejado porque o cartão vai ser RECORTADO — a linha é onde
     passa a tesoura, não um enfeite. */
  .cart { border: 1px dashed #666; }
}

/* ============================================================
   LEITURA DA CARTEIRINHA NA CHAMADA
   ============================================================ */
/* A fita do que foi lido. Fica na tela porque quem está na portaria
   com o celular na mão precisa conferir QUEM entrou — o bipe diz que
   leu, não diz quem. */
.scan-feed {
  width: 100%; max-width: 420px; display: flex; flex-direction: column; gap: 3px;
  font-size: .86rem; max-height: 190px; overflow-y: auto;
}
.scan-linha {
  padding: 5px 9px; border-radius: 7px; line-height: 1.25;
  background: var(--surface-2, rgba(0,0,0,.05));
}
.scan-linha b { font-weight: 800; margin-right: 4px; }
.scan-ok    { background: rgba(200,137,11,.16); }
.scan-aviso { background: rgba(200,137,11,.28); font-weight: 600; }
.scan-erro  { background: rgba(179,36,26,.16); color: var(--f, #b3241a); font-weight: 600; }
.scanner .balcao-linha { width: 100%; max-width: 420px; }

/* Como a presença foi marcada: QR (a pessoa estava com a carteirinha)
   ou ✋ (alguém marcou por ela). Discreto de propósito — é conferência,
   não a informação principal da linha. */
.tg-qr, .tg-mao {
  font-size: .58rem; font-weight: 800; letter-spacing: .04em;
  padding: 1px 4px; border-radius: 4px; vertical-align: middle;
}
.tg-qr  { background: rgba(200,137,11,.20); color: #7a5205; }
.tg-mao { background: var(--surface-2, rgba(0,0,0,.06)); color: var(--muted, #777); }
/* DOCUMENTO FORA DO PRAZO (16/08/2026). A Diretora de Carnaval fixou
   27/09 como limite para os menores, e pendente deixou de ser tudo a
   mesma coisa: pendente em agosto é rotina, pendente depois do prazo é
   assunto com o Juizado e vale −0,3 na nota.
   Este é o ÚNICO selo de linha que grita — os outros dois são
   conferência, este é cobrança. Escrito por extenso, e não como
   emoji: "atrasado" não depende de o aparelho ter a fonte certa, e
   ninguém precisa aprender o que o símbolo quer dizer. */
.tg-atraso {
  font-size: .58rem; font-weight: 800; letter-spacing: .04em;
  padding: 1px 4px; border-radius: 4px; vertical-align: middle;
  text-transform: uppercase;
  background: rgba(179,36,26,.14); color: var(--f, #b3241a);
}
/* Bipou pela carteirinha e não pela etiqueta — o operador confere que
   é a pessoa da frente dele. */
.via-cart { color: #7a5205; }
/* Botão dentro da fita de leitura ("Incluir e marcar presente").
   Vive na LINHA da pessoa: com a fila andando, um botão solto embaixo
   já estaria falando de outra pessoa quando a mão chegasse nele. */
.scan-btn {
  margin-left: 6px; padding: 3px 9px; border: none; border-radius: 6px;
  background: #7a0f12; color: #fff; font-size: .78rem; font-weight: 700;
  cursor: pointer; white-space: nowrap;
}
.scan-btn:disabled { opacity: .5; cursor: default; }

/* ============================================================
   AVISO DE OFFLINE

   Fica na barra de contexto, visível em TODAS as telas. Duas
   informações, e as duas importam na quadra:
     · a lista na tela é um retrato, e de quando ele é
     · quantas presenças ainda não saíram do celular

   Sem a segunda, quem lançou sessenta presenças na concentração não
   tem como saber se pode fechar o app — e vai fechar, e vai perder.
   ============================================================ */
.aviso-offline {
  font-size: .74rem; font-weight: 700; line-height: 1.2;
  padding: 3px 9px; border-radius: 999px;
  background: rgba(200,137,11,.20); color: #7a5205;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%;
}
@media (max-width: 520px) {
  /* No celular ele ganha a linha inteira: espremido entre o título e o
     seletor de ala, viraria reticências e não avisaria nada. */
  .aviso-offline { flex: 1 1 100%; order: 9; text-align: center; white-space: normal; }
}

/* ============================================================
   MURAL DE RECADOS
   ============================================================ */
.form-recado { display: flex; flex-wrap: wrap; gap: 10px; align-items: flex-end; margin-top: 10px; }
.form-recado .grow2 { flex: 1 1 100%; }
.form-recado textarea {
  width: 100%; resize: vertical; font: inherit; padding: 8px 10px;
  border-radius: 8px; border: 1px solid var(--border);
  background: var(--surface, #fff); color: inherit;
}

.recado {
  border: 1px solid var(--border); border-radius: 12px;
  padding: 12px 14px; margin-top: 10px; background: var(--surface, #fff);
}
/* Urgente ganha a barra vermelha da escola. Dois níveis só: escala
   longa vira tudo urgente em duas semanas. */
.recado--urgente { border-left: 5px solid #7a0f12; }
/* Já confirmado desce de tom — o que a pessoa procura ao abrir o
   Mural é o que ela ainda NÃO leu. */
.recado--lido { opacity: .72; }
.recado--velho { opacity: .5; }
.recado-topo { display: flex; justify-content: space-between; gap: 10px; align-items: flex-start; }
.recado-topo h4 { margin: 0; font-size: 1.02rem; line-height: 1.25; }
.recado-meta { margin: 3px 0 0; font-size: .76rem; color: var(--muted, #777); }
.recado-selo {
  flex: 0 0 auto; font-size: .72rem; font-weight: 700; white-space: nowrap;
  padding: 3px 9px; border-radius: 999px;
  background: rgba(200,137,11,.18); color: #7a5205;
}
.recado-corpo { margin-top: 8px; line-height: 1.5; overflow-wrap: anywhere; }
.recado-link { margin: 8px 0 0; font-size: .88rem; }
.recado-acoes { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.recado-acoes .btn { padding: 6px 12px; font-size: .82rem; }
/* Quem ainda não confirmou: é a razão de o Mural existir. "12 de 20
   leram" ainda obriga o autor a descobrir na mão quais são os oito. */
.recado-falta {
  margin-top: 10px; padding: 9px 12px; border-radius: 9px;
  background: var(--surface-2, rgba(0,0,0,.05)); font-size: .86rem;
}
.falta-lista { margin: 6px 0 0; padding-left: 18px; }
.falta-lista li { margin: 2px 0; }
.falta-lista small { color: var(--muted, #777); }

/* Contador de pendência no cartão do Início. Número no Início é o que
   faz alguém abrir; sem ele, recado urgente espera a pessoa lembrar. */
.tema-badge {
  display: inline-block; min-width: 20px; text-align: center;
  padding: 1px 6px; border-radius: 999px; margin-left: 4px;
  background: #7a0f12; color: #fff; font-size: .72rem; font-weight: 800;
  vertical-align: middle;
}

/* ============================================================
   ACERVO — samba, desfiles, história e diretoria
   ============================================================ */
.form-acervo { display: flex; flex-wrap: wrap; gap: 10px; align-items: flex-end; margin: 10px 0 14px; }
.form-acervo .grow2 { flex: 1 1 100%; }
.form-acervo textarea {
  width: 100%; resize: vertical; font: inherit; padding: 8px 10px;
  border-radius: 8px; border: 1px solid var(--border);
  background: var(--surface, #fff); color: inherit;
}

/* DOCUMENTOS DA TEMPORADA — sinopse, regulamento, critérios.

   A hierarquia visual aqui é o produto, não enfeite: o RESUMO ("o que
   muda para a escola") vem em destaque, ANTES do botão que abre o
   documento oficial. Ninguém lê quarenta páginas de regulamento; se a
   tela abrisse com o botão, a pessoa abriria o PDF, veria o tamanho e
   fecharia. As cinco linhas que importam têm de estar na frente. */
.doc-item {
  border: 1px solid var(--border);
  border-radius: var(--radius, 12px);
  padding: 12px 14px;
  margin-bottom: 12px;
  background: var(--surface-2);
}
.doc-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 10px; }
.doc-head h4 { margin: 0; font-size: 1rem; }
.doc-meta { margin: 2px 0 0; font-size: .8rem; color: var(--muted); }
.doc-resumo {
  margin: 10px 0;
  padding: 10px 12px;
  border-left: 3px solid var(--marca-amarelo, #f5b301);
  border-radius: 0 8px 8px 0;
  background: color-mix(in srgb, var(--marca-amarelo, #f5b301) 12%, transparent);
}
.doc-resumo b {
  display: block; font-size: .72rem; text-transform: uppercase;
  letter-spacing: .04em; opacity: .75; margin-bottom: 4px;
}
.doc-resumo p { margin: 0; }
.doc-item details { margin-top: 8px; }
.doc-item summary { cursor: pointer; font-size: .88rem; color: var(--muted); }
/* <pre> pelo mesmo motivo da letra do samba: a quebra de linha de uma
   sinopse é do autor, e em parágrafo corrido o texto vira outra coisa. */
.doc-texto {
  white-space: pre-wrap; font: inherit; margin: 8px 0 0;
  max-height: 60vh; overflow: auto;
  padding: 10px; border-radius: 8px; background: var(--surface);
}

/* Um <details> por ano. O mais novo abre sozinho: é o samba que a
   escola está decorando agora, e é o que quase toda visita ao módulo
   veio buscar. */
.samba { border-bottom: 1px solid var(--border); padding: 10px 0; }
.samba summary { cursor: pointer; font-size: 1rem; }
.samba-atual {
  font-size: .7rem; font-weight: 800; padding: 1px 7px; border-radius: 999px;
  background: rgba(200,137,11,.20); color: #7a5205; vertical-align: middle;
}
.samba-meta { margin: 6px 0; font-size: .84rem; color: var(--muted, #777); }
/* <pre> e não <p>: a quebra de verso da letra é significativa — em
   parágrafo o samba vira prosa e ninguém consegue acompanhar cantando. */
.samba-letra {
  white-space: pre-wrap; font-family: inherit; font-size: .95rem; line-height: 1.65;
  margin: 8px 0 0; padding: 12px 14px; border-radius: 10px;
  background: var(--surface-2, rgba(0,0,0,.04));
}

.linha-tempo { list-style: none; margin: 8px 0 0; padding: 0; }
.linha-tempo li {
  display: flex; gap: 12px; padding: 10px 0;
  border-left: 2px solid var(--border); padding-left: 14px; margin-left: 6px;
}
.lt-ano { flex: 0 0 auto; color: #7a0f12; font-size: .95rem; min-width: 48px; }
.lt-txt p { margin: 4px 0 0; line-height: 1.5; }

.lista-diretoria { list-style: none; margin: 8px 0 0; padding: 0; }
.diretor {
  display: flex; flex-wrap: wrap; gap: 4px 10px; align-items: baseline;
  padding: 7px 0; border-bottom: 1px solid var(--border);
}
.diretor b { color: #7a0f12; font-size: .82rem; text-transform: uppercase; letter-spacing: .03em; flex: 0 0 190px; }
.diretor span { font-size: 1rem; }
.diretor small { color: var(--muted, #777); }
.diretor--antigo { opacity: .65; }
.gestoes { margin-top: 14px; }
.gestoes summary { cursor: pointer; color: var(--muted, #777); font-size: .88rem; }

@media (max-width: 520px) { .diretor b { flex: 1 1 100%; } }

/* ============================================================
   FOTOS

   A mesma galeria em quatro lugares: avaria, fantasia, lote e recado.
   Miniatura quadrada porque foto de peça vem em orientação
   imprevisível — retrato, paisagem, torta —, e uma grade que muda de
   altura a cada linha fica impossível de varrer com o olho.
   ============================================================ */
.fotos-grade {
  display: grid; gap: 8px; margin-top: 8px;
  grid-template-columns: repeat(auto-fill, minmax(96px, 1fr));
}
.foto-item {
  position: relative; margin: 0; border-radius: 9px; overflow: hidden;
  background: var(--surface-2, rgba(0,0,0,.05)); aspect-ratio: 1;
}
.foto-item img { width: 100%; height: 100%; object-fit: cover; display: block; }
.foto-item figcaption {
  position: absolute; left: 0; right: 0; bottom: 0;
  padding: 3px 6px; font-size: .68rem; line-height: 1.2;
  background: rgba(0,0,0,.6); color: #fff;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.foto-quebrada {
  display: flex; align-items: center; justify-content: center; height: 100%;
  font-size: .7rem; color: var(--muted, #777);
}
.foto-x {
  position: absolute; top: 4px; right: 4px; width: 22px; height: 22px;
  border: none; border-radius: 50%; cursor: pointer; line-height: 1;
  background: rgba(0,0,0,.55); color: #fff; font-size: .8rem; font-weight: 700;
}
/* O "adicionar" ocupa uma célula igual às fotos: assim ele fica no fim
   da fila em vez de flutuar num canto que ninguém procura. */
.foto-add {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 2px; aspect-ratio: 1; cursor: pointer; border-radius: 9px;
  border: 2px dashed var(--border); color: var(--muted, #777);
}
.foto-add span { font-size: 1.4rem; }
.foto-add small { font-size: .68rem; }
.foto-aviso { margin: 6px 0 0; font-size: .82rem; }
/* O prazo de expurgo fica à vista: foto de avaria é prova, e quem
   depende dela precisa saber até quando pode contar com ela. */
.foto-prazo { margin-top: 6px; font-size: .74rem; }

.fx-fotos { margin-top: 14px; }
.fx-fotos h4 { margin: 0 0 4px; font-size: .92rem; }
.recado-fotos { margin-top: 10px; }

/* Rodapé em TRÊS linhas: produto · cliente+versão · fabricante.
   A do meio ganha peso porque é a que se pede para ler quando alguém
   relata um problema — build antigo é cache, não bug. */
.app-footer .rod-produto { opacity: .8; }
/* A linha do cliente: o NOME na cor da escola, o técnico em texto
   comum. Mesma composição da linha da MAD logo abaixo — lá o nome vai
   no marinho da MAD, aqui no vinho da Tom Maior.

   O peso saiu do container e foi para o <b>: antes a linha inteira era
   bold, e o "Versão X · carimbo" competia com o nome da escola.

   MAS A PARTE TÉCNICA NÃO PERDE COR. É ela que se pede para ler quando
   alguém relata um problema — o build ficou visível em 07/08 justamente
   porque o David publicou, viu "Versão 2.5" e concluiu que a correção
   não funcionava, quando era o service worker servindo cache. Apagá-la
   em '--muted' desfaria essa decisão. A hierarquia vem do PESO, não da
   cor. */
.app-footer .rod-cliente { color: var(--txt, #222); font-size: .8rem; font-weight: 400; }
:root[data-theme="dark"] .app-footer .rod-cliente { color: var(--txt, #eee); }
.app-footer .rod-cliente b { color: var(--marca-vermelho); font-weight: 700; }
:root[data-theme="dark"] .app-footer .rod-cliente b { color: var(--marca-amarelo); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .app-footer .rod-cliente b { color: var(--marca-amarelo); }
}
/* E-mail embaixo do nome na lista de acessos: com sessenta contas, dois
   nomes iguais são indistinguíveis, e desativar a pessoa errada é o tipo
   de engano que ninguém percebe na hora. */
.lider-email { color: var(--muted, #777); font-size: .74rem; }

/* A ala em que a Fantasia está operando. Não é seletor — é a leitura do
   que foi escolhido na barra do topo (09/08/2026). Parece um campo para
   ficar alinhada com o seletor de fantasia ao lado, mas não recebe
   clique: escolher ala é numa tela só, num lugar só. */
.fz-ala-atual {
  display: inline-flex; align-items: center;
  min-height: var(--tap, 44px); padding: 10px 12px;
  border: 1px dashed var(--border); border-radius: 10px;
  background: var(--surface-2); color: var(--ink);
  font: inherit; font-weight: 600;
}


/* ============================================================
   AJUDA — chamados de suporte (10/08/2026)

   Cores: os selos de prioridade usam a paleta da própria escola
   (amarelo e vermelho da marca) e não verde/vermelho de semáforo —
   verde aqui é a cor da rival, e o app inteiro evita. "Resolvido"
   fica em amarelo-marca, que é como '.sit--ok' já resolve o mesmo
   problema na tela da meta.
   ============================================================ */
.aj-lista { display: flex; flex-direction: column; gap: 12px; }

.aj-card {
  border: 1px solid var(--border); border-radius: 12px;
  padding: 12px 14px; background: var(--surface);
}
/* Prazo estourado tem de saltar: é o número que diz se a tabela de
   prazos é real ou ficção. */
.aj-venceu { border-color: var(--f); box-shadow: inset 3px 0 0 var(--f); }

.aj-card-topo { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 4px; }
.aj-card-topo b { font-size: 1rem; margin-right: auto; }

.aj-meta { font-size: .78rem; color: var(--muted); margin-bottom: 8px; }
.aj-desc { white-space: pre-wrap; margin-bottom: 8px; }

.aj-prazo-linha {
  font-size: .85rem; padding: 6px 10px; border-radius: 8px;
  background: var(--surface-2); border: 1px solid var(--border); margin-bottom: 8px;
}

/* A resposta é o que o usuário veio ler: destacada e à esquerda do
   cartão, para achar sem procurar. */
.aj-resposta {
  border-left: 3px solid var(--marca-amarelo); padding: 8px 12px;
  background: var(--surface-2); border-radius: 0 8px 8px 0;
}
.aj-resposta p { white-space: pre-wrap; margin: 4px 0; }
.aj-resposta small { color: var(--muted); }

.aj-selo {
  display: inline-block; padding: 2px 9px; border-radius: 999px;
  font-size: .7rem; font-weight: 800; letter-spacing: .04em;
  text-transform: uppercase; white-space: nowrap;
}
.aj-s-aberto     { background: var(--marca-vermelho); color: #fff; }
.aj-s-em_analise { background: var(--marca-amarelo); color: #3a2600; }
.aj-s-resolvido  { border: 1px solid var(--border); color: var(--muted); }
.aj-s-sem_acao   { border: 1px solid var(--border); color: var(--muted); }
.aj-p-alta   { border: 1px solid var(--f); color: var(--f); }
.aj-p-media  { border: 1px solid var(--j); color: var(--j); }
.aj-p-baixa  { border: 1px solid var(--border); color: var(--muted); }
.aj-p-duvida { border: 1px solid var(--border); color: var(--muted); }

/* Contexto técnico dobrado: é para a MAD, não para quem abriu. Aberto
   o tempo todo empurraria a resposta para fora da tela. */
.aj-ctx { margin-top: 8px; }
.aj-ctx summary { cursor: pointer; font-size: .76rem; color: var(--muted); font-weight: 600; }
.aj-ctx-linhas { display: flex; flex-wrap: wrap; gap: 4px 16px; padding: 8px 0 0; font-size: .76rem; color: var(--ink-2); }

.aj-fotos { display: flex; gap: 8px; flex-wrap: wrap; margin: 8px 0; }
.aj-fotos img { max-width: 200px; border-radius: 8px; border: 1px solid var(--border); }

.aj-form-resp { border-top: 1px dashed var(--border); margin-top: 10px; padding-top: 10px; }
.aj-resp-linha { display: flex; gap: 10px; flex-wrap: wrap; margin-bottom: 8px; }
.aj-resp-linha label { display: flex; flex-direction: column; gap: 4px; font-size: .7rem; color: var(--muted); font-weight: 600; text-transform: uppercase; letter-spacing: .4px; }
.aj-form-resp textarea { width: 100%; margin-bottom: 8px; }

.aj-preview { display: flex; align-items: center; gap: 10px; margin-top: 8px; }
.aj-preview img { max-width: 160px; border-radius: 8px; border: 1px solid var(--border); }

@media (max-width: 560px) {
  .aj-resp-linha label { flex: 1 1 100%; }
  .aj-fotos img, .aj-preview img { max-width: 100%; }
}

/* ---------- Prestação de Contas ----------
   O SELO DIZ EM QUE MÃO A PRESTAÇÃO ESTÁ, e a cor acompanha a
   temperatura: cinza enquanto é rascunho da ala, âmbar enquanto
   alguém tem de agir, verde quando fechou, vermelho quando voltou.

   Deliberadamente NÃO reusa --p/--f/--j: aquelas três são presença
   (Presente, Falta, Justificada) e aparecem lado a lado com estas em
   quem acumula papéis. Cor repetida com significado diferente é o
   tipo de coisa que se aprende errado uma vez e não se desaprende. */
.pc-selo { display: inline-block; font-size: .68rem; font-weight: 800;
  letter-spacing: .06em; text-transform: uppercase; padding: 2px 8px;
  border-radius: 999px; vertical-align: middle; color: #fff; }
.pc-selo.e-rasc { background: #7d7b74; }
.pc-selo.e-env  { background: #b26a00; }
.pc-selo.e-conf { background: #8a5a00; }
.pc-selo.e-apr  { background: #2f6f2f; }
.pc-selo.e-paga { background: #0d2542; }
.pc-selo.e-dev  { background: #b3161b; }

/* O saldo que fechou certo. Só aqui o verde aparece — para o número
   que não pede ação nenhuma. */
.pc-ok { color: #2f6f2f; font-weight: 700; }

/* O QUE FALTA, na própria linha do gasto. Com vinte lançamentos,
   "3 sem comprovante" no alto da tela não diz QUAIS. */
.pc-falta { display: inline-block; font-size: .68rem; font-weight: 700;
  background: rgba(179,22,27,.12); color: #b3161b; border-radius: 5px;
  padding: 1px 6px; margin-right: 4px; }

/* Gasto do próprio bolso: some do saldo do adiantamento e entra no
   reembolso. São contas diferentes, e a linha precisa dizer qual. */
.pc-proprio { font-weight: 600; }

/* '.grow' existia só para '.field'. O formulário de gasto usa
   '.cv-campo', e a descrição precisa da largura — sem isto ela sai do
   mesmo tamanho do campo de valor. */
.cv-campo.grow { flex: 1 1 320px; }

/* O seletor de mês da competência. Classe de largura nomeada, como
   '.inp-pos' e '.inp-minimo' — em '.form-inline' todo input cresce
   ('flex: 1 1 140px'), e um seletor de mês esticado por 700px é o que
   o David viu e reprovou. */
.form-inline .inp-comp { flex: 0 0 auto; max-width: 210px; }

/* PDF no lugar da miniatura. Nota eletrônica não se fotografa, e um
   quadrado cinza escrito "PDF" diz mais do que um ícone genérico —
   quem procura o comprovante sabe na hora qual dos dois abrir. */
.pc-pdf { font-weight: 800; letter-spacing: .08em; color: var(--marca-vermelho); }

/* A FAIXA DE GRUPO na lista de gastos pendentes. Separa por destino
   do dinheiro — o adiantamento da escola de um lado, cada pessoa a
   reembolsar do outro. É faixa e não título de tabela porque os
   grupos convivem numa lista só, e o olho precisa saber onde um
   termina sem perder as colunas. */
.pc-grupo td {
  background: var(--barra-grupo, rgba(200,137,11,.10));
  font-size: .88rem; padding-top: 10px; padding-bottom: 10px;
}
.pc-grupo-rot { display: flex; align-items: center; gap: 8px; cursor: pointer; }
.pc-grupo-rot input { width: 18px; height: 18px; flex: none; }
/* A caixa de cada gasto tem o mesmo tamanho da do grupo: no celular,
   alvo de toque menor que isso erra. */
#pcListaPendentes tbody input[type="checkbox"] { width: 18px; height: 18px; }

@media (prefers-color-scheme: dark) {
  .pc-grupo td { background: rgba(240,181,42,.10); }
}

@media (prefers-color-scheme: dark) {
  .pc-ok { color: #55b555; }
  .pc-falta { background: rgba(224,90,90,.18); color: #e05a5a; }
}
