/*
 * 18_app.css — ONDA N · o SHELL DE APLICATIVO do aluno (PWA)
 * ═══════════════════════════════════════════════════════════════════════════
 * O que faz o produto, no celular, parecer aplicativo e não site:
 *
 *   · barra inferior de 4 destinos (`.barra-do-app`), ícone + rótulo, com o
 *     item atual marcado por `aria-current` (é `item_de_navegacao` quem
 *     emite; o CSS só pinta) e um indicador que ENTRA por `transform`;
 *   · cabeçalho compacto (`.cabecalho--app`: marca + chip, 52 px) e o sinal
 *     de rede/sincronização (`.sinal--do-app`) como pílula flutuante acima da
 *     barra — fora do cabeçalho, que não tem largura para ele a 390;
 *   · a transição entre telas (`.app__tela--entra`): o conteúdo entra de
 *     baixo a cada visita do Turbo. `transform` + `opacity`, 60 fps, e
 *     `prefers-reduced-motion` desliga (02_base.css já zera as animações no
 *     atacado; aqui se repete o essencial para não depender da ordem);
 *   · o convite de instalar (`.instalar`): folha que sobe de baixo, acima da
 *     barra — o padrão de modal no celular (MARCA.md §3);
 *   · a página offline e o bloco "este aparelho" de Você.
 *
 * No desktop (≥ 48rem) a barra vira uma fita sob o cabeçalho, com a MESMA
 * marcação — a folga do conteúdo (`.conteudo--aluno`) é a de 20_navegacao.css,
 * que já previa barra embaixo no celular e fita em cima no desktop.
 *
 * Tudo por token; nenhum hex aqui.
 */

/* `hidden` tem que vencer o `display` dos componentes desta folha: sem isto
   o convite "escondido" continua na tela (foi assim no primeiro print). */
.sinal[hidden], .instalar[hidden], .aparelho__cartao[hidden],
.offline__pendentes[hidden], .aparelho__cartao [hidden], .instalar [hidden] { display: none !important }

/* ═══ CABEÇALHO COMPACTO ══════════════════════════════════════════════════ */

/* 52 px no celular, 56 no desktop (a fita do desktop começa em 3.5rem — se o
   cabeçalho passar disso, ela sobrepõe a borda; foi medido em 65 px antes,
   porque `.marca` herdava `min-height: var(--alvo)` + 16 px de padding).
   Seletores COMPOSTOS (`.cabecalho.cabecalho--app`) de propósito: esta folha
   (18) carrega ANTES de 20_navegacao.css, e no empate de especificidade quem
   vence é a última — `.cabecalho--app` sozinho perdia o padding para
   `.cabecalho` (medido: 65 px de novo).

   O TOPO DO iPHONE: o <head> pede `black-translucent`, então o conteúdo corre
   por baixo da barra de status e o `env(safe-area-inset-top)` vira real.
   `02_base.css` dá esse recuo ao <html>, mas um `sticky; top: 0` gruda no
   scrollport (y=0) e, ao rolar, entrava debaixo do relógio. Aqui o cabeçalho
   ANULA o recuo do <html> (margem negativa) e o absorve no próprio padding:
   ele pinta desde y=0, com fundo, e o relógio fica sobre o fundo dele. Fora
   do iOS instalado o env() é 0 e nada muda. */
.cabecalho.cabecalho--app {
  top: 0;
  min-height: calc(3.25rem + env(safe-area-inset-top));
  margin-top: calc(-1 * env(safe-area-inset-top));
  padding-block: var(--esp-1);
  padding-top: calc(var(--esp-1) + env(safe-area-inset-top));
  gap: var(--esp-2);
}
/* A marca CEDE (ellipsis) para o chip; o chip é o que muda todo dia. */
.marca.marca--app { flex: 1 1 auto; min-width: 0; min-height: 2.5rem; font-size: var(--texto-md) }
.cabecalho--app .cabecalho__acoes { min-width: 0 }
.cabecalho--app .nivel-chip { min-height: 2.75rem; padding-block: 0 }   /* 44 px: cabe nos 52 do cabeçalho */
@media (min-width: 48rem) {
  .cabecalho.cabecalho--app { min-height: calc(3.5rem + env(safe-area-inset-top)) }
}

