/* ibsala v5 — estrutura do v1 repaginada.
   DNA herdado: fundo claro azulado, cards brancos, navy #002555 + ouro #F5AC00,
   Inter, filete dourado no topo, header-card com listra azul→ouro. */

/* Inter self-hospedada (SIL OFL 1.1, licença em fonts/OFL.txt). Um arquivo
   variável por subset: o navegador só baixa latin-ext se precisar de glifo dele.
   Antes vinha do fonts.googleapis.com por um <link media="print" onload=...>,
   e a CSP sem 'unsafe-inline' em script-src matava o onload: a Inter nunca
   entrava e o site inteiro rodava na fonte do sistema. */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url(fonts/inter-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url(fonts/inter-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
  color-scheme: light;
  --bg: #f7faff;
  --bg2: #eef3fb;
  --bg3: #e3ebf6;
  --surface: #ffffff;
  --border: #d6deec;
  --border-soft: #e9eef7;
  --blue: #002555;
  --blue-2: #0a3570;
  --gold: #F5AC00;
  --gold-dim: #d89700;
  --gold-soft: #fff4d0;
  /* aviso e perigo eram literais espalhados: o #dc2626 do "Excluir minha conta"
     não era token e por isso nunca passou pelo checador de contraste */
  --aviso: #b45309;
  --aviso-soft: #fff8ef;
  --aviso-borda: #f0d9b8;
  --perigo: #c62828;
  /* pós-graduação: fonte separada, identidade vermelha. Vermelho sozinho não
     basta (daltonismo, e vermelho já significa erro aqui), por isso a etiqueta
     PÓS anda junto em todo cartão. */
  --pos-vermelho: #b3261e;
  --pos-sobre-vermelho: #ffffff;
  --pos-suave: #fff4f3;
  --pos-borda: #e0a49e;
  --pos-texto: #8c1d18;
  --text: #0b1220;
  --text-dim: #475168;
  --text-muted: #62708c;
  --sobre-ouro: #241a00;      /* texto que fica em cima do ouro, nos dois temas */
  --sobre-azul: #ffffff;      /* texto que fica em cima do azul da pill */
  /* ouro como COR DE TEXTO em fundo claro: o #d89700 dava 2,40:1 no eyebrow,
     que é 12,5px e portanto texto normal pra WCAG */
  --gold-texto: #8a6100;
  --hover: #f2f6fd;
  --press: #e6ecf8;
  --shadow-sm: 0 1px 2px rgba(0,37,85,.05);
  --shadow-md: 0 4px 16px rgba(0,37,85,.08), 0 1px 3px rgba(0,37,85,.05);
  /* escala de espaçamento: antes eram 20 valores soltos (2, 3, 4, 5, 6, 7, 8,
     10, 11, 12, 14, 15, 16, 18, 20, 22, 24, 26, 28 e 30px), sem grade nenhuma */
  --s-1: 4px;
  --s-2: 8px;
  --s-3: 12px;
  --s-4: 16px;
  --s-5: 24px;
  --s-6: 32px;
  --pad-card: 16px 18px;
  --pad-linha: 12px 16px;

  --r-sm: 8px;
  --r-md: 10px;
  --r-lg: 14px;
  --font: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;

  /* escala tipográfica: sete passos, no lugar dos onze literais espalhados */
  --t-xs: 12.5px;
  --t-sm: 13.5px;
  --t-sm2: 14px;
  --t-md: 15px;
  --t-lg: 17px;
  --t-xl: 20px;
  --t-2xl: 26px;
  --t-hero: 56px;

  --col: 640px;               /* largura da coluna de conteúdo, por breakpoint */
}

/* Paleta escura em DOIS lugares de propósito, e não é descuido: uma para quem
   deixa o app seguir o sistema, outra para quem escolheu escuro no Ajustes. Sem
   build step não dá pra ter uma fonte só, então `scripts/contraste.py` compara
   os dois blocos token a token e o CI reprova se divergirem. */
@media (prefers-color-scheme: dark) {
  :root:not([data-tema="claro"]) {
    color-scheme: dark;
    --bg: #0b0f17;
    --bg2: #141a28;
    --bg3: #1c2436;
    --surface: #161c2c;
    --border: #2a3350;
    --border-soft: #1f2740;
    --blue: #6b9dff;
    --blue-2: #5688e8;
    --gold: #F5AC00;
    --gold-dim: #d89700;
    --gold-soft: #3a2a00;
    --aviso: #f0b429;
    --aviso-soft: #2a2008;
    --aviso-borda: #4a3a17;
    /* #dc2626 sobre o cartão escuro dava 4,45:1 e reprovava AA por pouco */
    --perigo: #ff7a6b;
    --pos-vermelho: #ff8a7a;
    --pos-sobre-vermelho: #2b0d0a;
    --pos-suave: #241412;
    --pos-borda: #5c2a24;
    --pos-texto: #ffb4a8;
    --text: #e8edf8;
    --text-dim: #a8b4d0;
    --text-muted: #8896c0; /* sólido; nunca opacity em texto */
    /* no dark o azul da pill clareia, então texto branco cai pra ~3,4:1:
       inverte pra texto escuro e volta pra ~5,4:1 */
    --sobre-azul: #0b1220;
    --gold-texto: #d89700;
    --hover: #1d2436;
    --press: #232c42;
    --shadow-sm: 0 1px 2px rgba(0,0,0,.35);
    --shadow-md: 0 4px 16px rgba(0,0,0,.45), 0 1px 3px rgba(0,0,0,.35);
  }
}

:root[data-tema="escuro"] {
  color-scheme: dark;
    color-scheme: dark;
    --bg: #0b0f17;
    --bg2: #141a28;
    --bg3: #1c2436;
    --surface: #161c2c;
    --border: #2a3350;
    --border-soft: #1f2740;
    --blue: #6b9dff;
    --blue-2: #5688e8;
    --gold: #F5AC00;
    --gold-dim: #d89700;
    --gold-soft: #3a2a00;
    --aviso: #f0b429;
    --aviso-soft: #2a2008;
    --aviso-borda: #4a3a17;
    /* #dc2626 sobre o cartão escuro dava 4,45:1 e reprovava AA por pouco */
    --perigo: #ff7a6b;
    --pos-vermelho: #ff8a7a;
    --pos-sobre-vermelho: #2b0d0a;
    --pos-suave: #241412;
    --pos-borda: #5c2a24;
    --pos-texto: #ffb4a8;
    --text: #e8edf8;
    --text-dim: #a8b4d0;
    --text-muted: #8896c0; /* sólido; nunca opacity em texto */
    /* no dark o azul da pill clareia, então texto branco cai pra ~3,4:1:
       inverte pra texto escuro e volta pra ~5,4:1 */
    --sobre-azul: #0b1220;
    --gold-texto: #d89700;
    --hover: #1d2436;
    --press: #232c42;
    --shadow-sm: 0 1px 2px rgba(0,0,0,.35);
    --shadow-md: 0 4px 16px rgba(0,0,0,.45), 0 1px 3px rgba(0,0,0,.35);
}

* { box-sizing: border-box; margin: 0; }

/* qualquer `display` de autor vence o `display:none` que o atributo hidden
   traz da folha do navegador, e foi assim que o aviso de falha apareceu com o
   mapa carregado direitinho */
[hidden] { display: none !important; }

html { height: 100%; }

body {
  min-height: 100%;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font);
  font-size: var(--t-md);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  /* o filete dourado do v1 */
  border-top: 3px solid var(--gold);
}

