/* ═══════════════════════════════════════════════════════════════════════════
   OSS YOGA · DESIGN SYSTEM — COMPONENTES
   Carregar depois de oss-tokens.css e oss-base.css.
   ═══════════════════════════════════════════════════════════════════════════

   Um componente entra aqui quando aparece em DUAS telas. Antes disso ele é
   detalhe de uma tela e mora lá — sistema que cresce por antecipação vira
   biblioteca de peças que ninguém usa.

   Cada componente respeita quatro coisas, sem exceção:
     · alvo de toque de 44px em tudo que se clica;
     · anel de foco visível pelo teclado;
     · estado desabilitado e estado carregando previstos;
     · nenhuma informação transmitida só por cor.

   E uma regra de movimento: transição só em `color`, `background`,
   `border-color`, `box-shadow`, `opacity` e `transform`. Nunca `all` — `all`
   anima também o que você não sabe que existe, e é como interface fica lenta. */

/* ═══════════════════════════════════════════════════════════════════════════
   BOTÃO
   ═══════════════════════════════════════════════════════════════════════════
   Retangular, caixa alta, espacejado. O primário é a floresta; o secundário
   é só fio; o fantasma não tem moldura nenhuma. Três, e chega.

   O `:active` desce 1px em vez de encolher: encolher deforma a letra em caixa
   alta, e o toque fica visivelmente "borrachudo". Descer parece pressionar. */
.oss-botao {
  --_fundo: var(--oss-escuro);
  --_letra: var(--oss-tinta-clara);
  --_borda: var(--oss-escuro);

  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--oss-e-2);
  min-height: var(--oss-toque);
  padding: var(--oss-e-3) var(--oss-e-5);
  border: 1px solid var(--_borda);
  border-radius: var(--oss-curva-sm);
  background: var(--_fundo);
  color: var(--_letra);
  font-family: var(--oss-sans);
  font-size: var(--oss-t-peq);
  font-weight: var(--oss-peso-medio);
  letter-spacing: var(--oss-tracking-alta);
  text-transform: uppercase;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  white-space: nowrap;
  transition: background var(--oss-tempo) var(--oss-curva-saida),
              border-color var(--oss-tempo) var(--oss-curva-saida),
              color var(--oss-tempo) var(--oss-curva-saida),
              transform var(--oss-tempo-rapido) var(--oss-curva-saida);
}
.oss-botao:hover { --_fundo: var(--oss-escuro-2); --_borda: var(--oss-escuro-2); }
.oss-botao:active { transform: translateY(1px); }
.oss-botao:disabled, .oss-botao[aria-disabled="true"] {
  opacity: .45; cursor: not-allowed; transform: none;
}

.oss-botao.oss-secundario {
  --_fundo: transparent;
  --_letra: var(--oss-tinta);
  --_borda: var(--oss-fio-forte);
}
.oss-botao.oss-secundario:hover { --_fundo: var(--oss-carta); --_borda: var(--oss-tinta); }

.oss-botao.oss-fantasma {
  --_fundo: transparent;
  --_letra: var(--oss-tinta-2);
  --_borda: transparent;
  letter-spacing: var(--oss-tracking-medio);
  text-transform: none;
  padding-inline: var(--oss-e-3);
}
.oss-botao.oss-fantasma:hover { --_fundo: var(--oss-carta-2); --_letra: var(--oss-tinta); }

/* Destrutivo. Existe para suspender acesso e apagar — e é o único componente
   do sistema que pode assustar um pouco. */
.oss-botao.oss-perigo { --_fundo: transparent; --_letra: var(--oss-erro); --_borda: var(--oss-erro); }
.oss-botao.oss-perigo:hover { --_fundo: var(--oss-erro); --_letra: var(--oss-carta); }

/* Sobre faixa escura. */
:where(.oss-escuro) .oss-botao.oss-secundario,
.oss-botao.oss-secundario.oss-sobre-escuro {
  --_letra: var(--oss-tinta-clara); --_borda: var(--oss-fio-claro);
}
:where(.oss-escuro) .oss-botao.oss-secundario:hover { --_fundo: rgba(245,241,232,.08); --_borda: var(--oss-ouro); }

.oss-botao.oss-sm { min-height: 36px; padding: var(--oss-e-2) var(--oss-e-3); font-size: var(--oss-t-micro); }
.oss-botao.oss-bloco { display: flex; width: 100%; }

/* Carregando: a palavra troca, e um risco gira ao lado. O botão não muda de
   tamanho — botão que encolhe ao ser apertado faz a página inteira pular. */
