/*
 * Estruturas do portal Aura.
 *
 * Desde 2026-08-04 este arquivo **não tem cor própria**. A paleta, a tipografia, os raios e a escala
 * de espaçamento vêm dos arquivos de tema em `css/aura/temas/`, e `css/aura/aura-componentes.css`
 * cuida das regras de elemento (`body`, `a`, foco) e das classes `aura-*`.
 *
 * O que sobra aqui são as estruturas que o portal montou antes de o kit de temas existir — o painel
 * de estado da aula, os cartões de ação, o painel de salas, os blocos de resumo da saúde. Elas
 * continuam com os nomes de classe em português e passam a ler **só variáveis**, e é isso que faz os
 * cinco temas valerem para as sete telas sem reescrever marcação.
 *
 * Migrar essas estruturas para as classes `aura-*` do kit é o passo seguinte, tela por tela — ver
 * BKL-116. Enquanto conviverem, a regra é uma: nenhum valor de cor literal entra aqui. Um hexadecimal
 * neste arquivo é uma cor que um tema não consegue mudar.
 */

/* ---------------------------------------------------------------- casca */

.app-frame {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
}

/* `flex: 1` para o rodapé encostar no fim da janela mesmo numa tela curta — sem isso a assinatura
   sobe e fica no meio da página em telas vazias, como a de salas de uma escola nova. */
.dashboard,
.simple-page {
    flex: 1;
    margin: 0 auto;
    max-width: 1200px;
    padding: var(--sp-6) 20px 72px;
    width: 100%;
}

/* ---------------------------------------------------------------- rodapé */

.rodape {
    background: var(--bg);
    border-top: var(--bw) solid var(--line);
    display: flex;
    justify-content: center;
    padding: var(--sp-5) 20px;
}

.rodape-assinatura {
    color: var(--ink-2);
    font-size: var(--fs-label);
}

.rodape-assinatura strong {
    color: var(--ink);
    font-weight: 700;
}

/* Os sinais na cor de destaque do tema, o nome na cor do texto — é assim que a assinatura aparece nos
   cinco protótipos, cada um com a sua cor. */
.rodape-assinatura strong span {
    color: var(--assinatura-cor, var(--accent));
    font-weight: 800;
}

/*
 * A barra é tratada **por tema**, e não sempre escura. Nos protótipos, quatro das cinco são claras
 * com uma linha embaixo; só o Cyber E-dux usa a faixa com gradiente, porque o gradiente é a marca do
 * cliente. Forçar a faixa escura nos cinco foi o que mais os fez parecerem o mesmo tema com cores
 * diferentes — encontrado ao comparar com os protótipos em 2026-08-04.
 */
.topbar {
    align-items: center;
    background: var(--barra-fundo, var(--deep-grad, var(--deep)));
    border-bottom: var(--barra-borda, 0) solid var(--barra-borda-cor, transparent);
    color: var(--barra-texto, var(--ink-inv));
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-3) var(--sp-5);
    padding: 12px clamp(18px, 4vw, 40px);
}

/*
 * A marca é desenhada em CSS puro — sem imagem e sem SVG —, e **cada tema decide a forma dela**.
 *
 * O contrato vive no fim de cada arquivo de tema, e cobre as duas formas que os protótipos usam:
 *
 * - **A palavra dentro de uma placa** — pílula do Cyber E-dux, plaqueta de patrimônio da Ficha,
 *   tarja de censura da Tarja. Vem de `--marca-fundo`, `--marca-borda`, `--marca-raio`,
 *   `--marca-padding` e, na Ficha, `--marca-parafusos`.
 * - **Um disco ao lado da palavra** — Pátio e A luz da sala. Vem de `--marca-ponto`,
 *   `--marca-ponto-cor` e `--marca-ponto-halo`; com `--marca-ponto: 0` o disco não existe.
 *
 * Um tema pode usar as duas, uma, ou nenhuma. Foi essa generalidade que faltou na primeira versão:
 * eu tinha assumido "forma pequena ao lado da palavra" e nenhum dos cinco protótipos era só isso.
 */