button, input, select, a {
  /* mata o atraso de 300ms do toque e o realce cinza padrão do mobile */
  touch-action: manipulation;
  -webkit-tap-highlight-color: rgb(245 172 0 / .22);
}

main {
  max-width: var(--col);
  margin: 0 auto;
  padding: 20px 18px 28px;
}

/* header-card do v1: listra vertical azul→ouro + mark com bolinha dourada */
.topo {
  position: relative;
  display: block;
  max-width: calc(var(--col) - 36px);
  /* o card vive FORA do <main>, então a safe area do iOS é problema dele: com
     viewport-fit=cover o conteúdo sobe por baixo da barra de status e o relógio
     do iPhone ficava escrito em cima da marca */
  margin: calc(18px + env(safe-area-inset-top)) auto 0;
  background: linear-gradient(135deg, var(--surface) 0%, var(--bg2) 100%);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: var(--pad-card);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
}

.topo::before {
  content: "";
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 4px;
  background: linear-gradient(180deg, var(--blue) 0%, var(--gold) 100%);
}

/* virou <button> pra levar pra home; o reset existe pra ele continuar parecendo
   a marca, e não um botão de formulário */
.marca {
  display: flex;
  align-items: center;
  gap: 10px;
  background: none;
  border: 0;
  padding: 0;
  margin: 0;
  font: inherit;
  text-align: left;
  cursor: pointer;
  color: inherit;
}

.marca-nome {
  display: block;
  font-size: var(--t-xl);
  font-weight: 900;
  letter-spacing: 1.2px;
  color: var(--blue);
  line-height: 1.2;
}

.marca-sub { display: block; font-size: var(--t-xs); color: var(--text-muted); }

.marca img { border-radius: var(--r-sm); box-shadow: var(--shadow-sm); }

@media (max-width: 640px) {
  .topo { margin: calc(14px + env(safe-area-inset-top)) 18px 0; }
}

.tela { display: none; }
.tela.ativa { display: block; }

/* ── títulos ───────────────────────────────────────────────────────────────── */
.home-titulo {
  font-size: var(--t-2xl);
  font-weight: 900;
  line-height: 1.15;
  letter-spacing: -.4px;
  padding-top: 4px;
  color: var(--text);
}

.tela-titulo {
  font-size: var(--t-2xl);
  font-weight: 800;
  line-height: 1.2;
  letter-spacing: -.3px;
  padding-top: 6px;
}

/* segunda parte do título: "Planilha dinâmica" é o nome do arquivo da faculdade
   e não diz o que a tela faz. Fica em linha própria, mais leve, pra explicar sem
   competir com o h1 */
.titulo-sub {
  display: block;
  font-size: var(--t-md);
  font-weight: 600;
  letter-spacing: 0;
  color: var(--text-dim);
  padding-top: 2px;
}

/* o título recebe foco por programa quando a tela troca, pra o leitor de tela
   acompanhar; anel não entra porque título não é controle operável, e o anel
   aparecia como uma caixa dourada em volta do h1 a cada navegação */
[data-cabeca]:focus, [data-cabeca]:focus-visible { outline: none; box-shadow: none; }

