/* =========================================================
   Componente: Bottom Sheet e Command Palette (overlays)
   ========================================================= */

.overlay-cf {
  position: fixed;
  inset: 0;
  background: rgba(10, 12, 20, 0.5);
  backdrop-filter: blur(2px);
  z-index: 1400;
  opacity: 0;
  transition: opacity var(--dur-base) var(--ease-out);
}
.overlay-cf.show { opacity: 1; }

/* ---------- Bottom Sheet ---------- */
.sheet-cf {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 1401;
  background: var(--bg-surface);
  border-top-left-radius: var(--radius-panel);
  border-top-right-radius: var(--radius-panel);
  box-shadow: var(--shadow-xl);
  transform: translateY(100%);
  transition: transform var(--dur-base) var(--ease-out);
  max-height: 88vh;
  display: flex;
  flex-direction: column;
  padding-bottom: env(safe-area-inset-bottom, 0);
}
.sheet-cf.show { transform: translateY(0); }
.sheet-cf__handle {
  width: 40px; height: 4px;
  border-radius: var(--radius-full);
  background: var(--border-color);
  margin: var(--space-3) auto var(--space-2);
  flex-shrink: 0;
  cursor: grab;
}
.sheet-cf__header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 0 var(--space-5) var(--space-3);
}
.sheet-cf__title { font-size: var(--text-lg); font-weight: var(--fw-semibold); margin: 0; }
.sheet-cf__body { padding: 0 var(--space-5) var(--space-6); overflow-y: auto; }

/* Em telas largas o sheet vira um dialog centralizado (desktop-friendly) */
@media (min-width: 768px) {
  .sheet-cf:not(.sheet-force-bottom) {
    left: 50%; right: auto; bottom: auto; top: 50%;
    transform: translate(-50%, -50%) scale(0.96);
    width: min(520px, 92vw);
    border-radius: var(--radius-panel);
    max-height: 85vh;
    opacity: 0;
    transition: opacity var(--dur-base) var(--ease-out), transform var(--dur-base) var(--ease-out);
  }
  .sheet-cf:not(.sheet-force-bottom).show {
    transform: translate(-50%, -50%) scale(1);
    opacity: 1;
  }
  .sheet-cf:not(.sheet-force-bottom) .sheet-cf__handle { display: none; }
}

/* ---------- Command Palette ---------- */
.cmdk-cf {
  position: fixed;
  top: 14vh; left: 50%;
  transform: translateX(-50%) translateY(-8px);
  width: min(620px, 94vw);
  background: var(--bg-surface);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-panel);
  box-shadow: var(--shadow-xl);
  z-index: 1401;
  overflow: hidden;
  opacity: 0;
  transition: opacity var(--dur-fast) var(--ease-out), transform var(--dur-fast) var(--ease-out);
}
.cmdk-cf.show { opacity: 1; transform: translateX(-50%) translateY(0); }
.cmdk-cf__search {
  display: flex; align-items: center; gap: var(--space-3);
  padding: var(--space-4) var(--space-5);
  border-bottom: 1px solid var(--border-color);
}
.cmdk-cf__search i { color: var(--text-muted); }
.cmdk-cf__search input {
  flex: 1; border: none; background: transparent; outline: none;
  font-size: var(--text-md); color: var(--text-primary);
  font-family: var(--font-sans);
}
.cmdk-cf__search kbd {
  font-size: var(--text-xs); color: var(--text-muted);
  background: var(--bg-muted); border: 1px solid var(--border-color);
  border-radius: var(--radius-xs); padding: 2px 6px;
}
.cmdk-cf__list { max-height: 52vh; overflow-y: auto; padding: var(--space-2); }
.cmdk-cf__group-label {
  font-size: var(--text-xs); text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--text-muted); font-weight: var(--fw-semibold);
  padding: var(--space-3) var(--space-3) var(--space-2);
}
.cmdk-cf__item {
  display: flex; align-items: center; gap: var(--space-3);
  padding: var(--space-3);
  border-radius: var(--radius-sm);
  cursor: pointer;
  font-size: var(--text-base);
}
.cmdk-cf__item .ic {
  width: 30px; height: 30px; border-radius: var(--radius-xs);
  display: grid; place-items: center;
  background: var(--bg-muted); color: var(--text-secondary);
  flex-shrink: 0;
}
.cmdk-cf__item.active, .cmdk-cf__item:hover {
  background: var(--pitch-50);
  color: var(--pitch-700);
}
[data-theme='dark'] .cmdk-cf__item.active,
[data-theme='dark'] .cmdk-cf__item:hover {
  background: rgba(79, 70, 229, 0.18);
  color: var(--text-primary);
}
.cmdk-cf__empty { padding: var(--space-8); text-align: center; color: var(--text-muted); }

