/*
 * A CASCA: barra de cima e menu lateral. UM arquivo para as duas telas.
 *
 * Ele pediu em 09/08/2026: *"deixa só um menu, usa algo como require ou include; não tem
 * necessidade de ser diferente. O topo também."*
 *
 * A marcação já tinha virado uma só (`casca.js`); faltava o estilo. Medido no momento da
 * extração: das dez peças da casca, nove já tinham estilo idêntico nas duas telas — e a
 * décima, `.rail .avatar img`, existia só no painel. Sem ela, a foto do perfil era
 * desenhada em **1080x1080** no visualizador e vazava pelo menu inteiro.
 *
 * Uma regra faltando estragou a tela. Enquanto houvesse duas cópias, a próxima entraria
 * numa e faltaria na outra.
 *
 * **Este arquivo é linkado ANTES do `<style>` de cada página**, de propósito: regra própria
 * de uma tela continua vencendo o comum, como vencia quando tudo estava no mesmo lugar.
 */

/* AS VARIAVEIS QUE A CASCA USA, declaradas por ela mesma.
   Sem isto o arquivo depende do `:root` de quem o inclui — e foi o que
   aconteceu: `--tinta-esc-2` so existia no painel, entao no visualizador os
   botoes do menu cairam para a cor do texto comum, rgb(23,32,46) sobre navy.
   Medido. Cada tela pode redefinir depois; o `:root` dela vem por ultimo. */
:root {
  --tinta-esc-2: #9fb0c7;
  --tinta-esc-off: #5b6a82;
}

