/* Exceções de classe própria (radzen-native-ui, D5). Todo o resto do visual vem de css/theme.css e dos parâmetros
   e Style dos componentes Radzen. Classe nova aqui só com motivo registrado no design da change ou no CLAUDE.md. */

/* Números e códigos da ficha (protocolo, código de material, data): a máquina de escrever. O Radzen não tem família
   monoespaçada nem font-variant-numeric por parâmetro. */
.mono { font-family: var(--font-mono); font-variant-numeric: tabular-nums; letter-spacing: 0; }

/* Tela de carregamento e aviso de erro do index.html: aparecem antes de o Blazor carregar os componentes. */
/* O respiro lateral não muda nada hoje (o conteúdo é centrado na altura da tela), mas o aço sangra até a borda:
   sem ele, texto mais longo ou tela estreita encostaria no fio do painel. */
.loading-screen { min-height: 100dvh; display: flex; flex-direction: column; justify-content: center; align-items: center; gap: 24px; padding: 24px; text-align: center; background: var(--steel); color: var(--steel-ink); }
.loading-screen img { filter: invert(1); }
#blazor-error-ui { display: none; position: fixed; bottom: 0; width: 100%; z-index: 9999; padding: 16px; background: #fff3cd; color: #333; }

/* Logo oficial da CCB: linha preta sobre transparente. No aço (trilho e cabeçalho) e no tema escuro inverte para branco,
   sem nenhuma outra alteração; depende de [data-theme] e da estrutura do Radzen. */
.logo { display: block; height: auto; }
[data-theme="dark"] .logo, .rz-sidebar .logo, .rz-header .logo { filter: invert(1); }

/* Menu inferior do celular: o Radzen não tem barra de navegação inferior; RadzenFooter com links, e só a posição fixa
   usa classe (o conteúdo ganha o respiro para não ficar embaixo da barra). */
.mobile-nav { position: fixed; left: 0; right: 0; bottom: 0; height: calc(70px + env(safe-area-inset-bottom)); padding-bottom: env(safe-area-inset-bottom); z-index: 20; }
.rz-layout:has(> .mobile-nav) .rz-body { padding-bottom: 76px; }

/* Link de pular para o conteúdo: o Radzen não tem um, e o padrão exige um elemento fora da tela que aparece ao
   receber o foco — não dá para fazer com parâmetro nem com variável do tema. Vestido como a etiqueta de gaveta
   (o mesmo cartão claro do item ativo do trilho), para não parecer peça de outro sistema. */
.skip-link {
  position: fixed; top: 8px; left: 8px; z-index: 100;
  transform: translateY(calc(-100% - 16px));
  padding: 12px 16px; min-height: 48px; display: inline-flex; align-items: center;
  background: var(--insert); color: var(--insert-ink);
  border-radius: 4px; font-weight: 650; font-size: 15px;
  box-shadow: 0 0 0 1px var(--steel-line), 0 0 0 3px var(--steel-raised);
}
.skip-link:focus-visible { transform: translateY(0); }
@media (prefers-reduced-motion: no-preference) { .skip-link { transition: transform 150ms ease-out; } }
/* O corpo é o alvo do link: recebe o foco por programa, então não leva anel (a regra global já trata tabindex -1). */
.rz-body:focus { outline: none; }

/* Alvo de toque da caixa de marcar (CheckTarget). O Radzen desenha um quadrado de 18 px e não expõe o alvo por
   parâmetro nem por variável: o invólucro de 48 px era só espaço morto, e o clique fora do quadrado não marcava
   nada. O ::before estende a área sensível do próprio controle (o elemento que tem o role="checkbox") até os
   48 px do invólucro, então o dedo acerta em qualquer ponto dele; o anel de foco continua abraçando o quadrado. */
.check-target { display: inline-flex; align-items: center; justify-content: center; width: 48px; height: 48px; flex: none; }
.check-target .rz-chkbox { position: relative; }
.check-target .rz-chkbox::before { content: ""; position: absolute; inset: -15px; border-radius: 4px; }

/* Régua de estado (StatusRail): o deslize do cavaleiro e o preenchimento do trecho percorrido. Fica aqui, e não no
   Style do componente, porque media query não alcança estilo inline — em Style a régua continuava animando para
   quem pede menos movimento. O trecho percorrido encolhe por scaleX (não refaz layout e nunca passa da régua);
   o cavaleiro anda por left, porque em transform ele precisaria ter a largura da régua e sairia da tela. */
.rail-rider { transition: left 220ms cubic-bezier(.2, .8, .2, 1); }
.rail-fill { transform-origin: left; transition: transform 220ms cubic-bezier(.2, .8, .2, 1); }
@media (prefers-reduced-motion: reduce) {
  .rail-rider, .rail-fill { transition: none; }
}

/* Carregando (componente Loading): a espera do app tem uma forma só, o cavaleiro de sinal da régua de estado
   percorrendo um trilho curto. Antes cada tela inventava a sua — texto solto, círculo do Radzen, ampulheta de
   estado vazio, esqueleto pulsando. Precisa de classe porque o Radzen não tem indicador indeterminado com esta
   forma, e porque keyframes e prefers-reduced-motion não cabem no Style de um componente (o mesmo motivo do
   rail-rider). A geometria é a da régua: trilho de 2 px, cavaleiro de 16×14 px com o topo levemente arredondado. */