.painel-titulo { font-size: var(--t-xl); font-weight: 800; }

/* hero de salas livres: card destacado, número grande navy, contagem no ouro */
/* quando vem depois do rótulo de seção, o espaçamento é o do rótulo (8px), e é
   isso que faz o card da esquerda alinhar com o board da direita no desktop */
.secao + .painel-cabeca { margin-top: 0; }

/* botão logo abaixo do card não pode encostar nele: encostado, o canto
   arredondado do card ficava escondido atrás do botão */
.painel-cabeca + .btn-menu { margin-top: 18px; }

.painel-cabeca {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-sm);
  padding: var(--s-5) var(--s-5) var(--s-4);
  margin-top: 16px;
}

.hero-num {
  font-size: var(--t-hero);
  line-height: 1.05;
  font-weight: 900;
  letter-spacing: -2px;
  color: var(--blue);
  font-variant-numeric: tabular-nums;
}

.hero-rotulo { color: var(--text-dim); margin-top: 6px; }

.grade-salas {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  padding: 14px 0 2px;
}

.grupo-rotulo {
  width: 100%;
  font-size: var(--t-xs);
  font-weight: 800;
  letter-spacing: 1.6px;
  color: var(--text-muted);
  padding-top: 6px;
}

.grupo-rotulo:first-child { padding-top: 0; }

/* cabeçalho de cada turno na lista do resto do dia: o rótulo do turno e a conta
   na mesma linha, mais forte que o rótulo de prédio que vem abaixo dele */
.turno-cabeca {
  font-size: var(--t-sm);
  font-weight: 800;
  color: var(--text);
  padding: 18px 0 2px;
  border-top: 1px solid var(--border-soft);
  margin-top: 14px;
}

#livres-turnos .turno-cabeca:first-child { margin-top: 6px; }
#livres-turnos .grade-salas { padding-top: 8px; }

/* o interruptor é um card dentro de outro card, e sem margem ele encostava nos
   chips de sala em cima e na borda do painel embaixo. Escopado no painel pra não
   mexer nos switches de Ajustes, que já têm o espaçamento das `.dica`. */
.painel-cabeca .linha-switch { margin-top: 18px; }
.painel-cabeca #livres-turnos { padding-top: 6px; }

/* "Enviar aviso de teste" é um botão solto entre dois cards de interruptor, e
   encostava no de baixo: sem faixa de respiro ele parecia parte do card de
   emails, que é outro assunto */
#btn-push-teste { margin-top: 6px; }
#push-teste-status + .linha-switch { margin-top: 20px; }

.sala-chip {
  font-size: var(--t-sm);
  font-weight: 600;
  padding: 5px 12px;
  color: var(--text);
  background: var(--bg2);
  border: 1px solid var(--border);
  border-radius: 999px;
  font-variant-numeric: tabular-nums;
}

/* `.secao` é rótulo de agrupamento (12,5px, uppercase, muted). Ele estava
   encabeçando instrução de verdade, tipo "Escolha seu username", e ficava MENOR
   e mais apagado que o parágrafo abaixo: heading que perde do corpo. */
.secao-forte {
  display: block;
  font-size: var(--t-md);
  font-weight: 700;
  color: var(--text);
  padding: 22px 4px 4px;
}

.secao {
  font-size: var(--t-xs);
  font-weight: 800;
  letter-spacing: 1.8px;
  text-transform: uppercase;
  color: var(--text-muted);
  padding: 26px 4px 8px;
}

/* listas em card branco, linhas divididas (estrutura do v1) */
.board {
  list-style: none;
  padding: 0;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
}

.board:empty { display: none; }

/* o comentário de `.painel-cabeca + .btn-menu` documenta o mesmo defeito; a
   variante que sobrou era o botão dourado encostando no canto arredondado da
   LISTA de matérias */
.board + .btn-menu, .vazio + .btn-menu, .falha + .btn-menu { margin-top: 18px; }

.board li {
  display: grid;
  /* a coluna do chip é limitada a 38% da linha: com `auto` + nowrap, rótulo
     longo da planilha ("207 (P2) LAB.PROJETOS ELETRICOS/206 (P2)") reivindicava
     a linha inteira e a disciplina saía uma letra por linha no celular */
  grid-template-columns: minmax(0, 1fr) minmax(0, max-content);
  grid-template-areas:
    "disc  sala"
    "meta  sala"
    "dias  dias"
    "acoes acoes";
  gap: 2px 12px;
  padding: var(--pad-linha);
}

.board li + li { border-top: 1px solid var(--border-soft); }

/* ── pós-graduação ──────────────────────────────────────────────────────────
   Fonte separada da graduação, com identidade própria. A cor não carrega o
   recado sozinha: a etiqueta PÓS anda em todo cartão, porque vermelho aqui já
   significa erro e porque cor sozinha não chega em leitor de tela nem em quem
   não distingue vermelho. */
.board li[data-origem="pos"] {
  background: var(--pos-suave);
  box-shadow: inset 3px 0 0 var(--pos-vermelho);
}

.tag-pos {
  display: inline-block;
  background: var(--pos-vermelho);
  color: var(--pos-sobre-vermelho);
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 1px;
  border-radius: 3px;
  padding: 2px 6px;
  margin-right: 6px;
  vertical-align: 1px;
}

