@charset "UTF-8";
/* =============================================================================
   FORJA: CSS da camada de câmera (static/js/camera/camada.js)
   -----------------------------------------------------------------------------
   Só o que o forja.css não tem: o quadro do preview com a caixa canônica, o
   fantasma por composição CSS, as guias, o obturador e a ancoragem medida dos
   controles. Botões, chips, selos, faixa e spinner vêm do design system.
   Nenhum hex solto: tudo em token, salvo branco/preto com alpha (mesmo
   critério das bordas do forja.css).

   O fantasma é `<video>` ao vivo + `<img>` por cima, com opacity e (no modo
   precisão) mix-blend-mode: difference. Composição de GPU, custo desprezível,
   funciona em qualquer resolução; o canvas entra UMA vez, no disparo.
   ============================================================================= */

/* --- A camada, de borda a borda ------------------------------------------- */

.fj-camada--camera {
  padding-inline: 0;
  padding-block-end: 0;
  background: var(--fj-fundo);
}

.fj-camada--camera .fj-camada__topo {
  padding-inline: var(--fj-gutter);
  padding-block-end: var(--fj-e-4);
}

/* O X sobre a mídia: mesmo desenho do `--sobre-midia` do design system. */
.fj-camada--camera .fj-camada__topo .fj-icon-btn {
  background: rgba(0, 0, 0, .45);
  border-color: rgba(255, 255, 255, .12);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
}

/* --- Corpo ------------------------------------------------------------------ */

.fj-cam {
  /* Lido pelo JS (getComputedStyle) para somar a safe area à folga do
     obturador. Fica em custom property porque env() não é legível de outro
     jeito. */
  --fj-cam-safe-base: env(safe-area-inset-bottom, 0px);
  --fj-cam-fantasma: .35;

  position: relative;
  flex: 1;
  min-block-size: 0;
  inline-size: 100%;
  color: var(--fj-txt-1);
}

/* --- Palco e quadro --------------------------------------------------------- */

.fj-cam__palco {
  position: absolute;
  inset-block-start: 0;
  inset-inline: 0;
  block-size: var(--fj-cam-palco-altura, 60%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--fj-e-4);
  padding-inline: 0;
}

/* O quadro tem a proporção da caixa canônica. Largura e altura vêm do JS a
   partir do espaço disponível: CSS `aspect-ratio` sozinho não encolhe a
   largura quando a altura bate no teto. `--fj-cam-alvo` fica como reforço. */
.fj-cam__quadro {
  position: relative;
  overflow: hidden;
  inline-size: var(--fj-cam-quadro-l, 100%);
  block-size: var(--fj-cam-quadro-a, auto);
  aspect-ratio: var(--fj-cam-alvo, 3 / 4);
  background: rgba(0, 0, 0, .6);
  border-radius: var(--fj-r-md);
  flex: none;
}

/* Vídeo, fantasma e quadro congelado: a MESMA caixa, todos em cover. Como a
   proporção do contêiner é a da caixa canônica, o `cover` mostra exatamente o
   que o drawImage recorta. */
.fj-cam__video,
.fj-cam__fantasma,
.fj-cam__congelado {
  position: absolute;
  inset: 0;
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
  display: block;
}

.fj-cam__video { background: rgba(0, 0, 0, .8); }

.fj-cam__fantasma {
  opacity: var(--fj-cam-fantasma);
  pointer-events: none;
  user-select: none;
  -webkit-user-select: none;
}

/* Modo precisão: alinhou = escurece. */
.fj-cam__fantasma.is-precisao {
  opacity: 1;
  mix-blend-mode: difference;
}

/* Silhueta (sem foto anterior da pose): branco com a mesma opacidade. */
.fj-cam__fantasma--silhueta {
  fill: rgba(255, 255, 255, .85);
  stroke: rgba(255, 255, 255, .95);
  stroke-width: 2;
  stroke-linejoin: round;
}

.fj-cam__congelado { background: var(--fj-fundo); }

/* Guias por perfil. */
.fj-cam__guia {
  position: absolute;
  inset: 0;
  inline-size: 100%;
  block-size: 100%;
  pointer-events: none;
  color: rgba(255, 255, 255, .85);
}