.brand {
    align-items: center;
    background: var(--marca-fundo, transparent);
    background-image: var(--marca-parafusos, none);
    border: var(--marca-borda, 0) solid var(--marca-borda-cor, transparent);
    border-radius: var(--marca-raio, 0);
    color: var(--marca-cor, var(--barra-texto, var(--ink-inv)));
    display: inline-flex;
    font-family: var(--font-brand, var(--font-ui));
    font-size: var(--marca-tamanho, 18px);
    font-weight: var(--marca-peso, 600);
    gap: 10px;
    letter-spacing: var(--marca-espaco, 0.16em);
    line-height: 1;
    padding: var(--marca-padding, 0);
    text-decoration: none;
    text-transform: var(--marca-caixa, uppercase);
}

.brand:hover {
    color: var(--marca-cor, var(--barra-texto, var(--ink-inv)));
    text-decoration: none;
}

/* O disco. `width: 0` o apaga sem tirar o elemento da marcação, o que mantém uma única marcação
   para os cinco temas — quem decide se ele existe é o tema, não a tela. */
.brand-mark {
    background: var(--marca-ponto-cor, transparent);
    border-radius: 50%;
    box-shadow: var(--marca-ponto-halo, none);
    display: inline-block;
    flex: none;
    height: var(--marca-ponto, 0);
    width: var(--marca-ponto, 0);
}

/*
 * O nome vem do tema porque **um** dos cinco não se chama Aura: o Cyber E-dux é assinado com a marca
 * do cliente. Vindo de `content`, ele troca junto com o resto do tema, sem a marcação de todas as
 * telas ter de saber qual tema está em uso.
 *
 * O preço é acessibilidade: texto de `content` não é lido de forma confiável por todo leitor de tela.
 * Por isso o `<a class="brand">` carrega um `aria-label` com o nome do produto — quem ouve a página
 * ouve "Aura", que é o que ele é, independentemente de quem o assina na tela.
 */
.brand-nome::after {
    content: var(--marca-nome, "Aura");
}

.who {
    color: var(--barra-texto-2, var(--ink-inv-2));
    font-size: var(--fs-label);
}

.topbar-nav {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
}

.topbar-nav a {
    border-radius: var(--r-pill);
    color: var(--barra-texto-2, var(--ink-inv-2));
    padding: 8px 14px;
    text-decoration: none;
}

.topbar-nav a:hover {
    background: var(--barra-hover, rgb(255 255 255 / 0.14));
    color: var(--barra-texto, var(--ink-inv));
    text-decoration: none;
}

/* Operação à esquerda e maior; administração à direita e menor. A hierarquia está no tamanho e na
   posição, e não num título de seção que ninguém lê. */
.topbar-nav--operacao a {
    color: var(--barra-texto, var(--ink-inv));
    font-size: var(--fs-h3);
    font-weight: 600;
}

.topbar-nav--admin a {
    font-size: var(--fs-label);
}

.topbar-fim {
    align-items: center;
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-2) var(--sp-4);
    margin-left: auto;
}

.topbar-fim form {
    margin: 0;
}

/* Os controles da barra herdam a cor **dela**, e não a do resto da página: numa barra clara, um
   botão branco translúcido sobre branco desapareceria. */
.topbar-sair,
.tema-troca {
    background: transparent;
    border: var(--bw) solid var(--barra-linha, rgb(255 255 255 / 0.28));
    border-radius: var(--r-pill);
    color: var(--barra-texto, var(--ink-inv));
    font-size: var(--fs-label);
    margin: 0;
    padding: 7px 14px;
}

.topbar-sair:hover,
.tema-troca:hover {
    background: var(--barra-hover, rgb(255 255 255 / 0.22));
    color: var(--barra-texto, var(--ink-inv));
}

/* Seletor provisório dos cinco temas. Sai quando a escolha estiver feita — BKL-117. */
.tema-escolha {
    align-items: center;
    display: inline-flex;
    gap: 8px;
}

.tema-escolha select {
    background: transparent;
    border: var(--bw) solid var(--barra-linha, rgb(255 255 255 / 0.28));
    border-radius: var(--r-pill);
    color: var(--barra-texto, var(--ink-inv));
    font-size: var(--fs-label);
    padding: 7px 12px;
    width: auto;
}

/* A lista aberta é desenhada pelo sistema operacional, sobre fundo dele — herdar a cor da barra
   deixaria texto claro sobre lista clara. */
.tema-escolha select option {
    color: var(--ink);
}

/* ---------------------------------------------------------------- texto */

h1 {
    font-size: var(--fs-h1);
    font-weight: 600;
    line-height: 1.1;
    margin: 0 0 var(--sp-4);
}

h2 {
    font-size: var(--fs-h2);
    font-weight: 600;
    margin: 0 0 var(--sp-3);
}