/* O curso é o que diferencia duas linhas da pós entre si, então ele não é meta:
   fica na cor da própria origem e numa linha própria. `dias` é a faixa que a
   lista já reserva embaixo da meta e que a pós não usa para outra coisa; sem
   isso curso e professor caem na MESMA célula do grid e se sobrepõem, que foi o
   que o render dos dois temas mostrou. */
.board li[data-origem="pos"] .curso {
  grid-area: dias;
  font-size: var(--t-sm);
  color: var(--pos-texto);
  font-weight: 600;
  padding-top: 2px;
}

.board li[data-origem="pos"] .sala {
  color: var(--pos-sobre-vermelho);
  background: var(--pos-vermelho);
}

.board .sala {
  grid-area: sala;
  align-self: center;
  font-size: var(--t-lg);
  font-weight: 800;
  color: var(--blue);
  background: var(--gold-soft);
  border-radius: var(--r-md);
  padding: 6px 12px;
  /* largura mínima igual pra todo mundo: com `3L2` e `P2-202` na mesma lista,
     cada badge terminava numa coluna diferente e a direita da tela ficava
     serrilhada */
  min-width: 4.6em;
  overflow-wrap: anywhere;
  text-align: center;
  font-variant-numeric: tabular-nums;
}

/* o dia da semana em "Minhas matérias" usava o chip DOURADO de sala. O ouro é o
   sinal mais forte do app e é do número da porta; dia da semana é etiqueta. */
.board .dia-chip {
  grid-area: sala;
  align-self: center;
  font-size: var(--t-sm);
  font-weight: 700;
  letter-spacing: .04em;
  color: var(--text-dim);
  background: var(--bg2);
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  padding: 5px 10px;
  text-align: center;
}

/* uma matéria é UM bloco, com uma pílula por dia em que ela acontece: a lista
   repetia a mesma disciplina uma vez por dia, cada cópia com seu Remover. O ×
   tira só aquele dia; o Remover do bloco tira a matéria inteira. */
/* faixa própria, largura inteira: na coluna da direita (que é `max-content` com
   teto de 38%) as pílulas empilhavam uma por linha a partir do terceiro dia e
   ainda espremiam a meta em três alturas. Deitadas, é a mesma disposição das
   pílulas de escolha na tela de adicionar. */
.board .dias {
  grid-area: dias;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  justify-content: flex-start;
  padding-top: 8px;
}

.pill-dia {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  min-height: 32px;
  font: inherit;
  font-size: var(--t-sm);
  font-weight: 700;
  letter-spacing: .04em;
  color: var(--text-dim);
  background: var(--bg2);
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  padding: 5px 8px 5px 10px;
  cursor: pointer;
}

.pill-x { font-size: var(--t-md); line-height: 1; opacity: .55; }
.pill-dia:hover .pill-x { opacity: 1; }

/* mesma pílula, outro papel: na busca ela ESCOLHE o dia em vez de tirar. Fica na
   área de ações, alinhada à esquerda, e o dia já cadastrado vem tracejado pra
   dizer "isso você já tem" antes do toque, não depois do erro do servidor. */
/* a fila ocupa a linha inteira e o botão desce pra linha de baixo: dividindo a
   largura com ele, as pílulas quebravam em duas fileiras e o botão saía com o
   texto partido no meio ("Adicionar / na QUI") */
/* Seis colunas iguais em vez de flex com quebra: apertando o padding a fila
   ainda saía 5 + 1 em 390px, e a sexta pílula sozinha numa segunda fileira é a
   "linha estourando" que apareceu no print. Com o grid, os seis dias dividem a
   largura e a fila é uma linha só em qualquer tela. */
.board .dias-escolha {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: 4px;
}

.pill-escolha {
  min-height: 38px;
  padding: 5px 2px;
  justify-content: center;
  gap: 3px;
  font-size: var(--t-xs);
  letter-spacing: .02em;
}

/* o cinza mais claro reprovava no contraste (4,47:1 no tema claro), então o "já
   tenho" é dito por borda tracejada e pelo ✓ no rótulo, não por cor mais fraca */
.pill-escolha.ja-tem { border-style: dashed; }

/* sem sala conhecida: não finge destaque de sala */
.board .sala-vazia {
  color: var(--text-dim);
  background: var(--bg2);
  font-weight: 700;
}

.board .disc { grid-area: disc; font-weight: 600; overflow-wrap: anywhere; }

.board .meta {
  grid-area: meta;
  color: var(--text-muted);
  font-size: var(--t-sm);
  overflow-wrap: anywhere;
}

/* meta de uma linha só: com o nome inteiro do professor e a turma dos dois
   cursos, a linha virava três alturas em 390px e o cartão da busca passava de
   meia tela. O texto completo fica no title. */
.board .meta-1l {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  overflow-wrap: normal;
}

/* sobrou pro painel do admin (Resolver, Bloquear): a busca e as matérias
   deixaram de ter botão na linha */
.board .acoes {
  grid-area: acoes;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
  padding-top: 8px;
}

/* no desktop as ações não precisam de uma faixa inteira embaixo da linha */
@media (min-width: 1100px) {
  .board .acoes { justify-content: flex-end; padding-top: 4px; }
}

/* `.vazio` fazia dois trabalhos opostos com o mesmo visual: DICA de ajuda e
   ESTADO vazio. Agora .dica é ajuda e .vazio é ausência de dado. */