.fj-cam__guia-veu { fill: rgba(0, 0, 0, .38); }

.fj-cam__guia-moldura {
  fill: none;
  stroke: currentColor;
  stroke-width: 2px;
  stroke-dasharray: 10 6;
}

.fj-cam__guia-eixo {
  stroke: rgba(255, 255, 255, .45);
  stroke-width: 1px;
  stroke-dasharray: 6 6;
}

/* Na revisão do rótulo a imagem já É o recorte da moldura: a moldura some. */
.fj-cam[data-estado="revisando"][data-perfil="rotulo"] .fj-cam__guia,
.fj-cam[data-estado="enviando"][data-perfil="rotulo"] .fj-cam__guia { opacity: 0; }

/* Selo do ângulo (Frente / Lateral / Costas). */
.fj-cam__selo {
  position: absolute;
  inset-block-start: var(--fj-e-6);
  inset-inline-start: var(--fj-e-6);
  padding: var(--fj-e-3) var(--fj-e-6);
}

/* Contagem regressiva do temporizador. */
.fj-cam__contagem {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  font-family: var(--fj-fonte-num);
  font-size: 96px;
  font-weight: var(--fj-w-forte);
  line-height: var(--fj-lh-1);
  color: var(--fj-txt-1);
  text-shadow: 0 2px 24px rgba(0, 0, 0, .6);
  pointer-events: none;
  animation: fj-cam-pulso 1s var(--fj-ease-saida) infinite;
}

@keyframes fj-cam-pulso {
  from { opacity: 1; scale: 1; }
  to   { opacity: .6; scale: .92; }
}

/* Véu de estado sobre o palco (quadro + dica): abrindo, ocioso, suspensa,
   erro. Rola se não couber, em vez de cortar botão. */
.fj-cam__veu {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--fj-e-6);
  padding: var(--fj-e-11) var(--fj-gutter);
  text-align: center;
  overflow-y: auto;
  background: rgba(11, 7, 20, .72);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}

.fj-cam__veu[data-tipo="erro"] { background: rgba(11, 7, 20, .9); }

.fj-cam__veu-titulo {
  font-size: var(--fj-fs-3xl);
  font-weight: var(--fj-w-forte);
  letter-spacing: var(--fj-ls-leve);
  outline: none;
}

.fj-cam__veu-texto {
  max-inline-size: 300px;
  font-size: var(--fj-fs-md);
  line-height: var(--fj-lh-corpo);
  color: var(--fj-txt-2);
}

.fj-cam__veu-nota {
  max-inline-size: 300px;
  font-size: var(--fj-fs-sm);
  line-height: var(--fj-lh-corpo);
  color: var(--fj-txt-3);
}

.fj-cam__veu-acoes {
  display: flex;
  flex-direction: column;
  gap: var(--fj-e-4);
  inline-size: 100%;
  max-inline-size: 300px;
  margin-block-start: var(--fj-e-4);
}

.fj-cam__spinner {
  inline-size: 28px;
  block-size: 28px;
  border-radius: 50%;
  border: 3px solid rgba(255, 255, 255, .25);
  border-top-color: var(--fj-txt-1);
  animation: fj-girar .8s linear infinite;
}

/* Dica de enquadramento e faixa de degradação, abaixo do quadro. */
.fj-cam__dica {
  padding-inline: var(--fj-gutter);
  font-size: var(--fj-fs-md);
  line-height: var(--fj-lh-corpo);
  text-align: center;
  color: var(--fj-txt-2);
}

.fj-cam__faixa {
  inline-size: auto;
  margin-inline: var(--fj-gutter);
}

/* --- Controles, ancorados por medição ---------------------------------------
   Até o JS medir, o fallback é a safe area mais 62 px acima do fundo do
   contêiner. Depois da medição (`.is-medido`), o topo é o número calculado a
   partir do visualViewport: o obturador fica a >= 62 px do fundo VISÍVEL da
   tela, independente do que o containing block fixed acha que é a tela. */