p {
    text-wrap: pretty;
}

code {
    font-family: var(--font-mono);
}

.eyebrow,
.subtitle,
.hint,
.empty,
.signed-out,
.mudo {
    color: var(--ink-2);
}

.hint {
    font-size: var(--fs-support);
}

.migalha {
    color: var(--ink-2);
    font-size: var(--fs-label);
    margin: 0 0 var(--sp-2);
}

.migalha a {
    color: var(--ink-2);
    text-decoration: none;
}

.migalha a:hover {
    color: var(--brand);
    text-decoration: underline;
}

.pagina-cabecalho {
    align-items: flex-end;
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-4);
    justify-content: space-between;
    margin-bottom: var(--sp-2);
}

.pagina-cabecalho h1,
.pagina-cabecalho h2 {
    margin: 0;
}

/* ---------------------------------------------------------------- ações */

/*
 * A causa de a tela parecer "não fluida" era esta: todo botão tinha o mesmo peso e descia pela tela
 * empilhado por `margin-top`, em larguras diferentes. A regra agora é uma — botões vivem numa linha,
 * a ação principal primeiro, e o que destrói trabalho fica separado do resto.
 */
button {
    background: var(--brand);
    border: var(--bw) solid transparent;
    border-radius: var(--r);
    color: var(--brand-ink);
    cursor: pointer;
    font: inherit;
    font-weight: 600;
    margin-top: var(--sp-4);
    padding: 11px 20px;
}

button:hover:not(:disabled) {
    background: var(--brand-hover);
}

button:disabled {
    cursor: not-allowed;
    opacity: 0.55;
}

/*
 * O quinto estado, que faltava: **carregando**. Os protótipos têm uma seção "Ações · quatro níveis,
 * cinco estados", e o portal tinha quatro — só reduzia a opacidade.
 *
 * Não é enfeite. A faixa "Enviando…" existe para impedir clique duplo, e o botão que disparou a ação
 * é onde a pessoa está olhando no instante em que clica: é ali que a resposta precisa aparecer.
 * `cursor: progress` diz a mesma coisa ao ponteiro.
 */
button.is-loading {
    cursor: progress;
    opacity: 1;
}

.botao-giro {
    animation: auraGiro 0.9s linear infinite;
    border: 3px solid currentColor;
    border-radius: 50%;
    border-top-color: transparent;
    display: inline-block;
    height: 16px;
    margin-right: 8px;
    vertical-align: -3px;
    width: 16px;
}

@keyframes auraGiro {
    to { transform: rotate(360deg); }
}

/*
 * A secundária tem **a mesma forma** da primária, e é a forma que faz as duas parecerem da mesma
 * família. Antes a ação secundária era um link sublinhado encostado num botão sólido, e era o que
 * estava feio no cartão de sala.
 *
 * A declaração de forma é repetida para `a` porque a regra de `button` não alcança âncora. Os
 * protótipos demonstram os dois lado a lado justamente para provar que são indistinguíveis.
 */
a.secondary {
    border-radius: var(--r);
    border-style: solid;
    border-width: var(--bw);
    display: inline-block;
    font-weight: 600;
    padding: 11px 20px;
    text-decoration: none;
}

button.secondary,
a.secondary {
    background: var(--surface);
    border-color: var(--line-2);
    color: var(--ink);
}

button.secondary:hover:not(:disabled),
a.secondary:hover {
    background: var(--surface-2);
    color: var(--ink);
    text-decoration: none;
}

button.destrutiva {
    background: var(--danger);
    color: var(--danger-ink);
}

button.destrutiva:hover:not(:disabled) {
    filter: brightness(0.92);
}

/*
 * Destrutiva de contorno, como os protótipos desenham "Arquivar": fundo transparente, borda e texto
 * na cor de perigo. A diferença com a preenchida não é enfeite — a preenchida é para o que **destrói
 * trabalho agora** (desligar a sala), e o contorno para o que é grave e reversível (arquivar uma
 * sala, revogar uma matrícula). Preencher as duas igual apagaria essa distinção.
 */
button.destrutiva-contorno {
    background: transparent;
    border-color: var(--danger);
    color: var(--danger);
}

button.destrutiva-contorno:hover:not(:disabled) {
    background: var(--danger-fill);
    color: var(--danger);
}