.vazio { color: var(--text-muted); padding: 12px 4px; }
.dica { color: var(--text-dim); font-size: var(--t-sm); padding: 8px 4px; }
.linha-form + .vazio, .linha-form + .dica { padding-top: 10px; }

/* erro de formulário ao lado do campo, no lugar do toast que sumia em 3,2s */
.erro {
  color: var(--perigo);
  font-size: var(--t-sm);
  font-weight: 600;
  padding: 8px 4px 0;
}

.falha {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin-top: 14px;
  padding: var(--pad-linha);
  color: var(--text);
  background: var(--aviso-soft);
  border: 1px solid var(--aviso-borda);
  border-left: 3px solid var(--aviso);
  border-radius: var(--r-md);
}

.busca-wrap { display: block; padding-top: 16px; }

/* a lista de resultados não pode encostar no campo de busca */
/* a tela de adicionar disciplinas nasceu sem este par e o cartão do primeiro
   resultado encostava no campo de busca */
#busca-lista, #adicionar-lista { margin-top: 14px; }

.rotulo-campo {
  display: block;
  font-size: var(--t-xs);
  font-weight: 700;
  letter-spacing: .6px;
  text-transform: uppercase;
  color: var(--text-muted);
  padding-bottom: 6px;
}

input[type="search"], input[type="text"] {
  width: 100%;
  padding: 12px 14px;
  font-size: 16px;                 /* 16px trava o zoom automático do iOS */
  font-family: var(--font);
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-sm);
}

input[type="search"]:focus, input[type="text"]:focus { border-color: var(--blue-2); }

/* Era ouro: 1,00:1 sobre o botão dourado (a MESMA cor, foco invisível) e 1,86:1
   sobre o fundo claro. Azul funciona sobre superfície, sobre bg2 e sobre o ouro,
   e o halo da cor do fundo separa o anel de qualquer coisa atrás dele. */
input:focus-visible, button:focus-visible, select:focus-visible,
a:focus-visible, [tabindex]:focus-visible:not([data-cabeca]) {
  outline: 3px solid var(--blue-2);
  outline-offset: 2px;
  box-shadow: 0 0 0 5px var(--bg);
  border-radius: var(--r-sm);
}

/* `min-width: auto` do item flex trava o input no tamanho intrínseco (~210px a
   16px de fonte), e a linha inteira transbordava em 320px: iPhone SE, e qualquer
   iPhone com Zoom de Tela ligado */
.linha-form { display: flex; flex-wrap: wrap; gap: 8px; padding-top: 14px; }
.linha-form input { flex: 1 1 12ch; min-width: 0; }

/* ── botões ────────────────────────────────────────────────────────────────── */
/* Antes daqui não havia UMA regra :hover ou :active no arquivo: no PC o clique
   funcionava, mas nada respondia ao mouse e a interface parecia morta. */
.botao-primario {
  font-family: var(--font);
  font-weight: 700;
  font-size: var(--t-md);
  color: var(--sobre-ouro);
  background: linear-gradient(180deg, var(--gold) 0%, var(--gold-dim) 100%);
  border: 0;
  border-radius: var(--r-md);
  padding: 12px 18px;
  min-height: 44px;
  cursor: pointer;
  box-shadow: var(--shadow-sm);
  transition: filter .14s, transform .08s, background-color .14s, border-color .14s;
}

.botao-raso {
  margin-top: 22px;
  font-size: var(--t-sm2);
  color: var(--text-dim);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  padding: 10px 16px;
  min-height: 44px;
  cursor: pointer;
  transition: background-color .14s, transform .08s, border-color .14s;
}

.mini {
  font-family: var(--font);
  font-size: 13px;
  /* alvo de 44px: com 4px de padding o botão dava 26px e era inacertável em
     tela sensível ao toque */
  min-height: 44px;
  padding: 6px 14px;
  color: var(--text);
  background: var(--bg2);
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  cursor: pointer;
  transition: background-color .14s, transform .08s, border-color .14s;
}

select.mini { padding-right: 8px; }

.btn-menu {
  width: 100%;
  font-family: var(--font);
  font-weight: 700;
  font-size: 15.5px;
  text-align: left;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: 15px 18px;
  min-height: 44px;
  cursor: pointer;
  box-shadow: var(--shadow-sm);
  /* filter e opacity em .42s são a saída do estado de carregando (o vulto vira
     botão); o resto é o toque, que precisa ser curto */
  transition: background-color .14s, transform .08s, border-color .14s, box-shadow .14s,
    filter .42s ease, opacity .42s ease;
}

/* na MESMA linha, à direita do rótulo: em linha própria o botão engordava 20px
   e virava o dobro dos vizinhos. Mesmo tom do rótulo, nunca opacity em texto,
   que é como o contraste se perde sem ninguém ver. */
.btn-sub {
  font-size: var(--t-sm);
  font-weight: 600;
  white-space: nowrap;
}

.btn-menu.primario {
  color: var(--sobre-ouro);
  background: linear-gradient(180deg, var(--gold) 0%, var(--gold-dim) 100%);
  border-color: transparent;
}

/* dentro da grade 2x2 o stretch esticava este botão à altura do vizinho e ele
   virava uma CAIXA VAZIA com borda ao lado de três cards sólidos */