/* O cabeçalho do painel é UMA linha também no celular: "Olá, Josi" à esquerda
   e "Ver o tour de novo" à direita, em vez de o tour ocupar uma linha inteira
   da primeira dobra acima de "O que fazer agora" (R16 da rodada Q+R). */
/* Especificidade 0,2,0 de propósito: `.tela-cabecalho { flex-direction: column }`
   em 20_navegacao.css carrega DEPOIS deste arquivo e, com 0,1,0, vencia —
   deixando só o `align-items: center` vivo, que centralizava o h1 (regressão
   pega pelo verificador da rodada 1). */
.tela-cabecalho.tela-cabecalho--painel {
  flex-direction: row;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--esp-2) var(--esp-4);
}
.tela-cabecalho.tela-cabecalho--painel > div { min-width: 0 }

/* ═══ O SINAL (rede / sincronização) ═════════════════════════════════════ */

.sinal {
  display: inline-flex;
  align-items: center;
  gap: var(--esp-2);
  min-height: 2.25rem;
  padding: 0 var(--esp-4);
  border-radius: var(--raio-redondo);
  border: 1px solid transparent;
  font-size: var(--texto-xs);
  font-weight: var(--peso-medio);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  animation: entra-de-baixo var(--tempo-normal) var(--curva-entrada) both;
}
.sinal::before {
  content: "";
  flex: none;
  width: 0.5rem;
  height: 0.5rem;
  border-radius: var(--raio-redondo);
  background: currentColor;
}
.sinal--offline  { background: var(--cor-descanso-suave);   color: var(--cor-descanso);   border-color: var(--cor-descanso-forte) }
.sinal--pendente { background: var(--cor-aguardando-suave); color: var(--cor-aguardando); border-color: var(--cor-aguardando-forte) }
.sinal--enviando { background: var(--cor-marca-suave);      color: var(--cor-marca);      border-color: var(--cor-marca-tenue) }
.sinal--enviando::before { animation: sinal-pulsa 1s ease-in-out infinite }
.sinal--ok       { background: var(--cor-aprovado-suave);   color: var(--cor-aprovado);   border-color: var(--cor-aprovado-forte) }
@keyframes sinal-pulsa { 50% { opacity: 0.35; transform: scale(0.8) } }

/* O sinal do app NÃO mora no cabeçalho: marca + chip + "Progresso
   sincronizado" não cabem em 358 px (medido: a marca virava "Uppe" e a página
   rolava de lado). É a pílula flutuante logo acima da barra — onde os
   aplicativos põem "sem conexão" —, centrada, com o mesmo `role="status"`.
   No desktop desce para o rodapé da janela (a barra está em cima). Ela é
   filha direta de `.app` (não do <header>): `backdrop-filter` faz do
   cabeçalho um contêiner de `fixed`, e a pílula ficaria presa nele. */
.sinal--do-app {
  position: fixed;
  left: var(--esp-4);
  right: var(--esp-4);
  bottom: calc(var(--alvo) + var(--esp-4) + env(safe-area-inset-bottom));
  z-index: var(--z-menu);
  width: fit-content;
  max-width: calc(100% - 2 * var(--esp-4));
  margin-inline: auto;
  box-shadow: var(--sombra-3);
}
/* Sinal e convite de instalar no mesmo lugar: o convite sobe para dar
   passagem — os dois juntos são raros (2ª visita E rede caindo). */
.app:has(.sinal--do-app:not([hidden])) .instalar { bottom: calc(var(--alvo) + var(--esp-4) + 2.75rem + env(safe-area-inset-bottom)) }
@media (min-width: 48rem) {
  .sinal--do-app { bottom: var(--esp-6) }
  .app:has(.sinal--do-app:not([hidden])) .instalar { bottom: calc(var(--esp-6) + 2.75rem) }
}

/* Sem rede, o que precisa de rede fica visivelmente indisponível — sem JS
   por componente: o `rede_controller` carimba o <html>. */
[data-rede="offline"] .player__botao,
[data-rede="offline"] .acao__botao,
[data-rede="offline"] .botao--primario[href*="/aulas/"] { opacity: 0.55; pointer-events: none }

/* ═══ A TRANSIÇÃO ENTRE TELAS ════════════════════════════════════════════ */

.app__tela--entra { animation: app-tela-entra var(--tempo-normal) var(--curva-entrada) both }
@keyframes app-tela-entra {
  from { opacity: 0; transform: translate3d(0, 0.6rem, 0) }
}

