/* Ajustes que o Tailwind não cobre. Carregado depois do CSS gerado,
   por causa do prefixo numérico: o Dash lê assets/ em ordem alfanumérica. */

/* Alerta temporário.
   Some sozinho por animação, sem callback e sem Interval: um dcc.Interval
   por mensagem seria uma requisição a cada tique, para nada. Fica visível
   por ~5s, depois desaparece e para de ocupar espaço. */
@keyframes alerta-sumir {
  0%,
  75% {
    opacity: 1;
    transform: translateY(0);
    max-height: 120px;
  }
  100% {
    opacity: 0;
    transform: translateY(-4px);
    max-height: 0;
    margin: 0;
    padding-top: 0;
    padding-bottom: 0;
    visibility: hidden;
  }
}

.alerta-temporario {
  animation: alerta-sumir 6s ease-in forwards;
  overflow: hidden;
}

/* Dropdown do Dash com a cara do resto da interface.
   O react-select traz o próprio estilo, e sem isto os seletores destoam
   dos inputs de texto ao lado. */
.Select-control,
.is-searchable .Select-control {
  border-radius: 0.5rem !important;
  border-color: #e9ebef !important;
  min-height: 2.625rem;
}

.is-focused:not(.is-open) > .Select-control {
  border-color: #1f3b6e !important;
  box-shadow: none !important;
}

.Select-placeholder,
.Select--single > .Select-control .Select-value {
  line-height: 2.5rem !important;
}

.Select-menu-outer {
  border-radius: 0.5rem !important;
  border-color: #e9ebef !important;
  box-shadow: 0 8px 24px rgba(31, 59, 110, 0.1) !important;
  z-index: 40;
}

.Select-option.is-selected {
  background-color: #fbf6ec !important;
  color: #8a6526 !important;
}

.Select-option.is-focused {
  background-color: #f8f9fa !important;
}

/* O seletor de data usa a mesma família de estilo do react-select. */
.DateInput_input,
.SingleDatePickerInput,
.DateRangePickerInput {
  border-radius: 0.5rem !important;
  border-color: #e9ebef !important;
  font-size: 0.875rem;
}

.CalendarDay__selected,
.CalendarDay__selected:hover {
  background: #1f3b6e !important;
  border-color: #1f3b6e !important;
}

/* Radio da prova: alvo de clique grande e marcação dourada.
   A questão é respondida no celular, em pé, de luva. */
input[type="radio"],
input[type="checkbox"] {
  accent-color: #d9a85b;
  width: 1rem;
  height: 1rem;
}

/* Alvo de toque de 40 px, só onde o ponteiro é o dedo.

   Os controles pequenos deste sistema são pequenos de propósito: a nota de
   BOTAO_PRIMARIO_MINI em tokens.py explica que o botão com padding cheio
   engorda a linha da tabela e desalinha a coluna de ação. Isso vale para o
   mouse, que acerta um alvo de 28 px sem esforço; não vale para o dedo, que
   erra. Medidos aqui: lixeira e lápis de tabela a 28 px, "Cancelar/Excluir"
   da confirmação em linha a 28, botões de paginação a 32, e os três da barra
   do topo — abrir menu, avisos, ajuda — a 36.

   `min-height`/`min-width` em vez de área invisível com `::after`: as ações
   de linha nascem em par com `gap-1.5`, e um alvo invisível de 44 px sobre
   dois botões de 28 px separados por 6 px se sobrepõe no meio. Encostar na
   borda direita do lápis dispararia a lixeira — trocar "difícil de acertar"
   por "acerta o botão errado" seria piorar. Ocupando espaço de verdade, o
   `gap` continua separando os dois.

   `pointer: coarse` é o ponteiro PRIMÁRIO. Notebook com tela sensível ao
   toque continua sendo `fine` enquanto o mouse for o ponteiro principal, e
   por isso nada muda no desktop — nem meio pixel. */
@media (pointer: coarse) {
  .alvo-toque {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 40px;
    min-height: 40px;
  }
}

/* Setinhas de campo numérico.
   O Dash 4 desenha os próprios botões "−/+" (.dash-input-stepper) dentro do
   campo, e o navegador desenha os dele por cima. Juntos comem metade da
   largura útil e brigam com o sufixo "%" da nota mínima. Quem preenche nota,
   meta ou quantidade digita o número; ninguém clica de 1 em 1 até 70. */
.dash-input-stepper {
  display: none !important;
}