.btn-menu.menor {
  font-size: var(--t-sm2);
  font-weight: 600;
  padding: 11px 18px;
  color: var(--text-dim);
  background: transparent;
  border-color: transparent;
  box-shadow: none;
}

.link-botao {
  font-family: var(--font);
  font-size: inherit;
  font-weight: 700;
  color: var(--blue-2);
  background: none;
  border: 0;
  padding: 10px 0;
  min-height: 44px;
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 3px;
}

button:disabled {
  cursor: not-allowed;
  filter: grayscale(.4);
  color: var(--text-muted);
}

/* hover só onde existe ponteiro de verdade, senão o estado gruda no celular */
@media (hover: hover) and (pointer: fine) {
  .btn-menu:hover:not(:disabled) {
    background: var(--hover);
    border-color: var(--blue-2);
    box-shadow: var(--shadow-md);
  }
  .btn-menu.primario:hover:not(:disabled) { filter: brightness(1.06); background: var(--gold); }
  .btn-menu.menor:hover:not(:disabled) { background: var(--hover); color: var(--text); }
  .botao-primario:hover:not(:disabled) { filter: brightness(1.06); }
  .botao-raso:hover:not(:disabled) { background: var(--hover); border-color: var(--blue-2); }
  .mini:hover:not(:disabled) { background: var(--hover); border-color: var(--blue-2); }
  .voltar:hover { color: var(--blue-2); }
  .saiba:hover, .link-botao:hover { color: var(--blue); }
}

/* pressão vale pro mouse E pro toque */
.btn-menu:active:not(:disabled),
.botao-primario:active:not(:disabled),
.botao-raso:active:not(:disabled),
.mini:active:not(:disabled) {
  transform: translateY(1px);
  background-color: var(--press);
}
.btn-menu.primario:active:not(:disabled),
.botao-primario:active:not(:disabled) {
  background: var(--gold-dim);
  filter: none;
}
.voltar:active { transform: translateY(1px); }

@media (prefers-reduced-motion: reduce) {
  .btn-menu, .botao-primario, .botao-raso, .mini, .voltar { transition: none; }
  .btn-menu:active, .botao-primario:active, .botao-raso:active, .mini:active,
  .voltar:active { transform: none; }
}

/* home do v1: menu de botões grandes */
.menu { display: flex; flex-direction: column; gap: 12px; padding-top: 18px; }

/* enquanto o app não sabe se tem sessão, os botões da home aparecem como vulto:
   a forma e o lugar já estão lá (a tela não pula quando o dado chega), mas nada
   é legível nem clicável. O `inert` no <nav> é quem impede toque e tab; o blur
   só conta a história. Nada de `transform` aqui: o `.btn-menu` anima transform em
   80ms pro toque, e esticar isso pra meio segundo deixaria o botão mole. */
.menu[data-carregando] .btn-menu {
  filter: blur(5px);
  opacity: .5;
}

/* sem desfoque pra quem pediu menos animação: o vulto vira só opacidade menor */
@media (prefers-reduced-motion: reduce) {
  .menu[data-carregando] .btn-menu { filter: none; opacity: .55; }
}

.eyebrow {
  padding-top: 22px;
  font-size: var(--t-xs);
  font-weight: 800;
  letter-spacing: 2.2px;
  text-transform: uppercase;
  color: var(--gold-texto);
}

.tagline { color: var(--text-dim); padding-top: 6px; }

.saiba {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  margin-top: 20px;
  color: var(--blue-2);
  font-size: var(--t-sm2);
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* link DENTRO de frase: sem margem, sem virar bloco. O `.saiba` é o link
   avulso de fim de tela, e usar ele no meio de um parágrafo quebrava a linha */
.link {
  color: var(--blue-2);
  text-decoration: underline;
  text-underline-offset: 2px;
}

.cta-suave {
  margin-top: 22px;
  padding: var(--pad-linha);
  color: var(--text-dim);
  font-size: var(--t-sm2);
  background: var(--bg2);
  border: 1px dashed var(--border);
  border-radius: var(--r-md);
}

.voltar {
  margin-top: 14px;
  font-family: var(--font);
  font-size: var(--t-sm2);
  font-weight: 600;
  color: var(--text-dim);
  background: none;
  border: 0;
  padding: 6px 0;
  min-height: 44px;
  cursor: pointer;
  transition: color .14s, transform .08s;
}

.pills { display: flex; flex-wrap: wrap; gap: 7px; padding-top: 12px; }

.pill {
  font-size: var(--t-xs);
  font-weight: 600;
  color: var(--text-dim);
  background: var(--bg2);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 3px 11px;
  font-variant-numeric: tabular-nums;
}

/* valor da última sessão, esperando a rede confirmar: ocupa o tamanho final
   desde o primeiro quadro (é isso que tira o solavanco da abertura) e diz, pelo
   borrado, que ainda não é dado firme */
.vulto { filter: blur(4px); }
.pill { transition: filter .42s ease; }

@media (prefers-reduced-motion: reduce) {
  .vulto { filter: none; opacity: .55; }
  .pill { transition: opacity .2s linear; }
}

.pill-azul { color: var(--sobre-azul); background: var(--blue-2); border-color: transparent; }

.pill-ouro {
  color: var(--sobre-ouro);
  background: var(--gold);
  border-color: transparent;
  font-weight: 700;
}

.pill-fraco { color: var(--text-muted); background: transparent; }

/* ── componentes fantasma (carregando) ─────────────────────────────────────── */
.ghost {
  display: block;
  border-radius: var(--r-sm);
  background: linear-gradient(90deg, var(--bg2) 0%, var(--bg3) 50%, var(--bg2) 100%);
  background-size: 200% 100%;
  animation: ghost-desliza 1.3s linear infinite;
}

.ghost-li { pointer-events: none; }
.ghost-li .g-disc { grid-area: disc; height: 15px; width: 62%; }
.ghost-li .g-meta { grid-area: meta; height: 12px; width: 84%; margin-top: 5px; }
.ghost-li .g-sala { grid-area: sala; align-self: center; height: 30px; width: 58px; border-radius: var(--r-md); }

.g-chip { height: 27px; width: 58px; border-radius: 999px; }

.hero-num.ghost-num {
  color: transparent;
  border-radius: var(--r-md);
  background: linear-gradient(90deg, var(--bg2) 0%, var(--bg3) 50%, var(--bg2) 100%);
  background-size: 200% 100%;
  animation: ghost-desliza 1.3s linear infinite;
  width: 2.2ch;
}

@keyframes ghost-desliza {
  from { background-position: 200% 0; }
  to { background-position: -200% 0; }
}

@media (prefers-reduced-motion: reduce) {
  .ghost, .hero-num.ghost-num { animation: none; background: var(--bg3); }
}

/* ── trava do site ─────────────────────────────────────────────────────────── */
body.bloqueado main,
body.bloqueado .pills,
body.bloqueado .rodape { display: none; }

.bloqueio { max-width: var(--col); margin: 0 auto; padding: 24px 18px; }

.bloqueio-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-left: 4px solid var(--gold);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-md);
  padding: var(--s-5);
}