.fj-cam__controles {
  position: absolute;
  inset-inline: 0;
  inset-block-end: calc(var(--fj-cam-safe-base) + 62px);
  display: flex;
  flex-direction: column;
  gap: var(--fj-e-6);
  padding-inline: var(--fj-gutter);
}

.fj-cam.is-medido .fj-cam__controles {
  inset-block-end: auto;
  inset-block-start: var(--fj-cam-controles-top, 0px);
}

.fj-cam__linha {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: var(--fj-e-6);
}

.fj-cam__lado {
  display: flex;
  align-items: center;
  gap: var(--fj-e-4);
}

.fj-cam__lado--dir { justify-content: flex-end; }

/* Obturador: 76 de caixa, anel branco e miolo branco. */
.fj-cam__obturador {
  position: relative;
  inline-size: 76px;
  block-size: 76px;
  border-radius: 50%;
  border: 4px solid var(--fj-txt-1);
  background: transparent;
  padding: 0;
  cursor: pointer;
  transition: transform var(--fj-dur-instante) var(--fj-ease-saida),
              opacity   var(--fj-dur-rapida)   var(--fj-ease-saida);
}

.fj-cam__obturador::before {
  content: "";
  position: absolute;
  inset: 4px;
  border-radius: 50%;
  background: var(--fj-txt-1);
  transition: transform var(--fj-dur-instante) var(--fj-ease-saida);
}

.fj-cam__obturador:active:not(:disabled)::before { transform: scale(.88); }

.fj-cam__obturador:disabled {
  opacity: var(--fj-desativado-opacidade);
  cursor: not-allowed;
}

/* Capturando / enviando sem revisão: o miolo vira spinner. */
.fj-cam__obturador.is-carregando::before { background: rgba(255, 255, 255, .25); }

.fj-cam__obturador.is-carregando::after {
  content: "";
  position: absolute;
  inset: 50% auto auto 50%;
  translate: -50% -50%;
  inline-size: 28px;
  block-size: 28px;
  border-radius: 50%;
  border: 3px solid rgba(255, 255, 255, .3);
  border-top-color: var(--fj-txt-1);
  animation: fj-girar .8s linear infinite;
}

/* Sobre o vídeo, o anel branco de foco some: anel escuro por dentro. */
.fj-cam__obturador:focus-visible {
  outline-color: var(--fj-foco-interno);
  box-shadow: 0 0 0 6px var(--fj-foco);
}

/* Linha do fantasma: rótulo + slider + chip Precisão. */
.fj-cam__fantasma-controles {
  display: flex;
  align-items: center;
  gap: var(--fj-e-6);
}

.fj-cam__fantasma-controles .fj-rotulo { flex: none; }

/* Slider nativo com a cor do módulo de peso; 44 px de alvo. */
.fj-cam__slider {
  flex: 1;
  min-inline-size: 0;
  block-size: var(--fj-toque);
  margin: 0;
  accent-color: var(--fj-ciano);
  cursor: pointer;
}

.fj-cam__slider:focus-visible {
  outline: var(--fj-foco-largura) solid var(--fj-foco);
  outline-offset: var(--fj-foco-folga);
  border-radius: var(--fj-r-pill);
}

/* Linha de revisão: Refazer / Usar foto. */
.fj-cam__revisao {
  display: grid;
  grid-template-columns: 1fr 1.4fr;
  gap: var(--fj-e-6);
}

/* --- Preferências do sistema ------------------------------------------------ */

@media (prefers-reduced-motion: reduce) {
  .fj-cam__contagem { animation: none; }
  /* Spinner é leitura de estado: continua, como no design system. */
  .fj-cam__spinner,
  .fj-cam__obturador.is-carregando::after { animation: fj-girar 1.2s linear infinite !important; }
}

@media (prefers-reduced-transparency: reduce) {
  .fj-cam__veu,
  .fj-camada--camera .fj-camada__topo .fj-icon-btn {
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }
  .fj-cam__veu { background: rgba(11, 7, 20, .94); }
}

/* Telas baixas: contagem e obturador menores para o quadro não sumir. */
@media (max-height: 700px) {
  .fj-cam__obturador { inline-size: 66px; block-size: 66px; }
  .fj-cam__contagem { font-size: 72px; }
}
