* { box-sizing: border-box; }
html { font-size: 100%; }
body {
  margin: 0; font-family: var(--fonte); font-size: 1rem; line-height: 1.5;
  color: var(--texto); background: var(--fundo);
}
h1 { font-family: var(--fonte-editorial); font-weight: 600; font-size: 1.6rem; line-height: 1.25; margin: 0 0 0.75rem; }
h2 { font-size: 1.15rem; margin: 1.5rem 0 0.5rem; }
h3 { font-size: 1.05rem; margin: 0; }
p { margin: 0 0 0.75rem; }
a { color: var(--tinta); }
.suave { color: var(--suave); font-size: 0.925rem; }
.mono { font-family: var(--fonte-mono); }
.salto { position: absolute; left: -999px; top: 0; background: var(--ouro); color: var(--tinta); padding: 0.5rem 1rem; z-index: 50; }
.salto:focus { left: 0; }
:focus-visible { outline: 3px solid var(--ouro); outline-offset: 2px; }

/* cabeçalho e menu */
.cabecalho { background: var(--tinta); color: #fff; padding: 0.75rem 1rem; }
.cabecalho-topo { display: flex; justify-content: space-between; align-items: baseline; gap: 1rem; flex-wrap: wrap; }
.marca { font-weight: 700; letter-spacing: 0.01em; }
.marca span { color: var(--ouro); }
.cabecalho .quem { font-size: 0.925rem; opacity: 0.9; }
.cabecalho .quem button { background: none; border: 0; color: inherit; text-decoration: underline; cursor: pointer; font: inherit; padding: 0 0 0 0.5rem; }
/* achados reais (produção): (1) position:sticky não pega num elemento que também tem overflow
   não-visible nele próprio (nav tem overflow-x:auto, para os separadores deslizarem em mobile) —
   por isso o sticky está num wrapper .nav-barra à parte, nunca em <nav>. (2) sticky só "flutua"
   dentro da altura do seu bloco-contentor (o elemento pai) — dentro do <header>, que só tinha a
   altura do título+nav, não havia espaço nenhum para o sticky ser visível. .nav-barra tem de ser
   irmão do <header> e do <main> (nunca filho do <header>), para o contentor relevante ser o
   <body> inteiro, com toda a altura da página.
*/
.nav-barra { position: sticky; top: env(safe-area-inset-top, 0px); z-index: 5; background: var(--tinta); padding: 0.5rem 0; }
nav {
  display: flex; gap: 0.25rem; overflow-x: auto; padding: 0 1rem; scrollbar-width: none;
}
nav a {
  color: #fff; text-decoration: none; padding: 0.6rem 0.9rem; white-space: nowrap;
  border-bottom: 3px solid transparent; min-height: var(--toque); display: inline-flex; align-items: center;
}
nav a[aria-current="page"] { border-bottom-color: var(--ouro); font-weight: 600; }

/* 60rem era demasiado apertado para tabelas de muitas colunas (Temas, Utilizadores) — espremia-as
   para uma largura fixa bem menor do que a janela real tinha disponível, forçando quebras de
   linha em nomes curtos e scroll horizontal mesmo em ecrãs largos (achado real, 2026-10-07). */
main { max-width: 90rem; margin: 0 auto; padding: 1.25rem 1rem 4rem; outline: none; }

/* Deslizar entre menus (js/deslizar.js): o JS trata do gesto horizontal e o browser só do vertical. As
   tabelas largas (.rolar) e a barra de menu são contentores de scroll próprios e continuam a poder
   deslizar na horizontal. O <main> é arrastado com transform: sem clip, o ecrã arrastado criava
   scroll horizontal na página. */
/* O <html> também: abaixo de um conteúdo curto o dedo cai nele (não no <body>) e, sem isto, o browser
   ficava com o gesto horizontal e cancelava-o. */
html, body { touch-action: pan-y pinch-zoom; }
body { overflow-x: clip; }
main { touch-action: pan-y pinch-zoom; will-change: auto; }
.rolar { touch-action: pan-x pan-y pinch-zoom; }

/* botões */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 0.4rem;
  min-height: var(--toque); padding: 0.5rem 1rem; border-radius: 10px; border: 1px solid var(--borda);
  background: var(--superficie); color: var(--tinta); font: inherit; font-weight: 600; cursor: pointer; text-decoration: none;
  transition: background 150ms, border-color 150ms;
}
.btn:hover { border-color: var(--tinta-clara); }
.btn-primario { background: var(--tinta); border-color: var(--tinta); color: #fff; }
.btn-primario:hover { background: var(--tinta-clara); }
.btn-perigo { color: var(--erro); border-color: var(--erro); }
.btn[disabled], .btn.desativado, .btn[aria-disabled="true"] { opacity: 0.5; cursor: not-allowed; pointer-events: none; }
/* botão só com ícone — o descritivo completo vive no aria-label/title, nunca como texto visível.
   SVG próprio em vez de emoji: a fonte do sistema (Windows/Chrome, achado real) nem sempre tem
   glifo para todos os emoji e mostra uma caixa em branco em vez do símbolo. */
.btn-icone { padding: 0.5rem; min-width: var(--toque); }
.btn-icone svg { display: block; }
.acoes { display: flex; gap: 0.5rem; flex-wrap: wrap; margin-top: 0.75rem; }
/* a classe e [hidden] têm a mesma especificidade — sem o 2º seletor, o CSS ganhava ao atributo
   nativo e a barra ficava sempre visível mesmo com hidden=true (achado real, apanhado pelo e2e). */
.barra-acoes-lote { display: flex; align-items: center; gap: 0.75rem; flex-wrap: wrap; margin-bottom: 0.75rem; padding: 0.6rem 0.9rem; background: var(--fundo); border: 1px solid var(--borda); border-radius: 10px; }
.barra-acoes-lote[hidden] { display: none; }
.barra-acoes-lote .btn svg { flex-shrink: 0; }
.contagem-lote { font-weight: 600; font-size: 0.9rem; }

/* cartões e chips */
.grelha { display: grid; gap: 0.75rem; grid-template-columns: repeat(auto-fill, minmax(min(100%, 19rem), 1fr)); }
.cartao { background: var(--superficie); border: 1px solid var(--borda); border-radius: var(--raio); box-shadow: var(--sombra); padding: 1rem; }
/* secções do formulário de tema (Nome/Tema/Acompanhamento/Backing/Notas) — mesmo cartão, só
   empilhado verticalmente com espaço entre cada um, em vez de lado a lado numa grelha. */
.secao { margin-bottom: 1rem; }
.cartao-topo { display: flex; justify-content: space-between; align-items: flex-start; gap: 0.75rem; }
/* Um título ou autor comprido sem espaços (ex.: um link colado) não pode empurrar o cartão para
   fora do ecrã a 375px; min-width:0 é necessário para overflow-wrap valer dentro de um flex item. */
.cartao h3, .cartao p, .aviso { overflow-wrap: anywhere; }
.cartao-topo > * { min-width: 0; }
.chip {
  display: inline-block; padding: 0.15rem 0.6rem; border-radius: 999px; font-size: 0.8rem; font-weight: 600;
  font-family: var(--fonte-mono);
  background: #EEF1F2; color: var(--tinta); white-space: nowrap;
}
/* Em desktop todas as linhas têm a altura da que leva o botão da guitarra (44 px de toque), para ficarem iguais. */
@media (min-width: 640px) { .linha-tema td { height: 63px; } }
/* A tabela de Temas usa a largura toda do ecrã (as outras páginas ficam centradas, com limite de largura). */
main:has(.tabela-temas), main:has(.tabela-combos) { max-width: none; }
@media (min-width: 1400px) { .tabela.tabela-temas .col-flexivel { max-width: 22rem; } }
.linha-tema .chips { flex-wrap: nowrap; }
.linha-tema .chip { white-space: nowrap; }
.chip-tipo { background: var(--cor-tipo); color: #fff; font-weight: 600; }
.chip-classe { background: color-mix(in srgb, var(--cor-classe) 14%, #fff); color: var(--cor-classe); border: 1px solid color-mix(in srgb, var(--cor-classe) 45%, #fff); font-weight: 600; }
.chip-sem_tema { background: var(--aviso-fundo); color: var(--aviso); }
.chip-com_tema { background: var(--ok-fundo); color: var(--ok); }
.chip-ausente, .chip-nao_convocado { background: var(--borda); color: var(--suave); }
.chips { display: flex; flex-wrap: wrap; gap: 0.4rem; }

/* Tabela de Temas (redesenho de 2026-10-07): em mobile só Classe/Aluno(s)/Tema ficam sempre
   visíveis (.col-desktop esconde o resto); clicar na linha abre o diálogo de detalhes completo,
   também por teclado (tabindex + Enter/Espaço, ver linhaTema() em pecas.js). Em desktop já não há
   nada escondido — todas as colunas estão à vista e "Editar"/"Ver" dá acesso direto — por isso a
   linha deixa de reagir ao clique (só o cabeçalho/células ordenáveis ou o link ficam ativos); o
   cursor de "clicável" só faz sentido abaixo do breakpoint onde o clique ainda faz algo. */
/* Só o aluno vai a negrito; tema e autor ficam em peso normal (pedido de 2026-11-02). */
.col-aluno .celula-texto { font-weight: 600; }
.icone-backing { display: inline-flex; align-items: center; justify-content: center; width: 1.6rem; height: 1.6rem; border-radius: 999px; font-weight: 700; }
.backing-ok { background: var(--ok-fundo); color: #1B7F4C; }
.backing-falta { background: var(--erro-fundo); color: var(--erro); }
.chip-backing-falta { background: var(--erro-fundo); color: var(--erro); }
/* Em desktop a tabela de Temas rola dentro de uma caixa da altura do ecrã: a barra de scroll
   horizontal fica sempre à vista no fundo, sem ter de descer até ao fim da lista; o cabeçalho
   fica fixo no topo da caixa. A barra é desenhada à mão porque Mac/Chrome a escondem sem rato. */
@media (min-width: 640px) {
  .rolar-temas { max-height: calc(100vh - 12rem); overflow: auto; }
  /* Sem a margem grande do fundo, a barra de scroll encosta ao fundo do ecrã. */
  main:has(.rolar-temas) { padding-bottom: 0.25rem; }
  .rolar-temas thead th { position: sticky; top: 0; z-index: 1; background: var(--superficie); }
  .rolar-temas::-webkit-scrollbar { height: 12px; width: 12px; }
  .rolar-temas::-webkit-scrollbar-thumb { background: #B9BEC2; border-radius: 6px; border: 2px solid var(--fundo); }
  .rolar-temas::-webkit-scrollbar-track { background: var(--fundo); }
}
.col-desktop { display: none; }
@media (max-width: 639px) {
  .linha-tema { cursor: pointer; }
  .linha-tema:hover, .linha-tema:focus-visible { background: var(--fundo); }
}
@media (min-width: 640px) {
  .col-desktop { display: table-cell; }
}

/* Cabeçalho ordenável: botão a ocupar o <th> todo, sem o "balão" de botão por cima do fundo já
   claro do cabeçalho da tabela — só herda a tipografia e ganha cursor + seta (▲/▼) quando ativo. */
.th-ordenar {
  all: unset; cursor: pointer; display: flex; align-items: center; width: 100%; min-height: var(--toque);
}
.th-ordenar:hover, .th-ordenar:focus-visible { color: var(--tinta); }

/* avisos, barras, filtros */
.aviso { border-radius: var(--raio); padding: 0.75rem 1rem; margin-bottom: 1rem; background: var(--aviso-fundo); color: var(--aviso); }
.aviso.erro { background: var(--erro-fundo); color: var(--erro); }
.aviso.ok { background: var(--ok-fundo); color: var(--ok); }
.barra { height: 0.6rem; border-radius: 999px; background: var(--borda); overflow: hidden; margin: 0.35rem 0; }
.barra > span { display: block; height: 100%; background: var(--ouro); border-radius: 999px; }
.filtros { display: flex; gap: 0.4rem; flex-wrap: wrap; margin: 0.75rem 0 1rem; }
.filtro { min-height: var(--toque); padding: 0 0.9rem; border-radius: 999px; border: 1px solid var(--borda); background: var(--superficie); font: inherit; cursor: pointer; }
.filtro[aria-pressed="true"] { background: var(--tinta); color: #fff; border-color: var(--tinta); }

/* formulários */
.campo { margin-bottom: 1rem; }
.campo label, .campo legend { display: block; font-weight: 600; margin-bottom: 0.25rem; padding: 0; }
.campo label.rotulo-leve { font-weight: 400; }
input[type="text"], input[type="search"], input[type="number"], select, textarea {
  width: 100%; min-height: var(--toque); padding: 0.5rem 0.75rem; font: inherit; color: inherit;
  border: 1px solid var(--borda); border-radius: 10px; background: #fff;
}
textarea { min-height: 5.5rem; }
fieldset { border: 0; padding: 0; margin: 0 0 1rem; }
.erro-campo { color: var(--erro); font-size: 0.9rem; margin: 0.25rem 0 0; }
.segmentos { display: flex; gap: 0.4rem; flex-wrap: wrap; }
/* flex: 1 1 8rem do .segmento controla a largura na horizontal, mas passa a controlar a altura
   assim que o eixo principal roda para coluna — sem isto, cada opção ficava com ~8rem de altura. */
.segmentos-vertical { flex-direction: column; flex-wrap: nowrap; }
.segmentos-vertical .segmento { flex: none; }
.segmento { flex: 1 1 8rem; }
.segmento input { position: absolute; opacity: 0; }
.segmento label {
  display: flex; align-items: center; justify-content: center; min-height: var(--toque); padding: 0 0.75rem; margin: 0;
  border: 1px solid var(--borda); border-radius: 10px; background: #fff; cursor: pointer; font-weight: 600; text-align: center;
}
.segmento input:checked + label { background: var(--tinta); border-color: var(--tinta); color: #fff; }
.segmento input:focus-visible + label { outline: 3px solid var(--ouro); outline-offset: 2px; }
.duracao { display: flex; align-items: center; gap: 0.5rem; }
.duracao input { width: 5rem; text-align: center; }
.duracao .btn { min-width: var(--toque); padding: 0; font-size: 1.25rem; }
.participante { display: flex; align-items: center; gap: 0.5rem; background: #EEF1F2; border-radius: 999px; padding: 0.25rem 0.25rem 0.25rem 0.75rem; }
.participante input { width: 7rem; min-height: var(--toque); padding: 0.15rem 0.5rem; border-radius: 999px; }
.participante button { border: 0; background: transparent; cursor: pointer; font-size: 1.1rem; min-width: var(--toque); min-height: var(--toque); }
.resultados { list-style: none; margin: 0.4rem 0; padding: 0; border: 1px solid var(--borda); border-radius: 10px; background: #fff; }
.resultados li button { width: 100%; text-align: left; border: 0; background: none; min-height: var(--toque); padding: 0 0.75rem; font: inherit; cursor: pointer; }
.resultados li + li { border-top: 1px solid var(--borda); }

/* diálogos e avisos flutuantes */
dialog.modal { border: 0; border-radius: var(--raio); padding: 1.25rem; max-width: min(92vw, 30rem); width: 100%; box-shadow: 0 10px 40px rgba(0,0,0,0.25); }
dialog.modal::backdrop { background: rgba(26, 26, 31, 0.55); }
.erro-form { color: var(--erro); min-height: 1.25rem; margin: 0.25rem 0 0; }
.toasts { position: fixed; left: 0; right: 0; bottom: 1rem; display: flex; flex-direction: column; align-items: center; gap: 0.5rem; pointer-events: none; z-index: 60; }
.toast { background: var(--tinta); color: #fff; padding: 0.7rem 1rem; border-radius: 10px; box-shadow: var(--sombra); max-width: 92vw; }
.toast-erro { background: var(--erro); }
.toast-ok { background: var(--ok); }

/* tabelas simples — adaptável (achado real, 2026-10-07): por omissão as células não quebram linha
   (nomes/badges/datas curtos ficam sempre numa só linha, em vez de partidos ao meio), só o texto
   livre que pode mesmo ser longo (.col-flexivel: autor, tema, aluno(s), observações) é que quebra
   — assim é esse texto que absorve o aperto do ecrã, não as colunas curtas. .rolar continua a
   existir como rede de segurança, mas só entra em jogo quando mesmo assim não há espaço nenhum. */
.tabela { width: 100%; border-collapse: collapse; background: var(--superficie); border: 1px solid var(--borda); border-radius: var(--raio); overflow: hidden; }
.tabela th, .tabela td { padding: 0.55rem 0.75rem; text-align: left; border-bottom: 1px solid var(--borda); vertical-align: middle; white-space: nowrap; }
.tabela th { background: var(--fundo); font-family: var(--fonte-mono); font-weight: 500; font-size: 0.75rem; letter-spacing: 0.02em; color: var(--suave); }
.tabela tbody tr:hover { background: var(--fundo); }
.tabela td.num, .tabela th.num { text-align: right; }
/* Linhas todas com a mesma altura (pedido de 2026-10-11): o texto livre das colunas flexíveis (aluno,
   autor, tema, observações) fica numa só linha, cortado com reticências — o texto completo está no
   `title` e no diálogo de detalhes. É o `.celula-texto` que corta; a coluna só limita a largura. */
.tabela .col-flexivel { max-width: 8.5rem; }
@media (min-width: 640px) { .tabela .col-flexivel { max-width: 14rem; } }
.celula-linha { display: flex; align-items: center; gap: 0.4rem; min-width: 0; }
.celula-texto { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.mais-alunos {
  flex: none; border: 0; border-radius: 999px; padding: 0.1rem 0.5rem; cursor: pointer;
  font: inherit; font-size: 0.8rem; font-weight: 600; background: #EEF1F2; color: var(--tinta);
}
.mais-alunos:hover { background: var(--borda); }

/* Combos de outros professores (juntar/retirar alunos) */
.secao-combos { margin-top: 2rem; }
.lista-combo { list-style: none; margin: 0.5rem 0; padding: 0; }
.lista-combo li { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; padding: 0.3rem 0; border-top: 1px solid var(--borda); }
.lista-combo li > span { min-width: 0; overflow-wrap: anywhere; }
/* Página Combos: um tema por linha, instrumentos em colunas; verde = tem aluno, vermelho = Sem Aluno. */
.tabela-combos td { white-space: normal; vertical-align: middle; }
.tabela-combos .celula-tema { min-width: 14rem; }
.tabela-combos .celula-tema .suave { font-size: 0.8rem; }
.tabela-combos .celula-instrumento { min-width: 9rem; }
.tabela-combos .participante-combo { justify-content: flex-start; margin: 0.15rem 0; }
.tabela-combos .celula-acoes { white-space: nowrap; }
/* Fundo da célula branco; só o nome (verde) ou o "Sem Aluno" (vermelho) levam a etiqueta. */
.slot-vazio { display: inline-block; background: var(--erro-fundo); color: var(--erro); font-weight: 700; border-radius: 999px; padding: 0.15rem 0.75rem; }
.participante-combo { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; }
.participante-combo > span { flex: none; white-space: nowrap; font-weight: 600; background: var(--ok-fundo); color: var(--ok); border-radius: 999px; padding: 0.15rem 0.75rem; }
@media (max-width: 639px) {
  /* a linha vira cartão: cada célula com o seu rótulo à esquerda */
  .tabela-combos thead { display: none; }
  .tabela-combos, .tabela-combos tbody { display: block; background: transparent; border: 0; }
  .tabela-combos .linha-combo { display: block; background: var(--superficie); border: 1px solid var(--borda); border-radius: var(--raio); box-shadow: var(--sombra); margin-bottom: 0.75rem; overflow: hidden; }
  .tabela-combos td { display: grid; grid-template-columns: 6.5rem minmax(0, 1fr); align-items: center; gap: 0.5rem; border-bottom: 1px solid var(--borda); }
  .tabela-combos td[data-rotulo]::before { content: attr(data-rotulo); font-weight: 700; }
  .tabela-combos .celula-tema, .tabela-combos .celula-acoes { display: block; }
}
.btn-pequeno { min-height: var(--toque); padding: 0 0.75rem; font-size: 0.85rem; flex: none; }
.rolar { overflow-x: auto; }

/* colunas de acesso (link/código): botão + resultado lado a lado, nunca empilhados — cada coluna
   tem 1 só cabeçalho com nome próprio ("Acesso por link"/"Acesso por código"), em vez de várias
   colunas vazias de cabeçalho (achado real: ficava ilegível). */
.coluna-acesso { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; }
.resultado-acesso { display: inline-flex; align-items: center; gap: 0.35rem; }
.resultado-acesso code { font-size: 0.8rem; max-width: 14rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tabela-utilizadores td:first-child, .tabela-utilizadores th:first-child { padding-right: 0; }

.barra.ok > span { background: var(--ok); }
.barra.aviso > span { background: var(--aviso); }
.barra.erro > span { background: var(--erro); }
.colunas-sessoes { display: grid; gap: 0.75rem; grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr)); align-items: start; }
.coluna-sessao h3 { display: flex; justify-content: space-between; align-items: baseline; gap: 0.5rem; }
.cartao-peca { margin-bottom: 0.5rem; }
.cartao-peca select { width: 100%; margin-top: 0.4rem; }

.coluna-ensaio { min-height: 4rem; }
.coluna-ensaio h3 { display: flex; justify-content: space-between; align-items: baseline; gap: 0.5rem; }
.indicador-confirmados { font-family: var(--fonte-mono); font-size: 0.8rem; }

/* Reformulação do ecrã Ensaios: lista de dias, cada um expansível (fica sempre vertical, mesmo em
   desktop — nunca em colunas lado a lado). */
.dias-ensaios { display: flex; flex-direction: column; gap: 0.75rem; margin-top: 0.75rem; }
.dia-ensaio { padding: 0; overflow: hidden; }
.dia-ensaio-cabecalho {
  width: 100%; display: flex; justify-content: space-between; align-items: center; gap: 0.75rem;
  min-height: var(--toque); padding: 1rem; border: 0; background: none; font: inherit; font-weight: 600;
  color: inherit; cursor: pointer; text-align: left;
}
.dia-ensaio-corpo { padding: 0 1rem 1rem; display: flex; flex-direction: column; gap: 0.75rem; }

/* Cada elemento (aluno) de uma banda, com destaque verde/vermelho consoante respondeu que vai ou
   não vai — cinza enquanto não há resposta nenhuma. */
.lista-participantes { list-style: none; margin: 0.5rem 0; padding: 0; display: flex; flex-direction: column; gap: 0.25rem; }
.participante-resposta { padding: 0.25rem 0.5rem; border-radius: 8px; border-left: 4px solid var(--borda); font-size: 0.875rem; }
.participante-resposta.resposta-vou { border-left-color: var(--ok); background: var(--ok-fundo); }
.participante-resposta.resposta-nao-vou { border-left-color: var(--erro); background: var(--erro-fundo); }
.participante-resposta.resposta-pendente { border-left-color: var(--borda); }

/* Secção Confirmações: alunos agrupados por resposta, ao fundo do ecrã Ensaios. */
.confirmacoes-grelha { display: grid; gap: 0.75rem; grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr)); }
.confirmacoes-grupo h3 { margin: 0 0 0.5rem; font-size: 0.9375rem; }
.confirmacoes-grupo ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.25rem; font-size: 0.875rem; }
.confirmacoes-grupo.vou h3 { color: var(--ok); }
.confirmacoes-grupo.nao-vou h3 { color: var(--erro); }

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; scroll-behavior: auto !important; }
}