/* ---------------------------------------------------------- cabeçalho */
  header.topo {
    display: flex; align-items: center; gap: var(--s4);
    height: 60px; padding: 0 var(--s6);
    background: var(--navy); color: #fff;
    box-shadow: var(--sh-1); position: relative; z-index: 5;
  }
  header.topo img { height: 30px; display: block; }

  /* O SELO DO AMBIENTE DE TESTE — item 260, 17/08/2026.
     Ele é idêntico à produção na tela, e é isso que precisa ser desfeito num relance.
     Quem avisa de verdade é a BARRA INTEIRA mudando de cor; o selo diz o nome da coisa,
     ao lado da foto de quem entrou. Um chip discreto sozinho, no navy de sempre, seria
     lido como enfeite depois de dois dias. Onde ele entra, e por quê, está em `casca.js`. */
  header.topo .sh-selo-teste {
    /* SEM `margin-left`: ele entra DEPOIS da tagline, e o `auto` dela já empurrou o bloco
       inteiro para a direita. Um segundo `auto` aqui dividiria a sobra e deixaria o selo
       boiando no meio da barra — medido, x=780 numa janela de 1536. */
    flex: none; align-self: center;
    padding: 4px 10px; border-radius: 6px;
    background: #b45309; color: #fff;
    font: 700 11px/1 Montserrat, system-ui, sans-serif; letter-spacing: .08em;
    white-space: nowrap;
  }
  /* A barra em terra queimada, e não no navy do produto. A marca continua legível: medido,
     branco sobre #7c2d12 dá 9,4:1 de contraste. */
  body.sh-ambiente-de-teste header.topo { background: #7c2d12; }

  /* A MARCA OCUPA A LARGURA DO MENU ABERTO, e o risquinho vira o prolongamento da divisao
     entre o navy e o branco — uma linha so, subindo do menu ate o topo. Ver o comentario
     em `casca.js`, que explica por que 214 e fixo e nao segue o menu.

     O `padding: 0` no header e o `padding-left` aqui: a folga da esquerda tem de pertencer
     a MARCA, senao os 214 px comecariam depois dela e o risquinho passaria da divisao. */
  header.topo { padding-left: 0; }
  header.topo .sh-marca {
    width: 214px; flex: none; align-self: center;
    /* BLOCO, e nao flex-column. Com `flex-direction: column` cada pedaço do conteudo vira
       um ITEM do flex — e "Sherlock", o "3D" e o subtitulo empilharam em TRES linhas.
       Bloco simples: o texto flui numa linha e o `display:block` do subtitulo faz a
       segunda. Medido duas vezes antes de eu enxergar a causa. */
    display: block;
    padding-left: 22.3px;
    /* 24 px, e o numero foi MEDIDO e nao escolhido no olho. Ele pediu maior; entao
       varri de 18 a 28 px dentro dos 214 disponiveis: o texto vai de 118 a 181 px de
       largura, e ATE 28 cabe. Parei em 24 (155 px + 24 de folga = 179) porque sobram
       35 px — espaco para o dia em que a marca ou o subtitulo crescerem. Em 28 sobrariam
       9, e a proxima palavra a mais estouraria sem aviso. */
    font-family: var(--brand); font-weight: 800; font-size: 25.5px;
    letter-spacing: .005em; color: #fff; line-height: 1;
    /* NAO QUEBRA. Medido: com 20px e folga de 32, "Sherlock 3D" partia em duas linhas
       dentro dos 214 px — e a marca do produto partida ao meio e pior que marca pequena.
       18px com folga de 24 cabe, e o subtitulo embaixo continua legivel. */
    white-space: nowrap;
  }
  header.topo .sh-marca b { color: var(--orange); font-weight: 800; }
  header.topo .sh-marca small {
    display: block; margin-top: 3px;
    /* SEM `font-family`: o subtitulo HERDA a fonte da marca, e as duas linhas sao um
       wordmark so. Eu tinha escrito aqui uma variavel de fonte do corpo que NAO EXISTE em
       lugar nenhum do produto — inventei — e a guarda da casca me pegou. O subtitulo teria
       caido no Montserrat em silencio; desta vez era o que eu queria, da proxima pode ser
       a fonte errada e ninguem ve.
       (O nome da variavel inventada nao esta escrito aqui de proposito: a guarda procura
       o padrao de uso no arquivo inteiro, e citar o removido faria ela achar este
       comentario. E a terceira vez hoje que esta armadilha aparece.) */
    font-weight: 400; font-size: 8.5px;
    /* O ESPACAMENTO ENCAIXA O SUBTITULO NA LARGURA DO NOME, e o valor foi calculado e nao
       tateado. Medido: "Sherlock 3D" tem 155,3 px e o subtitulo tinha 156,2 — 0,9 px a
       mais, invisivel mas por acaso. Sao 24 caracteres, entao tirar 0,9/24 = 0,0375 px de
       cada um leva o espacamento de .055em para .0506em a 8,5 px.
       **Isto e um valor AJUSTADO, e ele so vale para ESTAS duas frases.** Trocar o nome do
       produto ou o subtitulo desencaixa, e a conta tem de ser refeita — o teste da casca
       guarda o numero para a mudanca nao passar calada. */
    letter-spacing: .1197em; text-transform: uppercase; color: #8698b3;
  }
  /* O RISQUINHO VAI DE PONTA A PONTA do cabecalho — 26px de altura o deixariam flutuando no
     meio, e o que ele precisa e continuar a linha que vem do menu de baixo. */
  /* O RISCO VAI DE PONTA A PONTA do cabecalho — 26px o deixariam flutuando no meio, e o
     que ele precisa e continuar a linha que vem do menu de baixo.
     E a MARGEM NEGATIVA come o `gap` do cabecalho: medido, o risco caia em x=230 com o
     menu terminando em 214 — 16 px de desvio, que sao exatamente o gap. Sem isso o
     alinhamento erra por uma folga que ninguem ve no CSS. */
  /* O RISCO — E ELE TINHA DESAPARECIDO. Ao reescrever este bloco eu apaguei sem querer a
     regra que dava `width` e `background` ao divisor; sobrou so a altura, e um elemento de
     zero largura sem fundo nao desenha nada. Medi a POSICAO (x=214, desvio zero) e conclui
     que estava certo — a posicao estava, a linha nao existia. Ele apontou numa imagem.
     Medir a coisa errada da uma resposta certa sobre nada. */
  header.topo .sh-divisor { width: 1px; height: 26px; background: rgba(255,255,255,.22); }
  header.topo .sh-marca + .sh-divisor { height: 100%; margin-left: calc(var(--s4) * -1); }
  header.topo .sh-tagline { margin-left: auto; font-size: 12px; color: #93a1b8;
                         letter-spacing: .02em; }

  /* ---- O MENU DO USUARIO E A TELA ESTREITA — vieram do `index.html` do painel em 17/08/2026
     (item 252), junto com os elementos. Enquanto a regra morava la, ela valia so no painel.

     Medido na epoca: com o chip no topo, a tagline quebra em duas linhas a partir de 980 px de
     largura; sem o chip, nao quebrava. **Some a tagline, e nao o menu** — "Do voo ao documento" e
     decoracao e nao diz nada que a pessoa precise; sair da propria conta e funcao. 1100 px e o
     ponto de quebra que a folha ja usa em tres lugares, com folga sobre os 980 medidos.

     O `margin-left: auto` mora na TAGLINE e e ele que empurra tudo para a direita. Escondendo a
     tagline sem passar o auto para o usuario, o chip voltaria a colar nas abas, no meio da barra. */
  @media (max-width: 1100px) {
    header.topo .sh-tagline { display: none; }
    header.topo .sh-usuario { margin-left: auto; }
  }

  /* ---- O RASTRO: Projetos / pasta / projeto — item 239, 17/08/2026
     Pedido dele: *"nome da pasta e projeto aberto sempre visivel no topo"*, com um print,
     e a forma escolhida foi de tres niveis: *"Projetos / pasta / projeto"*.

     POR QUE AQUI, E NAO NO BANNER NAVY DA TELA. "Sempre visivel" e literalmente isto: esta
     barra atravessa Importar, Processar, Anotar, Documentar, Entregar **e o visualizador 3D**,
     porque e a MESMA peca (`casca.js`) nas duas superficies. O banner e reescrito por cada
     tela, e no 3D nao existe — hoje o 3D nao diz em que projeto voce esta.

     Medido antes de desenhar: a 1536 de largura sobram **930 px** entre as abas (terminam em
     450) e a tagline (comeca em 1380). Cabe com folga; o teto do nome existe para o caso ruim.

     `min-width: 0` no rastro E OBRIGATORIO e nao e sobra: sem ele o `text-overflow` do nome
     nao tem como agir dentro de um flex, e um nome comprido empurra a tagline para fora da
     barra — que nao rola. */
  header.topo .rastro { display: flex; align-items: center; gap: 8px; min-width: 0;
                        font-size: 13px; }
  /* ⚠️ `padding: 0 0 1px` E O CONSERTO DO VAO DESIGUAL — item 245, 17/08/2026.
     Ele apontou o print: *"o projeto e um botao, nao precisaria ai; acho que resolveria esse
     espaco depois de projetos"*. **Medido, e ele achou a causa exata:** os vaos entre as CAIXAS
     eram todos 8 px, mas os niveis clicaveis sao `<button>` e herdavam **16 px de recheio de cada
     lado** da regra global de botao. Entao o vao VISIVEL depois de "Projetos" era 16+8 = **24 px**,
     e antes do nome do projeto — que e um `<span>`, sem recheio — era **8**. Tres vaos de 8 e um
     de 24 no mesmo rastro.
     Zerar o horizontal e manter o `padding-bottom: 1px` deixa os quatro iguais, e o 1px de baixo
     continua sendo o que dá lugar ao sublinhado do hover sem mexer no texto. */
  header.topo .rastro .rastro-no { color: #93a1b8; text-decoration: none; white-space: nowrap;
                            padding: 0 0 1px;
                            border-bottom: 1px solid transparent;
                            display: inline-flex; align-items: center; gap: 6px;
                            background: none; border-left: 0; border-right: 0; border-top: 0;
                            font: inherit; cursor: pointer; }
  header.topo .rastro .rastro-no:hover { color: #fff; border-bottom-color: rgba(255,255,255,.45); }
  header.topo .rastro .rastro-no:focus-visible { outline: 2px solid var(--orange); outline-offset: 2px; }
  /* A BARRA EM 55% E UM PONTO MAIOR — aprovado por print em 17/08/2026, item 244.
     Ele apontou o print e disse que ficou feio: no monitor dele, a 125%, uma barra de **5,1 px a
     30% de opacidade** lê como um PONTO, não como separador. Medido — não era impressão.
     O caractere sempre foi `/`; o que faltava era enxergá-lo. Mandei 30, 45, 55 e 70 lado a lado
     e ele escolheu o 55. O `15px` num rastro de 13px é o "ponto maior" da proposta, e o
     `translateY` corrige o meio-pixel que a barra sobe ao crescer. */
  header.topo .rastro .rastro-barra { color: rgba(255,255,255,.55); font-size: 15px;
                               transform: translateY(-.5px); }
  /* O ULTIMO nivel e onde voce esta: branco, 600, e NAO e link — link que nao vai a lugar
     nenhum ensina errado. */
  header.topo .rastro .rastro-aqui { color: #fff; font-weight: 600; white-space: nowrap;
                              overflow: hidden; text-overflow: ellipsis; max-width: 420px; }
  header.topo .rastro .rastro-pasta { display: inline-flex; flex: none; }

  /* ---- menu do usuário, no canto direito da barra
     O Sair morava só dentro da tela Conta — quem quisesse sair precisava saber
     que "sair" fica em "Conta", e ninguém sabe. Subiu para cá com o "Trocar
     minha senha" porque é o canto onde todo aplicativo os põe, e sair é a ação
     que a pessoa procura sem querer aprender onde fica. As duas cópias em Conta
     FICARAM: ali é a tela da pessoa, e quem já decorou o caminho não perde. */
  /* Sem margin: a barra já tem gap de 16px, e somar os dois daria 32.
     O `align-self: stretch` não é enfeite: é ele que faz o `100%` do menu valer
     os 60px da BARRA, e não os 40px do chip. Sem isso o menu subia 3px e o canto
     arredondado dele caía sobre o navy — medido. */
  header.topo .sh-usuario { position: relative; flex: none; align-self: stretch;
                         display: flex; align-items: center; }
  header.topo .sh-usuario > button {
    display: flex; align-items: center; gap: 8px; height: 40px;
    padding: 0 8px 0 5px; border: 1px solid transparent; border-radius: 999px;
    background: none; color: #fff; font: inherit; cursor: pointer; transition: var(--t);
  }
  header.topo .sh-usuario > button:hover,
  header.topo .sh-usuario > button[aria-expanded="true"] {
    background: rgba(255,255,255,.08); border-color: rgba(255,255,255,.14);
  }
  /* Círculo NEUTRO, e não laranja como o do menu lateral, porque os dois não
     mostram a mesma coisa: o do rail reflete o PERFIL (a marca que assina o
     relatório, que numa conta de empresa é a empresa), e este mostra QUEM ESTÁ
     LOGADO. Dois círculos laranja iguais exibindo nomes diferentes leriam como
     defeito. De quebra o laranja continua sendo só da ação principal. */
  header.topo .sh-usuario .avatar {
    flex: none; width: 28px; height: 28px; border-radius: 50%;
    background: rgba(255,255,255,.12); color: #fff; display: inline-flex;
    align-items: center; justify-content: center; font-weight: 700; font-size: 12.5px;
    border: 1px solid rgba(255,255,255,.18);
  }
  header.topo .sh-usuario .nome { font-size: 13px; font-weight: 600; max-width: 148px;
                               overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  header.topo .sh-usuario .seta { flex: none; opacity: .65; transition: var(--t); }
  header.topo .sh-usuario > button[aria-expanded="true"] .seta { transform: rotate(180deg); }

  /* abas do topo: indicam a tela atual e navegam entre elas */
  header.topo .sh-abas { display: flex; gap: 4px; background: rgba(255,255,255,.06);
                      padding: 4px; border-radius: 9px; }
  .sh-aba { padding: 6px 14px; border-radius: 8px; font-size: 13px; font-weight: 600;
         color: var(--tinta-esc-2); text-decoration: none; white-space: nowrap; transition: var(--t); cursor: pointer;
         display: inline-flex; align-items: center; gap: 7px; }
  .sh-aba svg { flex: none; }
  .sh-aba:hover { color: #fff; background: rgba(255,255,255,.06); }
  .sh-aba.sh-ativa { background: var(--orange); color: #fff; }
  .sh-aba.desativada { color: var(--tinta-esc-off); cursor: not-allowed; }
  .sh-aba.desativada:hover { background: none; color: var(--tinta-esc-off); }        /* a lista de projetos virou a tela "Projetos" */
  .rail button.rail-ativo { background: rgba(255,101,1,.16); color: #fff; }
  .rail button.rail-ativo svg { color: var(--orange); }
  /* itens que dependem de um projeto aberto ficam apagados e sem clique */
  .rail button.rail-off { opacity: .34; cursor: not-allowed; }
  .rail button.rail-off:hover:not(:disabled) { background: none; }
  /* Andamento no próprio menu, na mesma linguagem da trilha da Visão geral:
     disco verde com ✓ no que está pronto, disco laranja no que está em curso.
     Saber onde o projeto parou sem abrir tela nenhuma. */
  /* -------------------------------------------- trilha de etapas no menu
     O menu não é uma lista com selos: é uma SEQUÊNCIA, e agora ela aparece.
     Um fio liga as etapas e se preenche conforme o trabalho anda.

     A cor mudou por medição, não por gosto: o ✓ usava `--good var(--good)`, que é
     calibrado para texto escuro sobre BRANCO. Sobre o navy ele apaga — mesmo
     matiz, sem luminosidade. Aqui vale a família clara (var(--good-claro)), com halo,
     que é o que o padrão manda usar em painel escuro. */
  .rail button.etapa-passo { position: relative; }

  /* O fio, atrás do nó. 3px e opaco: com 2px translúcidos ele lia como risco
     de fundo, e não como ligação entre as etapas. */
  .rail button.etapa-passo::before {
    content: ''; position: absolute; right: 17px; top: -2px; bottom: -2px; width: 3px;
    border-radius: 2px; background: rgba(255,255,255,.10); z-index: 0; }
  .rail button.etapa-passo.fio-feito::before { background: var(--good-claro); opacity: .75; }
  .rail button.etapa-passo.passo-primeiro::before { top: 50%; }
  .rail button.etapa-passo.passo-ultimo::before { bottom: 50%; }

  /* O nó. 20px, com anel de fundo navy separando-o do fio — sem esse anel o
     disco encosta na linha e os dois viram um borrão só. */
  .rail button.etapa-passo::after {
    content: ''; position: absolute; right: 8.5px; top: 50%; transform: translateY(-50%);
    /* `border-box` não é detalhe: sem ele a borda SOMA por fora, e o nó em curso
       — que tem borda mais grossa — ficava com 26px externos contra 24 dos
       concluídos. O Henrique viu como "laranja fora de proporção", e era isso:
       ele era mesmo 2px maior. Com border-box todos medem 22, qualquer que
       seja a espessura da borda. */
    box-sizing: border-box; width: 22px; height: 22px; border-radius: 50%; z-index: 1;
    background: var(--navy); box-shadow: 0 0 0 3px var(--navy);
    border: 2px solid rgba(255,255,255,.20);
    background-repeat: no-repeat; background-position: center; background-size: 13px 13px;
    transition: background-color var(--t), border-color var(--t); }

  /* Concluída: disco verde claro e ✓ BRANCO de traço grosso. O ✓ era verde
     escuro sobre verde claro, e a 10px isso não se lê — some no próprio disco. */
  .rail button.rail-ok.etapa-passo::after {
    background-color: var(--good-claro); border-color: var(--good-claro);
    filter: drop-shadow(0 0 6px rgba(46,224,138,.5));
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-width='4.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E"); }

  /* Em curso: alvo laranja. A borda era de 5px e o nó PESAVA mais que os
     discos verdes — mesma caixa, peso visual diferente, e o olho lê isso como
     "maior". Com 3,5px a área pintada fica equivalente à do disco cheio, e o
     halo baixa de 7 para 6px, o mesmo dos outros. */
  .rail button.rail-agora.etapa-passo::after {
    background-color: var(--navy); border-color: var(--orange); border-width: 4px;
    filter: drop-shadow(0 0 6px rgba(255,101,1,.6)); }

  /* Pendente: anel vazado, mais visível que antes. Uma etapa que ainda não
     chegou precisa aparecer na trilha; invisível, a sequência parece acabar. */
  .rail button.etapa-passo:not(.rail-ok):not(.rail-agora)::after {
    border-color: rgba(255,255,255,.28); }

  /* Retraído, a trilha encosta no ícone em vez de ficar na margem do rótulo. */
  .rail:not(.aberto) button.etapa-passo::after { right: 5px; }
  .rail:not(.aberto) button.etapa-passo::before { right: 13.5px; }

  /* ---------------------------------------------------------- rail de navegação */
  .rail { background: var(--navy); height: calc(100vh - 60px); overflow: hidden auto;
          display: flex; flex-direction: column; gap: 2px; padding: 10px 8px; }
  .sh-rail-grupo, .sh-rail-baixo { display: flex; flex-direction: column; gap: 2px; }
  .sh-rail-baixo { margin-top: auto; padding-top: 8px; border-top: 1px solid rgba(255,255,255,.12); }
  .rail button { display: flex; align-items: center; gap: 12px; width: 100%;
                 background: none; border: 0; color: var(--tinta-esc-2); cursor: pointer;
                 padding: 10px; border-radius: 12px; font: inherit;
                 transition: background var(--t), color var(--t); }
  /* O `:not(:disabled)` aqui não é firula: sem ele esta regra empata em
     especificidade com a genérica `button:hover:not(:disabled)`, que vem
     depois no arquivo e vence — pintando o item de branco sobre o navy e
     apagando o texto. */
  .rail button:hover:not(:disabled) { background: rgba(255,255,255,.09); color: #fff;
                                      border-color: transparent; }
  .rail button:active { transform: translateY(1px); }
  .rail button svg { width: 22px; height: 22px; flex: none; stroke-width: 1.7; }
  .rail button > span:not(.avatar) { font-size: 14px; font-weight: 600; white-space: nowrap;
                                     overflow: hidden; text-align: left; }
  /* ABERTO: ícone e rótulo encostados à ESQUERDA, e isto precisa estar ESCRITO.

     Ele viu em 10/08/2026, olhando o Visualizador: *"o menu lateral do Visualizador não é o
     mesmo do painel, veja, ele está centralizado"*. Estava, e a causa é o tipo de defeito
     que só aparece quando a mesma folha é usada em duas páginas diferentes.

     Esta regra NÃO EXISTIA. O estado aberto dependia do valor **padrão** do navegador
     (`justify-content: normal`), e valor padrão é o que a página em volta pode mudar sem
     saber que mudou:

       - no `/app`, nada mexe em `button` genérico  ->  ficava `normal`, à esquerda;
       - no `/3d`, a folha da própria página declara `button { justify-content: center }`
         para os botões dela, DEPOIS da casca  ->  os itens do menu centralizavam junto.

     Medido nas duas telas, com o menu aberto: mesma largura (214 px), mesmo `padding-left`
     (10 px), mesmo x — e `justify-content` `normal` de um lado, `center` do outro. A casca
     parecia igual em tudo o que ela declarava, e diferia justamente no que ela calava.

     **A lição, e ela vale para o resto desta folha:** componente compartilhado não pode
     herdar do padrão do navegador aquilo que define a aparência dele. O que não está escrito
     aqui é decidido pela página que hospeda — e são duas páginas. */
  .rail.aberto button { justify-content: flex-start; }
  /* retraído: só ícones, centralizados; rótulos somem */
  .rail:not(.aberto) button { justify-content: center; padding: 10px 0; }
  .rail:not(.aberto) button > span:not(.avatar) { display: none; }
  .rail .sh-sep { height: 1px; background: rgba(255,255,255,.12); margin: 8px 10px; flex: none; }

  /* ---------------------------------------------- o menu na tela BAIXA (item 162)
     **O menu não cabia na tela do notebook dele, e isso é medido.** A janela útil ali é de
     738 px (1080 a 125% de zoom, menos a barra de tarefas e o cromo do Chrome); o menu tem
     678 px e o conteúdo pedia 747. Configurações — o último item — terminava em y=797,
     59 px abaixo da dobra. O `overflow: auto` acima faz a régua rolar, e é por isso que
     ninguém tinha visto: não some, esconde.

     **Trinta e um daqueles pixels já faltavam antes de hoje**, com 15 itens e nenhum risco.
     Os outros 38 são meus: cada linha divisória custa 19 px (1 de traço e 18 de margem), e
     eu pus duas. Não dá para pôr as três camadas na tela e fingir que o espaço apareceu.

     Então a régua encolhe QUANDO A JANELA É BAIXA, e só aí. Na tela externa dele — 922 px —
     nada disto vale, e o menu continua com a folga de sempre. O corte em 860 px fica no
     meio das duas, longe de ambas: não é um valor que uma janela redimensionada tropece.

     Encolher é preferível a rolar porque **o pé do menu é justamente o que não pode sumir**:
     Ajuda e Configurações são a saída de quem está perdido, e quem está perdido não rola um
     menu para procurá-las.

     **O `height: auto` é a linha que faz o resto funcionar, e eu levei duas medições para
     enxergar isso.** A altura de um item do menu NÃO vem do recheio daqui: vem da regra
     `button, a.btn { height: 38px }` do `index.html`, que é a base de botão de todo o
     produto e alcança estes também. Apertar o recheio de 10 para 6 px mudou a altura em
     zero — medido, 38 px antes e 38 px depois. Só depois de soltar a altura o recheio passa
     a decidir alguma coisa, e o item cai para 34. */
  @media (max-height: 860px) {
    .rail { padding: 8px; }
    .rail button { height: auto; padding: 7px 10px; }
    .rail:not(.aberto) button { padding: 7px 0; }
    .rail button svg { width: 20px; height: 20px; }
    .rail .sh-sep { margin: 5px 10px; }
    .sh-rail-baixo { padding-top: 6px; }
  }
  /* Salvar e Cópia são AÇÃO, não etapa, e ganham o laranja da marca com halo —
     aceso, como letreiro. Era #ffc79e, um pêssego lavado que não é cor nenhuma
     da paleta. #ff6501 sobre o navy dá 5,60:1, acima do mínimo de leitura.
     O halo do ícone usa `currentColor`, que lê a propriedade `color` — por isso
     ele vem do próprio item e acompanha o estado sem repetir a cor. */
  .rail button.acao { color: var(--orange); text-shadow: 0 0 9px rgba(255,101,1,.55); }
  .rail button.acao svg { filter: drop-shadow(0 0 5px currentColor); }
  /* Desativado não acende: letreiro apagado é o que diz que não dá para clicar. */
  .rail button.acao:disabled { text-shadow: none; }
  .rail button.acao:disabled svg { filter: none; }
  .rail button.acao:hover:not(:disabled) { background: rgba(255,101,1,.16); color: #fff; }
  .sh-rail-toggle { color: #cdd8e6; margin-bottom: 4px; }

  /* ---- O RECOLHER FICA NA MESMA LINHA QUE PROJETOS — item 244, 17/08/2026.
     Ele mandou o print e o pedido: *"vi o ícone recolher na mesma linha que projetos, veja como
     fizemos em modelo"*. No painel Modelo o cabeçalho é título à esquerda e o botão à direita
     (`.cabPainel`, com `space-between`); aqui é a mesma ideia, com Projetos no papel do título.

     ## O buraco só existia com o menu ABERTO
     Medido: a fileira do ícone tem 38 px de altura e **174 px vazios à direita** do desenho com
     o menu aberto (214 px). Fechado o rail tem 66 px, a fileira tem 50 px úteis e o ícone fica
     centrado — não há buraco nenhum, e é justamente ali que se procura o "expandir".

     Daí a regra, e ela é uma linha de CSS: **aberto, o botão sai do fluxo e encosta à direita da
     primeira fileira; fechado, ele volta a ser a fileira de cima.** Projetos herda os 42 px que a
     fileira ocupava, e passa a ser a primeira coisa da tela.

     `position: absolute` e não `flex`: a alternativa seria envolver Projetos e o botão num
     `<div>`, e isso mudaria a marcação que o `_botoes()` gera para TODOS os itens — muito mais
     código para o mesmo pixel. O `rail` já é `position: relative`? Se não for, a linha abaixo
     garante. */
  .rail { position: relative; }
  .rail.aberto .sh-rail-toggle {
    position: absolute; top: 10px; right: 8px; z-index: 2;
    width: 38px; height: 38px; padding: 0; margin: 0;
    justify-content: center;
  }
  /* Sem o botão no fluxo, o `gap`/margem que ele deixava some junto — e é o que faz Projetos
     subir para o topo em vez de ficar com um vão de 42 px por cima. */
  .rail.aberto > .sh-rail-grupo { margin-top: 0; }
  /* AS QUATRO REGRAS DO ITEM DE CONTA NO MENU LATERAL SAIRAM em 17/08/2026, e elas estavam
     mortas desde 09/08 — quando ele apontou os dois menus com uma seta: *"esses menu estao
     repetidos, poderiam ficar so no canto superior direito"*. O ITEM foi removido naquele dia; o
     ESTILO ficou, sem casar com nada, por mais de uma semana.

     Quem as achou foi a guarda escrita hoje para outro defeito — o chip do usuario que perdeu o
     fundo. Ela procura regra que estiliza classe que ninguem escreve, e essa pergunta pega as
     duas coisas: renome pela metade e remocao pela metade. */

  /* A FOTO DENTRO DO AVATAR. Esta e a regra que motivou o arquivo inteiro.
     Ela vivia solta no fim da folha do /app, longe das outras da casca, e o visualizador
     nunca a teve — com isso a foto do perfil era desenhada em 1080x1080 e vazava pelo menu
     inteiro. Medido: 30x30 no painel contra 1080x1080 no visualizador.
     Vale para o avatar do menu E para o do topo: os dois usam a mesma classe. */
  .avatar img { width: 100%; height: 100%; object-fit: cover; border-radius: 50%; display: block; }

  /* ---- O AVISO DE VERSAO VELHA — item 237, 17/08/2026.
     Cartao FLUTUANTE, e nao barra no topo: barra empurraria a tela toda para baixo justamente
     quando a pessoa esta no meio de algo, e mexer no layout dela para dizer "recarregue" seria um
     segundo susto. Flutuante nao move nada.

     Mora na casca porque as DUAS telas o usam — o painel e o visualizador —, e um dos tres
     relatos falsos de 17/08 veio do 3D.

     `z-index` alto de proposito: ele tem de aparecer sobre o dialogo modal tambem. Uma tela velha
     com um dialogo aberto e exatamente o caso em que o aviso mais importa. */
  #avisoDeVersao {
    position: fixed; right: 18px; bottom: 18px; z-index: 9000;
    display: flex; align-items: center; gap: 12px;
    max-width: 420px; padding: 13px 15px;
    background: #fff; border: 1px solid var(--border); border-left: 4px solid var(--orange);
    border-radius: 11px; box-shadow: 0 6px 24px rgba(19,31,51,.18);
    font: 400 13px/1.45 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
    color: var(--ink);
  }
  #avisoDeVersao .sh-av-ico { color: var(--orange); flex: none; display: flex; }
  #avisoDeVersao .sh-av-txt { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
  #avisoDeVersao .sh-av-txt b { font-size: 13.5px; color: var(--ink); }
  #avisoDeVersao .sh-av-txt span { font-size: 12px; color: var(--ink-3); }
  #avisoDeVersao .sh-av-btn {
    flex: none; padding: 8px 14px; border: 0; border-radius: 8px;
    background: var(--orange); color: #fff; font: 600 13px/1 inherit; cursor: pointer;
  }
  #avisoDeVersao .sh-av-btn:hover { filter: brightness(1.07); }
  #avisoDeVersao .sh-av-btn:focus-visible { outline: 2px solid var(--navy); outline-offset: 2px; }
  /* NA TELA ESTREITA ele ocupa a largura, menos as margens: 420px num viewport de 375 sairia
     pela direita, e a tela do notebook dele tem 1536 mas o celular do aluno nao. */
  @media (max-width: 520px) {
    #avisoDeVersao { left: 12px; right: 12px; max-width: none; }
  }


  /* ---- O MENU SUSPENSO DO USUARIO — veio do `index.html` do painel em 17/08/2026 (item
     253), junto com a funcao que o monta. Enquanto o estilo morava la, o menu do 3D sairia
     sem cor, sem borda e sem sombra — visivel, e obviamente quebrado. */
  .usuario-menu {
    position: absolute; right: 0; top: calc(100% + var(--s2)); z-index: 30;
    min-width: 236px; padding: 6px; background: var(--surface);
    border: 1px solid var(--border); border-radius: 12px; box-shadow: var(--sh-2);
  }
  .usuario-menu .cabeca { padding: 7px 10px 9px; margin-bottom: 6px;
                          border-bottom: 1px solid var(--hair); }
  .usuario-menu .cabeca b { display: block; font-size: 13px; color: var(--ink);
                            overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .usuario-menu .cabeca small { font-size: 11.5px; color: var(--ink-3);
                                overflow: hidden; text-overflow: ellipsis;
                                white-space: nowrap; display: block; }
  .usuario-menu button {
    display: flex; align-items: center; gap: 9px; width: 100%; height: 34px;
    padding: 0 10px; border: 0; border-radius: 8px; background: none;
    font: inherit; font-size: 13px; color: var(--ink-2); text-align: left;
    cursor: pointer; transition: var(--t);
  }
  .usuario-menu button:hover { background: var(--surface-2); color: var(--ink); }
  .usuario-menu button svg { flex: none; opacity: .7; }
  /* Sair é a última linha e a única com cor: encerra sessão, não é navegação. */
  .usuario-menu .sair { color: var(--bad); }
  .usuario-menu .sair:hover { background: var(--bad-bg); color: var(--bad); }