/* ═══ A BARRA INFERIOR ═══════════════════════════════════════════════════ */

.barra-do-app {
  position: fixed;
  inset: auto 0 0;
  z-index: var(--z-grudado);
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--esp-1);
  padding: var(--esp-1) var(--esp-2) calc(var(--esp-1) + env(safe-area-inset-bottom));
  /* As DUAS declarações de background, como no cabeçalho de 20_navegacao.css:
     quem não entende `color-mix` fica com a primeira — e nunca sem fundo. */
  background: var(--fundo-cartao);
  background: color-mix(in srgb, var(--fundo-cartao) 94%, transparent);
  backdrop-filter: blur(14px);
  border-top: 1px solid var(--borda);
}
@supports not (backdrop-filter: blur(1px)) {
  .barra-do-app { background: var(--fundo-cartao) }
}

.barra-do-app > a {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.2rem;
  min-height: var(--alvo);
  padding: var(--esp-1) var(--esp-1);
  border-radius: var(--raio-2);
  color: var(--texto-tenue);
  font-size: var(--texto-xs);
  font-weight: var(--peso-medio);
  line-height: 1.1;
  text-align: center;
  text-decoration: none;
  -webkit-tap-highlight-color: transparent;
  transition: color var(--tempo-rapido) var(--curva-padrao);
}
.barra-do-app > a svg { flex: none; transition: transform var(--tempo-normal) var(--curva-elastica) }
.barra-do-app > a:hover { color: var(--texto-suave) }
.barra-do-app > a:active svg { transform: scale(0.9) }
.barra-do-app > a[aria-current] { color: var(--cor-marca) }
.barra-do-app > a[aria-current] svg { transform: translateY(-1px) }
/* O indicador: uma pastilha atrás do ícone, que ENTRA crescendo. Fica
   atrás do ícone e não embaixo do rótulo, para o alvo inteiro parecer um
   botão — é o que o dedo espera de um app. */
.barra-do-app > a::before {
  content: "";
  position: absolute;
  top: 0.3rem;
  width: 3.25rem;
  height: 1.75rem;
  border-radius: var(--raio-redondo);
  background: var(--cor-marca-suave);
  opacity: 0;
  transform: scaleX(0.4);
  transition: opacity var(--tempo-normal) var(--curva-entrada), transform var(--tempo-normal) var(--curva-elastica);
}
.barra-do-app > a[aria-current]::before { opacity: 1; transform: scaleX(1) }
.barra-do-app > a > span { position: relative }
.barra-do-app > a > svg { position: relative }

/* Foco visível vale para teclado e para o leitor de tela; toque não deixa
   anel. */
.barra-do-app > a:focus-visible { outline: 2px solid var(--cor-marca); outline-offset: -2px }

@media (min-width: 48rem) {
  .barra-do-app {
    inset: 3.5rem 0 auto;
    z-index: calc(var(--z-grudado) - 1);
    grid-template-columns: repeat(4, max-content);
    justify-content: center;
    gap: var(--esp-2);
    padding: var(--esp-2) var(--gutter);
    border-top: 0;
    border-bottom: 1px solid var(--borda);
  }
  .barra-do-app > a {
    flex-direction: row;
    gap: var(--esp-2);
    min-height: 2.5rem;
    padding: 0 var(--esp-4);
    font-size: var(--texto-sm);
  }
  .barra-do-app > a svg { width: 18px; height: 18px }
  .barra-do-app > a::before { inset: 0; top: auto; width: auto; height: auto; transform: scaleX(0.6) }
  .barra-do-app > a[aria-current] svg { transform: none }
}

/* ═══ O CONVITE DE INSTALAR ══════════════════════════════════════════════ */