.oss-botao.oss-carregando { pointer-events: none; opacity: .8; }
.oss-botao.oss-carregando::before {
  content: ""; width: 1em; height: 1em; flex: none;
  border: 2px solid currentColor; border-right-color: transparent;
  border-radius: 50%; opacity: .8;
  animation: oss-girar .7s linear infinite;
}
@keyframes oss-girar { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .oss-botao.oss-carregando::before { animation: none; border-right-color: currentColor; opacity: .4; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   CAMPO
   ═══════════════════════════════════════════════════════════════════════════
   16px é piso, não preferência: abaixo disso o iOS dá zoom ao focar e o
   formulário sai da tela. */
.oss-campo { display: block; }
.oss-campo + .oss-campo { margin-top: var(--oss-e-4); }

.oss-rotulo {
  display: block;
  margin-bottom: var(--oss-e-2);
  color: var(--oss-tinta);
  font-size: var(--oss-t-peq);
  font-weight: var(--oss-peso-nl);
  letter-spacing: var(--oss-tracking-medio);
}
.oss-rotulo .oss-opcional { color: var(--oss-tinta-3); font-weight: var(--oss-peso-leve); }

.oss-entrada {
  display: block;
  width: 100%;
  min-height: var(--oss-toque);
  padding: var(--oss-e-3) var(--oss-e-3);
  border: 1px solid var(--oss-fio-forte);
  border-radius: var(--oss-curva-sm);
  background: var(--oss-carta);
  color: var(--oss-tinta);
  font-family: var(--oss-sans);
  font-size: var(--oss-t-base);   /* nunca menos */
  font-weight: var(--oss-peso-leve);
  line-height: var(--oss-linha-normal);
  transition: border-color var(--oss-tempo) var(--oss-curva-saida),
              box-shadow var(--oss-tempo) var(--oss-curva-saida);
}
.oss-entrada::placeholder { color: var(--oss-tinta-3); opacity: 1; }
.oss-entrada:hover { border-color: var(--oss-tinta-3); }
.oss-entrada:focus {
  outline: none;                                     /* substituído logo abaixo */
  border-color: var(--oss-ouro);
  box-shadow: 0 0 0 3px var(--oss-fio-ouro);
}
.oss-entrada:disabled { background: var(--oss-carta-2); color: var(--oss-tinta-3); cursor: not-allowed; }
.oss-entrada[aria-invalid="true"] { border-color: var(--oss-erro); }
.oss-entrada[aria-invalid="true"]:focus { box-shadow: 0 0 0 3px rgba(140, 59, 46, .22); }

:where(textarea).oss-entrada { min-height: 120px; resize: vertical; line-height: var(--oss-linha-solta); }

:where(select).oss-entrada {
  appearance: none;
  /* A seta é desenhada em CSS para não depender de imagem nem de fonte de
     ícone — e para acompanhar a cor do texto em qualquer fundo. */
  background-image:
    linear-gradient(45deg, transparent 50%, currentColor 50%),
    linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: right 20px center, right 15px center;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  padding-right: var(--oss-e-7);
}

/* O campo do código de 6 números. Grande, espaçado, no meio: é o momento em
   que a pessoa copia do e-mail e precisa conferir dígito a dígito. */
.oss-entrada.oss-codigo {
  font-family: var(--oss-sans);
  font-size: var(--oss-t-xl);
  font-weight: var(--oss-peso-nl);
  letter-spacing: .45em;
  text-indent: .45em;             /* compensa o vão depois do último dígito */
  text-align: center;
  padding-block: var(--oss-e-4);
}

.oss-ajuda { margin: var(--oss-e-2) 0 0; font-size: var(--oss-t-mini); color: var(--oss-tinta-3); }

/* O erro do campo. Ícone + palavra: nunca a cor sozinha. */
.oss-erro-campo {
  display: flex; align-items: flex-start; gap: var(--oss-e-2);
  margin: var(--oss-e-2) 0 0;
  color: var(--oss-erro);
  font-size: var(--oss-t-peq);
  line-height: var(--oss-linha-normal);
}

/* ═══════════════════════════════════════════════════════════════════════════
   CARTA
   ═══════════════════════════════════════════════════════════════════════════
   Fundo branco, fio de 1px, sombra rasa. A variante `destaque` ganha o fio de
   ouro no topo — é o único lugar onde o ouro vira faixa, e é o que marca "a
   coisa principal desta tela". Usar uma vez por tela; duas já não destacam. */
.oss-carta {
  background: var(--oss-carta);
  border: 1px solid var(--oss-fio);
  border-radius: var(--oss-curva);
  box-shadow: var(--oss-sombra-1);
  padding: var(--oss-e-5);
}
.oss-carta.oss-destaque {
  border-top: 3px solid var(--oss-ouro);
  border-radius: 0 0 var(--oss-curva) var(--oss-curva);
  box-shadow: var(--oss-sombra-2);
  padding: var(--oss-e-6) var(--oss-e-5);
}
.oss-carta.oss-plana { box-shadow: none; }
.oss-carta.oss-densa { padding: var(--oss-e-4); }

/* Carta clicável (atalho no painel). Move-se 1px — nada mais. */
:where(a, button).oss-carta {
  display: block; width: 100%; text-align: left; cursor: pointer;
  color: inherit; text-decoration: none; font: inherit;
  transition: border-color var(--oss-tempo) var(--oss-curva-saida),
              box-shadow var(--oss-tempo) var(--oss-curva-saida),
              transform var(--oss-tempo) var(--oss-curva-saida);
}
:where(a, button).oss-carta:hover {
  border-color: var(--oss-fio-ouro);
  box-shadow: var(--oss-sombra-2);
  transform: translateY(-1px);
}

/* ═══════════════════════════════════════════════════════════════════════════
   SEÇÃO
   ═══════════════════════════════════════════════════════════════════════════
   O título de bloco do sistema: caixa alta, pequeno, com fio embaixo. Ele é
   quem organiza o /core e a ficha da pessoa. */
.oss-secao { margin-top: var(--oss-e-6); }
.oss-secao:first-child { margin-top: 0; }
.oss-secao-tit {
  display: flex; align-items: baseline; gap: var(--oss-e-3);
  margin: 0 0 var(--oss-e-3);
  padding-bottom: var(--oss-e-2);
  border-bottom: 1px solid var(--oss-fio);
  font-family: var(--oss-sans);
  font-size: var(--oss-t-micro);
  font-weight: var(--oss-peso-forte);
  letter-spacing: var(--oss-tracking-alta);
  text-transform: uppercase;
  color: var(--oss-tinta-3);
}
.oss-secao-tit .oss-conta {
  margin-left: auto; font-weight: var(--oss-peso-nl); letter-spacing: 0;
  font-size: var(--oss-t-mini); text-transform: none; color: var(--oss-tinta-3);
}

/* ═══════════════════════════════════════════════════════════════════════════
   NÚMERO
   ═══════════════════════════════════════════════════════════════════════════
   O indicador do painel. A serifada em corpo grande é o que faz um número
   parecer editorial em vez de planilha. */
.oss-numero { display: flex; flex-direction: column; gap: 2px; }
.oss-numero-valor {
  font-family: var(--oss-serif);
  font-size: var(--oss-t-2xl);
  font-weight: var(--oss-peso-leve);
  line-height: 1;
  color: var(--oss-tinta);
  font-variant-numeric: lining-nums tabular-nums;
}
.oss-numero-rotulo { font-size: var(--oss-t-peq); color: var(--oss-tinta-2); }
.oss-numero-nota   { font-size: var(--oss-t-mini); color: var(--oss-tinta-3); }
.oss-numero.oss-atencao .oss-numero-valor { color: var(--oss-atencao); }
.oss-numero.oss-mal    .oss-numero-valor { color: var(--oss-erro); }

/* Grade de números. minmax(150px) mantém dois por linha no celular. */
.oss-grade { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: var(--oss-e-3); }
/* No desktop o cartão cresce em vez de multiplicar: cinco cartões estreitos
   numa linha larga é planilha, não painel. */
@media (min-width: 900px) {
  .oss-grade { grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: var(--oss-e-4); }
}

/* ═══════════════════════════════════════════════════════════════════════════
   LISTA
   ═══════════════════════════════════════════════════════════════════════════
   Linhas separadas por fio, sem zebra: zebra em papel creme fica suja. No
   celular a linha empilha; a partir de 560px ela vira uma linha só, com o
   detalhe empurrado para a direita. */
.oss-lista { list-style: none; margin: 0; padding: 0; }
.oss-lista > li { border-bottom: 1px solid var(--oss-fio); }
.oss-lista > li:last-child { border-bottom: 0; }

.oss-item {
  display: flex; flex-direction: column; gap: 2px;
  padding: var(--oss-e-3) var(--oss-e-1);
  min-height: var(--oss-toque);
  color: inherit; text-decoration: none;
  transition: background var(--oss-tempo-rapido) var(--oss-curva-saida);
}
:where(a, button).oss-item:hover { background: var(--oss-carta-2); }
.oss-item-nome { font-weight: var(--oss-peso-nl); color: var(--oss-tinta); }
.oss-item-sub  { font-size: var(--oss-t-peq); color: var(--oss-tinta-2); }
.oss-item-fim  { font-size: var(--oss-t-mini); color: var(--oss-tinta-3); }

@media (min-width: 560px) {
  .oss-item { flex-direction: row; flex-wrap: wrap; align-items: baseline; gap: var(--oss-e-3); }
  .oss-item-fim { margin-left: auto; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   ETIQUETA (estado)
   ═══════════════════════════════════════════════════════════════════════════
   A pílula do sistema, e o único uso de canto redondo total. Sempre com
   palavra — e, quando o estado importa, com ícone. */
.oss-etiqueta {
  display: inline-flex; align-items: center; gap: var(--oss-e-1);
  padding: 3px var(--oss-e-2);
  border: 1px solid var(--oss-fio);
  border-radius: var(--oss-curva-pill);
  background: var(--oss-carta);
  color: var(--oss-tinta-2);
  font-family: var(--oss-sans);
  font-size: var(--oss-t-micro);
  font-weight: var(--oss-peso-medio);
  letter-spacing: var(--oss-tracking-medio);
  text-transform: uppercase;
  white-space: nowrap;
  font-style: normal;
}
.oss-etiqueta.oss-ok      { color: var(--oss-ok);      background: var(--oss-ok-fundo);      border-color: transparent; }
.oss-etiqueta.oss-atencao { color: var(--oss-atencao); background: var(--oss-atencao-fundo); border-color: transparent; }
.oss-etiqueta.oss-mal     { color: var(--oss-erro);    background: var(--oss-erro-fundo);    border-color: transparent; }

/* ═══════════════════════════════════════════════════════════════════════════
   CHIP (filtro)
   ═══════════════════════════════════════════════════════════════════════════ */
.oss-chips { display: flex; flex-wrap: wrap; gap: var(--oss-e-2); }
.oss-chip {
  min-height: 36px;
  padding: var(--oss-e-2) var(--oss-e-3);
  border: 1px solid var(--oss-fio);
  border-radius: var(--oss-curva-pill);
  background: var(--oss-carta);
  color: var(--oss-tinta-2);
  font: inherit; font-size: var(--oss-t-peq);
  cursor: pointer;
  transition: background var(--oss-tempo) var(--oss-curva-saida),
              border-color var(--oss-tempo) var(--oss-curva-saida),
              color var(--oss-tempo) var(--oss-curva-saida);
}
.oss-chip:hover { border-color: var(--oss-tinta-3); color: var(--oss-tinta); }
/* O chip ativo não muda só de cor: ele ganha peso e um fio mais forte. */
.oss-chip[aria-pressed="true"], .oss-chip.oss-ativo {
  border-color: var(--oss-ouro);
  background: var(--oss-atencao-fundo);
  color: var(--oss-tinta);
  font-weight: var(--oss-peso-medio);
}

/* ═══════════════════════════════════════════════════════════════════════════
   RECADO (faixa de aviso)
   ═══════════════════════════════════════════════════════════════════════════
   Fio grosso à esquerda, fundo lavado, ícone antes da palavra. É o que o
   /core usa para acender um sinal e o /entrar usa para explicar um erro. */
.oss-recado {
  display: flex; align-items: flex-start; gap: var(--oss-e-3);
  padding: var(--oss-e-3) var(--oss-e-4);
  border-left: 3px solid var(--oss-info);
  border-radius: 0 var(--oss-curva-sm) var(--oss-curva-sm) 0;
  background: var(--oss-info-fundo);
  color: var(--oss-tinta-2);
  font-size: var(--oss-t-peq);
  line-height: var(--oss-linha-normal);
}
:where(.oss-recado) .oss-i { margin-top: .15em; color: var(--oss-info); }
.oss-recado-corpo { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.oss-recado-tit { color: var(--oss-tinta); font-weight: var(--oss-peso-medio); }

.oss-recado.oss-ok      { border-left-color: var(--oss-ok);      background: var(--oss-ok-fundo); }
.oss-recado.oss-ok .oss-i      { color: var(--oss-ok); }
.oss-recado.oss-atencao { border-left-color: var(--oss-atencao); background: var(--oss-atencao-fundo); }
.oss-recado.oss-atencao .oss-i { color: var(--oss-atencao); }
.oss-recado.oss-mal     { border-left-color: var(--oss-erro);    background: var(--oss-erro-fundo); }
.oss-recado.oss-mal .oss-i     { color: var(--oss-erro); }

/* ═══════════════════════════════════════════════════════════════════════════
   ABAS
   ═══════════════════════════════════════════════════════════════════════════
   Rolam na horizontal no celular sem barra visível. A aba ativa é marcada por
   um fio de ouro embaixo E por peso — nunca só pela cor. */
.oss-abas {
  display: flex; gap: 0;
  overflow-x: auto;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
  border-bottom: 1px solid var(--oss-fio);
}
.oss-abas::-webkit-scrollbar { display: none; }
.oss-aba {
  flex: none;
  min-height: var(--oss-toque);
  display: inline-flex; align-items: center; gap: var(--oss-e-2);
  padding: var(--oss-e-3) var(--oss-e-4);
  border: 0; border-bottom: 2px solid transparent;
  background: none;
  color: var(--oss-tinta-2);
  font: inherit; font-size: var(--oss-t-peq);
  letter-spacing: var(--oss-tracking-medio);
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: color var(--oss-tempo) var(--oss-curva-saida),
              border-color var(--oss-tempo) var(--oss-curva-saida);
}
.oss-aba:hover { color: var(--oss-tinta); }
.oss-aba[aria-current], .oss-aba.oss-ativo {
  color: var(--oss-tinta);
  border-bottom-color: var(--oss-ouro);
  font-weight: var(--oss-peso-medio);
}

/* ═══════════════════════════════════════════════════════════════════════════
   VAZIO
   ═══════════════════════════════════════════════════════════════════════════
   Lista vazia não é erro, e não pode parecer erro. Uma frase que explica, e
   quando existe, o próximo passo. */
.oss-vazio {
  padding: var(--oss-e-7) var(--oss-e-4);
  text-align: center;
  color: var(--oss-tinta-3);
}
:where(.oss-vazio) .oss-i { color: var(--oss-fio-forte); margin-bottom: var(--oss-e-3); }
.oss-vazio-tit { color: var(--oss-tinta-2); font-size: var(--oss-t-md); font-family: var(--oss-serif); }
:where(.oss-vazio) p { color: var(--oss-tinta-3); font-size: var(--oss-t-peq); margin: var(--oss-e-2) 0 0; }

/* ═══════════════════════════════════════════════════════════════════════════
   CARREGANDO
   ═══════════════════════════════════════════════════════════════════════════
   Duas formas: o giro (espera curta, ação da pessoa) e o esqueleto (a tela
   inteira chegando). O esqueleto respeita a forma do que vai chegar — é o que
   evita a página "pular" quando o conteúdo entra. */
.oss-giro {
  width: 28px; height: 28px;
  border: 2px solid var(--oss-fio);
  border-top-color: var(--oss-ouro);
  border-radius: 50%;
  animation: oss-girar .8s linear infinite;
}
.oss-giro.oss-sm { width: 18px; height: 18px; border-width: 2px; }

.oss-esqueleto {
  background: linear-gradient(90deg, var(--oss-carta-2) 25%, var(--oss-fundo) 37%, var(--oss-carta-2) 63%);
  background-size: 400% 100%;
  animation: oss-brilho 1.4s ease-in-out infinite;
  border-radius: var(--oss-curva-sm);
  height: 1em;
}
.oss-esqueleto + .oss-esqueleto { margin-top: var(--oss-e-2); }
.oss-esqueleto.oss-curto { width: 40%; }
.oss-esqueleto.oss-medio { width: 70%; }
@keyframes oss-brilho { to { background-position: -135% 0; } }

@media (prefers-reduced-motion: reduce) {
  .oss-giro { animation: none; border-top-color: var(--oss-fio-forte); }
  .oss-esqueleto { animation: none; background: var(--oss-carta-2); }
}

/* ═══════════════════════════════════════════════════════════════════════════
   AVATAR
   ═══════════════════════════════════════════════════════════════════════════
   A inicial num círculo. Sem foto: a escola não pede foto de ninguém. */
.oss-avatar {
  display: inline-flex; align-items: center; justify-content: center;
  width: 36px; height: 36px; flex: none;
  border-radius: 50%;
  background: var(--oss-escuro);
  color: var(--oss-ouro);
  font-family: var(--oss-serif);
  font-size: var(--oss-t-md);
  line-height: 1;
  user-select: none;
}
.oss-avatar.oss-lg { width: 48px; height: 48px; font-size: var(--oss-t-lg); }

/* ═══════════════════════════════════════════════════════════════════════════
   LINHA DO TEMPO
   ═══════════════════════════════════════════════════════════════════════════
   A jornada de uma pessoa e o log de auditoria. Hora à esquerda, em números
   tabulares, para a coluna não dançar. */
.oss-tempo { list-style: none; margin: 0; padding: 0; }
.oss-tempo > li {
  display: grid; grid-template-columns: auto 1fr; gap: 2px var(--oss-e-4);
  padding: var(--oss-e-2) 0;
  border-bottom: 1px solid var(--oss-fio);
  font-size: var(--oss-t-peq);
}
.oss-tempo > li:last-child { border-bottom: 0; }
.oss-tempo-quando { color: var(--oss-tinta-3); font-variant-numeric: tabular-nums; white-space: nowrap; }
.oss-tempo-oque { color: var(--oss-tinta); }
.oss-tempo-nota { grid-column: 2; color: var(--oss-tinta-3); font-size: var(--oss-t-mini); }

/* ═══════════════════════════════════════════════════════════════════════════
   BARRA DE PROGRESSO
   ═══════════════════════════════════════════════════════════════════════════
   Fina, sem gradiente, com o número escrito ao lado — barra sozinha não
   informa nada a quem não enxerga bem. */
.oss-barra { height: 4px; background: var(--oss-fio); border-radius: var(--oss-curva-pill); overflow: hidden; }
.oss-barra-preenche {
  height: 100%; background: var(--oss-ouro); border-radius: inherit;
  transition: width var(--oss-tempo-calmo) var(--oss-curva-saida);
}

/* ═══════════════════════════════════════════════════════════════════════════
   FAIXA ESCURA
   ═══════════════════════════════════════════════════════════════════════════
   O cabeçalho do Dojo e o rodapé institucional. Sem gradiente: uma cor chapada
   com um fio de ouro embaixo lê melhor e envelhece melhor. */
.oss-escuro {
  background: var(--oss-escuro);
  color: var(--oss-tinta-clara);
  border-bottom: 1px solid var(--oss-fio-ouro);
}
:where(.oss-escuro) :is(h1, h2, h3) { color: var(--oss-tinta-clara); }
:where(.oss-escuro) :is(p, .oss-meta) { color: var(--oss-tinta-clara-2); }

/* ═══════════════════════════════════════════════════════════════════════════
   CASCA — a mesa de trabalho
   ═══════════════════════════════════════════════════════════════════════════
   No celular: cabeçalho em cima, abas rolando, conteúdo embaixo.
   No desktop (≥1024px): barra lateral fixa à esquerda, conteúdo à direita.

   A MESMA marcação serve às duas — só a grade muda. É isso que evita o painel
   ter dois HTML, que é como painel adaptado a celular costuma apodrecer.

   A barra lateral NÃO é uma coluna da grade: é casca. A grade do conteúdo
   começa depois dela. */
.oss-mesa {
  min-height: 100svh;
  display: grid;
  grid-template-areas: "topo" "nav" "corpo";
  grid-template-rows: auto auto 1fr;
  background: var(--oss-fundo);
}
.oss-mesa-topo  { grid-area: topo; }
.oss-mesa-nav   { grid-area: nav; }
.oss-mesa-corpo { grid-area: corpo; min-width: 0; padding-block: var(--oss-e-5) var(--oss-e-8); }

@media (min-width: 1024px) {
  .oss-mesa {
    grid-template-areas: "lado topo" "lado corpo";
    grid-template-columns: var(--oss-lateral) minmax(0, 1fr);
    grid-template-rows: auto 1fr;
  }
  .oss-mesa-nav {
    grid-area: lado;
    position: sticky; top: 0; align-self: stretch;
    /* `stretch` e não `start`: com `start` a barra tem a altura do conteúdo
       dela e o fio da direita para no meio da tela, cortando a coluna ao
       meio. Ela precisa acompanhar a mesa inteira. */
    min-height: 100vh; min-height: 100svh;
    overflow-y: auto;
    display: flex; flex-direction: column;
    padding: var(--oss-e-5) var(--oss-e-3);
    border-right: 1px solid var(--oss-fio);
    border-bottom: 0;
    background: var(--oss-carta-2);
  }
  .oss-mesa-corpo { padding-inline: var(--oss-e-6); }
}

/* O item da barra lateral. No celular ele é uma aba; no desktop, uma linha
   com ícone. A classe é a mesma e a diferença mora aqui — não em duas listas
   de links no HTML. */
@media (min-width: 1024px) {
  .oss-abas.oss-lado {
    flex-direction: column;
    gap: 2px;
    overflow: visible;
    border-bottom: 0;
  }
  .oss-abas.oss-lado .oss-aba {
    width: 100%;
    justify-content: flex-start;
    min-height: var(--oss-ctrl);
    padding: var(--oss-e-2) var(--oss-e-3);
    border-bottom: 0;
    border-radius: var(--oss-curva-sm);
    font-size: var(--oss-t-peq);
  }
  .oss-abas.oss-lado .oss-aba:hover { background: var(--oss-carta); color: var(--oss-tinta); }
  /* O ativo na lateral é uma superfície, não um fio: fio embaixo numa lista
     vertical parece separador de item, e não seleção. */
  .oss-abas.oss-lado .oss-aba[aria-current],
  .oss-abas.oss-lado .oss-aba.oss-ativo {
    background: var(--oss-carta);
    border-bottom: 0;
    box-shadow: var(--oss-elev-1), inset 2px 0 0 var(--oss-ouro);
  }
}

/* ═══════════════════════════════════════════════════════════════════════════
   BUSCA
   ═══════════════════════════════════════════════════════════════════════════
   Campo com o ícone dentro. O ícone é decorativo — quem descreve o campo é o
   rótulo, que existe mesmo quando está só para o leitor de tela. */
.oss-busca { position: relative; display: flex; align-items: center; flex: 1; min-width: 0; }
:where(.oss-busca) .oss-i {
  position: absolute; left: var(--oss-e-3);
  color: var(--oss-tinta-3); pointer-events: none;
}
:where(.oss-busca) .oss-entrada { padding-left: calc(var(--oss-e-3) * 2 + 1.15em); }

/* ═══════════════════════════════════════════════════════════════════════════
   MODAL
   ═══════════════════════════════════════════════════════════════════════════
   Construído sobre <dialog>: o navegador já sabe prender o foco, fechar no
   Esc e empilhar acima de tudo. Reimplementar isso em JavaScript é como se
   escreve armadilha de acessibilidade.

   Entra subindo 8px, e é o movimento mais longo do sistema — 320ms. Um modal
   que aparece instantaneamente assusta; um que demora meio segundo irrita. */
.oss-modal {
  width: min(520px, calc(100vw - var(--oss-e-6)));
  max-height: 85svh;
  padding: 0;
  border: 1px solid var(--oss-fio);
  border-radius: var(--oss-curva-md);
  background: var(--oss-carta);
  color: var(--oss-tinta);
  box-shadow: var(--oss-elev-3);
  overflow: hidden;
}
.oss-modal::backdrop { background: rgba(13, 26, 16, .42); backdrop-filter: blur(2px); }
.oss-modal[open] { animation: oss-sobe var(--oss-tempo-calmo) var(--oss-curva-saida); }
@keyframes oss-sobe { from { opacity: 0; transform: translateY(8px); } }

.oss-modal-topo {
  display: flex; align-items: flex-start; gap: var(--oss-e-3);
  padding: var(--oss-e-5) var(--oss-e-5) var(--oss-e-3);
}
.oss-modal-tit { font-family: var(--oss-serif); font-size: var(--oss-t-lg); color: var(--oss-tinta); }
.oss-modal-x {
  margin-left: auto; flex: none;
  width: var(--oss-ctrl-sm); height: var(--oss-ctrl-sm);
  display: inline-flex; align-items: center; justify-content: center;
  border: 0; border-radius: var(--oss-curva-sm);
  background: none; color: var(--oss-tinta-3); cursor: pointer;
  transition: background var(--oss-tempo) var(--oss-curva-saida),
              color var(--oss-tempo) var(--oss-curva-saida);
}
.oss-modal-x:hover { background: var(--oss-carta-2); color: var(--oss-tinta); }
.oss-modal-corpo { padding: 0 var(--oss-e-5); overflow-y: auto; color: var(--oss-tinta-2); }
.oss-modal-pe {
  display: flex; gap: var(--oss-e-2); justify-content: flex-end; flex-wrap: wrap;
  padding: var(--oss-e-5);
  margin-top: var(--oss-e-4);
  border-top: 1px solid var(--oss-fio);
  background: var(--oss-carta-2);
}

@media (prefers-reduced-motion: reduce) { .oss-modal[open] { animation: none; } }

/* ═══════════════════════════════════════════════════════════════════════════
   TOAST
   ═══════════════════════════════════════════════════════════════════════════
   O recado que confirma o que acabou de acontecer: "convite copiado",
   "acesso concedido". No celular sobe de baixo, onde o polegar está; no
   desktop aparece no canto inferior direito.

   Três regras que evitam o pior uso de toast:
     · toast NUNCA carrega erro que exige ação — erro fica na tela, perto do
       que falhou, e não some sozinho depois de 4 segundos;
     · toast NUNCA é o único registro de algo — quem perdeu o toast (foi ao
       banheiro, trocou de aba) não pode ficar sem saber;
     · a região é `aria-live="polite"`, e não `assertive`: confirmar não é
       urgente e não deve interromper a leitura em curso. */
.oss-toasts {
  position: fixed;
  left: var(--oss-e-4); right: var(--oss-e-4);
  bottom: calc(var(--oss-e-4) + env(safe-area-inset-bottom));
  z-index: var(--oss-z-recado);
  display: flex; flex-direction: column-reverse; gap: var(--oss-e-2);
  pointer-events: none;
}
@media (min-width: 640px) {
  .oss-toasts { left: auto; width: min(380px, calc(100vw - var(--oss-e-8))); right: var(--oss-e-5); bottom: var(--oss-e-5); }
}
.oss-toast {
  pointer-events: auto;
  display: flex; align-items: flex-start; gap: var(--oss-e-3);
  padding: var(--oss-e-3) var(--oss-e-4);
  border: 1px solid var(--oss-fio);
  border-radius: var(--oss-curva);
  background: var(--oss-carta);
  color: var(--oss-tinta);
  font-size: var(--oss-t-peq);
  box-shadow: var(--oss-elev-3);
  animation: oss-sobe var(--oss-tempo-calmo) var(--oss-curva-saida);
}
:where(.oss-toast) .oss-i { color: var(--oss-ok); margin-top: .1em; }
.oss-toast.oss-atencao .oss-i { color: var(--oss-atencao); }
.oss-toast.oss-mal .oss-i { color: var(--oss-erro); }
@media (prefers-reduced-motion: reduce) { .oss-toast { animation: none; } }

/* ═══════════════════════════════════════════════════════════════════════════
   GRÁFICO ORGÂNICO
   ═══════════════════════════════════════════════════════════════════════════
   A linha do tempo de prática, desenhada como respiração e não como cotação
   de bolsa: traço fino, curva suave, sem preenchimento gritante, sem grade,
   sem eixo. O NÚMERO fica escrito ao lado — gráfico sozinho não informa nada
   a quem enxerga pouco, e é por isso que ele nunca é a única fonte.

   O SVG é desenhado com `preserveAspectRatio="none"`: a linha estica com o
   cartão, e a espessura fica constante por `vector-effect`. */
.oss-linha-tempo { display: block; width: 100%; height: 40px; overflow: visible; }
.oss-linha-tempo path {
  fill: none;
  stroke: var(--oss-verde);
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
  opacity: .75;
}
.oss-linha-tempo .oss-area { fill: var(--oss-verde); stroke: none; opacity: .07; }

/* ═══════════════════════════════════════════════════════════════════════════
   LOGO
   ═══════════════════════════════════════════════════════════════════════════
   O logotipo caligráfico da escola, o mesmo do site — não uma palavra
   escrita numa fonte parecida.

   Ele entra como MÁSCARA, e não como imagem: assim o traço assume
   `currentColor` e o mesmo arquivo serve à tinta sobre o pergaminho, ao ouro
   num destaque e ao creme sobre a floresta. Um arquivo, três usos, e nenhuma
   chance de as versões saírem de sincronia quando o logo for redesenhado.

   `role="img"` e `aria-label="Oss Yoga"` no elemento: máscara é fundo, e fundo
   não tem nome para o leitor de tela. */
.oss-logo {
  display: block;
  width: 168px;
  aspect-ratio: 620 / 400;
  color: var(--oss-tinta);
  background-color: currentColor;
  -webkit-mask: var(--oss-logo-arquivo) center / contain no-repeat;
          mask: var(--oss-logo-arquivo) center / contain no-repeat;
}
.oss-logo.oss-sm { width: 108px; }
.oss-logo.oss-lg { width: 232px; }
/* NÃO existe variante dourada sobre fundo claro: o ouro dá 2:1 contra o
   pergaminho e o logo sumiria. Sobre a floresta ele funciona, e ali quem
   manda é a regra abaixo. (O teste do sistema reprovou a variante que eu
   tinha escrito aqui — e reprovou com razão.) */
:where(.oss-escuro) .oss-logo, .oss-logo.oss-sobre-escuro { color: var(--oss-tinta-clara); }

/* ═══════════════════════════════════════════════════════════════════════════
   TABELA
   ═══════════════════════════════════════════════════════════════════════════
   Para quando a lista tem colunas de verdade — turmas com data e vagas,
   matrículas com validade. Sem zebra: listra sobre papel creme fica suja. O
   que separa é o fio, e o que orienta o olho é o `:hover` da linha inteira.

   No celular ela **rola na horizontal**, dentro do próprio contêiner, e a
   primeira coluna fica grudada: perder o nome ao rolar é perder a referência
   do que se está lendo. A página nunca rola de lado — só a tabela. */
.oss-tabela-rolo { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.oss-tabela {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--oss-t-peq);
  color: var(--oss-tinta-2);
}
.oss-tabela th {
  position: sticky; top: 0;
  padding: var(--oss-e-2) var(--oss-e-3);
  border-bottom: 1px solid var(--oss-fio-forte);
  background: var(--oss-fundo);
  color: var(--oss-tinta-3);
  font-family: var(--oss-sans);
  font-size: var(--oss-t-micro);
  font-weight: var(--oss-peso-forte);
  letter-spacing: var(--oss-tracking-alta);
  text-transform: uppercase;
  text-align: left;
  white-space: nowrap;
}
.oss-tabela td {
  padding: var(--oss-e-3);
  border-bottom: 1px solid var(--oss-fio);
  vertical-align: baseline;
}
.oss-tabela tbody tr { transition: background var(--oss-tempo-rapido) var(--oss-curva-saida); }
.oss-tabela tbody tr:hover { background: var(--oss-carta-2); }
.oss-tabela td:first-child { color: var(--oss-tinta); font-weight: var(--oss-peso-nl); }
/* Número alinhado à direita e em algarismo tabular: é o que faz uma coluna de
   valores poder ser comparada de relance. */
.oss-tabela .oss-num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