/* Gatilho da command palette no header (substitui a antiga busca) */
.cmdk-trigger {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex: 1;
  max-width: 400px;
  min-height: 40px;
  padding: 0.5rem 0.6rem 0.5rem 1rem;
  /* Leva "layout premium": busca em PILULA de superficie, como na referencia —
     o mesmo tratamento dos botoes redondos do cabecalho ao lado dela. */
  background: var(--bg-surface);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-full);
  color: var(--text-muted);
  font-size: var(--text-sm);
  cursor: pointer;
  transition: border-color var(--dur-fast) var(--ease-out), background var(--dur-fast) var(--ease-out);
}
.cmdk-trigger:hover { border-color: var(--border-strong); background: var(--bg-surface); }
.cmdk-trigger__text { flex: 1; text-align: left; }
.cmdk-trigger kbd {
  font-size: 11px; font-family: var(--font-sans);
  background: var(--bg-surface); border: 1px solid var(--border-color);
  border-radius: var(--radius-full); padding: 1px 8px; color: var(--text-muted);
}
@media (max-width: 991px) {
  .cmdk-trigger__text, .cmdk-trigger kbd { display: none; }
  .cmdk-trigger { flex: 0 0 auto; max-width: none; padding: 0.55rem; }
}

/* Alvo de toque do gatilho da busca global (bloco H; regra em buttons.css).
   Presente em TODAS as rotas — aparecia nas 18 do inventario.

   Precisa de min-WIDTH tambem, e nao so de min-height: a regra logo acima
   esconde o texto e o `kbd` no celular e deixa so a lupa, com `flex: 0 0 auto`,
   o que encolhia o botao para 33px de LARGURA. Medir alvo de toque so pela
   altura teria dado o gatilho como resolvido — foi o que quase aconteceu aqui,
   porque a altura ja estava em 44px e a largura nao. */
@media (hover: none) and (pointer: coarse), (max-width: 991.98px) {
  .cmdk-trigger {
    min-height: 44px;
    min-width: 44px;
    justify-content: center;
  }
}

/* =========================================================
   O CORPO DO MODAL ROLA POR DENTRO — EM QUALQUER TAMANHO DE TELA

   A regra de tela cheia logo abaixo so vale em `max-width: 767.98px` ou
   `max-height: 600px`. Fora dessas duas faixas o `.modal-body` continuava com
   `overflow: visible` e o modal crescia sem limite: em Alunos o dialogo mede
   989px, entao qualquer janela de desktop com menos de ~1045px de altura
   (989 + as margens de 1,75rem) abre o formulario com o **Salvar fora da
   vista**. Um notebook de 768px de altura util e o caso comum, nao o raro.
   O Bootstrap deixa isso rolar no `.modal` inteiro, entao o botao existe e e
   alcancavel — mas so para quem descobre que aquilo rola.

   Este bloco e independente do defeito do stacking context (ver
   ui/modalHost.js): sobrevive a ele e continuaria valendo se os modais
   voltassem para dentro da pagina.

   E o mesmo efeito do `.modal-dialog-scrollable` do proprio Bootstrap,
   aplicado aos 9 modais de uma vez em vez de classe por classe — inclusive
   nos que vierem depois. Duas diferencas em relacao a classe original:

   1. O corte usa `100vh` e nao `100%`. A altura percentual so resolveria se o
      ancestral tivesse altura DEFINIDA, e `.modal-dialog-centered` usa
      `min-height` — altura que depende do proprio conteudo. Com `100vh` o
      limite e sempre o mesmo, venha de onde vier.
   2. O `<form>` fica ENTRE o `.modal-content` e o corpo/rodape (ver
      crudPage.js) e precisa repassar o flex adiante; o `.modal-dialog-scrollable`
      do Bootstrap pressupoe o corpo como filho direto e por isso sozinho nao
      resolveria nada aqui.
   ========================================================= */
.modal-content {
  max-height: calc(100vh - var(--bs-modal-margin) * 2);
}

/* =========================================================
   O MODAL VESTE O CARTAO (leva "layout premium", 2026-10-01).

   Os 9 modais do sistema eram o Bootstrap de fabrica: raio de 8px, fio cinza
   azulado (#dee2e6) sob o cabecalho e sobre o rodape, titulo em 20px. Agora
   sao o mesmo painel do resto: raio de PAINEL (20, o maior da escala — o
   conteiner que contem cartoes), superficie e fio do tema, cabecalho sem
   fio, rodape com fio sutil. Tudo pelas variaveis do proprio Bootstrap, sem
   reescrever a estrutura — o comportamento (foco, backdrop, rolagem por
   dentro, tela cheia no celular abaixo) nao muda.

   A superficie vem do NOSSO token, e nao do --bs-body-bg: assim o modal
   acompanha o tema mesmo se o data-bs-theme atrasar em relacao ao data-theme.
   ========================================================= */