/* Um link que é ação principal precisa ser o mesmo objeto que um botão. */
.botao {
    background: var(--brand);
    border: var(--bw) solid transparent;
    border-radius: var(--r);
    color: var(--brand-ink);
    display: inline-block;
    font-weight: 600;
    padding: 11px 20px;
    text-decoration: none;
}

.botao:hover {
    background: var(--brand-hover);
    color: var(--brand-ink);
    text-decoration: none;
}

/* A terciária é a mais fraca das três, e ainda assim tem forma: só o preenchimento sai. */
.terciaria {
    background: transparent;
    border: var(--bw) solid transparent;
    border-radius: var(--r);
    color: var(--brand);
    display: inline-block;
    font-weight: 600;
    padding: 11px 14px;
    text-decoration: none;
}

.terciaria:hover {
    background: var(--brand-fill);
    color: var(--brand);
    text-decoration: none;
}

.acoes {
    align-items: center;
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-3);
    margin-top: var(--sp-4);
}

.acoes button,
.acoes .botao,
.acoes .terciaria {
    margin: 0;
}

.acoes .afastar {
    margin-left: auto;
}

/* ---------------------------------------------------------------- formulário */

input,
textarea,
select {
    background: var(--surface);
    border: var(--bw) solid var(--line-2);
    border-radius: var(--r);
    color: var(--ink);
    font: inherit;
    padding: 11px 13px;
    width: 100%;
}

input:hover,
textarea:hover,
select:hover {
    border-color: var(--ink-2);
}

label {
    display: block;
    font-size: var(--fs-support);
    font-weight: 600;
    margin-bottom: 6px;
}

.filter {
    align-items: center;
    display: inline-flex;
    font-weight: 400;
    gap: 8px;
}

.filter input,
.targets input {
    width: auto;
}

.targets {
    color: var(--ink-2);
    font-size: var(--fs-support);
    margin-top: var(--sp-3);
}

.targets label {
    font-weight: 400;
}

/* ---------------------------------------------------------------- blocos */

.panel {
    background: var(--surface);
    border: var(--bw) solid var(--line);
    border-radius: var(--r-lg);
    box-shadow: var(--shadow-sm);
    margin: var(--sp-5) 0;
    max-width: 560px;
    padding: var(--sp-5);
}

.error {
    background: var(--danger-fill);
    border-left: 4px solid var(--danger);
    border-radius: var(--r);
    color: var(--ink);
    padding: var(--sp-3) var(--sp-4);
}

.text-danger {
    color: var(--danger);
}

.text-link {
    color: var(--brand);
}

/* ---------------------------------------------------------------- tabelas */

.devices {
    background: var(--surface);
    border: var(--bw) solid var(--line);
    border-collapse: collapse;
    border-radius: var(--r-lg);
    margin-top: var(--sp-4);
    overflow: hidden;
    width: 100%;
}

.devices caption {
    color: var(--ink-2);
    font-size: var(--fs-support);
    padding-bottom: var(--sp-2);
    text-align: left;
}

/* Mono no rótulo de coluna, como a identidade da Ficha pede: "códigos, contagens, cronômetro,
   rótulos de coluna". Não é estilo — mono separa o que se **confere** do que se **lê**, e um número
   que alguém vai comparar com outro número quer largura fixa. */
.devices th {
    background: var(--surface-2);
    font-family: var(--font-mono);
    font-size: var(--fs-label);
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

.devices th,
.devices td {
    border-bottom: var(--bw) solid var(--line);
    padding: 13px 15px;
    text-align: left;
}

.devices tr:last-child td {
    border-bottom: 0;
}

.devices tr.revoked {
    color: var(--ink-2);
}

.devices button {
    font-size: var(--fs-label);
    margin: 0;
    padding: 7px 13px;
}

/* ---------------------------------------------------------------- matrícula */

.ticket {
    background: var(--surface);
    border: var(--bw-strong) solid var(--brand);
    border-radius: var(--r-lg);
    margin-top: var(--sp-4);
    padding: var(--sp-5);
}

.ticket code {
    background: var(--surface-2);
    border-radius: var(--r);
    display: block;
    font-size: var(--fs-h2);
    font-weight: 600;
    letter-spacing: 0.06em;
    padding: var(--sp-3);
    word-break: break-all;
}

.ticket .hint {
    margin-bottom: 0;
}

/* ---------------------------------------------------------------- entrar */

.sign-in {
    margin: 0 auto;
    max-width: 440px;
    padding: 80px 24px;
}

/* No login a marca cresce, e é a única tela em que ela aparece sozinha, sem barra em volta. A forma
   continua inteiramente do tema: só a escala muda. */
.brand--grande {
    font-size: calc(var(--marca-tamanho, 20px) * 1.5);
    margin: 0 0 var(--sp-2);
}

.brand--grande .brand-mark {
    height: calc(var(--marca-ponto, 0px) * 1.4);
    width: calc(var(--marca-ponto, 0px) * 1.4);
}

.sign-in .subtitle {
    margin: 0 0 var(--sp-6);
}

.sign-in label {
    margin-top: var(--sp-4);
}

.sign-in button {
    width: 100%;
}

/* ---------------------------------------------------------------- aula */

/*
 * O painel de estado existe porque a versão anterior desta tela era uma pilha de cinco blocos de
 * peso igual, e o professor precisava descer até o quarto para saber se o Modo Foco estava ligado.
 * Aqui ele lê isso de dois metros de distância, sem rolar nada.
 */
.aula-estado {
    background: var(--deep-grad, var(--deep));
    border-radius: var(--r-lg);
    color: var(--ink-inv);
    padding: var(--sp-6);
}

.aula-estado-linha {
    align-items: center;
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-5);
    justify-content: space-between;
}