.instalar {
  position: fixed;
  inset: auto var(--esp-3) calc(var(--alvo) + var(--esp-4) + env(safe-area-inset-bottom));
  z-index: var(--z-menu);
  display: flex;
  justify-content: center;
  pointer-events: none;
}
.instalar__folha {
  pointer-events: auto;
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--esp-3) var(--esp-4);
  align-items: center;
  width: 100%;
  max-width: 28rem;
  padding: var(--esp-4);
  border: 1px solid var(--borda);
  border-radius: var(--raio-4);
  background: var(--fundo-elevado);
  box-shadow: var(--sombra-3);
  animation: entra-de-baixo var(--tempo-lento) var(--curva-entrada) both;
}
.instalar--saindo .instalar__folha { animation: some-no-lugar var(--tempo-normal) var(--curva-saida) both }
.instalar__icone { width: 3rem; height: 3rem; border-radius: var(--raio-3); flex: none }
.instalar__titulo { margin: 0; font-size: var(--texto-md) }
.instalar__corpo { margin: var(--esp-1) 0 0; font-size: var(--texto-sm); color: var(--texto-tenue) }
.instalar__acoes { grid-column: 1 / -1; display: flex; gap: var(--esp-2); justify-content: flex-end }
/* Dentro do app instalado o convite não existe. */
[data-app="standalone"] .instalar { display: none }
@media (min-width: 48rem) {
  .instalar { inset: auto var(--esp-6) var(--esp-6) auto }
  .instalar__folha { width: 24rem }
}

/* ═══ "ESTE APARELHO" (em Você) ══════════════════════════════════════════ */

/* O bloco entra DEPOIS do `.perfil` (30_identidade.css: 40rem, alinhado à
   esquerda da coluna de conteúdo, sem padding próprio) e usa a mesma coluna. */
.aparelho { max-width: 40rem; margin: var(--esp-8) 0 0; padding-inline: 0 }
/* O título da seção fica em cima do texto de apoio, não ao lado: "Este
   aparelho" ao lado de uma frase inteira quebrava em duas linhas a 390. */
.aparelho .secao__titulo { display: block; margin-bottom: var(--esp-4) }
.aparelho .secao__titulo h2 { margin-bottom: var(--esp-1) }
.aparelho__grade { display: grid; gap: var(--esp-4) }
@media (min-width: 48rem) {
  .aparelho__grade { grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr)) }
}
.aparelho__cartao { display: flex; flex-direction: column; gap: var(--esp-3) }
.aparelho__cartao .cartao__texto { margin: 0; font-size: var(--texto-sm); color: var(--texto-suave) }
.aparelho__cartao .cartao__acoes { margin-top: auto; display: flex; flex-wrap: wrap; gap: var(--esp-2) }
.aparelho__cartao .cartao__acoes form { display: contents }
.aparelho__estado { margin: 0; font-size: var(--texto-sm); color: var(--texto-tenue); min-height: 1.4em }
.aparelho__estado:empty { display: none }
/* Sair é uma AÇÃO, não um cartão com título "Sair" e botão "Sair": uma linha
   no fim, com a frase do que acontece. */
.aparelho__sair {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--esp-3);
  margin-top: var(--esp-6);
  padding-top: var(--esp-5);
  border-top: 1px solid var(--borda);
}
.aparelho__sair p { margin: 0; font-size: var(--texto-sm); color: var(--texto-tenue) }
.aparelho__sair form { display: contents }

/* ═══ A PÁGINA OFFLINE ═══════════════════════════════════════════════════ */

.offline {
  max-width: var(--largura-leitura);
  margin: var(--esp-8) auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--esp-4);
  text-align: center;
  animation: entra-de-baixo var(--tempo-lento) var(--curva-entrada) both;
}
.offline__icone { color: var(--cor-descanso) }
.offline__titulo { margin: 0 }
.offline__texto { margin: 0; color: var(--texto-suave) }
.offline__pendentes {
  margin: 0;
  padding: var(--esp-3) var(--esp-4);
  border-radius: var(--raio-3);
  background: var(--cor-aguardando-suave);
  color: var(--cor-aguardando);
  font-size: var(--texto-sm);
}
.offline__nao-da { margin: 0; font-size: var(--texto-sm); color: var(--texto-tenue) }
.offline__acoes { display: flex; flex-wrap: wrap; gap: var(--esp-3); justify-content: center; margin-top: var(--esp-2) }

/* ═══ MOVIMENTO REDUZIDO, IMPRESSÃO ══════════════════════════════════════ */

@media (prefers-reduced-motion: reduce) {
  .app__tela--entra, .sinal, .instalar__folha, .offline { animation: none }
  .sinal--enviando::before { animation: none }
  .barra-do-app > a::before, .barra-do-app > a svg { transition: none }
}

@media print {
  .barra-do-app, .instalar, .sinal { display: none }
}