.modal {
  --bs-modal-bg: var(--bg-surface);
  --bs-modal-color: var(--text-primary);
  --bs-modal-border-color: var(--card-border);
  --bs-modal-border-radius: var(--radius-panel);
  --bs-modal-inner-border-radius: calc(var(--radius-panel) - 1px);
  --bs-modal-box-shadow: var(--shadow-xl);
  --bs-modal-header-border-color: transparent;
  --bs-modal-footer-border-color: var(--border-color);
  --bs-modal-header-padding: var(--space-5) var(--space-6) var(--space-2);
  --bs-modal-padding: var(--space-5) var(--space-6);
  --bs-modal-footer-gap: var(--space-2);
}
.modal-content { box-shadow: var(--bs-modal-box-shadow); }
.modal-title {
  font-size: var(--text-lg);
  font-weight: var(--fw-bold);
  letter-spacing: -0.015em;
}
.modal-footer { padding: var(--space-4) var(--space-6); }
/* Fundo atras do modal: a tinta do escudo, nao o preto azulado de fabrica. */
.modal-backdrop {
  --bs-backdrop-bg: #0A1F14;
  --bs-backdrop-opacity: 0.45;
}
.modal-content > form {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
}
.modal-header,
.modal-footer {
  flex: none;
}
.modal-body {
  /* `min-height: 0` e obrigatorio: sem ele o item de flex assume o tamanho do
     conteudo (`auto`) e simplesmente nao rola. */
  min-height: 0;
  overflow-y: auto;
}

/* =========================================================
   FORMULARIO EM TELA CHEIA NO CELULAR (bloco H)

   Medido no Chrome, iPhone 390x844: o modal de Adicionar Aluno tinha **1789px
   de altura numa viewport de 844** (2,1 telas, 17 campos) e o `.modal-body`
   nao rolava por dentro (`overflow: visible`) — a pagina inteira e que rolava.
   Consequencia: o botao **Salvar ficava fora da vista** ao abrir. Mesma coisa
   em Turmas (1055px, 16 campos) e Professores (911px). Quem preenche um
   cadastro longo no celular tinha de rolar ate o fim para achar o botao, e o
   Cancelar ficava do lado dele — dois alvos parecidos no pior momento.

   A correcao e SO de CSS, de proposito: a estrutura
   `.modal-content > .modal-header + form > (.modal-body + .modal-footer)` e a
   mesma nos 9 modais do sistema (crudPage e mais 4 paginas), entao uma regra
   vale para todos, inclusive os que vierem depois. Trocar o componente por
   bottom sheet daria o mesmo ganho e jogaria fora validacao, focus trap e
   backdrop ja testados do Bootstrap.

   O corte e por TAMANHO DE JANELA, e nao por `pointer: coarse` como nos alvos
   de toque: aqui o que aperta e o espaco, nao o dedo. Num iPad em paisagem o
   modal centralizado cabe folgado e virar tela cheia so desperdicaria espaco.
   A segunda condicao (`max-height`) pega o celular DEITADO, que tem 844px de
   largura mas so 390px de altura — o caso em que a falta de espaco e pior.
   ========================================================= */
@media (max-width: 767.98px), (max-height: 600px) {
  .modal-dialog {
    margin: 0;
    max-width: none;
    width: 100%;
    height: 100%;
  }
  .modal-content {
    height: 100%;
    /* Desfaz o corte por `100vh` do bloco acima: aqui o modal e a tela
       inteira, e a altura certa e a do `.modal` (que ja e a viewport real).
       Sem isto sobraria a faixa das margens do Bootstrap no rodape — e em
       celular `100vh` ainda mede a viewport GRANDE, ignorando a barra do
       navegador. */
    max-height: none;
    border: 0;
    border-radius: 0;
    /* Coluna flex para o corpo poder tomar a sobra e o rodape ficar preso. */
    display: flex;
    flex-direction: column;
  }
  /* A cadeia de flex que faz o corpo rolar por dentro (o repasse pelo <form>,
     o `min-height: 0`, o rodape preso) agora vale em qualquer tamanho de tela
     e esta no bloco acima — aqui fica so o que e do celular. */
  .modal-body {
    /* Rolagem com inercia no iOS, como a de um app. */
    -webkit-overflow-scrolling: touch;
  }
  .modal-footer {
    /* Area segura do iPhone (bloco G): sem isto os botoes encostam no risco de
       gestos, que e justamente onde o dedo escorrega. */
    padding-bottom: calc(var(--space-3) + var(--safe-bottom));
  }
  /* Salvar e Cancelar deixam de disputar a mesma largura: o primario ocupa a
     linha inteira e o secundario fica embaixo. Dois alvos de 44px empilhados
     erram menos que dois lado a lado no canto da tela. */
  .modal-footer .btn-cf {
    flex: 1 1 100%;
    margin: 0;
  }
  .modal-header {
    padding-top: calc(var(--space-3) + var(--safe-top));
  }
}