.bloqueio-card h2 { font-size: var(--t-xl); font-weight: 800; padding-bottom: 6px; }
.bloqueio-card p { color: var(--text-dim); }

.rodape {
  max-width: var(--col);
  margin: 30px auto 0;
  padding: 16px 18px calc(20px + env(safe-area-inset-bottom));
  border-top: 2px solid var(--gold);
  color: var(--text-muted);
  font-size: 13px;
  text-align: center;
}

#toast {
  position: fixed;
  left: 50%;
  bottom: 40px;
  transform: translateX(-50%) translateY(20px);
  background: var(--surface);
  border: 1px solid var(--border);
  box-shadow: var(--shadow-md);
  color: var(--text);
  padding: 10px 16px;
  border-radius: var(--r-md);
  opacity: 0;
  transition: opacity .18s, transform .18s;
  pointer-events: none;
  max-width: 90vw;
  z-index: 10;
}

#toast.on { opacity: 1; transform: translateX(-50%) translateY(0); }

@media (prefers-reduced-motion: reduce) {
  #toast { transition: none; }
}

/* interruptor de avisos: estado visivel, em vez de um botao que descreve a
   proxima acao ("Desativar avisos") e obriga a ler pra saber se esta ligado */
.linha-switch {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-sm);
  padding: var(--pad-card);
  min-height: 56px;
  cursor: pointer;
}

.linha-switch-texto { font-weight: 700; font-size: 15.5px; }

.linha-switch:has(.switch:disabled) { cursor: not-allowed; }
.linha-switch:has(.switch:disabled) .linha-switch-texto { color: var(--text-muted); }

.switch {
  appearance: none;
  -webkit-appearance: none;
  flex: none;
  position: relative;
  width: 52px;
  height: 30px;
  margin: 0;
  border-radius: 999px;
  background: var(--bg3);
  border: 1px solid var(--border);
  cursor: inherit;
  transition: background-color .16s, border-color .16s;
}

.switch::after {
  content: "";
  position: absolute;
  top: 3px;
  left: 3px;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--surface);
  box-shadow: 0 1px 3px rgba(0,0,0,.35);
  transition: transform .16s;
}

.switch:checked { background: var(--gold); border-color: var(--gold-dim); }
.switch:checked::after { transform: translateX(22px); }
.switch:disabled { opacity: .55; }

@media (prefers-reduced-motion: reduce) {
  .switch, .switch::after { transition: none; }
}

.acoes-conta { display: flex; flex-wrap: wrap; gap: 10px; }

.acoes-conta .botao-raso { margin-top: 0; }

.perigo { color: var(--perigo); border-color: var(--perigo); }


/* ── colunas (só ganham vida no desktop) ───────────────────────────────────── */
.colunas { display: block; }

/* ── desktop: antes daqui o único @media de layout era um ajuste de margem em
   640px, então tela de 1440px mostrava a mesma coluna de celular esticada ─── */
/* No celular o cabeçalho rouba a primeira dobra: são cinco pills antes de
   qualquer conteúdo. A contagem de livres já é o número herói da tela ao lado, e
   a hora da captura é detalhe de auditoria, não decisão de aluno. Some nas duas
   no celular e volta no tablet pra cima, onde sobra largura. */
@media (max-width: 767px) {
  #pill-livres, #pill-frescor { display: none; }
}

