/* ===========================================================================
   CAMADA 2 - BASE
   A fonte, o reset, os defaults de elemento, o foco global e as animacoes
   compartilhadas.
   =========================================================================== */

/* --- A fonte da identidade -----------------------------------------------
   UM ARQUIVO SO, variavel: os pesos de 100 a 900 sao o mesmo arquivo de 34KB,
   em vez de um arquivo por peso. Recortado para o alfabeto latino, que e tudo
   o que o portugues usa (acentos, cedilha, R$, travessoes que a fonte de dado
   externo as vezes traz).

   `swap`: o texto aparece NA HORA na fonte do sistema e troca quando o
   arquivo chega. Esperar a fonte para desenhar o texto seria trocar uma
   piscada de estilo por uma tela em branco, que e pior. O arquivo e anunciado
   com `preload` no layouts/base.html, entao na pratica ele chega antes do
   primeiro quadro e a troca nem aparece.

   Hospedada no proprio sistema, e nao num servico de fontes: a CSP so aceita
   `font-src 'self'`, e um servico de fontes recebe o IP de cada visitante de
   cada tela, o que numa tela que mostra CPF nao e detalhe. */
@font-face {
  font-family: "iPresto Sans";
  src: url("../fonts/ipresto-sans.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

*, *::before, *::after { box-sizing: border-box; }

h1, h2, h3, h4, h5, h6, p, figure, blockquote, dl, dd { margin: 0; }

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  /* Ancora de rolagem: com a barra do topo grudada, um link para #ancora
     deixaria o titulo escondido atras dela. */
  scroll-padding-block-start: calc(var(--topbar-height) + var(--space-4));
}

body {
  min-height: 100dvh;
  margin: 0;
  background: var(--color-bg-base);
  color: var(--color-text-primary);
  font: var(--font-weight-regular) var(--font-size-md) / var(--line-normal) var(--font-sans);
  /* A Geist foi desenhada com espacamento para tela: nada de espacamento
     extra no corpo. Ligaduras padrao ficam ligadas, e as discricionarias nao:
     num CPF ou num codigo de contrato, uma ligadura e um caractere a menos
     para quem confere. */
  font-feature-settings: "liga" 1, "calt" 1;
  font-kerning: normal;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

h1, h2, h3, h4, h5, h6 {
  line-height: var(--line-tight);
  letter-spacing: var(--tracking-tight);
  font-weight: var(--font-weight-bold);
  /* Titulo de duas linhas quebra em pedacos equilibrados, e nao numa linha
     cheia seguida de uma palavra orfa. */
  text-wrap: balance;
}

p { text-wrap: pretty; }

a { color: var(--color-accent-300); text-underline-offset: .22em; text-decoration-thickness: from-font; }

/* NUMERO NAO DANCA. Toda celula, todo valor e todo campo usam algarismos de
   largura fixa: numa coluna, a casa do milhar fica embaixo da casa do milhar,
   e um valor que se atualiza nao empurra o texto ao lado. */
table, input, output, .ipr-numero { font-variant-numeric: tabular-nums; }

/* Pontuacao de caixa alta: hifen, parenteses e dois-pontos sobem para o meio
   da letra maiuscula em vez de ficarem na altura da minuscula. Detalhe de
   tipografia que so se nota quando falta. */
.ipr-eyebrow, th { font-feature-settings: "case" 1; }

img, svg, video { max-width: 100%; }

/* ATENCAO - esta regra e a ordem dela importam.
   `img, svg { display: block }` e declaracao de autor e venceria o
   `[hidden] { display: none }` que vem do navegador, independentemente de
   especificidade. Como o botao de mostrar/ocultar senha alterna exatamente o
   atributo `hidden` de dois <svg>, sem a linha abaixo os DOIS icones do olho
   apareceriam ao mesmo tempo, sempre. Vale para qualquer svg oculto em
   paginas futuras. */
:where(img, svg, video):not([hidden]) { display: block; }
[hidden] { display: none !important; }

button, input, select, textarea { font: inherit; color: inherit; letter-spacing: inherit; }

/* Campo de texto no TOQUE tem 16px no minimo. Abaixo disso o Safari do
   iPhone aproxima a pagina inteira a cada campo focado, e a pessoa precisa
   tirar o zoom com dois dedos para continuar. */
@media (pointer: coarse) {
  input, select, textarea { font-size: max(1rem, 1em); }
}

ul[class] { list-style: none; padding: 0; margin: 0; }

/* --- Foco ----------------------------------------------------------------
   A ordem importa: zerar :focus antes de definir :focus-visible garante que
   quem usa mouse nao veja o anel, sem tirar o indicador de quem usa teclado. */
:focus { outline: none; }
:focus-visible {
  outline: var(--ring-width) solid var(--color-focus);
  outline-offset: var(--ring-offset);
  border-radius: inherit;
}

::selection {
  background: var(--color-accent-tint-strong);
  color: var(--color-text-primary);
}

/* Barra de rolagem combinando com o tema: fina, e da cor da borda. */
* { scrollbar-color: var(--color-border-strong) transparent; scrollbar-width: thin; }

/* Correcao de autofill: sem isto o Chrome pinta o campo de amarelo claro e o
   texto branco fica ilegivel em cima. Essencial em tema escuro. */
input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus {
  -webkit-text-fill-color: var(--color-text-primary);
  caret-color: var(--color-text-primary);
  box-shadow: inset 0 0 0 100px var(--color-input-bg);
  transition: background-color 9999s;
}

/* --- Pular para o conteudo ---------------------------------------------- */
.ipr-skiplink {
  position: absolute;
  left: var(--space-4);
  top: -4rem;
  z-index: var(--z-toast);
  background: var(--color-surface-2);
  color: var(--color-text-primary);
  padding: var(--space-3) var(--space-5);
  border-radius: var(--radius-md);
  text-decoration: none;
  box-shadow: var(--shadow-lg);
  transition: top var(--dur-base) var(--ease-out);
}
.ipr-skiplink:focus-visible { top: var(--space-4); }

/* --- O contrato do ponteiro, registrado ----------------------------------
   O modulo `pointer-glow` escreve QUATRO variaveis: --pointer-x e --pointer-y
   em pixels (usadas como posicao em gradiente) e estas duas, normalizadas de
   -1 a 1 a partir do centro do elemento.

   ELAS PRECISAM SER REGISTRADAS, e nao e detalhe:

   1. `initial-value: 0` da um valor VALIDO antes de o modulo montar e depois
      de ele desistir (celular, movimento reduzido, JS fora do ar). Sem
      registro, `calc(var(--pointer-nx) * 4deg)` com a variavel vazia invalida
      a declaracao inteira no valor computado;
   2. registrada como `<number>`, a variavel INTERPOLA. E isso que permite
      amortecer o movimento com uma `transition` na propria variavel, em vez
      de um laco de lerp em JavaScript.

   Moram aqui, e nao no CSS de uma pagina, porque o modulo serve o cartao de
   login, a apresentacao publica e o que vier depois. */
@property --pointer-nx { syntax: "<number>"; inherits: true; initial-value: 0; }
@property --pointer-ny { syntax: "<number>"; inherits: true; initial-value: 0; }

/* --- Animacoes globais ---------------------------------------------------
   Declaradas uma vez e usadas por varios componentes. Nenhum keyframe fixa
   cor, tamanho ou posicao: so opacidade, transform, filtro e espacamento de
   letra. E isso que permite o MESMO keyframe servir a varios componentes. */
@keyframes ipr-spin  { to { transform: rotate(360deg); } }
@keyframes ipr-rise  { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
@keyframes ipr-fade  { from { opacity: 0; } to { opacity: 1; } }
/* O DESTINO vem por variavel, entao este unico keyframe serve a qualquer
   deslocamento lento: as duas auroras do login e a malha de pontos que
   escorre atras delas usam os tres o mesmo bloco, so trocando --drift-x,
   --drift-y e o periodo. */
@keyframes ipr-drift {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(var(--drift-x, -3%), var(--drift-y, 4%), 0); }
}
@keyframes ipr-shake {
  10%, 90% { transform: translateX(-1px); }
  20%, 80% { transform: translateX(2px); }
  30%, 50%, 70% { transform: translateX(-3px); }
  40%, 60% { transform: translateX(3px); }
}

/* Brilho que atravessa um bloco de carregamento (esqueleto). Anda pelo
   `background-position`, entao um gradiente so serve qualquer largura. */
@keyframes ipr-shimmer { from { background-position: 150% 0; } to { background-position: -50% 0; } }

/* Barra de progresso que nao sabe quanto falta: avanca rapido no comeco e
   freia perto do fim, sem nunca chegar. Quem chega ao fim e a pagina nova. */
@keyframes ipr-progresso {
  0%   { transform: scaleX(0); }
  20%  { transform: scaleX(.42); }
  50%  { transform: scaleX(.68); }
  100% { transform: scaleX(.92); }
}

/* Unico !important tolerado alem do [hidden], e por acessibilidade:
   respeitar quem pediu menos movimento no sistema operacional.

   `animation-delay: 0s` e obrigatorio junto com a duracao. Zerar so a duracao
   deixaria os ATRASOS de pe: a abertura do login ficaria quase um segundo
   parada na tela antes de sumir num quadro, e a entrada escalonada viraria
   uma espera com a tela vazia. Com o atraso zerado, tudo assume o estado
   final imediatamente, que e exatamente o que "menos movimento" significa. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-delay: 0s !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    transition-delay: 0s !important;
    scroll-behavior: auto !important;
  }
}