.load-rail { position: relative; width: 132px; height: 14px; flex: none; }
.load-rail::before { content: ""; position: absolute; left: 0; right: 0; top: 6px; border-top: 2px solid var(--border); }
.load-rider {
  position: absolute; left: 0; top: 0; width: 16px; height: 14px; --load-travel: 116px;
  border-radius: 3px 3px 2px 2px; background: var(--accent-solid);
  box-shadow: inset 0 2px 0 oklch(100% 0 0 / .35), 0 1px 2px oklch(0% 0 0 / .25);
}
/* Vai e volta de ponta a ponta do trilho (a largura menos os 16 px do cavaleiro), com a desaceleração nas duas
   pontas. O percurso é variável para a tela de partida poder alargar o trilho sem repetir a animação. */
@keyframes load-run { from { transform: translateX(0); } to { transform: translateX(var(--load-travel)); } }
@media (prefers-reduced-motion: no-preference) {
  .load-rider { animation: load-run 1.7s cubic-bezier(.45, 0, .55, 1) infinite alternate; }
}
/* Sem movimento, o cavaleiro para no meio do trilho e quem diz que a tela está carregando é o texto ao lado,
   que a espera sempre traz escrito. O mesmo vale para a onda de tinta do esqueleto do Radzen, que não tem
   parâmetro nem variável para desligar por media query. */
@media (prefers-reduced-motion: reduce) {
  .load-rider { transform: translateX(calc(var(--load-travel) / 2)); }
  .rz-skeleton { animation: none; }
}
/* Na abertura, três fichas se organizam num ciclo calmo. A logo oficial fica parada; a animação é só
   do arquivo. O mesmo markup aparece antes do Blazor e enquanto a sessão é preparada. */
.loading-screen { gap: 28px; }
.loading-screen img { width: 172px; max-width: 100%; height: auto; }
.loading-screen p { margin: 0; font-size: 16px; line-height: 1.5; color: var(--steel-muted); }
.load-arrangement { display: flex; align-items: center; justify-content: center; gap: 40px; max-width: 100%; }
.load-cards { width: 64px; height: 60px; position: relative; flex: none; }
.load-cards span {
  position: absolute; inset: 8px 0 0; height: 40px; border: 1px solid var(--steel-muted);
  border-radius: 4px; background: var(--steel-raised); transform-origin: 50% 100%;
}
.load-cards span:nth-child(1) { transform: translateY(-8px) rotate(-8deg); }
.load-cards span:nth-child(2) { transform: translateY(-4px) rotate(-4deg); }
.load-cards span:nth-child(3) { background: var(--insert); border-color: var(--insert); }
.load-cards span:nth-child(3)::after {
  content: ""; position: absolute; left: 9px; right: 9px; top: 11px; height: 3px;
  border-top: 1px solid var(--rule); border-bottom: 1px solid var(--rule);
}
@media (max-width: 420px) { .load-arrangement { flex-direction: column; gap: 30px; } }
@keyframes load-card-back {
  0%, 100% { transform: translateY(-8px) rotate(-8deg); }
  40%, 60% { transform: translateY(-12px) rotate(-12deg); }
}
@keyframes load-card-middle {
  0%, 100% { transform: translateY(-4px) rotate(-4deg); }
  40%, 60% { transform: translateY(-6px) rotate(0deg); }
}
@keyframes load-card-front {
  0%, 100% { transform: translateY(0) rotate(0deg); }
  40%, 60% { transform: translateY(-3px) rotate(6deg); }
}
@media (prefers-reduced-motion: no-preference) {
  .load-cards span { animation-duration: 2.8s; animation-timing-function: cubic-bezier(.22, 1, .36, 1); animation-iteration-count: infinite; }
  .load-cards span:nth-child(1) { animation-name: load-card-back; }
  .load-cards span:nth-child(2) { animation-name: load-card-middle; }
  .load-cards span:nth-child(3) { animation-name: load-card-front; }
}

/* Alvo do toque nos desenhos do passo a passo (/instalar, DeviceSketch): o anel azul da ação pulsa duas vezes sobre o
   botão desenhado e descansa, como um dedo mostrando onde tocar. Precisa de classe pelo mesmo motivo do load-rider:
   keyframes e prefers-reduced-motion não cabem no Style, e o desenho sai como SVG montado em texto. Sem movimento,
   fica só o anel parado, que já marca o ponto. */
.tap-pulse { transform-box: fill-box; transform-origin: center; opacity: 0; }
@keyframes tap-pulse {
  0% { transform: scale(1); opacity: .85; }
  28% { transform: scale(1.22); opacity: 0; }
  29% { transform: scale(1); opacity: 0; }
  30% { transform: scale(1); opacity: .85; }
  58% { transform: scale(1.22); opacity: 0; }
  100% { transform: scale(1.22); opacity: 0; }
}
@media (prefers-reduced-motion: no-preference) {
  .tap-pulse { animation: tap-pulse 2.6s cubic-bezier(.22, 1, .36, 1) .3s infinite; }
}