@media (min-width: 768px) {
  :root { --col: 720px; }

  /* menu 2x2: os quatro caminhos cabem sem rolagem */
  .menu {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 14px;
  }

  .home-titulo { font-size: 32px; }
  .tela-titulo { font-size: 30px; }
  .hero-num { font-size: 64px; }

  /* de 768 a 1099 a faixa herdava --col do desktop e NENHUMA das correções de
     layout dele: o chip de sala chegava a 248px no iPad em retrato */
  .colunas { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 22px;
    align-items: start; }
  .busca-wrap { max-width: 560px; }
}

@media (min-width: 1100px) {
  :root { --col: 1080px; }

  .colunas {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: var(--s-5);
    align-items: start;
  }

  .colunas-agora { grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr); }

  /* a primeira seção de cada coluna não pode empurrar a coluna pra baixo */
  .coluna > .secao:first-child { padding-top: 16px; }

  /* a largura extra vira informação lado a lado, não linha esticada */
  .board li {
    grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr) minmax(0, max-content);
    grid-template-areas:
      "disc meta sala"
      "acoes acoes acoes";
    align-items: center;
    gap: 4px 16px;
  }

  .ghost-li .g-meta { width: 92%; margin-top: 0; }

  .home-titulo { font-size: 38px; max-width: 26ch; text-wrap: balance; }
  .tela-titulo { font-size: 32px; }
  .tagline { max-width: 60ch; text-wrap: pretty; }
  .menu { max-width: 720px; }
  /* campo de busca de 1080px de largura é desconfortável de ler. A LISTA
     acompanha: com 560 no campo e 1044 na lista, a borda do campo caía no meio
     dos resultados */
  .busca-wrap, #busca-lista, #busca-dica, #busca-vazio,
  #busca-falha, #busca-sem-mapa, #cta-conta,
  #adicionar-lista, #adicionar-dica, #adicionar-vazio,
  #adicionar-falha, #adicionar-sem-mapa { max-width: 720px; }
}

/* mouse tem mira melhor que dedo: linha mais compacta e herói menos dramático.
   O alvo de 44px do .mini NÃO encolhe aqui: notebook com tela de toque casa
   `pointer: fine` pelo mouse e continua sendo tocado com o dedo. */
@media (pointer: fine) and (min-width: 1100px) {
  .board li { padding: 10px 16px; }
}


/* ── Cadastro: passos e aceite ───────────────────────────────────────────── */

.passos {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 14px;
  list-style: none;
  padding: 14px 0 2px;
  margin: 0;
}
.passos li {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: var(--t-sm);
  font-weight: 600;
  color: var(--text-muted);
}
.passo-num {
  display: grid;
  place-items: center;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  border: 1px solid var(--border);
  background: var(--surface);
  font-size: var(--t-xs);
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}
.passos .atual { color: var(--text); }
.passos .atual .passo-num {
  color: var(--sobre-ouro);
  background: var(--gold);
  border-color: var(--gold-dim);
}
.passos .feito { color: var(--text-dim); }
.passos .feito .passo-num {
  color: var(--sobre-azul);
  background: var(--blue-2);
  border-color: var(--blue-2);
}

.linha-aceite {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 12px 0 4px;
  font-size: var(--t-sm);
  color: var(--text-dim);
  cursor: pointer;
}
.caixa {
  flex: none;
  width: 22px;
  height: 22px;
  margin: 1px 0 0;
  accent-color: var(--gold);
}
.linha-aceite span { padding-top: 1px; line-height: 1.5; }
.linha-aceite .link { white-space: nowrap; }

#btn-cancelar-cadastro { margin-top: 10px; }

.rodape-links {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 20px;
  padding-top: 10px;
}
/* `.saiba` carrega margin-top de 26px pro link avulso de fim de tela; dentro de
   uma lista de links isso vira um buraco */
.rodape-links .saiba { margin-top: 0; }
.fim-pagina { padding-top: 24px; }


/* ── Ajustes ─────────────────────────────────────────────────────────────── */

/* seletor de 3 estados: mais claro que um switch quando a opção do meio é
   "segue o sistema" */
.segmentado {
  display: inline-flex;
  padding: 3px;
  gap: 3px;
  background: var(--bg2);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
}
.segmentado button {
  font-family: var(--font);
  font-size: var(--t-sm2);
  font-weight: 700;
  color: var(--text-dim);
  background: none;
  border: 0;
  border-radius: var(--r-sm);
  padding: 9px 14px;
  min-height: 44px;
  cursor: pointer;
}
.segmentado button.ativo {
  color: var(--sobre-ouro);
  background: var(--gold);
}

/* "Sair da conta" ficava colado em "Excluir minha conta", com a mesma cara e
   alvo de 44px: no celular era um convite a errar */
.acoes-fim {
  margin-top: 26px;
  padding-top: 18px;
  border-top: 1px solid var(--border-soft);
}

/* ── Acessibilidade ──────────────────────────────────────────────────────── */

/* texto que só o leitor de tela lê: o resultado da busca trocava sem nenhum
   anúncio, então quem navega por áudio digitava e não ouvia nada acontecer */
.so-leitor {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}


/* ── Páginas de texto (privacidade, termos) ──────────────────────────────── */
/* A política inteira usava `.tagline`, que é o subtítulo da home em --text-dim:
   corpo de página legal em cor de texto secundário. */
main > p {
  padding: 4px 4px 12px;
  max-width: 68ch;
  line-height: 1.65;
}
main > .fim-pagina { padding-top: var(--s-5); }