.aula-estado h1 {
    color: var(--ink-inv);
    font-size: var(--fs-h2);
    margin: 0;
}

.aula-cronometro {
    color: var(--accent);
    font-family: var(--font-mono);
    font-size: var(--fs-h3);
}

.aula-laboratorio {
    color: var(--ink-inv-2);
}

.aula-estado button {
    font-size: var(--fs-h3);
    font-weight: 700;
    margin: 0;
    padding: 16px 30px;
}

.aula-estado button.secondary {
    background: var(--surface);
    border-color: var(--surface);
}

.aula-chips {
    border-top: var(--bw) solid rgb(255 255 255 / 0.22);
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-3);
    margin-top: var(--sp-5);
    padding-top: var(--sp-5);
}

.chip {
    align-items: center;
    background: rgb(255 255 255 / 0.1);
    border: var(--bw) solid rgb(255 255 255 / 0.24);
    border-radius: var(--r-pill);
    display: inline-flex;
    font-size: var(--fs-support);
    gap: 10px;
    padding: 9px 16px;
}

/* 13 px é o mínimo do sistema para ponto de estado: abaixo disso ele desaparece em projeção. E a
   cor nunca vem sozinha — o texto ao lado diz a mesma coisa em palavra. */
.ponto {
    border-radius: 50%;
    flex: none;
    height: 13px;
    width: 13px;
}

.ponto-azul { background: var(--accent); }
.ponto-ambar { background: var(--warn); }
.ponto-verde { background: var(--ok); }
.ponto-neutro { background: var(--ink-2); }
.ponto-cinza { background: var(--line-2); }

/*
 * A faixa de retorno é a resposta ao clique duplo: um comando leva **até 10 segundos** para chegar
 * na máquina, e uma tela silenciosa nesse intervalo faz o professor clicar de novo. Também é onde
 * vive a frase que o produto não pode errar — "podem não ter recebido", nunca "não receberam",
 * porque o servidor de fato não sabe.
 */
.aula-envio {
    align-items: flex-start;
    border-radius: var(--r);
    display: flex;
    gap: var(--sp-3);
    margin-top: var(--sp-4);
    padding: var(--sp-4) var(--sp-5);
}

/*
    O aviso de saúde do topo — BKL-041. Mesma linguagem da faixa de envio da aula, de propósito:
    quem já viu uma reconhece a outra sem aprender nada novo. Fica em `warn` e não em `danger`
    porque nada aqui impede a aula de acontecer — é coisa para o técnico resolver hoje, não para a
    professora resolver agora.
*/
.aviso-saude {
    align-items: flex-start;
    background: var(--warn-fill);
    border: var(--bw) solid var(--warn);
    border-radius: var(--r);
    color: var(--ink);
    display: flex;
    gap: var(--sp-3);
    margin-bottom: var(--sp-5);
    padding: var(--sp-4) var(--sp-5);
}

.aviso-saude .ponto {
    background: var(--warn);
    margin-top: 5px;
}

.aviso-saude strong {
    display: block;
    font-size: var(--fs-h3);
    font-weight: 600;
}

.aviso-saude span {
    font-size: var(--fs-support);
}