input[type="number"]::-webkit-outer-spin-button,
input[type="number"]::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}
input[type="number"] {
  -moz-appearance: textfield;
  appearance: textfield;
}

/* Descrição de card em duas linhas, com reticência.
   `line-clamp` do Tailwind precisa do plugin; aqui vale a pena escrever. */
.line-clamp-2 {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* Rolagem discreta, para a sidebar de onze grupos não parecer um bloco pesado. */
::-webkit-scrollbar {
  width: 10px;
  height: 10px;
}
::-webkit-scrollbar-thumb {
  background: #d4d8de;
  border-radius: 6px;
}
::-webkit-scrollbar-track {
  background: transparent;
}

/* Impressão: o DRE e a tabela de custos são levados para reunião em papel.
   Sem isto, a sidebar e a barra do topo comem metade da folha. */
@media print {
  aside,
  header button,
  .no-print {
    display: none !important;
  }

  main {
    overflow: visible !important;
  }
}

/* Sombra de rolagem no menu lateral.

   Com o perfil de diretoria o menu tem 29 itens em 11 grupos: 1596 px de
   conteúdo numa faixa de 770 px, medido a 1440x900. Mais da metade do produto
   ficava abaixo da dobra — Financeiro, Compliance, Marketing e Configurações —
   sem nada na tela dizendo que havia mais.

   Esconder os grupos num acordeão resolveria a rolagem e criaria outro
   problema: o topo deste módulo diz, sobre o cadeado, que sumir esconde que a
   área existe. Vale para quem não tem permissão e vale aqui.

   A sombra usa `background-attachment: local` junto com `scroll`: as camadas
   brancas rolam com o conteúdo e cobrem a sombra quando não há mais nada para
   ver. Ou seja, ela aparece só quando há, e some sozinha no fim da lista — sem
   callback, sem Interval e sem medir altura em JavaScript.

   Perfil com poucos itens não vê sombra nenhuma, que é o certo. */
.menu-rolavel {
  background:
    linear-gradient(#ffffff 30%, rgba(255, 255, 255, 0)) top / 100% 20px no-repeat local,
    linear-gradient(rgba(255, 255, 255, 0), #ffffff 70%) bottom / 100% 20px no-repeat local,
    radial-gradient(farthest-side at 50% 0, rgba(31, 59, 110, 0.14), rgba(31, 59, 110, 0)) top / 100% 9px no-repeat scroll,
    radial-gradient(farthest-side at 50% 100%, rgba(31, 59, 110, 0.14), rgba(31, 59, 110, 0)) bottom / 100% 9px no-repeat scroll;
}

/* Rola o item ativo para dentro da faixa visível.

   `scroll-margin` reserva folga para o rótulo do grupo aparecer junto: chegar
   em "Campanhas" sem ver "Marketing e marca" em cima tira a referência de onde
   se está. Quem dispara o scroll é o próprio navegador, pelo âncora `:target`
   não — é o clientside do Dash em `layout.py`. */
.menu-item-ativo {
  scroll-margin-top: 3.5rem;
  scroll-margin-bottom: 2rem;
}

/* "Você está aqui" no menu lateral.

   O item ativo era decidido em `casca_autenticada`, comparando
   `flask.request.path` com a rota da página. Nunca funcionou: com `use_pages`,
   quem chama o layout é a requisição `/_dash-layout`, então `request.path`
   valia literalmente "/_dash-layout" e a comparação era falsa para todas as 29
   entradas. Depois, navegar por `dcc.Link` nem refaz o menu — ele é montado uma
   vez por carga de página.

   Verificado antes de mexer: o layout servido ao navegador tinha ZERO
   ocorrências de `bg-gold-50`. Num menu de 29 itens em 11 grupos, isso é o
   usuário sem referência de onde está.

   Agora quem marca é o callback `marcar_item_ativo`, que troca uma className
   só. Estas regras são o resto do estado ativo — barra e ícone — para que essa
   className única baste. */
.menu-barra {
  opacity: 0;
  transition: opacity 150ms ease-out;
}

.menu-item-ativo .menu-barra {
  opacity: 1;
}

/* O ícone acompanha o texto. Vale inclusive para os itens que já nascem
   dourados por serem frentes que a empresa vende (Academy, Certificações,
   Licitações, Private): a cor é a mesma, então nada pisca ao ativar. */
.menu-item-ativo svg {
  color: #d9a85b;
}