/* Empurrado para a direita: o link é a saída, e fica onde o olho termina de ler a frase. */
.aviso-saude a {
    margin-left: auto;
    white-space: nowrap;
}

.aula-envio-enviando {
    background: var(--warn-fill);
    border: var(--bw) solid var(--warn);
    color: var(--ink);
}

.aula-envio-feito {
    background: var(--ok-fill);
    border: var(--bw) solid var(--ok);
    color: var(--ink);
}

.aula-envio .ponto {
    margin-top: 5px;
}

.aula-envio-enviando .ponto {
    animation: auraPulse 1s infinite;
    background: var(--warn);
}

.aula-envio-feito .ponto {
    background: var(--ok);
}

.aula-envio strong {
    display: block;
    font-size: var(--fs-h3);
    font-weight: 600;
}

.aula-envio span {
    font-size: var(--fs-support);
    line-height: 1.45;
}

@keyframes auraPulse {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.35; }
}

.aula-acoes {
    display: grid;
    gap: var(--sp-4);
    grid-template-columns: 1fr 1fr;
    margin-top: var(--sp-5);
}

/* Sem aula iniciada nada pode ser enviado, e isso não é escolha da tela: `RequireActiveLessonAsync`
   recusa no servidor. Apagar os cartões é dizer isso antes de alguém tentar. */
.aula-acoes[data-inativa="true"] .cartao {
    opacity: 0.5;
}

.cartao {
    background: var(--surface);
    border: var(--bw) solid var(--line);
    border-radius: var(--r-lg);
    box-shadow: var(--shadow-sm);
    padding: var(--sp-5);
}

.cartao-titulo {
    align-items: baseline;
    display: flex;
    gap: var(--sp-3);
    justify-content: space-between;
}

.cartao h2 {
    margin: 0;
}

.cartao-nota {
    color: var(--ink-2);
    font-size: var(--fs-label);
}

.cartao-contador {
    color: var(--ink-2);
    font-family: var(--font-mono);
    font-size: var(--fs-label);
}

.cartao p {
    margin: var(--sp-3) 0 0;
    min-height: 52px;
}

.cartao textarea {
    margin-top: var(--sp-3);
    min-height: 96px;
    resize: vertical;
}

.cartao button {
    width: 100%;
}

.cartao-botoes {
    display: flex;
    gap: var(--sp-3);
}

.cartao-botoes button {
    flex: 1;
}

/* A borda destacada não vem só: o rótulo "Ativo" ao lado do título diz o mesmo em palavra, para
   quem não distingue a cor. */
.cartao-foco-ativo {
    border: var(--bw-strong) solid var(--brand);
}

.cartao-estado {
    font-size: var(--fs-support);
    font-weight: 600;
}

.cartao-estado-ativo { color: var(--brand); }
.cartao-estado-inativo { color: var(--ink-2); }

.aula-historico {
    align-items: start;
    display: grid;
    gap: var(--sp-4);
    /* Uma coluna hoje. O histórico de recados entra como segunda quando existir o `GET` que hoje
       falta — só o `POST /messages` existe. Ver BKL-110. */
    grid-template-columns: 1fr;
    margin-top: var(--sp-5);
}

.shared-link {
    align-items: center;
    border-bottom: var(--bw) solid var(--line);
    display: flex;
    gap: var(--sp-4);
    justify-content: space-between;
    padding: var(--sp-3) 0;
}

.shared-link:last-child {
    border-bottom: 0;
}

.shared-link-enderecos {
    font-family: var(--font-mono);
    font-size: var(--fs-support);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.shared-link-detalhe {
    color: var(--ink-2);
    font-size: var(--fs-label);
}

.shared-link button {
    flex: none;
    font-size: var(--fs-label);
    margin: 0;
    padding: 7px 13px;
}

/* ---------------------------------------------------------------- painel de salas */

.laboratorios {
    display: grid;
    gap: var(--sp-4);
    grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));
    list-style: none;
    margin: 0;
    padding: 0;
}

.laboratorio {
    background: var(--surface);
    border: var(--bw) solid var(--line);
    border-radius: var(--r-lg);
    box-shadow: var(--shadow-sm);
    display: flex;
    flex-direction: column;
    gap: var(--sp-3);
    padding: var(--sp-5);
}

/* Aula em andamento é o único estado que muda a borda do cartão: é a informação que faz alguém
   escolher esta sala em vez de outra. */
.laboratorio--em-aula {
    border: var(--bw-strong) solid var(--brand);
}

.laboratorio h2 {
    margin: 0;
}

.laboratorio-estado {
    color: var(--ink-2);
    display: flex;
    flex-direction: column;
    font-size: var(--fs-support);
    gap: 6px;
}

.laboratorio-estado span {
    align-items: center;
    display: flex;
    gap: 8px;
}

.laboratorio-em-aula {
    color: var(--brand);
    font-weight: 600;
}

.laboratorio .acoes {
    margin-top: auto;
}

/* ---------------------------------------------------------------- resumo */

/*
 * Três números antes das três tabelas. A tela de saúde já dizia tudo, e dizia em três tabelas soltas
 * de peso igual — quem abre quer saber **se** há algo errado antes de descobrir **o quê**. Com os
 * três em zero, a página cabe numa olhada e ninguém desce.
 */
.resumo {
    display: grid;
    gap: var(--sp-4);
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    margin: 0 0 var(--sp-6);
}

.tile {
    background: var(--surface);
    border: var(--bw) solid var(--line);
    border-left: 5px solid var(--line-2);
    border-radius: var(--r-lg);
    box-shadow: var(--shadow-sm);
    padding: var(--sp-5);
}

.tile--atencao {
    border-left-color: var(--warn);
}

.tile--tranquilo {
    border-left-color: var(--ok);
}

/* Contagem em mono, pelo mesmo motivo do rótulo de coluna: os três números da saúde são lidos em
   conjunto, e largura fixa é o que permite comparar sem reler. */
.tile strong {
    display: block;
    font-family: var(--font-mono);
    font-size: var(--fs-h1);
    font-weight: 600;
    line-height: 1.1;
}

.tile span {
    color: var(--ink-2);
    display: block;
    font-size: var(--fs-support);
    margin-top: 6px;
}

.secao {
    background: var(--surface);
    border: var(--bw) solid var(--line);
    border-radius: var(--r-lg);
    box-shadow: var(--shadow-sm);
    margin-bottom: var(--sp-5);
    padding: var(--sp-5);
}

.secao h2 {
    margin-bottom: 6px;
}

.secao > p {
    color: var(--ink-2);
    margin-top: 0;
    max-width: 80ch;
}

.secao .devices {
    border: 0;
    box-shadow: none;
    margin-top: var(--sp-4);
}

/* ---------------------------------------------------------------- painel lateral */

.gaveta-fundo {
    background: rgb(0 0 0 / 0.55);
    inset: 0;
    position: fixed;
    z-index: 40;
}

.gaveta {
    background: var(--bg);
    display: flex;
    flex-direction: column;
    height: 100%;
    margin-left: auto;
    width: min(680px, 100%);
}

.gaveta-cabecalho {
    align-items: center;
    background: var(--deep-grad, var(--deep));
    color: var(--ink-inv);
    display: flex;
    justify-content: space-between;
    padding: var(--sp-5) var(--sp-6);
}

.gaveta-cabecalho h2 {
    color: var(--ink-inv);
    margin: 0;
}

.gaveta-cabecalho button {
    background: rgb(255 255 255 / 0.12);
    border: var(--bw) solid rgb(255 255 255 / 0.28);
    color: var(--ink-inv);
    font-size: var(--fs-label);
    margin: 0;
    padding: 7px 14px;
}

.gaveta-corpo {
    flex: 1;
    overflow-y: auto;
    padding: var(--sp-5) var(--sp-6);
}

.gaveta-rodape {
    align-items: end;
    background: var(--surface);
    border-top: var(--bw) solid var(--line);
    display: flex;
    gap: var(--sp-4);
    padding: var(--sp-4) var(--sp-6);
}

.gaveta-rodape label {
    margin: 0 0 6px;
}

.gaveta-rodape > div {
    max-width: 240px;
}

.gaveta-rodape button {
    flex: 1;
    font-size: var(--fs-h3);
    font-weight: 700;
    margin: 0;
}

.categoria {
    margin-bottom: var(--sp-5);
}

.categoria > span {
    color: var(--ink-2);
    font-size: var(--fs-label);
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

.categoria-itens {
    display: grid;
    gap: 10px;
    grid-template-columns: 1fr 1fr;
    margin-top: 10px;
}

.app-item {
    align-items: center;
    background: var(--surface);
    border: var(--bw) solid var(--line-2);
    border-radius: var(--r);
    color: var(--ink);
    cursor: pointer;
    display: flex;
    font-size: var(--fs-support);
    font-weight: 400;
    gap: var(--sp-3);
    margin: 0;
    padding: 12px 14px;
    text-align: left;
    width: 100%;
}

.app-item:hover:not(:disabled) {
    background: var(--surface-2);
    border-color: var(--ink-2);
}

.caixa {
    border: var(--bw-strong) solid var(--ink-2);
    border-radius: 4px;
    color: transparent;
    flex: none;
    font-size: 14px;
    height: 22px;
    line-height: 18px;
    text-align: center;
    width: 22px;
}

.app-item[aria-pressed="true"] .caixa {
    background: var(--brand);
    border-color: var(--brand);
    color: var(--brand-ink);
}

.fora-do-catalogo {
    border-top: var(--bw) solid var(--line);
    margin-top: var(--sp-5);
    padding-top: var(--sp-5);
}

.fora-do-catalogo input {
    font-family: var(--font-mono);
}

/* ---------------------------------------------------------------- zona de perigo */

/* Uma tira no fim da página, e não um bloco no meio dela. Desligar trinta computadores não pode
   ficar à mesma distância do dedo que "gerar código de matrícula". */
.zona-perigo {
    align-items: center;
    background: var(--surface);
    border: var(--bw) solid var(--danger);
    border-radius: var(--r-lg);
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-4);
    justify-content: space-between;
    margin-top: var(--sp-7);
    padding: var(--sp-5);
}

.zona-perigo p {
    margin: 0;
    max-width: 60ch;
}

.zona-perigo strong {
    display: block;
    font-size: var(--fs-h3);
}

/* ---------------------------------------------------------------- promessa */

/*
 * A promessa de privacidade **não** vive num rodapé de todas as telas: repetida onde não custa nada,
 * viraria papel de parede em uma semana. Ela aparece em Salas, com peso, e dentro do painel do Modo
 * Foco — o único momento em que a escola exerce poder sobre a máquina do aluno, e portanto o único
 * em que dizer o que o Aura não observa é informação, e não slogan.
 */
.promessa {
    background: var(--deep-grad, var(--deep));
    border-radius: var(--r-lg);
    color: var(--ink-inv);
    margin: var(--sp-5) 0;
    padding: var(--sp-5) var(--sp-6);
}

.promessa strong {
    display: block;
    font-size: var(--fs-h3);
    margin-bottom: 8px;
}

.promessa p {
    color: var(--ink-inv-2);
    margin: 0;
}

.gaveta .promessa {
    background: var(--surface-2);
    color: var(--ink);
    margin: 0 0 var(--sp-5);
    padding: var(--sp-4);
}

.gaveta .promessa strong {
    font-size: var(--fs-body);
}

.gaveta .promessa p {
    color: var(--ink-2);
    font-size: var(--fs-support);
}

/* ---------------------------------------------------------------- listas simples */

.labs {
    display: grid;
    gap: 10px;
    list-style: none;
    max-width: 620px;
    padding: 0;
}

.labs li a {
    background: var(--surface);
    border: var(--bw) solid var(--line);
    border-radius: var(--r);
    display: block;
    font-weight: 600;
    padding: var(--sp-4);
    text-decoration: none;
}

.labs li a:hover {
    border-color: var(--ink-2);
    text-decoration: none;
}

/* ---------------------------------------------------------------- estreito */

@media (max-width: 900px) {
    .aula-acoes,
    .categoria-itens {
        grid-template-columns: 1fr;
    }

    .dashboard,
    .simple-page {
        padding: var(--sp-5) 16px 64px;
    }

    .aula-estado {
        padding: var(--sp-5) var(--sp-4);
    }
}

@media (prefers-reduced-motion: reduce) {
    .aula-envio-enviando .ponto,
    .botao-giro {
        animation: none;
    }
}

/* ---------------------------------------------------------------- Blazor */

.components-reconnect-container {
    display: none;
}

.components-reconnect-container.components-reconnect-first-attempt-visible,
.components-reconnect-container.components-reconnect-repeated-attempt-visible,
.components-reconnect-container.components-reconnect-failed-visible,
.components-reconnect-container.components-pause-visible,
.components-reconnect-container.components-resume-failed-visible {
    align-items: center;
    background: rgb(0 0 0 / 0.62);
    color: var(--ink-inv);
    display: flex;
    font-size: var(--fs-h3);
    inset: 0;
    justify-content: center;
    position: fixed;
    z-index: 50;
}
